Cantera  2.1.2
importKinetics.cpp
Go to the documentation of this file.
1 /**
2  * @file importKinetics.cpp
3  * Declarations of global routines for the importing
4  * of kinetics data from XML files (see \ref inputfiles).
5  *
6  * This file contains routines which are global routines, i.e.,
7  * not part of any object. These routine take as input, ctml
8  * pointers to data, and pointers to %Cantera objects. The purpose
9  * of these routines is to initialize the %Cantera objects with data
10  * from the ctml tree structures.
11  */
12 // Copyright 2002 California Institute of Technology
13 
16 
17 // Cantera includes
27 #include "cantera/base/global.h"
29 
30 #include "cantera/base/xml.h"
31 #include "cantera/base/ctml.h"
32 
33 using namespace ctml;
34 using namespace std;
35 
36 namespace Cantera
37 {
38 
39 ReactionRules::ReactionRules() :
40  skipUndeclaredSpecies(false),
41  skipUndeclaredThirdBodies(false),
42  allowNegativeA(false)
43 {
44 }
45 
46 //! these are all used to check for duplicate reactions
47 class rxninfo
48 {
49 public:
50  std::vector<ReactionData*> m_rdata;
51 
52  //! Map of (key indicating participating species) to reaction numbers
53  //! Used to speed up duplicate reaction checks.
54  std::map<unsigned long int, std::vector<size_t> > m_participants;
55 
56  /**
57  * Install an individual reaction into a kinetics manager. The
58  * data for the reaction is in the xml_node r. In other words, r
59  * points directly to a ctml element named "reaction". i refers
60  * to the number id of the reaction in the kinetics object.
61  *
62  * @param i Reaction number.
63  * @param r XML_Node containing reaction data.
64  * @param kin Kinetics manager to which reaction will be added.
65  * @param default_phase Default phase for locating a species
66  * @param rules Rule for handling reactions with missing species
67  * (skip or flag as error)
68  * @param validate_rxn If true, check that this reaction is not a
69  * duplicate of one already entered, and check that
70  * the reaction balances.
71  *
72  * @ingroup kineticsmgr
73  */
74  bool installReaction(int i, const XML_Node& r, Kinetics& kin,
75  std::string default_phase, ReactionRules& rules,
76  bool validate_rxn) ;
77 
78  ~rxninfo() {
79  for (size_t i = 0; i < m_rdata.size(); i++) {
80  delete m_rdata[i];
81  }
82  }
83 };
84 
86  const ReactionData& rdata, doublereal errorTolerance)
87 {
88  doublereal kstoich;
89 
90  map<string, double> bal, balr, balp;
91  bal.clear();
92  balp.clear();
93  balr.clear();
94  //cout << "checking " << rdata.equation << endl;
95  size_t np = rdata.products.size();
96 
97  // iterate over the products
98  for (size_t index = 0; index < np; index++) {
99  size_t kp = rdata.products[index]; // index of the product in 'kin'
100  size_t n = kin.speciesPhaseIndex(kp); // phase this product belongs to
101  size_t klocal = kp - kin.kineticsSpeciesIndex(0,n); // index within this phase
102  kstoich = rdata.pstoich[index]; // product stoichiometric coeff
103  const ThermoPhase& ph = kin.speciesPhase(kp);
104  for (size_t m = 0; m < ph.nElements(); m++) {
105  bal[ph.elementName(m)] += kstoich*ph.nAtoms(klocal,m);
106  balp[ph.elementName(m)] += kstoich*ph.nAtoms(klocal,m);
107  //cout << "product species " << ph.speciesName(klocal) << " has " << ph.nAtoms(klocal,m)
108  // << " atoms of " << ph.elementName(m) << " and kstoich = " << kstoich << endl;
109  }
110  }
111  for (size_t index = 0; index < rdata.reactants.size(); index++) {
112  size_t kr = rdata.reactants[index];
113  size_t n = kin.speciesPhaseIndex(kr);
114  //klocal = kr - kin.start(n);
115  size_t klocal = kr - kin.kineticsSpeciesIndex(0,n);
116  kstoich = rdata.rstoich[index];
117  const ThermoPhase& ph = kin.speciesPhase(kr);
118  for (size_t m = 0; m < ph.nElements(); m++) {
119  bal[ph.elementName(m)] -= kstoich*ph.nAtoms(klocal,m);
120  balr[ph.elementName(m)] += kstoich*ph.nAtoms(klocal,m);
121  //cout << "reactant species " << ph.speciesName(klocal) << " has " << ph.nAtoms(klocal,m)
122  // << " atoms of " << ph.elementName(m) << " and kstoich = " << kstoich << endl;
123  }
124  }
125 
126  map<string, double>::iterator b = bal.begin();
127  string msg = "\n\tElement Reactants Products";
128  bool ok = true;
129  doublereal err, elemsum;
130  for (; b != bal.end(); ++b) {
131  elemsum = fabs(balr[b->first]) + fabs(balp[b->first]);
132  if (elemsum > 0.0) {
133  err = fabs(b->second/elemsum);
134  if (err > errorTolerance) {
135  ok = false;
136  msg += "\n\t"+b->first+" "+ fp2str(balr[b->first])
137  +" "+ fp2str(balp[b->first]);
138  }
139  }
140  }
141  if (!ok) {
142  msg = "The following reaction is unbalanced:\n\t"
143  + rdata.equation + "\n" + msg + "\n";
144  throw CanteraError("checkRxnElementBalance",msg);
145  }
146 }
147 
148 bool getReagents(const XML_Node& rxn, Kinetics& kin, int rp,
149  std::string default_phase, std::vector<size_t>& spnum,
150  vector_fp& stoich, vector_fp& order,
151  const ReactionRules& rules)
152 {
153 
154  string rptype;
155 
156  /*
157  * The id of reactants and products are kept in child elements
158  * of reaction, named "reactants" and "products". We search
159  * the xml tree for these children based on the value of rp,
160  * and store the xml element pointer here.
161  */
162  if (rp == 1) {
163  rptype = "reactants";
164  } else {
165  rptype = "products";
166  }
167  const XML_Node& rg = rxn.child(rptype);
168 
169  /*
170  * The species and stoichiometric coefficient for the species
171  * are stored as a colon separated pair. Get all of these
172  * pairs in the reactions/products object.
173  */
174  vector<string> key, val;
175  getPairs(rg, key, val);
176 
177  /*
178  * Loop over each of the pairs and process them
179  */
180  doublereal ord, stch;
181  string ph, sp;
182  map<string, size_t> speciesMap;
183  for (size_t n = 0; n < key.size(); n++) {
184  sp = key[n]; // sp is the string name for species
185  ph = "";
186  /*
187  * Search for the species in the kinetics object using the
188  * member function kineticsSpeciesIndex(). We will search
189  * for the species in all phases defined in the kinetics operator.
190  */
191  size_t isp = kin.kineticsSpeciesIndex(sp);
192  if (isp == npos) {
193  if (rules.skipUndeclaredSpecies) {
194  return false;
195  } else {
196  throw CanteraError("getReagents",
197  "Undeclared reactant or product species "+sp);
198  return false;
199  }
200  }
201 
202  /*
203  * For each reagent, we store the the species number, isp
204  * the stoichiometric coefficient, val[n], and the order
205  * species in the reaction rate expression. We assume mass
206  * action kinetics here, but will modify this below for
207  * specified species.
208  */
209  spnum.push_back(isp);
210  stch = fpValue(val[n]);
211  stoich.push_back(stch);
212  ord = doublereal(stch);
213  order.push_back(ord);
214  //cout << key[n] << " " << isp << " " << stch << endl;
215 
216  /*
217  * Needed to process reaction orders below.
218  */
219  speciesMap[sp] = order.size();
220  }
221 
222  /*
223  * Check to see if reaction orders have been specified.
224  */
225  if (rp == 1 && rxn.hasChild("order")) {
226  vector<XML_Node*> ord;
227  rxn.getChildren("order",ord);
228  doublereal forder;
229  for (size_t nn = 0; nn < ord.size(); nn++) {
230  const XML_Node& oo = *ord[nn];
231  string sp = oo["species"];
232  size_t loc = speciesMap[sp];
233  if (loc == 0)
234  throw CanteraError("getReagents",
235  "reaction order specified for non-reactant: "
236  +sp);
237  forder = fpValue(oo());
238  if (forder < 0.0) {
239  throw CanteraError("getReagents",
240  "reaction order must be non-negative");
241  }
242  // replace the stoichiometric coefficient
243  // stored above in 'order' with the specified
244  // reaction order
245  order[loc-1] = forder;
246  }
247  }
248  return true;
249 }
250 
251 /**
252  * getArrhenius() parses the xml element called Arrhenius.
253  * The Arrhenius expression is
254  * \f[ k = A T^(b) exp (-E_a / RT). \f]
255  */
256 static void getArrhenius(const XML_Node& node, int& labeled,
257  doublereal& A, doublereal& b, doublereal& E)
258 {
259 
260  if (node["name"] == "k0") {
261  labeled = -1;
262  } else if (node["name"] == "kHigh") {
263  labeled = 1;
264  } else {
265  labeled = 0;
266  }
267  /*
268  * We parse the children for the A, b, and E components.
269  */
270  A = getFloat(node, "A", "toSI");
271  b = getFloat(node, "b");
272  E = getFloat(node, "E", "actEnergy");
273  E /= GasConstant;
274 }
275 
276 /**
277  * getStick() processes the XML element called Stick that specifies
278  * the sticking coefficient reaction. This routine will
279  * translate the sticking coefficient value into a "normal"
280  * rate constant for the surface reaction.
281  *
282  * Output
283  * -----------
284  * Output is the normal Arrhenius expressions for a surface
285  * reaction rate constant.
286  *
287  * A - units such that rate of rxn has kmol/m^2/s when
288  * A is multiplied by activity concentrations of
289  * reactants in the normal manner.
290  * n - unitless
291  * E - Units 1/Kelvin
292  */
293 static void getStick(const XML_Node& node, Kinetics& kin,
294  ReactionData& r, doublereal& A, doublereal& b, doublereal& E)
295 {
296  size_t nr = r.reactants.size();
297  size_t k, klocal, not_surf = 0;
298  size_t np = 0;
299  doublereal f = 1.0;
300  doublereal order;
301  /*
302  * species is the name of the special reactant whose surface
303  * flux rate will be calculated.
304  * isp = species # in the local phase
305  * ispKinetics = species # in the kinetics object
306  * ispPhaseIndex = phase # of the special species
307  */
308  string spname = node["species"];
309  ThermoPhase& th = kin.speciesPhase(spname);
310  size_t isp = th.speciesIndex(spname);
311  size_t ispKinetics = kin.kineticsSpeciesIndex(spname);
312  size_t ispPhaseIndex = kin.speciesPhaseIndex(ispKinetics);
313 
314  doublereal ispMW = th.molecularWeights()[isp];
315  doublereal sc;
316 
317  // loop over the reactants
318  for (size_t n = 0; n < nr; n++) {
319  k = r.reactants[n];
320  order = r.rorder[n]; // stoich coeff
321 
322  // get the phase species k belongs to
323  np = kin.speciesPhaseIndex(k);
324  const ThermoPhase& p = kin.thermo(np);
325 
326  // get the local index of species k in this phase
327  klocal = p.speciesIndex(kin.kineticsSpeciesName(k));
328 
329  // if it is a surface species, divide f by the standard
330  // concentration for this species, in order to convert
331  // from concentration units used in the law of mass action
332  // to coverages used in the sticking probability
333  // expression
334  if (p.eosType() == cSurf || p.eosType() == cEdge) {
335  sc = p.standardConcentration(klocal);
336  f /= pow(sc, order);
337  }
338  // Otherwise:
339  else {
340  // We only allow one species to be in the phase
341  // containing the special sticking coefficient
342  // species.
343  if (ispPhaseIndex == np) {
344  not_surf++;
345  }
346  // Other bulk phase species on the other side
347  // of ther interface are treated like surface
348  // species.
349  else {
350  sc = p.standardConcentration(klocal);
351  f /= pow(sc, order);
352  }
353  }
354  }
355  if (not_surf != 1) {
356  throw CanteraError("getStick",
357  "reaction probabilities can only be used in "
358  "reactions with exactly 1 gas/liquid species.");
359  }
360 
361  doublereal cbar = sqrt(8.0*GasConstant/(Pi*ispMW));
362  A = 0.25 * getFloat(node, "A", "toSI") * cbar * f;
363  b = getFloat(node, "b") + 0.5;
364  E = getFloat(node, "E", "actEnergy");
365  E /= GasConstant;
366 }
367 
368 static void getCoverageDependence(const XML_Node& node,
369  thermo_t& surfphase, ReactionData& rdata)
370 {
371  vector<XML_Node*> cov;
372  node.getChildren("coverage", cov);
373  size_t k, nc = cov.size();
374  doublereal e;
375  string spname;
376  if (nc > 0) {
377  for (size_t n = 0; n < nc; n++) {
378  const XML_Node& cnode = *cov[n];
379  spname = cnode["species"];
380  k = surfphase.speciesIndex(spname);
381  rdata.cov.push_back(doublereal(k));
382  rdata.cov.push_back(getFloat(cnode, "a"));
383  rdata.cov.push_back(getFloat(cnode, "m"));
384  e = getFloat(cnode, "e", "actEnergy");
385  rdata.cov.push_back(e/GasConstant);
386  }
387  }
388 }
389 
390 //! Get falloff parameters for a reaction.
391 /*!
392  * This routine reads the falloff XML node and extracts parameters into a
393  * vector of doubles
394  *
395  * @verbatim
396  <falloff type="Troe"> 0.5 73.2 5000. 9999. </falloff>
397  @endverbatim
398 */
399 static void getFalloff(const XML_Node& f, ReactionData& rdata)
400 {
401  string type = f["type"];
402  vector<string> p;
403  getStringArray(f,p);
404  vector_fp c;
405  int np = static_cast<int>(p.size());
406  for (int n = 0; n < np; n++) {
407  c.push_back(fpValue(p[n]));
408  }
409  if (type == "Troe") {
410  if (np == 4) {
411  rdata.falloffType = TROE4_FALLOFF;
412  } else if (np == 3) {
413  rdata.falloffType = TROE3_FALLOFF;
414  } else {
415  throw CanteraError("getFalloff()", "Troe parameterization is specified by number of parameters, "
416  + int2str(np) + ", is not equal to 3 or 4");
417  }
418  } else if (type == "SRI") {
419  if (np == 5) {
420  rdata.falloffType = SRI5_FALLOFF;
421  if (c[2] < 0.0) {
422  throw CanteraError("getFalloff()", "SRI5 m_c parameter is less than zero: " + fp2str(c[2]));
423  }
424  if (c[3] < 0.0) {
425  throw CanteraError("getFalloff()", "SRI5 m_d parameter is less than zero: " + fp2str(c[3]));
426  }
427  } else if (np == 3) {
428  rdata.falloffType = SRI3_FALLOFF;
429  if (c[2] < 0.0) {
430  throw CanteraError("getFalloff()", "SRI3 m_c parameter is less than zero: " + fp2str(c[2]));
431  }
432  } else {
433  throw CanteraError("getFalloff()", "SRI parameterization is specified by number of parameters, "
434  + int2str(np) + ", is not equal to 3 or 5");
435  }
436  }
437  rdata.falloffParameters = c;
438 }
439 
440 /**
441  * Get the enhanced collision efficiencies. It is assumed that the
442  * reaction mechanism is homogeneous, so that all species belong
443  * to phase(0) of 'kin'.
444  */
445 static void getEfficiencies(const XML_Node& eff, Kinetics& kin,
446  ReactionData& rdata, const ReactionRules& rules)
447 {
448  // set the default collision efficiency
449  rdata.default_3b_eff = fpValue(eff["default"]);
450 
451  vector<string> key, val;
452  getPairs(eff, key, val);
453  string nm;
454  string phse = kin.thermo(0).id();
455  for (size_t n = 0; n < key.size(); n++) { // ; bb != ee; ++bb) {
456  nm = key[n];// bb->first;
457  size_t k = kin.kineticsSpeciesIndex(nm, phse);
458  if (k != npos) {
459  rdata.thirdBodyEfficiencies[k] = fpValue(val[n]); // bb->second;
460  } else if (!rules.skipUndeclaredThirdBodies) {
461  throw CanteraError("getEfficiencies", "Encountered third-body "
462  "efficiency for undefined species \"" + nm + "\"\n"
463  "while adding reaction " + int2str(rdata.number+1) + ".");
464  }
465  }
466 }
467 
468 void getRateCoefficient(const XML_Node& kf, Kinetics& kin,
469  ReactionData& rdata, const ReactionRules& rules)
470 {
471  if (rdata.reactionType == PLOG_RXN) {
472  rdata.rateCoeffType = PLOG_REACTION_RATECOEFF_TYPE;
473  for (size_t m = 0; m < kf.nChildren(); m++) {
474  const XML_Node& node = kf.child(m);
475  double p = getFloat(node, "P", "toSI");
476  vector_fp& rate = rdata.plogParameters.insert(
477  std::make_pair(p, vector_fp()))->second;
478  rate.resize(3);
479  rate[0] = getFloat(node, "A", "toSI");
480  rate[1] = getFloat(node, "b");
481  rate[2] = getFloat(node, "E", "actEnergy") / GasConstant;
482  }
483 
484  } else if (rdata.reactionType == CHEBYSHEV_RXN) {
485  rdata.rateCoeffType = CHEBYSHEV_REACTION_RATECOEFF_TYPE;
486  rdata.chebTmin = getFloat(kf, "Tmin", "toSI");
487  rdata.chebTmax = getFloat(kf, "Tmax", "toSI");
488  rdata.chebPmin = getFloat(kf, "Pmin", "toSI");
489  rdata.chebPmax = getFloat(kf, "Pmax", "toSI");
490  const XML_Node& coeffs = kf.child("floatArray");
491  rdata.chebDegreeP = atoi(coeffs["degreeP"].c_str());
492  rdata.chebDegreeT = atoi(coeffs["degreeT"].c_str());
493  getFloatArray(kf, rdata.chebCoeffs, false);
494 
495  } else {
496 
497  string type = kf.attrib("type");
498  if (type == "") {
499  type = "Arrhenius";
500  rdata.rateCoeffType = ARRHENIUS_REACTION_RATECOEFF_TYPE;
501  }
502  if (type == "ExchangeCurrentDensity") {
503  rdata.rateCoeffType = EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE;
504  } else if (type == "Arrhenius") {
505 
506  } else {
507  throw CanteraError("getRateCoefficient", "Unknown type: " + type);
508  }
509 
510  vector_fp c_alt(3,0.0), c_base(3,0.0);
511  for (size_t m = 0; m < kf.nChildren(); m++) {
512  const XML_Node& c = kf.child(m);
513  string nm = c.name();
514  int labeled=0;
515 
516  if (nm == "Arrhenius") {
517  vector_fp coeff(3);
518  if (c["type"] == "stick") {
519  getStick(c, kin, rdata, coeff[0], coeff[1], coeff[2]);
520  c_base = coeff;
521  } else {
522  getArrhenius(c, labeled, coeff[0], coeff[1], coeff[2]);
523  if (labeled == 0 || rdata.reactionType == THREE_BODY_RXN
524  || rdata.reactionType == ELEMENTARY_RXN) {
525  c_base = coeff;
526  } else {
527  c_alt = coeff;
528  }
529  }
530  if (rdata.reactionType == SURFACE_RXN || rdata.reactionType == EDGE_RXN) {
531  getCoverageDependence(c,
532  kin.thermo(kin.surfacePhaseIndex()), rdata);
533  }
534 
535  if (coeff[0] < 0.0 && !rules.allowNegativeA) {
536  throw CanteraError("getRateCoefficient",
537  "negative A coefficient for reaction "+int2str(rdata.number));
538  }
539  } else if (nm == "Arrhenius_ExchangeCurrentDensity") {
540  vector_fp coeff(3);
541  getArrhenius(c, labeled, coeff[0], coeff[1], coeff[2]);
542  c_base = coeff;
543  rdata.rateCoeffType = EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE;
544  } else if (nm == "falloff") {
545  getFalloff(c, rdata);
546  } else if (nm == "efficiencies") {
547  getEfficiencies(c, kin, rdata, rules);
548  } else if (nm == "electrochem") {
549  rdata.beta = fpValue(c["beta"]);
550  }
551  }
552  /*
553  * Store the coefficients in the ReactionData object for return
554  * from this function.
555  */
556  if (rdata.reactionType == FALLOFF_RXN) {
557  rdata.rateCoeffParameters = c_base;
558  rdata.auxRateCoeffParameters = c_alt;
559  } else if (rdata.reactionType == CHEMACT_RXN) {
560  rdata.rateCoeffParameters = c_alt;
561  rdata.auxRateCoeffParameters = c_base;
562  } else {
563  rdata.rateCoeffParameters = c_base;
564  }
565 
566  }
567 }
568 
569 doublereal isDuplicateReaction(std::map<int, doublereal>& r1,
570  std::map<int, doublereal>& r2)
571 {
572 
573  map<int, doublereal>::const_iterator b = r1.begin(), e = r1.end();
574  int k1 = b->first;
575  doublereal ratio = 0.0;
576  if (r1[k1] == 0.0 || r2[k1] == 0.0) {
577  goto next;
578  }
579  ratio = r2[k1]/r1[k1];
580  ++b;
581  for (; b != e; ++b) {
582  k1 = b->first;
583  if (r1[k1] == 0.0 || r2[k1] == 0.0) {
584  goto next;
585  }
586  if (fabs(r2[k1]/r1[k1] - ratio) > 1.e-8) {
587  goto next;
588  }
589  }
590  return ratio;
591 next:
592  ratio = 0.0;
593  b = r1.begin();
594  k1 = b->first;
595  if (r1[k1] == 0.0 || r2[-k1] == 0.0) {
596  return 0.0;
597  }
598  ratio = r2[-k1]/r1[k1];
599  ++b;
600  for (; b != e; ++b) {
601  k1 = b->first;
602  if (r1[k1] == 0.0 || r2[-k1] == 0.0) {
603  return 0.0;
604  }
605  if (fabs(r2[-k1]/r1[k1] - ratio) > 1.e-8) {
606  return 0.0;
607  }
608  }
609  return ratio;
610 }
611 
612 bool rxninfo::installReaction(int iRxn, const XML_Node& r, Kinetics& kin,
613  string default_phase, ReactionRules& rules,
614  bool validate_rxn)
615 {
616  // Check to see that we are in fact at a reaction node
617  if (r.name() != "reaction") {
618  throw CanteraError(" rxninfo::installReaction",
619  " expected xml node reaction, got " + r.name());
620  }
621 
622  // We use the ReactionData object to store initial values read in from the
623  // xml data. Then, when we have collected everything we add the reaction to
624  // the kinetics object, kin, at the end of the routine.
625  ReactionData& rdata = **m_rdata.insert(m_rdata.end(), new ReactionData());
626  rdata.validate = validate_rxn;
627 
628  // Check to see if the reaction is specified to be a duplicate of another
629  // reaction. It's an error if the reaction is a duplicate and this is not
630  // set.
631  rdata.duplicate = (r.hasAttrib("duplicate")) ? 1 : 0;
632 
633  // Check to see if the reaction rate constant can be negative. It's an
634  // error if a negative rate constant is found and this is not set.
635  rules.allowNegativeA = (r.hasAttrib("negative_A")) ? 1 : 0;
636 
637  // Use the contents of the "equation" child element as the reaction's
638  // string representation. Post-process to convert "[" and "]" characters
639  // back into "<" and ">" which cannot easily be stored in an XML file. This
640  // reaction string is used only for display purposes. It is not parsed for
641  // the identities of reactants or products.
642  rdata.equation = (r.hasChild("equation")) ? r("equation") : "<no equation>";
643  for (size_t nn = 0; nn < rdata.equation.size(); nn++) {
644  if (rdata.equation[nn] == '[') {
645  rdata.equation[nn] = '<';
646  } else if (rdata.equation[nn] == ']') {
647  rdata.equation[nn] = '>';
648  }
649  }
650 
651  // get the reactants
652  bool ok = getReagents(r, kin, 1, default_phase, rdata.reactants,
653  rdata.rstoich, rdata.rorder, rules);
654 
655  // Get the products. We store the id of products in rdata.products
656  ok = ok && getReagents(r, kin, -1, default_phase, rdata.products,
657  rdata.pstoich, rdata.porder, rules);
658 
659  // if there was a problem getting either the reactants or the products,
660  // then abort.
661  if (!ok) {
662  return false;
663  }
664 
665  // check whether the reaction is specified to be
666  // reversible. Default is irreversible.
667  string isrev = r["reversible"];
668  rdata.reversible = (isrev == "yes" || isrev == "true");
669 
670  // If reaction orders are specified, then this reaction does not follow
671  // mass-action kinetics, and is not an elementary reaction. So check that
672  // it is not reversible, since computing the reverse rate from
673  // thermochemistry only works for elementary reactions. Set the type to
674  // global, so that kinetics managers will know to process the reaction
675  // orders.
676  if (r.hasChild("order")) {
677  if (rdata.reversible == true)
678  throw CanteraError("installReaction",
679  "reaction orders may only be given for "
680  "irreversible reactions");
681  rdata.global = true;
682  }
683 
684  // Some reactions can be elementary reactions but have fractional
685  // stoichiometries wrt to some products and reactants. An example of these
686  // are solid reactions involving phase transformations. Species with
687  // fractional stoichiometries must be from single-species phases with
688  // unity activities. For these reactions set the bool isReversibleWithFrac
689  // to true.
690  if (rdata.reversible == true) {
691  for (size_t i = 0; i < rdata.products.size(); i++) {
692  doublereal po = rdata.porder[i];
693  AssertTrace(po == rdata.pstoich[i]);
694  doublereal chk = po - 1.0 * int(po);
695  if (chk != 0.0) {
696  size_t k = rdata.products[i];
697  // Special case when k is a single species phase.
698  if (kin.speciesPhase(k).nSpecies() == 1) {
699  rdata.porder[i] = 0.0;
700  }
701 
702  rdata.isReversibleWithFrac = true;
703  }
704  }
705  for (size_t i = 0; i < rdata.reactants.size(); i++) {
706  doublereal ro = rdata.rorder[i];
707  AssertTrace(ro == rdata.rstoich[i]);
708  doublereal chk = ro - 1.0 * int(ro);
709  if (chk != 0.0) {
710  size_t k = rdata.reactants[i];
711  // Special case when k is a single species phase.
712  if (kin.speciesPhase(k).nSpecies() == 1) {
713  rdata.rorder[i] = 0.0;
714  }
715  rdata.isReversibleWithFrac = true;
716  }
717  }
718  }
719 
720  /*
721  * Search the reaction element for the attribute "type".
722  * If found, then branch on the type, to fill in appropriate
723  * fields in rdata.
724  */
726  string typ = r["type"];
727  if (typ == "falloff") {
728  rdata.reactionType = FALLOFF_RXN;
729  rdata.falloffType = SIMPLE_FALLOFF;
730  } else if (typ == "chemAct") {
731  rdata.reactionType = CHEMACT_RXN;
732  rdata.falloffType = SIMPLE_FALLOFF;
733  } else if (typ == "threeBody") {
735  } else if (typ == "plog") {
736  rdata.reactionType = PLOG_RXN;
737  } else if (typ == "chebyshev") {
738  rdata.reactionType = CHEBYSHEV_RXN;
739  } else if (typ == "surface") {
740  rdata.reactionType = SURFACE_RXN;
741  } else if (typ == "edge") {
742  rdata.reactionType = EDGE_RXN;
743  } else if (typ != "") {
744  throw CanteraError("installReaction", "Unknown reaction type: " + typ);
745  }
746 
747  rdata.number = iRxn;
748  rdata.rxn_number = iRxn;
749 
750  // Read the rate coefficient data from the XML file. Trigger an
751  // exception for negative A unless specifically authorized.
752  getRateCoefficient(r.child("rateCoeff"), kin, rdata, rules);
753 
754  if (validate_rxn) {
755  // Look for undeclared duplicate reactions.
756  unsigned long int participants = 0;
757  for (size_t nn = 0; nn < rdata.reactants.size(); nn++) {
758  rdata.net_stoich[-1 - int(rdata.reactants[nn])] -= rdata.rstoich[nn];
759  participants += rdata.reactants[nn];
760  }
761  for (size_t nn = 0; nn < rdata.products.size(); nn++) {
762  rdata.net_stoich[int(rdata.products[nn])+1] += rdata.pstoich[nn];
763  participants += 1000000 * rdata.products[nn];
764  }
765 
766  vector<size_t>& related = m_participants[participants];
767  for (size_t mm = 0; mm < related.size(); mm++) {
768  ReactionData& other = *m_rdata[related[mm]];
769  if (rdata.reactants.size() != other.reactants.size()) {
770  continue; // different numbers of reactants
771  } else if (rdata.reactionType != other.reactionType) {
772  continue; // different reaction types
773  } else if (rdata.duplicate && other.duplicate) {
774  continue; // marked duplicates
775  }
776  doublereal c = isDuplicateReaction(rdata.net_stoich, other.net_stoich);
777  if (c == 0) {
778  continue; // stoichiometries differ (not by a multiple)
779  } else if (c < 0.0 && !rdata.reversible && !other.reversible) {
780  continue; // irreversible reactions in opposite directions
781  } else if (rdata.reactionType == FALLOFF_RXN ||
782  rdata.reactionType == THREE_BODY_RXN ||
783  rdata.reactionType == CHEMACT_RXN) {
784  bool thirdBodyOk = true;
785  for (size_t k = 0; k < kin.nTotalSpecies(); k++) {
786  if (rdata.efficiency(k) * other.efficiency(k) != 0.0) {
787  thirdBodyOk = false;
788  }
789  }
790  if (thirdBodyOk) {
791  continue; // No overlap in third body efficiencies
792  }
793  }
794  string msg = string("Undeclared duplicate reactions detected: \n")
795  +"Reaction "+int2str(other.number+1)+": "+other.equation
796  +"\nReaction "+int2str(iRxn+1)+": "+rdata.equation+"\n";
797  throw CanteraError("installReaction", msg);
798  }
799  m_participants[participants].push_back(m_rdata.size() - 1);
800 
801  // Check to see that the elements balance in the reaction.
802  // Throw an error if they don't
803  checkRxnElementBalance(kin, rdata);
804  }
805 
806  // Ok we have read everything in about the reaction. Add it to the
807  // kinetics object by calling the Kinetics member function addReaction()
808  kin.addReaction(rdata);
809  return true;
810 }
811 
813  std::string default_phase, bool check_for_duplicates)
814 {
815  rxninfo _rxns;
816 
817  vector<XML_Node*> rarrays;
818  int itot = 0;
819  /*
820  * Search the children of the phase element for the
821  * xml element named reactionArray. If we can't find it,
822  * then return signaling having not found any reactions.
823  * Apparently, we allow multiple reactionArray elements here
824  * Each one will be processed sequentially, with the
825  * end result being purely additive.
826  */
827  p.getChildren("reactionArray",rarrays);
828  int na = static_cast<int>(rarrays.size());
829  if (na == 0) {
830  kin.finalize();
831  return false;
832  }
833  for (int n = 0; n < na; n++) {
834  /*
835  * Go get a reference to the current xml element,
836  * reactionArray. We will process this element now.
837  */
838  const XML_Node& rxns = *rarrays[n];
839  /*
840  * The reactionArray element has an attribute called,
841  * datasrc. The value of the attribute is the xml
842  * element comprising the top of the
843  * tree of reactions for the phase.
844  * Find this datasrc element starting with the root
845  * of the current xml node.
846  */
847  const XML_Node* rdata = get_XML_Node(rxns["datasrc"], &rxns.root());
848  /*
849  * If the reactionArray element has a child element named "skip", and
850  * if the attribute of skip called "species" has a value of "undeclared",
851  * we will set rxnrule.skipUndeclaredSpecies to 'true'. rxnrule is
852  * passed to the routine that parses each individual reaction so that
853  * the parser will skip all reactions containing an undefined species
854  * without throwing an error.
855  *
856  * Similarly, an attribute named "third_bodies" with the value of
857  * "undeclared" will skip undeclared third body efficiencies (while
858  * retaining the reaction and any other efficiencies).
859  */
860  ReactionRules rxnrule;
861  if (rxns.hasChild("skip")) {
862  const XML_Node& sk = rxns.child("skip");
863  string sskip = sk["species"];
864  if (sskip == "undeclared") {
865  rxnrule.skipUndeclaredSpecies = true;
866  }
867  if (sk["third_bodies"] == "undeclared") {
868  rxnrule.skipUndeclaredThirdBodies = true;
869  }
870  }
871  int i, nrxns = 0;
872  /*
873  * Search for child elements called include. We only include
874  * a reaction if it's tagged by one of the include fields.
875  * Or, we include all reactions if there are no include fields.
876  */
877  vector<XML_Node*> incl;
878  rxns.getChildren("include",incl);
879  int ninc = static_cast<int>(incl.size());
880 
881  vector<XML_Node*> allrxns;
882  rdata->getChildren("reaction",allrxns);
883  nrxns = static_cast<int>(allrxns.size());
884  // if no 'include' directive, then include all reactions
885  if (ninc == 0) {
886  for (i = 0; i < nrxns; i++) {
887  const XML_Node* r = allrxns[i];
888  if (r) {
889  if (_rxns.installReaction(itot, *r, kin,
890  default_phase, rxnrule, check_for_duplicates)) {
891  ++itot;
892  }
893  }
894  }
895  } else {
896  for (int nii = 0; nii < ninc; nii++) {
897  const XML_Node& ii = *incl[nii];
898  string imin = ii["min"];
899  string imax = ii["max"];
900 
901  string::size_type iwild = string::npos;
902  if (imax == imin) {
903  iwild = imin.find("*");
904  if (iwild != string::npos) {
905  imin = imin.substr(0,iwild);
906  imax = imin;
907  }
908  }
909 
910  for (i = 0; i < nrxns; i++) {
911  const XML_Node* r = allrxns[i];
912  string rxid;
913  if (r) {
914  rxid = (*r)["id"];
915  if (iwild != string::npos) {
916  rxid = rxid.substr(0,iwild);
917  }
918  /*
919  * To decide whether the reaction is included or not
920  * we do a lexical min max and operation. This
921  * sometimes has surprising results.
922  */
923  if ((rxid >= imin) && (rxid <= imax)) {
924  if (_rxns.installReaction(itot, *r, kin,
925  default_phase, rxnrule, check_for_duplicates)) {
926  ++itot;
927  }
928  }
929  }
930  }
931  }
932  }
933  }
934 
935  /*
936  * Finalize the installation of the kinetics, now that we know
937  * the true number of reactions in the mechanism, itot.
938  */
939  kin.finalize();
940 
941  return true;
942 }
943 
944 bool importKinetics(const XML_Node& phase, std::vector<ThermoPhase*> th,
945  Kinetics* k)
946 {
947 
948  if (k == 0) {
949  return false;
950  }
951 
952  Kinetics& kin = *k;
953 
954  // This phase will be the owning phase for the kinetics operator
955  // For interfaces, it is the surface phase between two volumes.
956  // For homogeneous kinetics, it's the current volumetric phase.
957  string owning_phase = phase["id"];
958 
959  bool check_for_duplicates = false;
960  if (phase.parent()->hasChild("validate")) {
961  const XML_Node& d = phase.parent()->child("validate");
962  if (d["reactions"] == "yes") {
963  check_for_duplicates = true;
964  }
965  }
966 
967  // if other phases are involved in the reaction mechanism,
968  // they must be listed in a 'phaseArray' child
969  // element. Homogeneous mechanisms do not need to include a
970  // phaseArray element.
971 
972  vector<string> phase_ids;
973  if (phase.hasChild("phaseArray")) {
974  const XML_Node& pa = phase.child("phaseArray");
975  getStringArray(pa, phase_ids);
976  }
977  phase_ids.push_back(owning_phase);
978 
979  int np = static_cast<int>(phase_ids.size());
980  int nt = static_cast<int>(th.size());
981 
982  // for each referenced phase, attempt to find its id among those
983  // phases specified.
984  bool phase_ok;
985 
986  string phase_id;
987  string msg = "";
988  for (int n = 0; n < np; n++) {
989  phase_id = phase_ids[n];
990  phase_ok = false;
991 
992  // loop over the supplied 'ThermoPhase' objects representing
993  // phases, to find an object with the same id.
994  for (int m = 0; m < nt; m++) {
995  if (th[m]->id() == phase_id) {
996  phase_ok = true;
997 
998  // if no phase with this id has been added to
999  //the kinetics manager yet, then add this one
1000  if (kin.phaseIndex(phase_id) == npos) {
1001  kin.addPhase(*th[m]);
1002  }
1003  }
1004  msg += " "+th[m]->id();
1005  }
1006  if (!phase_ok) {
1007  throw CanteraError("importKinetics",
1008  "phase "+phase_id+" not found. Supplied phases are:"+msg);
1009  }
1010  }
1011 
1012  // allocates arrays, etc. Must be called after the phases have
1013  // been added to 'kin', so that the number of species in each
1014  // phase is known.
1015  kin.init();
1016 
1017  // Install the reactions.
1018  return installReactionArrays(phase, kin, owning_phase, check_for_duplicates);
1019 }
1020 
1021 bool buildSolutionFromXML(XML_Node& root, const std::string& id,
1022  const std::string& nm, ThermoPhase* th, Kinetics* k)
1023 {
1024  XML_Node* x;
1025  x = get_XML_NameID(nm, string("#")+id, &root);
1026  // x = get_XML_Node(string("#")+id, &root);
1027  if (!x) {
1028  return false;
1029  }
1030 
1031  /*
1032  * Fill in the ThermoPhase object by querying the
1033  * const XML_Node tree located at x.
1034  */
1035  importPhase(*x, th);
1036  /*
1037  * Create a vector of ThermoPhase pointers of length 1
1038  * having the current th ThermoPhase as the entry.
1039  */
1040  vector<ThermoPhase*> phases(1);
1041  phases[0] = th;
1042  /*
1043  * Fill in the kinetics object k, by querying the
1044  * const XML_Node tree located by x. The source terms and
1045  * eventually the source term vector will be constructed
1046  * from the list of ThermoPhases in the vector, phases.
1047  */
1048  importKinetics(*x, phases, k);
1049  return true;
1050 }
1051 
1052 }
these are all used to check for duplicate reactions
XML_Node * get_XML_Node(const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
Definition: global.cpp:249
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
double efficiency(size_t k) const
Get the actual third-body efficiency for species k
Definition: ReactionData.h:152
doublereal nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
Definition: Phase.cpp:215
const int PLOG_RXN
A pressure-dependent rate expression consisting of several Arrhenius rate expressions evaluated at di...
Definition: reaction_defs.h:46
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:40
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
void checkRxnElementBalance(Kinetics &kin, const ReactionData &rdata, doublereal errorTolerance)
This function will check a specific reaction to see if the elements balance.
Header for a simple thermodynamics model of a surface phase derived from ThermoPhase, assuming an ideal solution model (see Thermodynamic Properties and class SurfPhase).
vector_fp falloffParameters
Values used in the falloff parameterization.
Definition: ReactionData.h:104
std::multimap< double, vector_fp > plogParameters
Arrhenius parameters for P-log reactions.
Definition: ReactionData.h:139
size_t nElements() const
Number of elements.
Definition: Phase.cpp:139
double chebPmin
Minimum pressure for Chebyshev fit.
Definition: ReactionData.h:143
int reactionType
Type of the reaction.
Definition: ReactionData.h:39
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:534
thermo_t & thermo(size_t n=0)
This method returns a reference to the nth ThermoPhase object defined in this kinetics mechanism...
Definition: Kinetics.h:288
vector_fp auxRateCoeffParameters
Vector of auxiliary rate coefficient parameters.
Definition: ReactionData.h:96
bool duplicate
True if the current reaction is marked as duplicate.
Definition: ReactionData.h:79
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:173
int falloffType
Type of falloff parameterization to use.
Definition: ReactionData.h:100
const int EDGE_RXN
A reaction occurring at a one-dimensional interface between two surface phases.
Definition: reaction_defs.h:71
const int CHEBYSHEV_RXN
A general pressure-dependent reaction where k(T,P) is defined in terms of a bivariate Chebyshev polyn...
Definition: reaction_defs.h:52
doublereal beta
for electrochemical reactions
Definition: ReactionData.h:133
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
vector_fp pstoich
Product stoichiometric coefficients, in the order given by products.
Definition: ReactionData.h:62
static void getStick(const XML_Node &node, Kinetics &kin, ReactionData &r, doublereal &A, doublereal &b, doublereal &E)
getStick() processes the XML element called Stick that specifies the sticking coefficient reaction...
std::string kineticsSpeciesName(size_t k) const
Return the name of the kth species in the kinetics manager.
Definition: Kinetics.cpp:186
vector_fp porder
Reaction order of the reverse reaction with respect to each product species, in the order given by pr...
Definition: ReactionData.h:55
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
size_t nTotalSpecies() const
The total number of species in all phases participating in the kinetics mechanism.
Definition: Kinetics.h:300
doublereal getFloat(const Cantera::XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:267
bool validate
Perform validation of the rate coefficient data.
Definition: ReactionData.h:41
static void getArrhenius(const XML_Node &node, int &labeled, doublereal &A, doublereal &b, doublereal &E)
getArrhenius() parses the xml element called Arrhenius.
const doublereal Pi
Pi.
Definition: ct_defs.h:51
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, HTML_logs (see Input File Handling, Diagnostic Output, Writing messages to the screen and Writing HTML Logfiles).
const int CHEMACT_RXN
A chemical activation reaction.
Definition: reaction_defs.h:60
bool buildSolutionFromXML(XML_Node &root, const std::string &id, const std::string &nm, ThermoPhase *th, Kinetics *k)
Build a single-phase ThermoPhase object with associated kinetics mechanism.
bool isReversibleWithFrac
Some reactions can be elementary reactions but have fractional stoichiometries with respect to some p...
Definition: ReactionData.h:131
vector_fp rateCoeffParameters
Vector of rate coefficient parameters.
Definition: ReactionData.h:91
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:584
std::map< size_t, doublereal > thirdBodyEfficiencies
Map of species index to third body efficiency.
Definition: ReactionData.h:68
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
Definition: ThermoPhase.h:487
ThermoPhase thermo_t
typedef for the ThermoPhase class
Definition: ThermoPhase.h:1684
bool installReactionArrays(const XML_Node &p, Kinetics &kin, std::string default_phase, bool check_for_duplicates)
Install information about reactions into the kinetics object, kin.
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:101
const int cSurf
A surface phase. Used by class SurfPhase.
Definition: mix_defs.h:40
const int FALLOFF_RXN
The general form for an association or dissociation reaction, with a pressure-dependent rate...
Definition: reaction_defs.h:38
virtual void init()
Prepare the class for the addition of reactions.
Definition: Kinetics.h:791
size_t chebDegreeT
Degree of Chebyshev fit in T.
Definition: ReactionData.h:145
Contains const definitions for types of species reference-state thermodynamics managers (see Species ...
std::string equation
The reaction equation. Used only for display purposes.
Definition: ReactionData.h:109
bool installReaction(int i, const XML_Node &r, Kinetics &kin, std::string default_phase, ReactionRules &rules, bool validate_rxn)
Install an individual reaction into a kinetics manager.
std::vector< size_t > products
Indices of product species.
Definition: ReactionData.h:45
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:229
size_t surfacePhaseIndex()
This returns the integer index of the phase which has ThermoPhase type cSurf.
Definition: Kinetics.h:263
bool importPhase(XML_Node &phase, ThermoPhase *th, SpeciesThermoFactory *spfactory)
Import a phase information into an empty thermophase object.
double chebPmax
Maximum pressure for Chebyshev fit.
Definition: ReactionData.h:144
bool getReagents(const XML_Node &rxn, Kinetics &kin, int rp, std::string default_phase, std::vector< size_t > &spnum, vector_fp &stoich, vector_fp &order, const ReactionRules &rules)
Get the reactants or products of a reaction.
bool importKinetics(const XML_Node &phase, std::vector< ThermoPhase * > th, Kinetics *k)
Import a reaction mechanism for a phase or an interface.
std::map< unsigned long int, std::vector< size_t > > m_participants
Map of (key indicating participating species) to reaction numbers Used to speed up duplicate reaction...
doublereal isDuplicateReaction(std::map< int, doublereal > &r1, std::map< int, doublereal > &r2)
This function returns a ratio if two reactions are duplicates of one another, and 0...
static void getFalloff(const XML_Node &f, ReactionData &rdata)
Get falloff parameters for a reaction.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
Definition: stringUtils.cpp:29
std::string name() const
Returns the name of the XML node.
Definition: xml.h:390
thermo_t & speciesPhase(const std::string &nm)
This function looks up the name of a species and returns a reference to the ThermoPhase object of the...
Definition: Kinetics.cpp:229
This file defines some constants used to specify reaction types.
Classes providing support for XML data files.
Public interface for kinetics managers.
Definition: Kinetics.h:131
int number
Index of this reaction within the mechanism.
Definition: ReactionData.h:42
Rules for parsing and installing reactions.
doublereal default_3b_eff
The default third body efficiency for species not listed in thirdBodyEfficiencies.
Definition: ReactionData.h:113
size_t chebDegreeP
Degree of Chebyshev fit in P.
Definition: ReactionData.h:146
Intermediate class which stores data about a reaction and its rate parameterization before adding the...
Definition: ReactionData.h:16
std::string id() const
Return the string id for the phase.
Definition: Phase.cpp:119
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:68
const int SURFACE_RXN
A reaction occurring on a surface.
Definition: reaction_defs.h:65
int getPairs(const Cantera::XML_Node &node, std::vector< std::string > &key, std::vector< std::string > &val)
This function interprets the value portion of an XML element as a series of "Pairs" separated by whit...
Definition: ctml.cpp:527
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:574
const int cEdge
An edge between two 2D surfaces.
Definition: mix_defs.h:58
const int THREE_BODY_RXN
A reaction that requires a third-body collision partner.
Definition: reaction_defs.h:32
size_t kineticsSpeciesIndex(size_t k, size_t n) const
The location of species k of phase n in species arrays.
Definition: Kinetics.h:331
std::map< int, doublereal > net_stoich
Net stoichiometric coefficients for participating species.
Definition: ReactionData.h:73
std::vector< size_t > reactants
Indices of reactant species.
Definition: ReactionData.h:44
vector_fp rstoich
Reactant stoichiometric coefficients, in the order given by reactants.
Definition: ReactionData.h:59
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:252
bool reversible
True if the current reaction is reversible. False otherwise.
Definition: ReactionData.h:76
int rateCoeffType
Type of the rate coefficient for the forward rate constant.
Definition: ReactionData.h:86
Definitions of global routines for the importing of data from XML files (see Input File Handling)...
const vector_fp & molecularWeights() const
Return a const reference to the internal vector of molecular weights.
Definition: Phase.cpp:505
#define AssertTrace(expr)
Assertion must be true or an error is thrown.
Definition: ctexceptions.h:216
Header for factory to build instances of classes that manage the standard-state thermodynamic propert...
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:165
void getStringArray(const Cantera::XML_Node &node, std::vector< std::string > &v)
This function interprets the value portion of an XML element as a string.
Definition: ctml.cpp:639
virtual int eosType() const
Equation of state type flag.
Definition: ThermoPhase.h:151
size_t speciesPhaseIndex(size_t k)
This function takes as an argument the kineticsSpecies index (i.e., the list index in the list of spe...
Definition: Kinetics.cpp:244
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:66
const int ELEMENTARY_RXN
A reaction with a rate coefficient that depends only on temperature.
Definition: reaction_defs.h:26
Contains declarations for string manipulation functions within Cantera.
bool global
True for "global" reactions which do not follow elementary mass action kinetics, i.e.
Definition: ReactionData.h:124
std::string elementName(size_t m) const
Name of the element with index m.
Definition: Phase.cpp:158
static void getEfficiencies(const XML_Node &eff, Kinetics &kin, ReactionData &rdata, const ReactionRules &rules)
Get the enhanced collision efficiencies.
void getRateCoefficient(const XML_Node &kf, Kinetics &kin, ReactionData &rdata, const ReactionRules &rules)
Read the rate coefficient data from the XML file.
virtual void addReaction(ReactionData &r)
Add a single reaction to the mechanism.
Definition: Kinetics.h:810
XML_Node & root() const
Return the root of the current XML_Node tree.
Definition: xml.cpp:1091
virtual void finalize()
Finish adding reactions and prepare for use.
Definition: Kinetics.cpp:290
Header file for class ThermoPhase, the base class for phases with thermodynamic properties, and the text for the Module thermoprops (see Thermodynamic Properties and class ThermoPhase).
virtual void addPhase(thermo_t &thermo)
Add a phase to the kinetics manager object.
Definition: Kinetics.cpp:255
XML_Node * parent() const
Returns a pointer to the parent node of the current node.
Definition: xml.cpp:563
double chebTmax
Maximum temperature for Chebyshev fit.
Definition: ReactionData.h:142
vector_fp chebCoeffs
Chebyshev coefficients. length chebDegreeT * chebDegreeP.
Definition: ReactionData.h:149
vector_fp rorder
Reaction order with respect to each reactant species, in the order given by reactants.
Definition: ReactionData.h:50
XML_Node * get_XML_NameID(const std::string &nameTarget, const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
Definition: global.cpp:271
size_t getFloatArray(const Cantera::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:419
Declarations for the EdgePhase ThermoPhase object, which models the interface between two surfaces (s...
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:594
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:916
size_t phaseIndex(const std::string &ph)
Return the phase index of a phase in the list of phases defined within the object.
Definition: Kinetics.h:250
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
Definition: xml.cpp:579
double chebTmin
Minimum temperature for Chebyshev fit.
Definition: ReactionData.h:141