1 Irradiation continue, réacteur
parfaitement agité photochim_1.cpp |
2 Irradiation continue, agitation
imparfaite photochim_2.cpp |
En appliquant l'AEQS, une réaction photochimique peut s'écrire sous forme pseudo-élémentaire :
A + hν → P φIa (r 12)
et ses équations cinétiques sont
dP/dt = − dA/dt = φI0 (1 − 10−Abs) ℓεAA / Abs (V.61)
avec
Abs = ℓ [εA A + εP (A0 − A)]
Une première remarque concerne le nombre de paramètres. Alors que seule une constante de vitesse est nécessaire pour une réaction non photochimique, cinq paramètres figurent dans l'équation ci-dessus. Certains peuvent être regroupés puisqu'ils figurent toujours ensembles sous forme d'un produit : φI0, ℓεA, ℓεP, de sorte que mathématiquement l'équation cinétique ne dépend que de trois paramètres. Nous faisons cependant le choix, pour la programmation, de les écrire tous, afin de rester le plus proche possible de leur signification physique.
En conséquence, lors de l'optimisation de ces paramètres, il sera indispensable de ne laisser ajuster qu'un seul de ces paramètres. On devra, par exemple, maintenir constants I0 et ℓ, et ajuster uniquement φ, εA et εP. Il en est de même évidemment lorsque des paramètres apparaissent toujours ensembles (et jamais isolés) sous forme d'une fonction quelconque (pas nécessairement un produit) .
D'autre part, apparaît dans cette équation une division par une quantité variable, Abs. Il est dès lors indispensable de protéger le programme à coup sûr d'une division par zéro, qui entraînerait une erreur. En effet, même si physiquement certaines grandeurs ne peuvent s'annuler, on ne peut pas exclure que cela arrive au cours d'un calcul, par exemple aux conditions aux limites, ou, dans le cas d'un calcul itératif, lors d'essais internes de celui-ci. Cette protection est très simple :
1 void eqdiff (Sa_data x, Sa_data* y, Sa_data* dy)
2 {
3 // A + hv -> P (phi:p[0],
Io:p[1])
4 Sa_data Abs = p[2]*(p[3]*y[0] + p[4]*y[1]); //
l:p[2] epsA:p[3] epsP:p[4]
5 if (Abs == 0)
6 dy[0] = 0;
7 else
8 dy[0] = - p[0]*p[1]*(1 - pow(10, -Abs))*p[2]*p[3]*y[0]/Abs; // dA/dt
9 dy[1] = - dy[0]; // dP/dt
10 }
L'absorbance est déclarée et calculée ligne 4. Puis, sa
valeur est testée ligne 5. Noter l'utilisation du double-signe
==
, de comparaison. Le résultat de
l'expression (Abs == 0)
est vrai ou faux
(true
, false
). Une erreur fréquente consiste à
utiliser à la place le simple signe =
,
d'affectation, dont le résultat serait ici d'affecter
systématiquement 0
à Abs
!
L'instruction ligne 6 est exécutée seulement si le résultat du test est
vrai, c'est-à-dire si l'absorbance est effectivement nulle. La dérivée dA/dt est alors logiquement mise également à zéro,
puisqu'il ne peut y avoir de réaction photochimique sans absorption de
photons.
Sinon, c'est l'instruction suivant la ligne 7 (else
) qui est
exécutée : c'est l'équation cinétique de la réaction.
Comme une seule instruction suffit dans les deux cas, il n'est pas
nécessaire de la délimiter par des accolades { }
, et le programme
reprend son cours normal, indépendant du résultat du test, à, la ligne 9. Des
accolades seraient obligatoires si plusieurs instructions étaient à exécuter,
soit dans le if
, soit dans le else
. Noter
l'importance pratique de l'indentation (non obligatoire) du texte du
programme qui en fait apparaître clairement la structure logique.
Le bloc else
n'est pas obligatoire, si il n'y a rien de
particulier à faire lorsque le résultat du test est faux.
Enfin, nous utilisons dans l'équation cinétique, ligne 8, la
fonction pow(x,y)
, avec
ici x = 10
et y = -Abs
, qui retourne xy. Cette fonction fait partie de la bibliothèque
de fonctions mathématiques standard du langage C, dont les principales sont
accessibles depuis l'éditeur Sa (menu Templates → Math.
functions). Elles sont également décrites dans le manuel de Sa
(tome 1. chap. XII, p. 61).
Ce n'est pas le cas ici, mais la fonction pow(x,y)
nécessite
parfois d'être "protégée", comme les divisions par zéro. Elle peut en effet
générer deux types d'erreurs :
- "Result out of range" si le résultat xy est plus grand que le nombre le plus grand
représentable en virgule flottante (3.4×10308 par défaut). Les
fonctions exponentielle et hyperboliques,
exp(x)
, cosh(x)
et sinh(x)
peuvent
générer également ce type d'erreur.
- "Domain error" si x est un
réel < 0 et y non entier, ou
si x = y = 0. En effet, xy
= ey ln x, n'est pas défini pour x ≤
0, puisque ln x ne l'est pas, par contre les
puissances entières d'un réel < 0 sont définies, et la fonction
pow
accepte de tels arguments). Les fonctions logarithme
népérien, log(x)
, et décimal, log10(x)
, ainsi que
racine carrée, sqrt(x)
(pour x strictement négatif)
génèrent également ce type d'erreur. Il s'agit d'une erreur qui interrompt le
programme : il est donc particulièrement important de le protéger en indiquant
précisément que faire lorsque cette situation se présente, à l'aide d'un test
des arguments, ou de faire en sorte que cette situation n'intervienne jamais,
par une pré-protection (un exemple se trouve dans le manuel de Sa,
tome 2, Exemple 7, pp. 51 et 54).
Télécharger photochim_1.cpp Télécharger photochim_1.sac
A- Faites varier le rapport εP/εA, en maintenant εA constant et retrouvez les caractéristiques de la figure V.9. Vérifiez en particulier que la vitesse initiale ne change pas, mais que la réaction est inhibée par le produit lorsque celui-ci absorbe.
B- Placez-vous dans une situation d'absorption totale (par exemple : ℓ = 1 cm ; εA = 8×104 et εP = 104 mol−1.L.cm−1 ; A0 = 10−4 mol.L−1), puis diminuez progressivement le trajet optique ℓ jusqu'à le diviser par 10. Que constatez-vous ?
Le but de cet exercice est de simuler, très grossièrement, ce qui se passe dans un réacteur photochimique imparfaitement agité. La modélisation fait appel ici à la notion de réacteurs ouverts et couplés entre eux, qui ne sera abordée que dans la deuxième partie du cours. Il s'agit donc d'une anticipation et certains seront peut-être un peu déroutés : qu'ils ne s'inquiètent pas, fassent confiance à la modélisation proposée et s'attachent surtout aux simulations. Il nous a semblé intéressant d'évoquer ici ce problème très important.
Le principe de la modélisation consiste à diviser le réacteur en
deux sous-réacteurs parallélépipédiques, supposés chacun parfaitement agités,
et communicant entre eux par des tubulures de volume nul, avec un débit D ( en L.s−1), égal dans les deux sens.
- Si ce débit est très grand devant la vitesse de réaction, les concentrations
seront homogènes et le réacteur global pourra être considéré lui-même comme
parfaitement agité.
- Un débit faible fera apparaître les défauts dus à une agitation imparfaite.
- Un débit nul correspondra à l'absence totale d'agitation.
On pourrait réaliser une modélisation plus fine en divisant le réacteur en un nombre plus grand de sous-réacteurs, chacun communicant avec ses voisins immédiats.
Soient V1 et V2 les volumes des deux réacteurs, l'indice 1
désignant celui qui est directement exposé à la lumière, et ℓ1, ℓ2, les trajets optiques correspondant. On
suppose que la surface d'irradiation est égale à l'unité, de sorte que les
volumes et les trajets optiques s'expriment par un même paramètre numérique
(p[2]
et p[5]
dans le programme) : V1/ℓ1 =
V2/ℓ2 = S = 1.
Ces volumes pouvant être différents, il est préférable de raisonner en nombres de moles plutôt qu'en concentrations : a1 et p1 désignent les nombres de moles de A et P dans V1, a2 et p2 dans V2.
Les absorbances des réacteurs V1 et V2 sont, compte
tenu de l'égalité numérique des trajets et des volumes :
Abs1 =
ℓ1(εAa1/V1
+ εPp1/V1) =
(εAa1 +
εPp1) / S (a)
Abs2 =
ℓ2(εAa2/V2
+ εPp2/V2) =
(εAa2 +
εPp2) / S (b)
Si i0 désigne le flux lumineux incident, en
moles de photons par seconde (einstein.s−1), la lumière
absorbée dans V1 est
ia1 = i0 (1 −
10−Abs1) (c)
et le flux incident sur V2 n'est plus que
i0 − ia1 =
10−Abs1 (d)
et la lumière absorbée dans V2 est donc
ia2 =
10−Abs1 (1 −
10−Abs2) (e)
Les vitesses photochimiques sont alors (en
mol.s−1) :
r1 = φ ia1
ℓ1εA(a1/V1)
/ Abs1 = φ i0 (1 −
10−Abs1) εAa1
/ (Abs1 S) (f)
r2 = φ ia2
ℓ2εA(a2/V2)
/ Abs2 = φ
10−Abs1 (1 −
10−Abs2) εAa2
/ (Abs2 S) (g)
Aux vitesses photochimiques, il faut adjoindre les flux de matière dus à la circulation entre les deux réacteurs. A cause de la circulation de V1 vers V2, les nombres de moles de A et P qui disparaissent de V1 sont respectivement D a1/V1 et D p1/V1, et les même nombres doivent apparaître dans V2. De même, à cause de la circulation de V2 vers V1, les nombres de moles de A et P qui disparaissent de V2 (et apparaissent dans V1) sont D a2/V2 et D p2/V2.
Les équations cinétiques du système complet s'écrivent donc :
da1/dt = −
r1 + D (a2/V2 −
a1/V1) (h)
dp1/dt = r1 + D
(p2/V2 −
p1/V1) (i)
da2/dt = − r2
+ D (a1/V1 −
a2/V2) (j)
dp2/dt = r2 + D
(p1/V1 −
p2/V2) (k)
Le fichier photochim_2.cpp contient la programmation de ces équations. On y a ajouté, après l'intégration numérique, le calcul des concentrations "globales", c'est-à-dire les nombres totaux de moles dans V1 et V2 divisés par V1+V2, afin de pouvoir évaluer l'effet global du défaut d'agitation.
Noter quelques particularités de programmation :
- le paramètre p[5]
est utilisé pour V2, mais il est
calculé par le programme, en fonction du volume total p[8]
et de
V1 (p[2]
). Cela ne pose pas de problème particulier à
condition de garder présent à l'esprit que l'affectation manuelle d'une valeur
à ce paramètre n'aura aucun effet puisqu'elle sera "écrasée" par le programme.
Nous avons mis une astérisque * dans son nom pour le rappeler
(photochim_2.sac).
- de même, les nombres de moles initiaux sont affectés par programme en
fonction de la concentration globale initiale, p[7]
, supposée
identique dans les deux volumes. Les conditions initiales affectées
manuellement seront donc également sans effet.
- les initialisations des volumes, qui précèdent l'appel de l'intégrateur
numérique, ont pour but d'assurer qu'on partage un volume total donné en
parties complémentaires et non nulles (puisqu'il y aura des divisions par ces
volumes).
Télécharger photochim_2.cpp Télécharger photochim_2.sac
A- (1) Simulez d'abord avec les
paramètres du fichier photochim_2.sac, c'est-à-dire dans une situation
d'absorption totale (εA = 8×104 et
εP = 2×104
mol−1.L.cm−1 ; A0 =
10−4 mol.L−1 ; V1 = 0.2
Vtotal) et avec un débit nul (D = p[6]
= 0), correspondant à un réacteur non agité. Tracez les évolutions de
a1, a2 et Atotal.
(2) Mettez maintenant V1 = p[2]
= 1 (
le programme le mettra en réalité à 0.99) et comparez les évolutions obtenues
avec les précédentes.
Avec V1 = 0.99, le réacteur presqu'entier est assimilé à un
réacteur parfaitement agité, homogène, le résultat est donc
pratiquement identique à ce que vous obtiendriez avec le programme précédent,
photochim_1.cpp (vous pouvez vérifier !). Vous constatez que la
réaction dans le réacteur mal agité (1) est globalement beaucoup plus lente que
dans la situation (2). Plus précisément, d'une part la réaction dans
V2 ne démarre vraiment que lorsqu'elle est presque terminée dans
V1, c'est-à-dire que V1 s'est "éclairci", mais, d'autre
part, avec une vitesse beaucoup plus faible, proportionnelle à i0 − ia1 (d).
B- Revenez à une situation analogue à (1) mais augmentez la taille de V1, par exemple V1 = 0.5. Que constatez-vous ?
C- Augmentez le coefficient d'extinction molaire du produit, par exemple εP = 6×104 mol−1.L.cm−1 . La situation, pourtant réaliste, devient catastrophique ! La réaction semble s'arrêter en route, ou du moins elle devient extrêmement lente.
D- En gardant les paramètres ci-dessus,
augmentez progressivement le débit, en démarrant à D = 10−3
L.s−1, de façon à vous rapprocher d'un réacteur
parfaitement agité. A partir de quelle valeur de débit obtenez-vous ce
résultat ? Pourquoi ?
(évaluez grossièrement la vitesse photochimique et le flux de matière ; vous
devez trouver un rapport flux / vitesse photochimique de l'ordre de 100)
Les valeurs intermédiaires donnent une idée de ce qui peut se passer dans un
réacteur imparfaitement agité.
E- Rechargez les paramètres du fichier
photochim_2.sac et changez seulement le coefficient d'extinction
molaire du produit : εP = 2×103
mol−1.L.cm−1 . Simulez une fois avec un débit
nul, puis avec le débit trouvé ci-dessus. Que constatez-vous ?
Diminuez encore le coefficient d'absorption du produit et recommencez ces
simulations.
Lorsque le produit n'absorbe pratiquement plus, les deux simulations donnent un
résultat global identique, bien que le résultat dans chaque volume soit
différent : comme déjà vu, la réaction dans V2 ne démarre
pratiquement que lorsqu'elle est terminée dans V1, mais cette fois
avec une vitesse maximale, proportionnelle à i0 puisque
V1 est complètement éclairci.