Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Reaction.cpp
Go to the documentation of this file.
1 /**
2  * @file Reaction.cpp
3  */
4 
7 #include "cantera/base/ctml.h"
8 #include "cantera/base/Array.h"
9 #include <sstream>
10 
11 namespace Cantera
12 {
13 
14 Reaction::Reaction(int type)
15  : reaction_type(type)
16  , reversible(true)
17  , duplicate(false)
18  , allow_nonreactant_orders(false)
19  , allow_negative_orders(false)
20 {
21 }
22 
23 Reaction::Reaction(int type, const Composition& reactants_,
24  const Composition& products_)
25  : reaction_type(type)
26  , reactants(reactants_)
27  , products(products_)
28  , reversible(true)
29  , duplicate(false)
30  , allow_nonreactant_orders(false)
31  , allow_negative_orders(false)
32 {
33 }
34 
35 void Reaction::validate()
36 {
37  if (!allow_nonreactant_orders) {
38  for (Composition::iterator iter = orders.begin();
39  iter != orders.end();
40  ++iter) {
41  if (reactants.find(iter->first) == reactants.end()) {
42  throw CanteraError("Reaction::validate", "Reaction order "
43  "specified for non-reactant species '" + iter->first + "'");
44  }
45  }
46  }
47 
48  if (!allow_negative_orders) {
49  for (Composition::iterator iter = orders.begin();
50  iter != orders.end();
51  ++iter) {
52  if (iter->second < 0.0) {
53  throw CanteraError("Reaction::validate", "Negative reaction "
54  "order specified for species '" + iter->first + "'");
55  }
56  }
57  }
58 }
59 
60 std::string Reaction::reactantString() const
61 {
62  std::ostringstream result;
63  for (Composition::const_iterator iter = reactants.begin();
64  iter != reactants.end();
65  ++iter) {
66  if (iter != reactants.begin()) {
67  result << " + ";
68  }
69  if (iter->second != 1.0) {
70  result << iter->second << " ";
71  }
72  result << iter->first;
73  }
74  return result.str();
75 }
76 
77 std::string Reaction::productString() const
78 {
79  std::ostringstream result;
80  for (Composition::const_iterator iter = products.begin();
81  iter != products.end();
82  ++iter) {
83  if (iter != products.begin()) {
84  result << " + ";
85  }
86  if (iter->second != 1.0) {
87  result << iter->second << " ";
88  }
89  result << iter->first;
90  }
91  return result.str();
92 }
93 
94 std::string Reaction::equation() const
95 {
96  if (reversible) {
97  return reactantString() + " <=> " + productString();
98  } else {
99  return reactantString() + " => " + productString();
100  }
101 }
102 
103 ElementaryReaction::ElementaryReaction(const Composition& reactants_,
104  const Composition products_,
105  const Arrhenius& rate_)
106  : Reaction(ELEMENTARY_RXN, reactants_, products_)
107  , rate(rate_)
108  , allow_negative_pre_exponential_factor(false)
109 {
110 }
111 
112 ElementaryReaction::ElementaryReaction()
113  : Reaction(ELEMENTARY_RXN)
114  , allow_negative_pre_exponential_factor(false)
115 {
116 }
117 
119 {
121  if (!allow_negative_pre_exponential_factor &&
122  rate.preExponentialFactor() < 0) {
123  throw CanteraError("ElementaryReaction::validate",
124  "Undeclared negative pre-exponential factor found in reaction '"
125  + equation() + "'");
126  }
127 }
128 
129 ThirdBody::ThirdBody(double default_eff)
130  : default_efficiency(default_eff)
131 {
132 }
133 
134 ThreeBodyReaction::ThreeBodyReaction()
135 {
137 }
138 
139 ThreeBodyReaction::ThreeBodyReaction(const Composition& reactants_,
140  const Composition& products_,
141  const Arrhenius& rate_,
142  const ThirdBody& tbody)
143  : ElementaryReaction(reactants_, products_, rate_)
144  , third_body(tbody)
145 {
147 }
148 
150  return ElementaryReaction::reactantString() + " + M";
151 }
152 
153 std::string ThreeBodyReaction::productString() const {
154  return ElementaryReaction::productString() + " + M";
155 }
156 
157 FalloffReaction::FalloffReaction()
159 {
160 }
161 
162 FalloffReaction::FalloffReaction(
163  const Composition& reactants_, const Composition& products_,
164  const Arrhenius& low_rate_, const Arrhenius& high_rate_,
165  const ThirdBody& tbody)
166  : Reaction(FALLOFF_RXN, reactants_, products_)
167  , low_rate(low_rate_)
168  , high_rate(high_rate_)
169  , third_body(tbody)
170 {
171 }
172 
173 std::string FalloffReaction::reactantString() const {
174  if (third_body.default_efficiency == 0 &&
175  third_body.efficiencies.size() == 1) {
176  return Reaction::reactantString() + " (+" +
177  third_body.efficiencies.begin()->first + ")";
178  } else {
179  return Reaction::reactantString() + " (+M)";
180  }
181 }
182 
183 std::string FalloffReaction::productString() const {
184  if (third_body.default_efficiency == 0 &&
185  third_body.efficiencies.size() == 1) {
186  return Reaction::productString() + " (+" +
187  third_body.efficiencies.begin()->first + ")";
188  } else {
189  return Reaction::productString() + " (+M)";
190  }
191 }
192 
195  if (low_rate.preExponentialFactor() < 0 ||
197  throw CanteraError("FalloffReaction::validate", "Negative "
198  "pre-exponential factor found for reaction '" + equation() + "'");
199  }
200 }
201 
202 ChemicallyActivatedReaction::ChemicallyActivatedReaction()
203 {
205 }
206 
207 ChemicallyActivatedReaction::ChemicallyActivatedReaction(
208  const Composition& reactants_, const Composition& products_,
209  const Arrhenius& low_rate_, const Arrhenius& high_rate_,
210  const ThirdBody& tbody)
211  : FalloffReaction(reactants_, products_, low_rate, high_rate, tbody)
212 {
214 }
215 
216 PlogReaction::PlogReaction()
217  : Reaction(PLOG_RXN)
218 {
219 }
220 
221 PlogReaction::PlogReaction(const Composition& reactants_,
222  const Composition& products_, const Plog& rate_)
223  : Reaction(PLOG_RXN, reactants_, products_)
224  , rate(rate_)
225 {
226 }
227 
228 ChebyshevReaction::ChebyshevReaction()
229  : Reaction(CHEBYSHEV_RXN)
230 {
231 }
232 
233 ChebyshevReaction::ChebyshevReaction(const Composition& reactants_,
234  const Composition& products_,
235  const ChebyshevRate& rate_)
236  : Reaction(CHEBYSHEV_RXN, reactants_, products_)
237  , rate(rate_)
238 {
239 }
240 
241 InterfaceReaction::InterfaceReaction()
242  : is_sticking_coefficient(false)
243 {
245 }
246 
247 InterfaceReaction::InterfaceReaction(const Composition& reactants_,
248  const Composition& products_,
249  const Arrhenius& rate_,
250  bool isStick)
251  : ElementaryReaction(reactants_, products_, rate_)
252  , is_sticking_coefficient(isStick)
253 {
255 }
256 
257 ElectrochemicalReaction::ElectrochemicalReaction()
258  : film_resistivity(0.0)
259  , beta(0.0)
260  , exchange_current_density_formulation(false)
261 {
262 }
263 
264 ElectrochemicalReaction::ElectrochemicalReaction(const Composition& reactants_,
265  const Composition& products_,
266  const Arrhenius& rate_)
267  : InterfaceReaction(reactants_, products_, rate_)
268  , film_resistivity(0.0)
269  , beta(0.0)
270  , exchange_current_density_formulation(false)
271 {
272 }
273 
274 
275 Arrhenius readArrhenius(const XML_Node& arrhenius_node)
276 {
277  return Arrhenius(getFloat(arrhenius_node, "A", "toSI"),
278  getFloat(arrhenius_node, "b"),
279  getFloat(arrhenius_node, "E", "actEnergy") / GasConstant);
280 }
281 
282 //! Parse falloff parameters, given a rateCoeff node
283 /*!
284  * @verbatim
285  <falloff type="Troe"> 0.5 73.2 5000. 9999. </falloff>
286  @endverbatim
287 */
288 void readFalloff(FalloffReaction& R, const XML_Node& rc_node)
289 {
290  XML_Node& falloff = rc_node.child("falloff");
291  std::vector<std::string> p;
292  vector_fp falloff_parameters;
293  getStringArray(falloff, p);
294  size_t np = p.size();
295  for (size_t n = 0; n < np; n++) {
296  falloff_parameters.push_back(fpValueCheck(p[n]));
297  }
298 
299  int falloff_type = 0;
300  if (lowercase(falloff["type"]) == "lindemann") {
301  falloff_type = SIMPLE_FALLOFF;
302  if (np != 0) {
303  throw CanteraError("readFalloff", "Lindemann parameterization "
304  "takes no parameters, but " + int2str(np) + "were given");
305  }
306  } else if (lowercase(falloff["type"]) == "troe") {
307  falloff_type = TROE_FALLOFF;
308  if (np != 3 && np != 4) {
309  throw CanteraError("readFalloff", "Troe parameterization takes "
310  "3 or 4 parameters, but " + int2str(np) + "were given");
311  }
312  } else if (lowercase(falloff["type"]) == "sri") {
313  falloff_type = SRI_FALLOFF;
314  if (np != 3 && np != 5) {
315  throw CanteraError("readFalloff", "SRI parameterization takes "
316  "3 or 5 parameters, but " + int2str(np) + "were given");
317  }
318  } else {
319  throw CanteraError("readFalloff", "Unrecognized falloff type: '" +
320  falloff["type"] + "'");
321  }
322  R.falloff = newFalloff(falloff_type, falloff_parameters);
323 }
324 
325 void readEfficiencies(ThirdBody& tbody, const XML_Node& rc_node)
326 {
327  if (!rc_node.hasChild("efficiencies")) {
328  tbody.default_efficiency = 1.0;
329  return;
330  }
331  const XML_Node& eff_node = rc_node.child("efficiencies");
332  tbody.default_efficiency = fpValue(eff_node["default"]);
333  tbody.efficiencies = parseCompString(eff_node.value());
334 }
335 
336 void setupReaction(Reaction& R, const XML_Node& rxn_node)
337 {
338  // Reactant and product stoichiometries
339  R.reactants = parseCompString(rxn_node.child("reactants").value());
340  R.products = parseCompString(rxn_node.child("products").value());
341 
342  // Non-stoichiometric reaction orders
343  std::vector<XML_Node*> orders = rxn_node.getChildren("order");
344  for (size_t i = 0; i < orders.size(); i++) {
345  R.orders[orders[i]->attrib("species")] = orders[i]->fp_value();
346  }
347 
348  // Flags
349  R.id = rxn_node.attrib("id");
350  R.duplicate = rxn_node.hasAttrib("duplicate");
351  const std::string& rev = rxn_node["reversible"];
352  R.reversible = (rev == "true" || rev == "yes");
353 }
354 
355 void setupElementaryReaction(ElementaryReaction& R, const XML_Node& rxn_node)
356 {
357  const XML_Node& rc_node = rxn_node.child("rateCoeff");
358  if (rc_node.hasChild("Arrhenius")) {
359  R.rate = readArrhenius(rc_node.child("Arrhenius"));
360  } else if (rc_node.hasChild("Arrhenius_ExchangeCurrentDensity")) {
361  R.rate = readArrhenius(rc_node.child("Arrhenius_ExchangeCurrentDensity"));
362  } else {
363  throw CanteraError("setupElementaryReaction", "Couldn't find Arrhenius node");
364  }
365  if (rxn_node["negative_A"] == "yes") {
366  R.allow_negative_pre_exponential_factor = true;
367  }
368  if (rxn_node["negative_orders"] == "yes") {
369  R.allow_negative_orders = true;
370  }
371  setupReaction(R, rxn_node);
372 }
373 
374 void setupThreeBodyReaction(ThreeBodyReaction& R, const XML_Node& rxn_node)
375 {
376  readEfficiencies(R.third_body, rxn_node.child("rateCoeff"));
377  setupElementaryReaction(R, rxn_node);
378 }
379 
380 void setupFalloffReaction(FalloffReaction& R, const XML_Node& rxn_node)
381 {
382  XML_Node& rc_node = rxn_node.child("rateCoeff");
383  std::vector<XML_Node*> rates = rc_node.getChildren("Arrhenius");
384  int nLow = 0;
385  int nHigh = 0;
386  for (size_t i = 0; i < rates.size(); i++) {
387  XML_Node& node = *rates[i];
388  if (node["name"] == "") {
389  R.high_rate = readArrhenius(node);
390  nHigh++;
391  } else if (node["name"] == "k0") {
392  R.low_rate = readArrhenius(node);
393  nLow++;
394  } else {
395  throw CanteraError("setupFalloffReaction", "Found an Arrhenius XML "
396  "node with an unexpected type '" + node["name"] + "'");
397  }
398  }
399  if (nLow != 1 || nHigh != 1) {
400  throw CanteraError("setupFalloffReaction", "Did not find the correct "
401  "number of Arrhenius rate expressions");
402  }
403  readFalloff(R, rc_node);
404  readEfficiencies(R.third_body, rc_node);
405  setupReaction(R, rxn_node);
406 }
407 
408 void setupChemicallyActivatedReaction(ChemicallyActivatedReaction& R,
409  const XML_Node& rxn_node)
410 {
411  XML_Node& rc_node = rxn_node.child("rateCoeff");
412  std::vector<XML_Node*> rates = rc_node.getChildren("Arrhenius");
413  int nLow = 0;
414  int nHigh = 0;
415  for (size_t i = 0; i < rates.size(); i++) {
416  XML_Node& node = *rates[i];
417  if (node["name"] == "kHigh") {
418  R.high_rate = readArrhenius(node);
419  nHigh++;
420  } else if (node["name"] == "") {
421  R.low_rate = readArrhenius(node);
422  nLow++;
423  } else {
424  throw CanteraError("setupChemicallyActivatedReaction", "Found an "
425  "Arrhenius XML node with an unexpected type '" + node["name"] + "'");
426  }
427  }
428  if (nLow != 1 || nHigh != 1) {
429  throw CanteraError("setupChemicallyActivatedReaction", "Did not find "
430  "the correct number of Arrhenius rate expressions");
431  }
432  readFalloff(R, rc_node);
433  readEfficiencies(R.third_body, rc_node);
434  setupReaction(R, rxn_node);
435 }
436 
437 void setupPlogReaction(PlogReaction& R, const XML_Node& rxn_node)
438 {
439  XML_Node& rc = rxn_node.child("rateCoeff");
440  std::multimap<double, Arrhenius> rates;
441  for (size_t m = 0; m < rc.nChildren(); m++) {
442  const XML_Node& node = rc.child(m);
443  rates.insert(std::make_pair(getFloat(node, "P", "toSI"),
444  readArrhenius(node)));
445  }
446  R.rate = Plog(rates);
447  setupReaction(R, rxn_node);
448 }
449 
451 {
453  rate.validate(equation());
454 }
455 
456 void setupChebyshevReaction(ChebyshevReaction& R, const XML_Node& rxn_node)
457 {
458  XML_Node& rc = rxn_node.child("rateCoeff");
459  const XML_Node& coeff_node = rc.child("floatArray");
460  size_t nP = atoi(coeff_node["degreeP"].c_str());
461  size_t nT = atoi(coeff_node["degreeT"].c_str());
462 
463  vector_fp coeffs_flat;
464  getFloatArray(rc, coeffs_flat, false);
465  Array2D coeffs(nT, nP);
466  for (size_t t = 0; t < nT; t++) {
467  for (size_t p = 0; p < nP; p++) {
468  coeffs(t,p) = coeffs_flat[nP*t + p];
469  }
470  }
471  R.rate = ChebyshevRate(getFloat(rc, "Tmin", "toSI"),
472  getFloat(rc, "Tmax", "toSI"),
473  getFloat(rc, "Pmin", "toSI"),
474  getFloat(rc, "Pmax", "toSI"),
475  coeffs);
476  setupReaction(R, rxn_node);
477 }
478 
479 void setupInterfaceReaction(InterfaceReaction& R, const XML_Node& rxn_node)
480 {
481  if (lowercase(rxn_node["type"]) == "global") {
482  R.reaction_type = GLOBAL_RXN;
483  }
484  XML_Node& arr = rxn_node.child("rateCoeff").child("Arrhenius");
485  if (lowercase(arr["type"]) == "stick") {
486  R.is_sticking_coefficient = true;
487  R.sticking_species = arr["species"];
488  }
489  std::vector<XML_Node*> cov = arr.getChildren("coverage");
490  for (std::vector<XML_Node*>::iterator iter = cov.begin();
491  iter != cov.end();
492  ++iter)
493  {
494  CoverageDependency& cdep = R.coverage_deps[(*iter)->attrib("species")];
495  cdep.a = getFloat(**iter, "a", "toSI");
496  cdep.m = getFloat(**iter, "m");
497  cdep.E = getFloat(**iter, "e", "actEnergy") / GasConstant;
498  }
499  setupElementaryReaction(R, rxn_node);
500 }
501 
502 void setupElectrochemicalReaction(ElectrochemicalReaction& R,
503  const XML_Node& rxn_node)
504 {
505  // Fix reaction_type for some specialized reaction types
506  std::string type = lowercase(rxn_node["type"]);
507  if (type == "butlervolmer") {
508  R.reaction_type = BUTLERVOLMER_RXN;
509  } else if (type == "butlervolmer_noactivitycoeffs") {
510  R.reaction_type = BUTLERVOLMER_NOACTIVITYCOEFFS_RXN;
511  } else if (type == "surfaceaffinity") {
512  R.reaction_type = SURFACEAFFINITY_RXN;
513  } else if (type == "global") {
514  R.reaction_type = GLOBAL_RXN;
515  }
516 
517  XML_Node& rc = rxn_node.child("rateCoeff");
518  std::string rc_type = lowercase(rc["type"]);
519  if (rc_type == "exchangecurrentdensity") {
520  R.exchange_current_density_formulation = true;
521  } else if (rc_type != "" && rc_type != "arrhenius") {
522  throw CanteraError("setupElectrochemicalReaction",
523  "Unknown rate coefficient type: '" + rc_type + "'");
524  }
525  if (rc.hasChild("Arrhenius_ExchangeCurrentDensity")) {
526  R.exchange_current_density_formulation = true;
527  }
528 
529  if (rc.hasChild("electrochem") && rc.child("electrochem").hasAttrib("beta")) {
530  R.beta = fpValueCheck(rc.child("electrochem")["beta"]);
531  }
532 
533  getOptionalFloat(rxn_node, "filmResistivity", R.film_resistivity);
534 
535  setupInterfaceReaction(R, rxn_node);
536 
537  // For Butler Volmer reactions, install the orders for the exchange current
538  if (R.reaction_type == BUTLERVOLMER_NOACTIVITYCOEFFS_RXN ||
539  R.reaction_type == BUTLERVOLMER_RXN) {
540  if (!R.reversible) {
541  throw CanteraError("setupElectrochemicalReaction",
542  "A Butler-Volmer reaction must be reversible");
543  }
544 
545  R.orders.clear();
546  // Reaction orders based on species stoichiometric coefficients
547  R.allow_nonreactant_orders = true;
548  for (Composition::const_iterator iter = R.reactants.begin();
549  iter != R.reactants.end();
550  ++iter) {
551  R.orders[iter->first] += iter->second * (1.0 - R.beta);
552  }
553  for (Composition::const_iterator iter = R.products.begin();
554  iter != R.products.end();
555  ++iter) {
556  R.orders[iter->first] += iter->second * R.beta;
557  }
558  }
559 
560  // For affinity reactions, fill in the global reaction formulation terms
561  if (rxn_node.hasChild("reactionOrderFormulation")) {
562  Composition initial_orders = R.orders;
563  R.orders.clear();
564  R.allow_nonreactant_orders = true;
565  const XML_Node& rof_node = rxn_node.child("reactionOrderFormulation");
566  if (lowercase(rof_node["model"]) == "reactantorders") {
567  R.orders = initial_orders;
568  } else if (lowercase(rof_node["model"]) == "zeroorders") {
569  for (Composition::const_iterator iter = R.reactants.begin();
570  iter != R.reactants.end();
571  ++iter) {
572  R.orders[iter->first] = 0.0;
573  }
574  } else if (lowercase(rof_node["model"]) == "butlervolmerorders") {
575  // Reaction orders based on provided reaction orders
576  for (Composition::const_iterator iter = R.reactants.begin();
577  iter != R.reactants.end();
578  ++iter) {
579  double c = getValue(initial_orders, iter->first, iter->second);
580  R.orders[iter->first] += c * (1.0 - R.beta);
581  }
582  for (Composition::const_iterator iter = R.products.begin();
583  iter != R.products.end();
584  ++iter) {
585  double c = getValue(initial_orders, iter->first, iter->second);
586  R.orders[iter->first] += c * R.beta;
587  }
588 
589  } else {
590  throw CanteraError("setupElectrochemicalReaction", "unknown model "
591  "for reactionOrderFormulation XML_Node: '" +
592  rof_node["model"] + "'");
593  }
594  }
595 
596  // Override orders based on the <orders> node
597  if (rxn_node.hasChild("orders")) {
598  Composition orders = parseCompString(rxn_node.child("orders").value());
599  for (Composition::iterator iter = orders.begin();
600  iter != orders.end();
601  ++iter) {
602  R.orders[iter->first] = iter->second;
603  }
604  }
605 }
606 
607 shared_ptr<Reaction> newReaction(const XML_Node& rxn_node)
608 {
609  std::string type = lowercase(rxn_node["type"]);
610 
611  // Modify the reaction type for edge reactions which contain electrochemical
612  // reaction data
613  if (rxn_node.child("rateCoeff").hasChild("electrochem") && type == "edge") {
614  type = "electrochemical";
615  }
616 
617  // Create a new Reaction object of the appropriate type
618  if (type == "elementary" || type == "arrhenius" || type == "") {
619  shared_ptr<ElementaryReaction> R(new ElementaryReaction());
620  setupElementaryReaction(*R, rxn_node);
621  return R;
622 
623  } else if (type == "threebody" || type == "three_body") {
624  shared_ptr<ThreeBodyReaction> R(new ThreeBodyReaction());
625  setupThreeBodyReaction(*R, rxn_node);
626  return R;
627 
628  } else if (type == "falloff") {
629  shared_ptr<FalloffReaction> R(new FalloffReaction());
630  setupFalloffReaction(*R, rxn_node);
631  return R;
632 
633  } else if (type == "chemact" || type == "chemically_activated") {
634  shared_ptr<ChemicallyActivatedReaction> R(new ChemicallyActivatedReaction());
635  setupChemicallyActivatedReaction(*R, rxn_node);
636  return R;
637 
638  } else if (type == "plog" || type == "pdep_arrhenius") {
639  shared_ptr<PlogReaction> R(new PlogReaction());
640  setupPlogReaction(*R, rxn_node);
641  return R;
642 
643  } else if (type == "chebyshev") {
644  shared_ptr<ChebyshevReaction> R(new ChebyshevReaction());
645  setupChebyshevReaction(*R, rxn_node);
646  return R;
647 
648  } else if (type == "interface" || type == "surface" || type == "edge" ||
649  type == "global") {
650  shared_ptr<InterfaceReaction> R(new InterfaceReaction());
651  setupInterfaceReaction(*R, rxn_node);
652  return R;
653 
654  } else if (type == "electrochemical" ||
655  type == "butlervolmer_noactivitycoeffs" ||
656  type == "butlervolmer" ||
657  type == "surfaceaffinity") {
658  shared_ptr<ElectrochemicalReaction> R(new ElectrochemicalReaction());
659  setupElectrochemicalReaction(*R, rxn_node);
660  return R;
661 
662  } else {
663  throw CanteraError("newReaction",
664  "Unknown reaction type '" + rxn_node["type"] + "'");
665  }
666 }
667 
668 std::vector<shared_ptr<Reaction> > getReactions(const XML_Node& node)
669 {
670  std::vector<shared_ptr<Reaction> > all_reactions;
671  std::vector<XML_Node*> reaction_nodes =
672  node.child("reactionData").getChildren("reaction");
673 
674  for (std::vector<XML_Node*>::iterator iter = reaction_nodes.begin();
675  iter != reaction_nodes.end();
676  ++iter)
677  {
678  all_reactions.push_back(newReaction(**iter));
679  }
680  return all_reactions;
681 }
682 
683 }
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
const int PLOG_RXN
A pressure-dependent rate expression consisting of several Arrhenius rate expressions evaluated at di...
Definition: reaction_defs.h:50
virtual std::string reactantString() const
The reactant side of the chemical equation for this reaction.
Definition: Reaction.cpp:60
void readFalloff(FalloffReaction &R, const XML_Node &rc_node)
Parse falloff parameters, given a rateCoeff node.
Definition: Reaction.cpp:288
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:39
virtual std::string reactantString() const
The reactant side of the chemical equation for this reaction.
Definition: Reaction.cpp:149
int reaction_type
Type of the reaction.
Definition: Reaction.h:43
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
A reaction which follows mass-action kinetics with a modified Arrhenius reaction rate.
Definition: Reaction.h:77
const int INTERFACE_RXN
A reaction occurring on an interface, e.g a surface or edge.
Definition: reaction_defs.h:75
A pressure-dependent reaction parameterized by a bi-variate Chebyshev polynomial in temperature and p...
Definition: Reaction.h:178
shared_ptr< Falloff > newFalloff(int type, const vector_fp &c)
Return a pointer to a new falloff function calculator.
virtual void validate()
Ensure that the rate constant and other parameters for this reaction are valid.
Definition: Reaction.cpp:193
virtual void validate()
Ensure that the rate constant and other parameters for this reaction are valid.
Definition: Reaction.cpp:118
const int CHEBYSHEV_RXN
A general gas-phase pressure-dependent reaction where k(T,P) is defined in terms of a bivariate Cheby...
Definition: reaction_defs.h:56
const int SURFACEAFFINITY_RXN
This is a surface reaction that is formulated using the affinity representation, common in the geoche...
Definition: reaction_defs.h:92
virtual std::string productString() const
The product side of the chemical equation for this reaction.
Definition: Reaction.cpp:183
virtual std::string productString() const
The product side of the chemical equation for this reaction.
Definition: Reaction.cpp:153
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
virtual std::string reactantString() const
The reactant side of the chemical equation for this reaction.
Definition: Reaction.cpp:173
Parameterizations for reaction falloff functions.
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
Definition: stringUtils.cpp:73
A pressure-dependent reaction parameterized by logarithmically interpolating between Arrhenius rate e...
Definition: Reaction.h:166
const int CHEMACT_RXN
A chemical activation reaction.
Definition: reaction_defs.h:64
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:573
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:29
Header file for class Cantera::Array2D.
const int FALLOFF_RXN
The general form for a gas-phase association or dissociation reaction, with a pressure-dependent rate...
Definition: reaction_defs.h:42
virtual void validate()
Ensure that the rate constant and other parameters for this reaction are valid.
Definition: Reaction.cpp:450
shared_ptr< Falloff > falloff
Falloff function which determines how low_rate and high_rate are combined to determine the rate const...
Definition: Reaction.h:148
std::map< std::string, doublereal > Composition
Map from string names to doubles.
Definition: ct_defs.h:153
A reaction occurring on an interface (i.e. a SurfPhase or an EdgePhase)
Definition: Reaction.h:204
A reaction that is first-order in [M] at low pressure, like a third-body reaction, but zeroth-order in [M] as pressure increases.
Definition: Reaction.h:126
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:99
shared_ptr< Reaction > newReaction(const XML_Node &rxn_node)
Create a new Reaction object for the reaction defined in rxn_node
Definition: Reaction.cpp:607
void validate(const std::string &equation)
Check to make sure that the rate expression is finite over a range of temperatures at each interpolat...
Definition: RxnRates.cpp:209
Intermediate class which stores data about a reaction and its rate parameterization so that it can be...
Definition: Reaction.h:20
const U & getValue(const std::map< T, U > &m, const T &key)
Const accessor for a value in a std::map.
Definition: utilities.h:714
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:563
double preExponentialFactor() const
Return the pre-exponential factor A (in m, kmol, s to powers depending on the reaction order) ...
Definition: RxnRates.h:106
const int THREE_BODY_RXN
A gas-phase reaction that requires a third-body collision partner.
Definition: reaction_defs.h:36
Arrhenius reaction rate type depends only on temperature.
Definition: RxnRates.h:31
virtual std::string productString() const
The product side of the chemical equation for this reaction.
Definition: Reaction.cpp:77
const int GLOBAL_RXN
A global reaction.
compositionMap parseCompString(const std::string &ss, const std::vector< std::string > &names)
Parse a composition string into a map consisting of individual key:composition pairs.
std::string equation() const
The chemical equation for this reaction.
Definition: Reaction.cpp:94
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:157
Composition efficiencies
Map of species to third body efficiency.
Definition: Reaction.h:101
virtual void validate()
Ensure that the rate constant and other parameters for this reaction are valid.
Definition: Reaction.cpp:35
void getStringArray(const XML_Node &node, std::vector< std::string > &v)
This function interprets the value portion of an XML element as a string.
Definition: ctml.cpp:503
size_t getFloatArray(const XML_Node &node, std::vector< doublereal > &v, const bool convert, const std::string &unitsString, const std::string &nodeName)
This function reads the current node or a child node of the current node with the default name...
Definition: ctml.cpp:323
A reaction with a non-reacting third body "M" that acts to add or remove energy from the reacting spe...
Definition: Reaction.h:110
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
const int ELEMENTARY_RXN
A reaction with a rate coefficient that depends only on temperature and voltage that also obeys mass-...
Definition: reaction_defs.h:30
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:194
Arrhenius high_rate
The rate constant in the high-pressure limit.
Definition: Reaction.h:141
Arrhenius low_rate
The rate constant in the low-pressure limit.
Definition: Reaction.h:138
const int BUTLERVOLMER_NOACTIVITYCOEFFS_RXN
This is a surface reaction that is formulated using the Butler-Volmer formulation and using concentra...
Definition: reaction_defs.h:80
const int BUTLERVOLMER_RXN
This is a surface reaction that is formulated using the Butler-Volmer formulation.
Definition: reaction_defs.h:86
std::vector< shared_ptr< Reaction > > getReactions(const XML_Node &node)
Create Reaction objects for all <reaction> nodes in an XML document.
Definition: Reaction.cpp:668
doublereal fpValueCheck(const std::string &val)
Translate a string into one doublereal value, with error checking.
double default_efficiency
The default third body efficiency for species not listed in efficiencies.
Definition: Reaction.h:105
An interface reaction which involves charged species.
Definition: Reaction.h:227
ThirdBody third_body
Relative efficiencies of third-body species in enhancing the reaction rate.
Definition: Reaction.h:144
void getChildren(const std::string &name, std::vector< XML_Node * > &children) const
Get a vector of pointers to XML_Node containing all of the children of the current node which matches...
Definition: xml.cpp:915
A reaction where the rate decreases as pressure increases due to collisional stabilization of a react...
Definition: Reaction.h:155
bool getOptionalFloat(const XML_Node &parent, const std::string &name, doublereal &fltRtn, const std::string &type)
Get an optional floating-point value from a child element.
Definition: ctml.cpp:252