Cantera  2.3.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.0)
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.0)
269  , exchange_current_density_formulation(false)
270 {
271 }
272 
273 
274 Arrhenius readArrhenius(const XML_Node& arrhenius_node)
275 {
276  return Arrhenius(getFloat(arrhenius_node, "A", "toSI"),
277  getFloat(arrhenius_node, "b"),
278  getFloat(arrhenius_node, "E", "actEnergy") / GasConstant);
279 }
280 
281 //! Parse falloff parameters, given a rateCoeff node
282 /*!
283  * @verbatim
284  <falloff type="Troe"> 0.5 73.2 5000. 9999. </falloff>
285  @endverbatim
286 */
287 void readFalloff(FalloffReaction& R, const XML_Node& rc_node)
288 {
289  XML_Node& falloff = rc_node.child("falloff");
290  std::vector<std::string> p;
291  vector_fp falloff_parameters;
292  getStringArray(falloff, p);
293  size_t np = p.size();
294  for (size_t n = 0; n < np; n++) {
295  falloff_parameters.push_back(fpValueCheck(p[n]));
296  }
297 
298  int falloff_type = 0;
299  if (ba::iequals(falloff["type"], "lindemann")) {
300  falloff_type = SIMPLE_FALLOFF;
301  if (np != 0) {
302  throw CanteraError("readFalloff", "Lindemann parameterization "
303  "takes no parameters, but {} were given", np);
304  }
305  } else if (ba::iequals(falloff["type"], "troe")) {
306  falloff_type = TROE_FALLOFF;
307  if (np != 3 && np != 4) {
308  throw CanteraError("readFalloff", "Troe parameterization takes "
309  "3 or 4 parameters, but {} were given", np);
310  }
311  } else if (ba::iequals(falloff["type"], "sri")) {
312  falloff_type = SRI_FALLOFF;
313  if (np != 3 && np != 5) {
314  throw CanteraError("readFalloff", "SRI parameterization takes "
315  "3 or 5 parameters, but {} were given", np);
316  }
317  } else {
318  throw CanteraError("readFalloff", "Unrecognized falloff type: '{}'",
319  falloff["type"]);
320  }
321  R.falloff = newFalloff(falloff_type, falloff_parameters);
322 }
323 
324 void readEfficiencies(ThirdBody& tbody, const XML_Node& rc_node)
325 {
326  if (!rc_node.hasChild("efficiencies")) {
327  tbody.default_efficiency = 1.0;
328  return;
329  }
330  const XML_Node& eff_node = rc_node.child("efficiencies");
331  tbody.default_efficiency = fpValue(eff_node["default"]);
332  tbody.efficiencies = parseCompString(eff_node.value());
333 }
334 
335 void setupReaction(Reaction& R, const XML_Node& rxn_node)
336 {
337  // Reactant and product stoichiometries
338  R.reactants = parseCompString(rxn_node.child("reactants").value());
339  R.products = parseCompString(rxn_node.child("products").value());
340 
341  // Non-stoichiometric reaction orders
342  std::vector<XML_Node*> orders = rxn_node.getChildren("order");
343  for (size_t i = 0; i < orders.size(); i++) {
344  R.orders[orders[i]->attrib("species")] = orders[i]->fp_value();
345  }
346 
347  // Flags
348  R.id = rxn_node.attrib("id");
349  R.duplicate = rxn_node.hasAttrib("duplicate");
350  const std::string& rev = rxn_node["reversible"];
351  R.reversible = (rev == "true" || rev == "yes");
352 }
353 
354 void setupElementaryReaction(ElementaryReaction& R, const XML_Node& rxn_node)
355 {
356  const XML_Node& rc_node = rxn_node.child("rateCoeff");
357  if (rc_node.hasChild("Arrhenius")) {
358  R.rate = readArrhenius(rc_node.child("Arrhenius"));
359  } else if (rc_node.hasChild("Arrhenius_ExchangeCurrentDensity")) {
360  R.rate = readArrhenius(rc_node.child("Arrhenius_ExchangeCurrentDensity"));
361  } else {
362  throw CanteraError("setupElementaryReaction", "Couldn't find Arrhenius node");
363  }
364  if (rxn_node["negative_A"] == "yes") {
365  R.allow_negative_pre_exponential_factor = true;
366  }
367  if (rxn_node["negative_orders"] == "yes") {
368  R.allow_negative_orders = true;
369  }
370  if (rxn_node["nonreactant_orders"] == "yes") {
371  R.allow_nonreactant_orders = true;
372  }
373  setupReaction(R, rxn_node);
374 }
375 
376 void setupThreeBodyReaction(ThreeBodyReaction& R, const XML_Node& rxn_node)
377 {
378  readEfficiencies(R.third_body, rxn_node.child("rateCoeff"));
379  setupElementaryReaction(R, rxn_node);
380 }
381 
382 void setupFalloffReaction(FalloffReaction& R, const XML_Node& rxn_node)
383 {
384  XML_Node& rc_node = rxn_node.child("rateCoeff");
385  std::vector<XML_Node*> rates = rc_node.getChildren("Arrhenius");
386  int nLow = 0;
387  int nHigh = 0;
388  for (size_t i = 0; i < rates.size(); i++) {
389  XML_Node& node = *rates[i];
390  if (node["name"] == "") {
391  R.high_rate = readArrhenius(node);
392  nHigh++;
393  } else if (node["name"] == "k0") {
394  R.low_rate = readArrhenius(node);
395  nLow++;
396  } else {
397  throw CanteraError("setupFalloffReaction", "Found an Arrhenius XML "
398  "node with an unexpected type '" + node["name"] + "'");
399  }
400  }
401  if (nLow != 1 || nHigh != 1) {
402  throw CanteraError("setupFalloffReaction", "Did not find the correct "
403  "number of Arrhenius rate expressions");
404  }
405  readFalloff(R, rc_node);
406  readEfficiencies(R.third_body, rc_node);
407  setupReaction(R, rxn_node);
408 }
409 
410 void setupChemicallyActivatedReaction(ChemicallyActivatedReaction& R,
411  const XML_Node& rxn_node)
412 {
413  XML_Node& rc_node = rxn_node.child("rateCoeff");
414  std::vector<XML_Node*> rates = rc_node.getChildren("Arrhenius");
415  int nLow = 0;
416  int nHigh = 0;
417  for (size_t i = 0; i < rates.size(); i++) {
418  XML_Node& node = *rates[i];
419  if (node["name"] == "kHigh") {
420  R.high_rate = readArrhenius(node);
421  nHigh++;
422  } else if (node["name"] == "") {
423  R.low_rate = readArrhenius(node);
424  nLow++;
425  } else {
426  throw CanteraError("setupChemicallyActivatedReaction", "Found an "
427  "Arrhenius XML node with an unexpected type '" + node["name"] + "'");
428  }
429  }
430  if (nLow != 1 || nHigh != 1) {
431  throw CanteraError("setupChemicallyActivatedReaction", "Did not find "
432  "the correct number of Arrhenius rate expressions");
433  }
434  readFalloff(R, rc_node);
435  readEfficiencies(R.third_body, rc_node);
436  setupReaction(R, rxn_node);
437 }
438 
439 void setupPlogReaction(PlogReaction& R, const XML_Node& rxn_node)
440 {
441  XML_Node& rc = rxn_node.child("rateCoeff");
442  std::multimap<double, Arrhenius> rates;
443  for (size_t m = 0; m < rc.nChildren(); m++) {
444  const XML_Node& node = rc.child(m);
445  rates.insert({getFloat(node, "P", "toSI"), readArrhenius(node)});
446  }
447  R.rate = Plog(rates);
448  setupReaction(R, rxn_node);
449 }
450 
452 {
454  rate.validate(equation());
455 }
456 
457 void setupChebyshevReaction(ChebyshevReaction& R, const XML_Node& rxn_node)
458 {
459  XML_Node& rc = rxn_node.child("rateCoeff");
460  const XML_Node& coeff_node = rc.child("floatArray");
461  size_t nP = atoi(coeff_node["degreeP"].c_str());
462  size_t nT = atoi(coeff_node["degreeT"].c_str());
463 
464  vector_fp coeffs_flat;
465  getFloatArray(rc, coeffs_flat, false);
466  Array2D coeffs(nT, nP);
467  for (size_t t = 0; t < nT; t++) {
468  for (size_t p = 0; p < nP; p++) {
469  coeffs(t,p) = coeffs_flat[nP*t + p];
470  }
471  }
472  R.rate = ChebyshevRate(getFloat(rc, "Tmin", "toSI"),
473  getFloat(rc, "Tmax", "toSI"),
474  getFloat(rc, "Pmin", "toSI"),
475  getFloat(rc, "Pmax", "toSI"),
476  coeffs);
477  setupReaction(R, rxn_node);
478 }
479 
480 void setupInterfaceReaction(InterfaceReaction& R, const XML_Node& rxn_node)
481 {
482  if (ba::iequals(rxn_node["type"], "global")) {
483  R.reaction_type = GLOBAL_RXN;
484  }
485  XML_Node& arr = rxn_node.child("rateCoeff").child("Arrhenius");
486  if (ba::iequals(arr["type"], "stick")) {
487  R.is_sticking_coefficient = true;
488  R.sticking_species = arr["species"];
489 
490  if (ba::iequals(arr["motz_wise"], "true")) {
491  R.use_motz_wise_correction = true;
492  } else if (ba::iequals(arr["motz_wise"], "false")) {
493  R.use_motz_wise_correction = false;
494  } else {
495  // Default value for all reactions
496  XML_Node* parent = rxn_node.parent();
497  if (parent && parent->name() == "reactionData"
498  && ba::iequals((*parent)["motz_wise"], "true")) {
499  R.use_motz_wise_correction = true;
500  }
501  }
502  }
503  std::vector<XML_Node*> cov = arr.getChildren("coverage");
504  for (const auto& node : cov) {
505  CoverageDependency& cdep = R.coverage_deps[node->attrib("species")];
506  cdep.a = getFloat(*node, "a", "toSI");
507  cdep.m = getFloat(*node, "m");
508  cdep.E = getFloat(*node, "e", "actEnergy") / GasConstant;
509  }
510  setupElementaryReaction(R, rxn_node);
511 }
512 
513 void setupElectrochemicalReaction(ElectrochemicalReaction& R,
514  const XML_Node& rxn_node)
515 {
516  // Fix reaction_type for some specialized reaction types
517  std::string type = ba::to_lower_copy(rxn_node["type"]);
518  if (type == "butlervolmer") {
519  R.reaction_type = BUTLERVOLMER_RXN;
520  } else if (type == "butlervolmer_noactivitycoeffs") {
521  R.reaction_type = BUTLERVOLMER_NOACTIVITYCOEFFS_RXN;
522  } else if (type == "surfaceaffinity") {
523  R.reaction_type = SURFACEAFFINITY_RXN;
524  } else if (type == "global") {
525  R.reaction_type = GLOBAL_RXN;
526  }
527 
528  XML_Node& rc = rxn_node.child("rateCoeff");
529  std::string rc_type = ba::to_lower_copy(rc["type"]);
530  if (rc_type == "exchangecurrentdensity") {
531  R.exchange_current_density_formulation = true;
532  } else if (rc_type != "" && rc_type != "arrhenius") {
533  throw CanteraError("setupElectrochemicalReaction",
534  "Unknown rate coefficient type: '" + rc_type + "'");
535  }
536  if (rc.hasChild("Arrhenius_ExchangeCurrentDensity")) {
537  R.exchange_current_density_formulation = true;
538  }
539 
540  if (rc.hasChild("electrochem") && rc.child("electrochem").hasAttrib("beta")) {
541  R.beta = fpValueCheck(rc.child("electrochem")["beta"]);
542  }
543 
544  getOptionalFloat(rxn_node, "filmResistivity", R.film_resistivity);
545  setupInterfaceReaction(R, rxn_node);
546 
547  // For Butler Volmer reactions, install the orders for the exchange current
548  if (R.reaction_type == BUTLERVOLMER_NOACTIVITYCOEFFS_RXN ||
549  R.reaction_type == BUTLERVOLMER_RXN) {
550  if (!R.reversible) {
551  throw CanteraError("setupElectrochemicalReaction",
552  "A Butler-Volmer reaction must be reversible");
553  }
554 
555  R.orders.clear();
556  // Reaction orders based on species stoichiometric coefficients
557  R.allow_nonreactant_orders = true;
558  for (const auto& sp : R.reactants) {
559  R.orders[sp.first] += sp.second * (1.0 - R.beta);
560  }
561  for (const auto& sp : R.products) {
562  R.orders[sp.first] += sp.second * R.beta;
563  }
564  }
565 
566  // For affinity reactions, fill in the global reaction formulation terms
567  if (rxn_node.hasChild("reactionOrderFormulation")) {
568  Composition initial_orders = R.orders;
569  R.orders.clear();
570  R.allow_nonreactant_orders = true;
571  const XML_Node& rof_node = rxn_node.child("reactionOrderFormulation");
572  if (ba::iequals(rof_node["model"], "reactantorders")) {
573  R.orders = initial_orders;
574  } else if (ba::iequals(rof_node["model"], "zeroorders")) {
575  for (const auto& sp : R.reactants) {
576  R.orders[sp.first] = 0.0;
577  }
578  } else if (ba::iequals(rof_node["model"], "butlervolmerorders")) {
579  // Reaction orders based on provided reaction orders
580  for (const auto& sp : R.reactants) {
581  double c = getValue(initial_orders, sp.first, sp.second);
582  R.orders[sp.first] += c * (1.0 - R.beta);
583  }
584  for (const auto& sp : R.products) {
585  double c = getValue(initial_orders, sp.first, sp.second);
586  R.orders[sp.first] += c * R.beta;
587  }
588  } else {
589  throw CanteraError("setupElectrochemicalReaction", "unknown model "
590  "for reactionOrderFormulation XML_Node: '" +
591  rof_node["model"] + "'");
592  }
593  }
594 
595  // Override orders based on the <orders> node
596  if (rxn_node.hasChild("orders")) {
597  Composition orders = parseCompString(rxn_node.child("orders").value());
598  for (const auto& order : orders) {
599  R.orders[order.first] = order.second;
600  }
601  }
602 }
603 
604 shared_ptr<Reaction> newReaction(const XML_Node& rxn_node)
605 {
606  std::string type = ba::to_lower_copy(rxn_node["type"]);
607 
608  // Modify the reaction type for edge reactions which contain electrochemical
609  // reaction data
610  if (rxn_node.child("rateCoeff").hasChild("electrochem") && type == "edge") {
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
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:299
void readFalloff(FalloffReaction &R, const XML_Node &rc_node)
Parse falloff parameters, given a rateCoeff node.
Definition: Reaction.cpp:287
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.
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:451
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
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:604
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
const U & getValue(const std::map< T, U > &m, const T &key)
Const accessor for a value in a std::map.
Definition: utilities.h:537
Base class for falloff function calculators.
Definition: Falloff.h:26
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.
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:470
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:178
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
Namespace for the Cantera kernel.
Definition: application.cpp:29
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:226