Table des matières ScilabPython

Calcul des constantes d'équilibre

1. Données thermodynamiques

La table suivante donne les enthalpies standard de formation et les entropies standard à 298 K (données extraites de [1] et [2]).

NomΔ Hf0 (kJ/mol)S0 (kJ/K/mol)
Ag(s)043
Ag(l)1151.9
Ag2O(s)-31121
Al(s)028.33
Al(l)10.5639.55
Al2O3(s)-1675.750.92
Au(s)047.4
Au(l)12.5556.76
C(s)05.74
CH4(g)-74.81186.26
C2H6(g)-84.68229.6
CH3OH(l)-238.66126.8
CH3OH(g)-200.66239.81
C2H5OH(l)-277.69160.7
C2H5OH(g)-235.1282.7
CH3COOH(l)-484.5159.8
CH3COOH(aq)-485.76178.7
CH3COO-(aq)-486.0186.6
Cl2(g)0223.07
Cl-(aq)-167.1656.5
CO(g)-110.53197.67
CO2(g)-393.51213.74
Cu(s)033.15
Cu(l)13.2642.92
Cu2+(aq)64.77-99.6
Cr(s)024
Cr2O3(s)-114081
CuO(s)-15743
CuO(l)-14550.5
Fe(s)027.28
Fe(l)13.7634.9
FeO(s)-27261
FeO(l)-24875.7
Fe3O4(s)-1118.4146.4
Fe3O4(l)-980.4220.3
Fe2O3(s)-82487
H2(g)0131
H+(aq)00
HCl(aq)-167.1656.5
H2O(l)-285.8369.91
H2O(g)-241.82188.83
H2O2(l)-187.78109.6
H2SO4(l)-813.99156.9
H2SO4(aq)-909.2720.1
Mg(s)033
Mg(l)8.442.1
Mg(g)147142.3
MgO(s)-60227
Mn(s)032
Mn(l)1541.9
MnO(s)-38560
N2(g)0193
NO(g)90.25210.76
NO2(g)33.18240.06
N2O4(g)9.16304.29
NH3(g)-46.11192.45
NH3(aq)-80.29111.3
NH4+(aq)-132.51113.4
Na(s)051.21
Na+(aq)-240.1259
NaCl(s)-411.1572.13
O2(g)0205.138
O3(g)142.7238.93
OH-(aq)-229.99-10.75
Pb(s)064.81
Pb(l)4.7772.76
PbO(s)-217.3268.7
S2(g)128.37228.18
SO2(g)-296.83248.22
SO3(g)-395.72256.76
SO42-(aq)-909.2720.1
Si(s)018.83
Si(l)50.2148.6
SiO2(s)-910.9441.84
Zn(s)041.63
Zn(l)6.751.3
Zn(g)121.5148.6
ZnO(s)-348.2843.64

2. Module de calcul Scilab

2.a. Code du module

Module scilab : télécharger.

Fichier de données : télécharger. La syntaxe des indices et exposants est celle de TeX/LaTeX.

La fonction readData lit le fichier de données et renvoit les données sous forme d'un objet struct.

function data=readData(filename)
    f=mopen(filename)
    n=0
    data=struct()
    while (n<>-1),
        [n,nom,h,s]=mfscanf(f,"%s%f%f\n");
        if (n<>-1) then
            data(nom)=struct('H',h,'S',s); 
        end;
    end
    mclose(f)
endfunction    
            

La fonction somme calcule l'enthalpie standard de formation et l'entropie standard pour une somme de composés affectés de coefficients. Il faut placer un * entre le coefficient et le nom. Voici par exemple une somme : C(s)+0.5*O_2(g).

function [H,S]=somme(data,som)
  sum = strsubst(som,"+}","@");
  sum = strsubst(sum,"^+","^@");
  c=tokens(som,'+');
  n=size(c);
  n=n(1);
  H=0;
  S=0;
  for i=1:n,
      x=tokens(c(i),"*");
      nx=size(x);
      nx=nx(1);
      if nx==1 then
        coef=1;
        nom=x(1);
      else
        coef=strtod(x(1));
        nom=x(2);
      end
      nom = strsubst(nom,"@","+}");
      nom = strsubst(nom,"^@","^+");
      H=H+coef*data(nom).H;
      S=S+coef*data(nom).S;
  end
