In questo notebook usiamo il programma Python melt_perplex.py che implementa un algoritmo in stile Perplex per il calcolo delle composizioni delle fasi solida e liquida in equilibrio a fissate condizioni P/T, nel caso dell'olivina.
Come di consueto, lanciamo il programma, usiamo matplotlib nella versione inline.
Il programma fa riferimento a un database termodinamico (perplex2_db.dat) che contiene i dati rilevanti, relativi ai termini puri che ci interessano nel caso specifico; questi vengono elencati non appena il programma venga lanciato e il database sia caricato:
%matplotlib inline
%run melt_perplex.py
import inspect as ins
Il programma implementa anche tutte le funzioni già usate in precedenza per il calcolo dell'equilibrio solido-liquido, che facevano uso delle funzioni della libreria scipy e che avevamo usato per la minimizzazione dell'energia libera. In particolare, la funzione melt, il cui uso è descritto dall'help:
help(melt)
melt(nt=20,nt_prt=10,ideal=True)
Qui abbiamo fatto un calcolo a pressione 0 (il valore di default per ip), specificando il parametro di Margules W=8400 j/mole (il valore di default).
La funzione composition ci restituisce le composizioni e le quantità relative di fase solida e liquida a P e T fissate, per una certa composizione globale del sistema. Per esempio, a T=1700 K, P=0 GPa e X(Mg) totale pari a 0.40 (con W=8400 j/mole) abbiamo:
composition(1700,0,8400,prt=True,xval=0.4)
Bene, fino a qui è storia già vista nelle esercitazioni precedenti. Usiamo adesso la nuova funzione perplex, il cui input è descritto nell'help:
help(perplex)
In primo luogo, la funzione procede definendo una griglia nello spazio X/Q (composizioni delle fasi/quantità relativa delle fasi). Questo compito è assegnato alla funzione perplex_comp, richiamata da perplex che gli fornisce la composizione globale del sistema in termini di frazione molare X(Mg) (inat). La funzione perplex_com provvede a definire un certo numero di pseudocomposti con composizione X(Mg)s (frazione molare di Mg nella fase solida) e, al variare delle rispettive quantità molari qs e ql di fase solida e liquida (qs è l'altro asse della griglia XQ), si calcola le corrispondenti composizioni della fase liquida.
Questo calcolo procede assumendo che $q^{tot}=q^S + q^L=1$ [una mole complessiva di $\rm (Mg,Fe)_2SiO_4$ in solido + liquido ]
La griglia X/Q è costruita facendo variare $x_{\rm Mg}^S$ e $q^S$ tra 0 e 1 in nx punti (nx è un argomento opzionale di perplex, il cui default è pari a 20).
Naturalmente non tutte le coppie $(x_{\rm Mg}^S, q^S)$ (i punti della griglia) sono lecite data la composizione globale $x_{\rm Mg}^{tot}$: se per esempio fosse $x_{\rm Mg}^{tot}=0.5$, avremmo 0.5 moli di Mg nel sistema complessivo $q^S+q^L$; in tal caso un punto $(x_{\rm Mg}^S, q^S)=(1,1)$, che equivale ad avere $n_{\rm Mg}^S=x_{\rm Mg}^Sq^S=1$, non sarebbe compatibile con $n_{\rm Mg}^{tot}=0.5$ (ovviamente dovrebbe essere $n_{\rm Mg}^{S} < n_{\rm Mg}^{tot}$). Tutte le coppie di punti XQ non compatibili con la composizione globale (inat) portano a valori di $x_{\rm Mg}^L$ fuori dall'intervallo [0,1] (una frazione molare è, per definizione, compresa tra 0 e 1...) e sono quindi scartate dalla funzione perplex_comp.
Il codice della funzione perplex_comp è mostrato nella cella successiva
print(ins.getsource(perplex_comp))
Ottenuta la griglia da perplex_comp, la funzione perplex calcola l'energia libera complessiva per ogni punto XQ della griglia, secondo l'equazione:
$$\mu(x,q) = q^S\mu(x^S)+q^L\mu(x^L)$$Si noti che, in ogni fase, $x_{\rm Fe}=1-x_{\rm Mg}$. La funzione perplex è riportata nella cella seguente:
print(ins.getsource(perplex))
Le due istruzioni chiave di perplex sono
xas_l, xal_l,qs_l,ql_l,chk_l=perplex_comp(inat,nx)
mu_l=perplex_g(it,ip,xas_l,xal_l,qs_l,ql_l,W)
La prima istruzione chiama perplex_comp per ottenere la griglia XQ; la seconda calcola l'energia di Gibbs alla T e P fissata e per tutti i nodi leciti della griglia, le cui coordinate sono conservate nelle liste xas_l (lista di $x_{\rm Mg}^S$), xal_l ($x_{\rm Mg}^L$), qs_l ($q^S$) e ql_l ($q^L$). Per ogni punto, G è calcolata usando la funzione perplex_g.
Usiamo perplex per fare un calcolo a T=1700 K, P=0 GPa e $x_{\rm Mg}^{tot}=0.40$ (con parametro di Margules W=8400 j/mole):
perplex(1700,0,0.40,8400)
La funzione fornisce anche una visualizzazione della griglia di punti XQ che è stata definita. Il marker in rosso identifica il punto della griglia che ha la più bassa energia libera e che quindi corrisponde alla situazione all'equilibrio.
Notate come il risultato sia praticamente identico a quello ottenuto con la funzione composition che usava una strategia di calcolo differente.
Nel caso specifico, l'algoritmo perplex è molto più lento rispetto a quello implementato in composition. I tempi di esecuzione sono stimabili con la funzione time (funzione di sistema di Python):
time(composition(1700,0,8400,prt=True,xval=0.4))
la funzione time esegue composition con il suo input, e scrive come ultima riga dell'output, il tempo di esecuzione (Wall time, che è il tempo complessivo di esecuzione). Qui abbiamo un tempo di esecuzione intorno ai 100 ms (millisecondi).
Con l'algoritmo perplex i tempi di calcolo sono ben più lunghi:
time(perplex(1700,0,0.40,8400))
siamo intorno ai 10 secondi. L'argoritmo perplex è meno efficiente dal punto di vista computazionale (tempi di calcolo lunghi), inoltre l'accuratezza dei risultati dipende dalla densità della griglia: tanti più punti abbiamo nella griglia, tanto maggiore è l'accuratezza del calcolo, ma tanto più aumenta il tempo di calcolo. Proviamo a rifare lo stesso calcolo passando da nx=20 (il default) a nx=40:
time(perplex(1700,0,0.40,8400,nx=40))
Siamo passati da 10 secondi a 40 secondi...
Tuttavia l'algoritmo perplex è quello usato nel programma PerpleX di Connolly perchè è molto più facile da implementare per un numero in generale molto alto di fasi da prendere simultaneamente in considerazione e per una chimica a molte componenti (nei nostri esempi abbiamo solo due fasi e due componenti...). In tal caso le tecniche di minimizzazione di una funzione (G) in uno spazio N-dimensionale (dove N diventa un numero molto grande al crescere della complessità chimica del sistema) come quelle usate in composition, diventano praticamente inapplicabili. Inoltre PerpleX è magistralmente ottimizzato per funzionare velocemente (ed è anche un programma scritto in un linguaggio compilato e non interpretato come Python, ma sorvoliamo su questi dettagli): i tempi di calcolo sono ben inferiori a quelli dati qui, per un sistema così semplice.