Optimisation de la température caractéristique du diamant suivant le modèle d039;Einstein
Ce modèle prévoie la dépendance à la température de la capacité calorifique d’un solide cristallin.
La détermination de la température caractéristique nécessite de “fitter” les données expérimentales en suivant une relation impliquant un paramètres qui sera optimisé pour minimiser la somme des carrés des écarts entre les valeurs modélisées et les valeurs expérimentales.
Le programme Python nécessite les librairies scipy (optimisation), numpy (manipulation des données) et matplotlib (représentation du fit).
<sxh python; title : fit-Cv-diamant-Einstein-04.py> #!/usr/bin/env python # -*- coding: utf-8 -*- “”“ Fit des données (température absolue, chaleur spécifique molaire à volume constant Diamant Modèle d039;Einstein : http://fr.wikipedia.org/wiki/Mod%C3%A8le_d%27Einstein ”“” import numpy as np import scipy as sp from scipy.optimize import leastsq import matplotlib.pyplot as plt
def cvEinstein(Tr):
# fonction à fitter # Tr = température réduite = T/TE return 3.*NA*kB*(1./Tr)**2*sp.exp(1./Tr)/(sp.exp(1./Tr)-1)**2
def residuals(p,x,y):
# erreur entre y donné et y calculé return cvEinstein(x/p[0]) - y
kB = 1.3806488E-23 # Constante de Boltzmann NA = 6.02214129E23 # Nombre d039;Avogadro # données expérimentales (T, Cv) : liste_data=[ [12.9,0.00053], [16.1,0.00081], [19.8,0.00138], [24.1,0.00257], [30.1,0.00494], [33.4,0.0074], [41.3,0.0133], [47.7,0.02], [57.2,0.0365], [67,0.0595], [76.1,0.092], [87,0.147], [100.4,0.24], [113.1,0.378], [126.3,0.56], [143.4,0.88], [159,1.19], [176,1.66], [197,2.21], [215,2.61], [264,4.18], [273,5.2], [280,5.43], [306,6.59], [335,7.81], [363,9.02], [412,11.8], [471,14.6], [516,15.6], [874,22.3], [1079,22.4], [1238,22.7]]
# transformation en tableau numpy data=np.array(zip(*liste_data)) # cf. http://docs.python.org/2.7/library/functions.html#zip
p=[1000.] # valeur initiale de l039;unique paramètre recherché (TE) plsq = leastsq(residuals, p, args=(data[0], data[1])) # fit par moindre carré # Résultat : print “Température caractéristique suivant le modèle d039;Einstein: ”,plsq[0]
# graphe x=np.linspace(1.,1.5*plsq[0],200) plt.plot(x,cvEinstein(x/plsq[0]),data[0], data[1],039;o039;) plt.title(u039;Capacité calorifique du diamant : optimisation par moindre carré039;) #plt.legend([039;Fit039;, 039;Experimental039;]) plt.show() </sxh>
Le programme fourni comme température caractéristique pour le diamant 1275.76 K.
Voici la graphe obtenu :
La zone à basse température pour laquelle on constate que le modèle d039;Einstein n039;est pas suffisamment correct :
Le modèle de Debye, qui utilise un spectre de fréquences plutôt qu039;une fréquence unique de vibration, pourra remplacer le modèle d039;Einstein. Le calcul nécessite d039;utiliser les fonctions d039;intégration scipy.integrate.quad, qui oblige de contourner l039;utilisation des tableau numpy : les valeurs d039;un tableau à traiter sont considérées une par une et le tableau numpy est recréé immédiatement. Voici un programme :
<sxh python; title : fit-Cv-diamant-Debye-02.py> #!/usr/bin/env python # -*- coding: utf-8 -*- “”“ Fit des données (température absolue, chaleur spécifique molaire à volume constant Diamant Modèle de Debye : http://fr.wikipedia.org/wiki/Mod%C3%A8le_de_Debye ”“” import numpy as np import scipy as sp from scipy.optimize import leastsq from scipy import integrate from scipy.integrate import simps import matplotlib.pyplot as plt
def f(x):
return x**4.*sp.exp(x)/(sp.exp(x)-1.)**2.
def cvDebye(Tr):
# Chaleur spécifique théorique (modèle de Debye) # Tr = température réduite = T/TD # problème : integrate.quad n039;accepte pas le broadcast pour les limites a, b # http://newscentral.exsees.com/item/12e4126a47e3411a138f5a3820eb62d1-71278f2740f3cd9c3dff2da0d78b6bc7 #solution : if 039;array039; in str(type(Tr)): return 9.*NA*kB*(Tr)**3 *np.array([integrate.quad(f,0,1./each_Tr)[0] for each_Tr in Tr]) # array else: return 9.*NA*kB*(Tr)**3 * integrate.quad(f,0,1./Tr)[0] # float
def residuals(p,x,y):
# erreur entre y donné et y calculé return cvDebye(x/p[0]) - y
kB = 1.3806488E-23 # Constante de Boltzmann NA = 6.02214129E23 # Nombre d039;Avogadro # données expérimentales (T, Cv) : liste_data=[ [12.9,0.00053], [16.1,0.00081], [19.8,0.00138], [24.1,0.00257], [30.1,0.00494], [33.4,0.0074], [41.3,0.0133], [47.7,0.02], [57.2,0.0365], [67,0.0595], [76.1,0.092], [87,0.147], [100.4,0.24], [113.1,0.378], [126.3,0.56], [143.4,0.88], [159,1.19], [176,1.66], [197,2.21], [215,2.61], [264,4.18], [273,5.2], [280,5.43], [306,6.59], [335,7.81], [363,9.02], [412,11.8], [471,14.6], [516,15.6], [874,22.3], [1079,22.4], [1238,22.7]]
# transformation en tableau numpy data=np.array(zip(*liste_data)) # cf. http://docs.python.org/2.7/library/functions.html#zip
p=[1000.] # valeur initiale de l039;unique paramètre recherché (TE) plsq = leastsq(residuals, p, args=(data[0], data[1])) # fit par moindre carré # Résultat : print “Température caractéristique suivant le modèle de Debye: ”,plsq[0]
# graphe x=np.linspace(1.,1.5*plsq[0],200) plt.plot(x,cvDebye(x/plsq[0]),data[0], data[1],039;o039;) plt.title(u039;Capacité calorifique du diamant : optimisation par moindre carré039;) #plt.legend([039;Fit039;, 039;Experimental039;]) plt.show() </sxh>