Ce document montre comment effectuer la simulation d'un dosage d'un polyacide par une base forte. Les courbes de pH et de composition sont tracées en fonction du volume de base versé. La méthode de calcul est tirée de [1].
On considère un polyacide en solution aqueuse pouvant libérer n protons, de la forme HnA. La forme ayant libéré p proton est Hn-pAp-. Sa réaction avec l'eau s'écrit :
On note Kn-p sa constante d'équilibre. K1 est celle de la dernière acidité, celle du dernier proton libéré. Si on note h la concentration en ion hydronium, la loi d'action de masse s'écrit :
On note cA la molarité du polyacide dans la solution et vA le volume de solution considéré. On étudie le dosage de cette solution par une solution d'une base forte, par exemple Na+OH-. On note cB la molarité de cette solution et vB le volume versé.
La conservation de A s'écrit :
En utilisant récursivement l'équation (2), on obtient :
Cette relation permet de calculer la concentration en An- en fonction de h et des constantes. Pour alléger, on introduit le dénominateur :
La seconde équation de conservation à écrire est celle de la charge électrique :
La conservation de l'ion sodium s'écrit :
L'équilibre d'autoprotolyse de l'eau s'écrit :
La concentration en An- peut être mise en facteur dans la somme de l'équation (6), ce qui donne :
On obtient ainsi une seconde expression de [An-], que l'on simplifie en posant :
En égalisant les deux expressions de [An-], on obtient le volume de base versé en fonction de h et des constantes :
Pour tracer une courbe pH=f(vB) on calcule donc la fonction réciproque. L'axe des ph de 0 à 14 est échantillonné. Pour chaque valeur de h, on calcule le volume vB et les concentrations des différentes espèces. On ne retient que les volumes compris entre 0 et le volume maximal versé.
La fonction suivante effectue le calcul du volume et des concentrations pour un pH donné. Les constantes du polyacide sont données sous forme d'une liste.
import numpy as np import math from matplotlib.pyplot import * def volume(pK,ca,va,cb,ph): n = len(pK) Ke = 1.0e-14 h = 10**(-ph) c = np.ones(n+1) Da = 1 kk = 1 for p in range(1,n+1): kk *= 10**(-pK[p-1]) x = h**p/kk c[p] = x Da += x Na = n kk = 1 for p in range(1,n): kk *= 10**(-pK[p-1]) Na += (n-p)*h**p/kk y = Ke/h-h vb = va*(y+Na*ca/Da)/(cb-y) for p in range(n+1): c[p] *= ca*va/(va+vb)/Da return [vb,c]
La fonction suivante trace le pH en fonction du volume versé
def plot_pH(pK,ca,va,cb,vb_max): npts = 1000 pH = np.zeros(npts) vb = np.zeros(npts) ph_max = 14+math.log10((vb_max*cb-ca*va)/(vb_max+va)) dph = ph_max/(npts-1) for i in range(npts): ph = dph*i [vb[i],c] = volume(pK,ca,va,cb,ph) pH[i] = ph plot(vb,pH) axis([0,vb_max,0,14]) xlabel("vB") ylabel("pH")
La fonction suivante trace les pourcentages des acides en fonction du volume versé :
def plot_frac(pK,ca,va,cb,vb_max): npts = 1000 n = len(pK) vb = np.zeros(npts) frac = np.zeros((n+1,npts)) ph_max = 14+math.log10((vb_max*cb-ca*va)/(vb_max+va)) dph = ph_max/(npts-1) for i in range(npts): ph = dph*i [vb[i],c] = volume(pK,ca,va,cb,ph) for p in range(n+1): frac[p][i] = c[p]*(vb[i]+va)/(ca*va)*100 for p in range(0,n+1): s1 = "H_{"+str(p)+"}" if p==0: s1 = "" elif p==1: s1 = "H" s2 = "A^{"+str(n-p)+"-}" if n-p==0: s2 = "A" elif n-p==1: s2 = "A^-" plot(vb,frac[p],label="$"+s1+s2+"$") axis([0,vb_max,0,100]) xlabel("vB") ylabel("%")
L'acide acétique est un mono-acide.
pK = [4.7] ca = 0.01 cb = 0.01 va = 10.0
figure(figsize=(10,6)) vb_max = 20.0 plot_pH(pK,ca,va,cb,vb_max) grid() title("$CH_3COOH+NaOH$")Figure pleine page
figure(figsize=(10,6)) plot_frac(pK,ca,va,cb,vb_max) legend(loc="upper right") grid() title("$CH_3COOH+NaOH$")Figure pleine page
L'acide oxalique est un diacide.
pK = [4.3,1.2] ca = 0.01 cb = 0.01 va = 10.0
figure(figsize=(10,6)) vb_max = 40.0 plot_pH(pK,ca,va,cb,vb_max) grid() title("$H_2C_2O_4+NaOH$")Figure pleine page
Dans ce cas, il n'y a pas de virage de pH correspondant à la première acidité (les écarts de pk sont trop faibles).
figure(figsize=(10,6)) plot_frac(pK,ca,va,cb,vb_max) legend(loc="upper right") grid() title("$H_2C_2O_4+NaOH$")Figure pleine page
pK = [12.1,7.2,2.15] ca = 0.01 cb = 0.01 va = 10.0
figure(figsize=(10,6)) vb_max = 40.0 plot_pH(pK,ca,va,cb,vb_max) grid() title("$H_3PO_4+NaOH$")Figure pleine page
figure(figsize=(10,6)) plot_frac(pK,ca,va,cb,vb_max) legend(loc="upper right") grid() title("$H_3PO_4+NaOH$")Figure pleine page