Fornecendo uma tabela de 10 pontos por exemplo (P,V(P)), podemos obter o resultado abaixo.
Uma Discretização não uniforme em P pode melhor em muito os resultados acima.
Código completo em Maple
O código em Maple a seguir é o resultado da generalização para quaisquer valor de m.
restart;
#############################
n := 2;
a := 3.64;
b := 0.0427;
T := 300;
R := 0.082;
Pini := 5.0;
Pfin := 40;
#############################
m := 10;
#############################
pressures := [seq(Pini + i*(Pfin - Pini)/m, i = 0 .. m)];
#############################
av := P -> P;
bv := P -> -P*n*b - n*R*T;
cv := a*n^2;
dv := -a*n^3*b;
#############################
h := P -> fsolve({av(P)*Vex^3 + bv(P)*Vex^2 + cv*Vex + dv = 0}, {Vex});
#############################
dados := [seq([P, rhs(h(P)[1])], P = Pini .. Pfin, 0.1)];
plot1 := plot(dados, color = red, style = point, symbol = circle, linestyle = dot, thickness = 3, legend = "numerico");
#############################
volumes := [seq(rhs(h(pressures[i])[1]), i = 1 .. m + 1)];
#############################
intervals := [];
ak_list := [];
bk_list := [];
for i to nops(pressures) - 1 do
P10 := pressures[i];
P20 := pressures[i + 1];
U10 := volumes[i];
U20 := volumes[i + 1];
ak := (U20 - U10)/(P20 - P10);
bk := (P10*U20 - P20*U10)/(P10 - P20);
ak_list := [op(ak_list), ak];
bk_list := [op(bk_list), bk];
intervals := [op(intervals), P10 <= P and P <= P20, P*ak + bk];
end do;
#############################
f := piecewise(op(intervals));
U := unapply(f, P);
#############################
a1 := P -> 3*U(P)^2*av(P) + 2*U(P)*bv(P) + cv;
b1 := P -> U(P)^3*av(P) + U(P)^2*bv(P) + cv*U(P) + dv;
theta := P -> -b1(P)/a1(P);
#############################
V := P -> theta(P) + U(P);
#############################
plot2 := plot(V(P), P = Pini .. Pfin, color = blue, style = line, symbol = point, linestyle = spacedash, thickness = 3, legend = "V(P)");
plot3 := plot(U(P), P = Pini .. Pfin, color = black, style = line, symbol = point, linestyle = dashdot, thickness = 3, legend = "U(P)");
plots[display]({plot1, plot2, plot3}, axes = boxed, labels = ["Pressão(atm)", "Volume(Litros)"], axis = [gridlines = [14, color = gray]], labeldirections = ["horizontal", "vertical"]);
Erro := [seq([P, 100*abs((rhs(h(P)[1]) - V(P))/rhs(h(P)[1]))], P = Pini .. Pfin, 0.1)];
plot4 := plot(Erro, color = black, style = line, symbol = circle, linestyle = dashdot, thickness = 3, legend = "SAAMM");
plots[display]({plot4}, axes = boxed, labels = ["Pressão(atm)", "Erro(%)"], axis = [gridlines = [14, color = gray]], labeldirections = ["horizontal", "vertical"], view = [Pini .. Pfin, 0 .. 100]);
Existem várias variações que podem ser realizadas neste projeto, como por exemplo, considerar uma divisão de pressões não-uniforme de modo a melhorar a precisão para um determinado número m de divisões no intervalo de pressões por exemplo. Ou ainda, considerar a aproximação parabólica em teta. (…->). Esses rascunhos representam apenas o início de uma nova abordagem. O método apresentado tem o potencial de abrir portas para a criação de diversas estratégias com o objetivo de melhorar significativamente a precisão. A flexibilidade oferecida permite não apenas ajustes pontuais, mas também o desenvolvimento de soluções adaptativas, possibilitando um refinamento contínuo e otimizações conforme necessário.
- Para m=1: Linearização única no intervalo inteiro, maior erro. (…->)
- Para m=2: Melhor aproximação com dois segmentos. (…->)
- Para m=3: Refinamento ainda maior, com possibilidades de erro relativo no resultado final, significativamente reduzido. (…->)
- Assim por diante. Generalização para m. (…->)
- Generalização para m com ajuste parabólico. (…->)