endfunction
            

La fonction reaction calcule l'enthalpie standard et l'entropie standard de réaction. L'équation de la réaction est de la forme C(s)+0.5*O_2(g)=CO(g). L'enthalpie est donnée en kJ/mol et l'entropie en J/K/mol.

function [DH,DS]=reaction(data,equation)
  n=strindex(equation,"=");
  som=strsplit(equation,[n-1 n]);
  reactifs=som(1);
  produits=som(3);
  [DH,DS]=somme(data,produits);
  [h,s]=somme(data,reactifs);
  DH=DH-h;
  DS=DS-s;
endfunction
            

La fonction constanteK calcule la constante d'équilibre pour une enthalpie standard de réaction, une entropie standard de réaction et une température fournies en argument. Le calcul effectué suppose que les grandeurs standard (enthalpie et entropie) ne dépendent pas de la température.

function K=constanteK(DH,DS,T)
  R=8.31;
  K=exp(-(DH*1e3-T*DS)/(R*T)) 
endfunction
            

La fonction plotK effectue le tracé du logarithme de la constante d'équilibre en fonction de la température :

function plotK(DH,DS,Tmin,Tmax,N)
    T=[Tmin:(Tmax-Tmin)/(N-1):Tmax];
    K=T;
    R=8.31;
    for i=1:N,
        K(i)=-(DH*1e3-T(i)*DS)/(R*T(i));
    end;
    plot2d(T,K)
    xtitle("Constante d''equilibre",'T (K)','ln(K)')
endfunction
            

2.b. Exemple

On considère comme exemple la réaction suivante :

2SO2(g)+O2(g)=2SO3(g)

