Bon, j'ai essayé de séparer les problèmes.
Grâce à un premier programme asymptote, je génère un fichier contenant, pour une température sous critique (t<1), la pression p du palier de liquéfaction ainsi que les deux volumes vmin et vmax le limitant. Cela est déterminé grâce à la méthode des aires de Maxwell et grâce à la méthode développée par Gaétan précédemment.
Code : Tout sélectionner
// Ce programme détermine les valeurs de v pour le palier de liquéfaction
// à t constant.
import graph;
file fichier=output("palier-isoT.dat");
// Volume minimal et maximal utilisés pour le calcul.
real vmin=1/3+0.000001;
real vmax=30;
// Précision du calcul d'aire (dichotomie)
real precision=.0001;
// Nombre de points pour le graphe (ne doit pas être trop petit)
int nb_points=1000;
// Intervalle de calcul
int imin=-30,imax=0;
// Les lignes commençant par # sont ignorées lors de la lecture
write(fichier,"# Nb de paliers déterminés",suffix=newl);
write(fichier,imax-imin+1,suffix=newl);
write(fichier,"# T p Vmin Vmax",suffix=newl);
real a,b,c,diff_aires,t;
path C_isotherme_VdW,Cg;
real[] v_palier_inter_isotherme_VdW;
path C_palier;
// Boucle sur différentes valeurs de la température réduite
for(int i=imin; i<imax; ++i){
t=1+i/100;
write(t);
write(fichier,t,suffix=tab);
// Équation de Van der Waals en coordonnées réduites
real p(real v){return 8*t/(3*v-1)-3/v^2;}
// La courbe représentant l'isotherme de Van der Waals est calculée
C_isotherme_VdW=graph(p,vmin,vmax,n=nb_points,Spline);
if(t>=1){
// On ne fait rien : pas de palier
}
else{
// On détermine la pression du palier par dichotomie (aires de Maxwell)
Cg=subpath(C_isotherme_VdW,
dirtime(C_isotherme_VdW,(1,0)),
reltime(C_isotherme_VdW,1));
Cg=subpath(Cg,0,maxtimes(Cg)[1]);
a=max(min(Cg).y,.02);
b=max(Cg).y;
diff_aires=2*precision;
while(abs(diff_aires)>precision)
{
c=(a+b)/2;
v_palier_inter_isotherme_VdW=times(C_isotherme_VdW,(0,c));
real g(real v){return p(v)-c;}
diff_aires=simpson(g,
point(C_isotherme_VdW,
v_palier_inter_isotherme_VdW[0]).x,
point(C_isotherme_VdW,
v_palier_inter_isotherme_VdW[2]).x);
if(diff_aires<0) b=c; else a=c;
}
// Construction du palier (la pression réduite de liquéfaction vaut c)
real h(real v){return c;}
write(fichier,c,suffix=tab);
// Deux points suffisent pour construire une droite
C_palier=graph(h,vmin,vmax,n=2);
real[] v_palier_inter_isotherme_VdW=times(C_isotherme_VdW,(0,c));
if(v_palier_inter_isotherme_VdW.length==3){
write(fichier,point(C_isotherme_VdW,
v_palier_inter_isotherme_VdW[0]).x,
suffix=tab);
write(fichier,point(C_isotherme_VdW,
v_palier_inter_isotherme_VdW[2]).x,
suffix=newl);}
}
}
Cela me donne le fichier palier-isoT.dat suivant
Code : Tout sélectionner
# Nb de paliers déterminés
31
# T p Vmin Vmax
0.7 0.200817 0.478516 7.79394
0.71 0.215621 0.479583 7.29381
0.72 0.23111 0.478963 6.83434
0.73 0.247478 0.480431 6.40532
0.74 0.264582 0.485125 6.00952
0.75 0.282471 0.491785 5.64273
0.76 0.301115 0.497957 5.30333
0.77 0.320478 0.502493 4.98969
0.78 0.340633 0.506436 4.69795
0.79 0.361604 0.511318 4.4259
0.8 0.383351 0.517601 4.17263
0.81 0.405957 0.524514 3.93529
0.82 0.429316 0.531217 3.71414
0.83 0.453511 0.53791 3.50668
0.84 0.478565 0.545172 3.31154
0.85 0.504515 0.553314 3.12739
0.86 0.531254 0.562044 2.95446
0.87 0.558876 0.571147 2.79085
0.88 0.587332 0.5809 2.63625
0.89 0.616731 0.591715 2.48892
0.9 0.647006 0.603374 2.34879
0.91 0.678116 0.616077 2.21539
0.92 0.710181 0.630233 2.08714
0.93 0.743224 0.645873 1.96314
0.94 0.77699 0.6637 1.8444
0.95 0.811886 0.684104 1.72703
0.96 0.847671 0.708114 1.61141
0.97 0.884393 0.737447 1.49521
0.98 0.921802 0.775763 1.37719
0.99 0.960312 0.831745 1.24546
Donc, les paliers, c'est fait une fois pour toute (au pire, si besoin est, on peut affiner, avoir plus de valeurs, mais je pense que c'est inutile).
Ensuite, j'ai fait le code suivant pour afficher les isothermes en 3D.
Code : Tout sélectionner
import graph3;
size3(150,IgnoreAspect);
size(8cm,0);
file fichier=input("palier-isoT.dat",comment="#");
int nb_palier=fichier;
write(nb_palier);
real[] t_palier,p_palier,vmin_palier,vmax_palier;
for(int i=0;i < nb_palier; ++i){
t_palier[i]=fichier;
p_palier[i]=fichier;
vmin_palier[i]=fichier;
vmax_palier[i]=fichier;
}
real t;
real vmin=1/3+0.12;
real vmax=5;
path3 C_isotherme_Andrews_liquide,C_isotherme_Andrews_vapeur,
C_isotherme_Andrews_liquide_vapeur,C_isotherme_Andrews;
int nb_points=20;
pen couleur_hypercritique = red;
pen couleur_liquide = .5green;
pen couleur_vapeur = purple;
pen couleur_liquide_vapeur = couleur_liquide + couleur_vapeur;
for(int i=4;i < nb_palier-1; ++i){
real t(real v){return t_palier[i];}
write(t_palier[i]);
real p(real v){return 8*t(v)/(3*v-1)-3/v^2;}
real v3D(real v){return v;}
C_isotherme_Andrews_liquide=graph(v3D,t,p,vmin,vmin_palier[i],n=nb_points,Spline);
draw(C_isotherme_Andrews_liquide,couleur_liquide);
C_isotherme_Andrews_vapeur=graph(v3D,t,p,vmax_palier[i],vmax,n=nb_points,Spline);
draw(C_isotherme_Andrews_vapeur,couleur_vapeur);
C_isotherme_Andrews_liquide_vapeur=(vmin_palier[i],t_palier[i],p_palier[i]) --
(vmax_palier[i],t_palier[i],p_palier[i]);
draw(C_isotherme_Andrews_liquide_vapeur,couleur_liquide_vapeur);
C_isotherme_Andrews=C_isotherme_Andrews_liquide --
C_isotherme_Andrews_liquide_vapeur -- C_isotherme_Andrews_vapeur;
// draw(C_isotherme_Andrews,couleur_liquide_vapeur);
}
limits((0,0,0),(5,1.5,4));
// Les quatres lignes qui suivent permettront dans la majorité
// des cas, d'avoir un angle de vue convenable.
triple m=currentpicture.userMin;
triple M=currentpicture.userMax;
triple target=0.5*(m+M);
currentprojection=perspective(camera=target+realmult(dir(50,40),M-m),
target=target);
xaxis3(Bounds(),OutTicks(endlabel=false),p=blue);
yaxis3(Bounds(),OutTicks(),p=red);
zaxis3(Bounds(),OutTicks,p=.8green);
write("Hypercritique");
for(real t=1;t < 1.1; t=t+.01){
real t3D(real v){return t;}
write(t);
real p(real v){return 8*t/(3*v-1)-3/v^2;}
real v(real v){return v;}
C_isotherme_Andrews=graph(v,t3D,p,vmin,vmax,n=2*nb_points,Spline);
draw(C_isotherme_Andrews,couleur_hypercritique);
}
Bon, ça commence à ressembler à quelque chose. Mais j'ai quelques soucis. Déjà, le point de vue donné par la camera n'est pas le bon et j'ai beau faire de l'essai/erreur, ça ne fonctionne pas. Ensuite, j'ai quelques lignes en purple qui dépassent du cadre et je ne comprends pas bien pourquoi. Enfin, je ne comprends pas l'utilisation de Crop en 3D, donc les courbes dépassent des limites. Bref, j'aurais encore besoin d'un petit coup de main. Si quelqu'un passe par là...
Merci d'avance
--
Christophe