TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Reaction.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Reaction.h>
17#include <Parser_U.h>
18#include <Param.h>
19#include <Equation_base.h>
20#include <Probleme_base.h>
21#include <Discretisation_base.h>
22
23Implemente_instanciable(Reaction,"Reaction",Objet_U_With_Params);
24// XD reaction objet_lecture nul BRACE Keyword to describe reaction: NL2 w =K pow(T,beta) exp(-Ea/( R T)) $\Pi$
25// XD_CONT pow(Reactif_i,activitivity_i). NL2 If K_inv >0, NL2 w= K pow(T,beta) exp(-Ea/( R T)) ( $\Pi$
26// XD_CONT pow(Reactif_i,activitivity_i) - Kinv/exp(-c_r_Ea/(R T)) $\Pi$ pow(Produit_i,activitivity_i ))
27
29{
30 os<<" { "<<finl;
31 os<<"reactifs "<<reactifs_<<finl;
32 os<<"produits "<<produits_<<finl;
33 os<<"exposant_beta "<<beta_<<finl;
34 os<<"constante_taux_reaction "<<constante_taux_reaction_<<finl;
35 os<<"Sc_t "<<Sc_t_<<finl;
36 os<<"enthalpie_reaction "<<enthalpie_reaction_<<" J/mol"<<finl;
37 os<<"energie_activation "<<Ea_<<" J/mol"<<finl;
38 os<<"proportion_max_admissible "<<proportion_max_admissible_<<finl;
39 os<<"nb_sous_pas_de_temps_reaction "<<nb_sous_pas_de_temps_reaction_<<finl;
40 os<<"contre_reaction "<<contre_reaction_<<finl;
41 os<<"contre_energie_activation "<<c_r_Ea_<<finl;
42 os<<" } "<<finl;
43 return os;
44}
45
46void extract_coef_local(ArrOfDouble& coeff_reactifs,const Nom& reactifs_,const Motcles& list_var)
47{
48 int sz=list_var.size();
49 assert(sz==list_var.size());
50
51 Parser_U parser;
52 parser.setNbVar(sz);
53 for (int i=0; i<sz; i++)
54 parser.addVar(list_var[i]);
55
56 Nom copie(reactifs_);
57 parser.setString(copie);
58 parser.parseString();
59 coeff_reactifs.resize_array(sz);
60 for (int i=0; i<sz; i++)
61 {
62 for (int j=0; j<sz; j++)
63 parser.setVar(j,0);
64 parser.setVar(i,1);
65 double val=parser.eval();
66 coeff_reactifs[i]=val;
67 }
68 Cerr<<reactifs_<<" "<<list_var<<" "<<coeff_reactifs<<finl;
69 for (int i=0; i<sz; i++) Cerr<<coeff_reactifs[i]<<"*"<<list_var[i]<<"+";
70 Cerr<<finl;
71}
72
73// Descrition:
74// prend une liste de nom de variables et extrait les coefficients de la reaction, et verifie que les masses molaires sont coherentes
75void Reaction::extract_coef(ArrOfDouble& coeff_reactifs,ArrOfDouble& coeff_produits,const Motcles& list_var,const ArrOfDouble& masse_molaire) const
76{
77 assert(masse_molaire.size_array()==list_var.size());
78 extract_coef_local(coeff_reactifs,reactifs_, list_var);
79 extract_coef_local(coeff_produits,produits_, list_var);
80}
81
82void Reaction::completer(const Motcles& list_var,const ArrOfDouble& masse_molaire)
83{
84 ArrOfDouble coeff_reactifs;
85 ArrOfDouble coeff_produits;
86 extract_coef(coeff_reactifs,coeff_produits,list_var,masse_molaire);
87 int sz=list_var.size();
88 double mreactif=0,mproduit=0;
89 coeff_Y_.resize_array(sz);
90 coeff_Y_=0;
91 coeff_stoechio_.resize_array(sz);
93 coeff_activite_.resize_array(sz);
95 for (int p=0; p<sz; p++)
96 {
97 mreactif+=masse_molaire[p]*coeff_reactifs[p];
98 mproduit+=masse_molaire[p]*coeff_produits[p];
99 coeff_Y_[p]+=masse_molaire[p]*coeff_reactifs[p];
100 coeff_Y_[p]-=masse_molaire[p]*coeff_produits[p];
101 coeff_stoechio_[p]+=coeff_reactifs[p];
102 coeff_stoechio_[p]-=coeff_produits[p];
103 }
104 if (!est_egal(mreactif,mproduit))
105 {
106 Cerr<<" erreur dans la chimie de "<<(*this)<<finl;
107 Cerr<<" mreactif "<< mreactif<<finl;
108 Cerr<<" mproduit "<< mproduit<<finl;
109 exit();
110 }
111 //coeff_Y_/=mreactif;
112 save_alias_=list_var;
113 Cerr<<" Extraction des activites "<<finl;
114 extract_coef_local(coeff_activite_,activite_,list_var);
115}
116
117void Reaction::set_param(Param& param) const
118{
119 param.ajouter( "reactifs",&reactifs_,Param::REQUIRED); // XD attr reactifs chaine reactifs REQ LHS of equation (ex
120 // XD_CONT CH4+2*O2)
121 param.ajouter( "produits",&produits_,Param::REQUIRED); // XD attr produits chaine produits REQ RHS of equation (ex
122 // XD_CONT CO2+2*H20)
123 param.ajouter( "constante_taux_reaction",&constante_taux_reaction_); // XD attr constante_taux_reaction floattant constante_taux_reaction OPT constante of cinetic K
124 param.ajouter( "enthalpie_reaction",&enthalpie_reaction_,Param::REQUIRED); // XD attr enthalpie_reaction floattant enthalpie_reaction REQ DH
125 param.ajouter( "energie_activation",&Ea_); // XD attr energie_activation floattant energie_activation REQ Ea
126 param.ajouter( "exposant_beta",&beta_); // XD attr exposant_beta floattant exposant_beta REQ Beta
127 param.ajouter_non_std("coefficients_activites",(this)); // XD attr coefficients_activites bloc_lecture coefficients_activites OPT coefficients od ativity (exemple { CH4 1 O2 2 })
128
129 param.ajouter( "contre_reaction",&contre_reaction_); // XD attr contre_reaction floattant contre_reaction OPT K_inv
130 param.ajouter( "contre_energie_activation",&c_r_Ea_); // XD attr contre_energie_activation floattant contre_energie_activation OPT c_r_Ea
131 param.ajouter( "Sc_t",&Sc_t_);
132}
134{
135 if (Sc_t_==0.)
136 {
137 Cerr<<"Reaction::validate_params: Turbulent Schmidt number cannot be 0 ! Try 1E30 instead !"<<finl;
138 exit();
139 }
140}
141
143{
144 if (motlu=="coefficients_activites")
145 {
146 Nom motlubis;
147 is >> motlubis;
148 if (motlubis!="{")
149 {
150 Cerr<<"On attendait { et non " <<motlubis<<" dans lire_motcle_non_standard de "<<que_suis_je()<<finl;
151 exit();
152 }
153 is>>motlubis;
154 while (motlubis!="}")
155 {
156 // on lit deux mots et on fait +mot1*mot2
157 activite_+="+";
158 activite_+=motlubis;
159 activite_+="*";
160 is>>motlubis;
161 activite_+=motlubis;
162 is>>motlubis;
163 }
164 }
165 else
166 {
167 Cerr<<"On attendait coefficients_activites et non " <<motlu<<" dans lire_motcle_non_standard de "<<que_suis_je()<<finl;
168 exit();
169 }
170 return 1;
171}
176
178{
179 const Equation_base& eqn=pb.equation(0);
180 eqn.discretisation().discretiser_champ("temperature",eqn.domaine_dis(),nom,"unit", -1,0.,omega_);
181}
182void Reaction::reagir(VECT(OBS_PTR(Champ_Inc_base))& liste_C,double deltat) const
183{
184 // il faut savoir e que l'on veut faire ....
185
186 // Cerr<<__FILE__<<" "<<(int)__LINE__<<" non code "<<finl; exit();
187 int size=liste_C.size();
188
189 ArrOfDouble C(size),C0(size);
190
191 int nb_case= liste_C[0]->valeurs().size();
192 if ((beta_!=0)||(Ea_!=0)||((c_r_Ea_!=0)&&(contre_reaction_>0)))
193 {
194 Cerr<<"Reaction : Donnees incompatibles avec le fait que l on n a pas de temperature"<<finl;
195 Cerr<<*this<<finl;
196 exit();
197 }
198
199 for (int elem=0; elem<nb_case; elem++)
200 {
201
202
203 // initialisation et rabotage des C
204 for (int i=0; i<size; i++)
205 {
206 if (coeff_Y_[i]!=0.) // c'est un reactif ou un produit
207 {
208 C[i]=liste_C[i]->valeurs()(elem);
209 if (C[i]<0)
210 {
211
212 if (C[i]<-1e-5)
213 {
214 Cerr<<" on rabote C_"<<i<<" dans la maille "<<elem<<" dans la chimie !!!!!! "<<C[i]<<finl;
215
216 exit();
217 }
218 C[i]=0;
219 }
220 }
221 else
222 C[i]=0;
223 }
224
225 // calcul du taux de reaction implicite
226 C0=C;
227 double proportion_directe;
228 double proportion=calcul_proportion_implicite(C,C0,deltat,1e-7,proportion_directe);
229 for (int i=0; i<size; i++)
230 if (coeff_Y_[i]!=0.) // c'est un reactif ou un produit
231 {
232 DoubleTab& C_i = liste_C[i]->valeurs(); // kg/kg
233 // C_i(elem)-=proportion*coeff_stoechio_[i];
234 C_i(elem)=C0[i]-proportion*coeff_stoechio_[i];
235 }
236 }
237
238}
239
240double Reaction::calcul_proportion_implicite(ArrOfDouble& C_temp,const ArrOfDouble& C0, double deltat, double seuil, double& proportion_directe) const
241{
242
243 int nbc=C0.size_array();
244 // double proportion_directe_es;
245 double proportion=-1, omegapoint, dy_omega, proportion_inverse=-1;
246
247 double rho_mel=1 ; //tab_rho(elem); // kg/m3
248 double T_elem=1 ; //temperature(elem); // K
249 omegapoint=constante_taux_reaction_; // 1/s // prefacteur du taux de reaction volumique local
250 //omegapoint*=pow(T_elem,beta_)*exp(-Ea_/(R_gaz_parfait*T_elem)); // Arrhenius et facteur temperature
251 dy_omega=omegapoint/rho_mel; // m3/kg/s // prefacteur du taux de reaction volumique local
252 //proportion=dy_omega*deltat; // m3/kg a ce stade si une seule activite exposant 1
253 double produit_activite=1;
254 double produit_contre=1;
255 double R_gaz_parfait=8.3143;
256
257 double securite=1-1e-6;
258
259 if (contre_reaction_>0)
260 securite=0.5;
261 ArrOfDouble& C=C_temp;
262 C=C0;
263
264 int ite=0;
265 double dmax=2*seuil;
266
267 while((dmax>seuil)&&(ite<1000))
268 // while(ite<5)
269 {
270
271 dmax=0;
272 produit_activite=1;
273 produit_contre=1;
274 proportion=dy_omega*deltat;
275 // calcul du taux de reaction brut
276 for (int i=0; i<nbc; i++)
277 {
278 if (coeff_Y_[i]>0.) // c'est un reactif gazeux => produit par son activite
279 {
280 produit_activite*=pow(C[i],coeff_activite_[i]);
281 }
282 else if (contre_reaction_>0)
283 if (coeff_Y_[i]<0.)
284 {
285 produit_contre*=pow(C[i],coeff_activite_[i]);
286 }
287 } // mol/kg a ce stade
288
289 assert(produit_contre>=0);
290 proportion_directe=produit_activite*proportion;
291 if (contre_reaction_>0)
292 {
293 proportion_inverse=produit_contre/(contre_reaction_*exp(-c_r_Ea_/(R_gaz_parfait*T_elem)))*proportion; // contre-Arrhenius
294 proportion=proportion_directe-proportion_inverse;
295 }
296 else
297 proportion=proportion_directe;
298
299 // proportion*=produit_activite;
300 if (1)
301 {
302 // conditionnement en temps pour ne pas consommer plus que ce qui est present
303 if (proportion>0)
304 for (int i=0; i<nbc; i++)
305 {
306 if (coeff_Y_[i]>0.) // c'est un reactif
307 {
308 if (proportion > C[i]/coeff_stoechio_[i]*securite) Cerr<<" on limite" <<finl;
309 proportion=std::min(proportion,C[i]/coeff_stoechio_[i]*securite);
310 }
311 }
312 else
313 for (int i=0; i<nbc; i++)
314 {
315 if (coeff_Y_[i]<0.) // c'est un reactif car on est dans le cas contre treaction
316 {
317 // on prend le max car proportion et Y_i(elem)/coeff_Y_[i] sont negatifs
318 proportion=std::max(proportion,C[i]/coeff_stoechio_[i]*securite);
319 }
320 }
321 }
322 proportion_max_sur_delta_t_=std::max(proportion_max_sur_delta_t_,std::fabs(proportion));
323 //if (ite==0)
324 // proportion_directe_es=proportion_directe;
325 for (int i=0; i<nbc; i++)
326
327 if (1)
328 {
329 if (coeff_Y_[i]!=0.) // c'est un reactif car on est dans le cas contre treaction
330 {
331 double pond=-1;
332 if (coeff_Y_[i]>0)
333 {
334 if (C[i]>0)
335 pond=proportion_directe*coeff_stoechio_[i]/C[i];
336 else
337 pond=0;
338 }
339 else
340 {
341 if ((contre_reaction_>0)&&(C[i]>0))
342 pond=-proportion_inverse*coeff_stoechio_[i]/C[i];
343 else
344 pond=0;
345 }
346 if (pond<0)
347 exit();
348 //pond=0;
349 double nc=((C0[i]-proportion*coeff_stoechio_[i]/2.+pond/2.*C[i])/(1.+pond/2.)-C[i]);
350 double dc=std::fabs(nc);
351 C[i]+=nc;
352 if (dc>dmax)
353 dmax=dc;
354 //Cerr<<ite<<" i "<< i<< " "<<C(i)-C0(i)<<" dc"<< dmax <<finl;
355 }
356 }
357 else
358 {
359 double nc=C0[i]-proportion*coeff_stoechio_[i]/2.-C[i];
360 C[i]+=nc;
361 double dc=std::fabs(nc);
362 if (dc>dmax)
363 dmax=dc;
364 }
365
366
367 ite++;
368 // Cerr<<ite<< " ici " <<proportion <<" "<<dmax<<" direct " <<proportion_directe<<finl;
369 //dmax=0;
370
371 }
372 // Cerr<<"convergence en "<<ite <<" "<<dmax<<" "<<proportion_directe<<finl;
373
374 return proportion;
375}
Classe Champ_Inc_base.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Un tableau d'objets de la classe Motcle.
Definition Motcle.h:63
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Inherits from Objet_U, adds the very common method set_param for the Objet_U hierarchy.
virtual void set_param(Param &) const
Definition Objet_U.h:135
friend class Entree
Definition Objet_U.h:76
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
classe Parser_U Version de la classe Parser, derivant de Objet_U.
Definition Parser_U.h:32
void setVar(const char *sv, double val)
Definition Parser_U.h:149
void setString(const std::string &s)
Definition Parser_U.h:194
void setNbVar(int nvar)
Definition Parser_U.h:174
void parseString()
Definition Parser_U.h:116
double eval()
Definition Parser_U.h:125
void addVar(const char *v)
Definition Parser_U.h:183
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
void extract_coef(ArrOfDouble &coeff_recactifs, ArrOfDouble &coeff_produits, const Motcles &list_var, const ArrOfDouble &masse_molaire) const
Definition Reaction.cpp:75
void completer(const Motcles &list_var, const ArrOfDouble &masse_molaire)
Definition Reaction.cpp:82
double proportion_max_sur_delta_t_
Definition Reaction.h:71
Nom activite_
Definition Reaction.h:57
Nom reactifs_
Definition Reaction.h:55
ArrOfDouble coeff_Y_
Definition Reaction.h:66
double contre_reaction_
Definition Reaction.h:61
double Ea_
Definition Reaction.h:64
Motcles save_alias_
Definition Reaction.h:68
ArrOfDouble coeff_activite_
Definition Reaction.h:67
double enthalpie_reaction_
Definition Reaction.h:60
double Sc_t_
Definition Reaction.h:63
void discretiser_omega(const Probleme_base &pb, const Nom &)
Definition Reaction.cpp:177
Nom produits_
Definition Reaction.h:56
int lire_motcle_non_standard(const Motcle &motlu, Entree &is) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Definition Reaction.cpp:142
double c_r_Ea_
Definition Reaction.h:62
double constante_taux_reaction_
Definition Reaction.h:59
double proportion_max_admissible_
Definition Reaction.h:72
int nb_sous_pas_de_temps_reaction_
Definition Reaction.h:73
double beta_
Definition Reaction.h:65
double calculer_pas_de_temps() const
Definition Reaction.cpp:172
void reagir(VECT(OBS_PTR(Champ_Inc_base))&liste_c, const double deltat) const
Definition Reaction.cpp:182
ArrOfDouble coeff_stoechio_
Definition Reaction.h:66
double calcul_proportion_implicite(ArrOfDouble &C_temp, const ArrOfDouble &C0, double deltat, double seuil, double &poroportion_directe) const
Definition Reaction.cpp:240
void validate_params() const override
Called in the readOn of Objet_U_With_Params, after reading the params.
Definition Reaction.cpp:133
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ size() const
Definition TRUSTVect.tpp:45