On commence par charger le module puis le fichier de données, en indiquant son chemin par rapport au répertoire courant de scilab (le répertoire d'où le programme est lancé).

exec('thermochim.sci')
data=readData('thermodata.txt');
            

Pour accéder par exemple à l'enthalpie standard de formation du dioxyde de soufre (à 298 K), on écrira :

data('SO_2(g)').H
-296.82999 

Les grandeurs standard de la réaction sont obtenues par :

[DH,DS]=reaction(data,'2*SO_2(g)+O_2(g)=2*SO_3(g)')
[DH,DS]
-197.78003 -188.05798 

La constante d'équilibre à 700 K :

constanteK(DH,DS,700)
86684.116 

La courbe donnant la constante d'équilibre en fonction de la température :

plotA=scf();
plotK(DH,DS,300,1500,100)
../../../../figures/sciphys/thermochim/equilibre/plotA.svgFigure pleine page

3. Module de calcul Python

Fichier de données : télécharger. La syntaxe des indices et exposants est celle de TeX/LaTeX.

Le module (télécharger) est constituée d'une classe Thermochimie et d'une classe Ellingham.

3.a. Classe Thermochimie

import re
from pylab import *
class Thermochimie:

Le constructeur lit le fichier de données et construit un dictionnaire :

    def __init__(self,dataFile):
        f = open(dataFile,"r") 
        self.data = {}
        for line in f.readlines():
            li = line.strip()
            t = re.split('[\s]+',li)
            if len(t)==3:
                self.data[t[0]]={'H':float(t[1]),'S':float(t[2])}
        f.close()

La méthode somme calcule l'enthalpie standard de formation et l'entropie standard pour une somme de composés affectés de coefficients. Il faut placer un * entre le coefficient et le nom. Voici par exemple une somme : C(s)+0.5*O_2(g).

    def somme(self,som):
        sum = som.replace("+}","@")
        sum = sum.replace("^+","^@")
        cliste = re.split("\+",sum)
        H = 0
        S = 0
        for c in cliste:
            a = re.split("\*",c)
            if len(a)==2:
                coef = float(a[0])
                nom = a[1]
            else:
                coef = 1
                nom = a[0]
            nom = nom.replace("@","+}")
            nom = nom.replace("^@","^+")
            if self.data.has_key(nom):
                H = H + coef*self.data[nom]['H']
                S = S + coef*self.data[nom]['S']
            else:
                print "Erreur : le compose %s n'est pas dans la table de donnees"%nom
                raise SystemExit
        return [H,S]

la méthode reaction calcule l'enthalpie standard et l'entropie standard de réaction. L'équation de la réaction est de la forme C(s)+0.5*O_2(g)=CO(g). L'enthalpie est donnée en kJ/mol et l'entropie en J/K/mol.

    def reaction(self,equation):
        [reactifs,produits]=re.split("=",equation)
        [Hp,Sp]=self.somme(produits)
        [Hr,Sr]=self.somme(reactifs)
        return [Hp-Hr,Sp-Sr]

Exemple d'utilisation de la classe :

from thermochimie import *
th = Thermochimie("thermodata.txt")
[DH,DS]=th.reaction("2*SO_2(g)+O_2(g)=2*SO_3(g)")
                
print([DH,DS])
--> [-197.7800000000001, -188.058]

3.b. Classe EnthalpieLibre

La classe EnthalpieLibre permet de calculer et tracer l'enthalpie libre standard de réaction en fonction de la température pour différentes réactions d'oxydation.

Les équations des réactions d'oxydation sont données par le fichier texte liste_reations.txt avec le domaine de température correspondant, un caractère (O ou N) indquant si l'équation doit être écrite et un numéro précisant la réaction d'oxydation.

class EnthalpieLibre:

Le constructeur prend en argument une instance de la classe Thermochimie et le nom du fichier comportant la liste des réactions. Un dictionnaire est constuit, dont chaque élément (clé entière) est une liste d'équations correspondant à une réaction d'oxydation.

    def __init__(self,thermo,reactionsFile):
        self.thermo = thermo
        self.reaction = {}
        f = open(reactionsFile,"r")
        for line in f.readlines():
            li = line.strip()
            t = re.split('[\s]+',li)
            if len(t)==5:
                n = int(t[3])
                equation = t[0]
                texte = t[2]
                marker = t[4]
                a = re.split('=|,',t[1]) 
                Tmin = float(a[1]) 
                Tmax = float(a[2])
                if not self.reaction.has_key(n):
                    self.reaction[n] = []
                self.reaction[n].append([equation,Tmin,Tmax,texte,marker])
        f.close()

La méthode plot trace l'enthalpie libre standard en fonction de la température pour la réaction d'oxydation dont le numéro est donné en argument :

    def plot(self,n,color):
        for e in self.reaction[n]:
            equation = e[0]
            Tmin = e[1]
            Tmax = e[2]
            texte = e[3]
            mark = e[4]
            [DH,DS] = self.thermo.reaction(equation)
            G1 = DH-DS*1e-3*Tmin
            G2 = DH-DS*1e-3*Tmax
            plot([Tmin,Tmax],[G1,G2],color=color)
            if mark=="T":
                scatter([Tmax],[G2],color=color,marker='o')
            if texte=='O' or texte=='o':
                eq = equation.replace("*","")
                text(Tmax,G2,r'$\rm %s$'%eq,color=color,size=12)

La méthode gstandard calcule l'enthalpie libre standard d'une réaction pour la température demandée :

    def gstandard(self,n,T):
        G = 0
        for e in self.reaction[n]:
            equation = e[0]
            Tmin = e[1]
            Tmax = e[2]
            if (T>=Tmin) and (T<=Tmax):
                [DH,DS] = self.thermo.reaction(equation)
                G = DH-DS*1e-3*T
        return G

Exemple :

G = EnthalpieLibre(th,"liste_reactions.txt")
            
print(G.reaction[6])
--> [['2*H_2(g)+O_2(g)=2*H_2O(l)', 300.0, 373.0, 'N', 'T'], ['2*H_2(g)+O_2(g)=2*H_2O(g)', 373.0, 2000.0, 'O', 'F']]
figure(figsize=(10,6))
xlabel('T (K)') 
ylabel(r'$\Delta_rG^0\ (kJ/mol)$')
G.plot(6,'r')
G.plot(5,'b')
G.plot(8,'g')
axis([300,3000,-1000,0])
grid(True)
            
plotBplotB.pdf
print(G.gstandard(6,1000))
--> -394.162
Références
[1]  P.W. Atkins,  Physical chemistry,  (Oxford University Press, 1990)
[2]  G. Aylward, T. Findlay,  SI Chemical data,  (John Wiley Sons, 1994)
Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.