TrioCFD 1.9.9_beta
TrioCFD documentation
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// Description:
74// Takes a list of variable names, extracts the reaction coefficients, and checks that the molar masses are consistent.
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<<" error in the chemistry of "<<(*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<<" Extracting activities "<<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<<"Expected { and not " <<motlubis<<" in lire_motcle_non_standard of "<<que_suis_je()<<finl;
151 exit();
152 }
153 is>>motlubis;
154 while (motlubis!="}")
155 {
156 // read two words and form +word1*word2
157 activite_+="+";
158 activite_+=motlubis;
159 activite_+="*";
160 is>>motlubis;
161 activite_+=motlubis;
162 is>>motlubis;
163 }
164 }
165 else
166 {
167 Cerr<<"Expected coefficients_activites and not " <<motlu<<" in lire_motcle_non_standard of "<<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 // we need to know what we want to do...
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: Data incompatible with the fact that there is no temperature"<<finl;
195 Cerr<<*this<<finl;
196 exit();
197 }
198
199 for (int elem=0; elem<nb_case; elem++)
200 {
201
202
203 // initialisation and clipping of C
204 for (int i=0; i<size; i++)
205 {
206 if (coeff_Y_[i]!=0.) // it is a reactant or a product
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<<" clipping C_"<<i<<" in cell "<<elem<<" in the chemistry !!!!!! "<<C[i]<<finl;
215
216 exit();
217 }
218 C[i]=0;
219 }
220 }
221 else
222 C[i]=0;
223 }
224
225 // compute implicit reaction rate
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.) // it is a reactant or a product
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 // prefactor of the local volumetric reaction rate
250 //omegapoint*=pow(T_elem,beta_)*exp(-Ea_/(R_gaz_parfait*T_elem)); // Arrhenius and temperature factor
251 dy_omega=omegapoint/rho_mel; // m3/kg/s // prefactor of the local volumetric reaction rate
252 //proportion=dy_omega*deltat; // m3/kg at this stage if a single activity with exponent 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 // compute the gross reaction rate
276 for (int i=0; i<nbc; i++)
277 {
278 if (coeff_Y_[i]>0.) // it is a gaseous reactant => multiplied by its activity
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 at this stage
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 // time conditioning to avoid consuming more than what is available
303 if (proportion>0)
304 for (int i=0; i<nbc; i++)
305 {
306 if (coeff_Y_[i]>0.) // it is a reactant
307 {
308 if (proportion > C[i]/coeff_stoechio_[i]*securite) Cerr<<" clipping" <<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.) // it is a reactant since we are in the reverse reaction case
316 {
317 // take the max because proportion and Y_i(elem)/coeff_Y_[i] are negative
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.) // it is a reactant or product in the reverse reaction case
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}
Class Champ_Inc_base.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
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
class Equation_base The role of an equation is the calculation of one or more fields....
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
A character string (Nom) in uppercase.
Definition Motcle.h:26
An array of Motcle objects.
Definition Motcle.h:63
class Nom: a character string for naming TRUST objects.
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:130
friend class Entree
Definition Objet_U.h:71
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
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
class Parser_U Version of the Parser class, deriving from 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
class Probleme_base It is a Probleme_U that is not a coupling.
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
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
Reads non-simple-type parameters of an Objet_U from an input stream.
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
Base class for output streams.
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