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