Cantera  2.5.1
RxnRates.h
Go to the documentation of this file.
1 /**
2  * @file RxnRates.h
3  */
4 
5 // This file is part of Cantera. See License.txt in the top-level directory or
6 // at https://cantera.org/license.txt for license and copyright information.
7 
8 #ifndef CT_RXNRATES_H
9 #define CT_RXNRATES_H
10 
14 #include "cantera/base/global.h"
15 
16 #include <iostream>
17 
18 namespace Cantera
19 {
20 
21 class Array2D;
22 
23 //! Arrhenius reaction rate type depends only on temperature
24 /**
25  * A reaction rate coefficient of the following form.
26  *
27  * \f[
28  * k_f = A T^b \exp (-E/RT)
29  * \f]
30  */
31 class Arrhenius
32 {
33 public:
34  //! return the rate coefficient type.
35  /*!
36  * @deprecated To be removed after Cantera 2.5.
37  */
38  static int type() {
39  warn_deprecated("Arrhenius::type()",
40  "To be removed after Cantera 2.5.");
41  return ARRHENIUS_REACTION_RATECOEFF_TYPE;
42  }
43 
44  //! Default constructor.
45  Arrhenius();
46 
47  /// Constructor.
48  /// @param A pre-exponential. The unit system is
49  /// (kmol, m, s). The actual units depend on the reaction
50  /// order and the dimensionality (surface or bulk).
51  /// @param b Temperature exponent. Non-dimensional.
52  /// @param E Activation energy in temperature units. Kelvin.
53  Arrhenius(doublereal A, doublereal b, doublereal E);
54 
55  //! Update concentration-dependent parts of the rate coefficient.
56  /*!
57  * For this class, there are no concentration-dependent parts, so this
58  * method does nothing.
59  */
60  void update_C(const doublereal* c) {
61  }
62 
63  /**
64  * Update the value of the natural logarithm of the rate constant.
65  */
66  doublereal updateLog(doublereal logT, doublereal recipT) const {
67  return m_logA + m_b*logT - m_E*recipT;
68  }
69 
70  /**
71  * Update the value the rate constant.
72  *
73  * This function returns the actual value of the rate constant. It can be
74  * safely called for negative values of the pre-exponential factor.
75  */
76  doublereal updateRC(doublereal logT, doublereal recipT) const {
77  return m_A * std::exp(m_b*logT - m_E*recipT);
78  }
79 
80  //! Return the pre-exponential factor *A* (in m, kmol, s to powers depending
81  //! on the reaction order)
82  double preExponentialFactor() const {
83  return m_A;
84  }
85 
86  //! Return the temperature exponent *b*
87  double temperatureExponent() const {
88  return m_b;
89  }
90 
91  //! Return the activation energy divided by the gas constant (i.e. the
92  //! activation temperature) [K]
93  doublereal activationEnergy_R() const {
94  return m_E;
95  }
96 
97 protected:
98  doublereal m_logA, m_b, m_E, m_A;
99 };
100 
101 
102 /**
103  * An Arrhenius rate with coverage-dependent terms.
104  *
105  * The rate expression is given by [Kee, R. J., Coltrin, M. E., & Glarborg, P.
106  * (2005). Chemically reacting flow: theory and practice. John Wiley & Sons.
107  * Eq 11.113]:
108  * \f[
109  * k_f = A T^b \exp \left(
110  * \ln 10 \sum a_k \theta_k
111  * - \frac{1}{RT} \left( E_a + \sum E_k\theta_k \right)
112  * + \sum m_k \ln \theta_k
113  * \right)
114  * \f]
115  * or, equivalently, and as implemented in Cantera,
116  * \f[
117  * k_f = A T^b \exp \left( - \frac{E_a}{RT} \right)
118  * \prod_k 10^{a_k \theta_k} \theta_k^{m_k}
119  * \exp \left( \frac{- E_k \theta_k}{RT} \right)
120  * \f]
121  * where the parameters \f$ (a_k, E_k, m_k) \f$ describe the dependency on the
122  * surface coverage of species \f$k, \theta_k \f$.
123  */
125 {
126 
127 public:
128  /*!
129  * @deprecated To be removed after Cantera 2.5.
130  */
131  static int type() {
132  warn_deprecated("SurfaceArrhenius::type()",
133  "To be removed after Cantera 2.5.");
134  return SURF_ARRHENIUS_REACTION_RATECOEFF_TYPE;
135  }
136 
138  explicit SurfaceArrhenius(double A, double b, double Ta);
139 
140  //! Add a coverage dependency for species *k*, with exponential dependence
141  //! *a*, power-law exponent *m*, and activation energy dependence *e*,
142  //! where *e* is in Kelvin, i.e. energy divided by the molar gas constant.
143  void addCoverageDependence(size_t k, doublereal a,
144  doublereal m, doublereal e);
145 
146  void update_C(const doublereal* theta) {
147  m_acov = 0.0;
148  m_ecov = 0.0;
149  m_mcov = 0.0;
150  size_t k;
151  doublereal th;
152  for (size_t n = 0; n < m_ac.size(); n++) {
153  k = m_sp[n];
154  m_acov += m_ac[n] * theta[k];
155  m_ecov += m_ec[n] * theta[k];
156  }
157  for (size_t n = 0; n < m_mc.size(); n++) {
158  k = m_msp[n];
159  th = std::max(theta[k], Tiny);
160  m_mcov += m_mc[n]*std::log(th);
161  }
162  }
163 
164  /**
165  * Update the value of the rate constant.
166  *
167  * This function returns the actual value of the rate constant. It can be
168  * safely called for negative values of the pre-exponential factor.
169  */
170  doublereal updateRC(doublereal logT, doublereal recipT) const {
171  return m_A * std::exp(std::log(10.0)*m_acov + m_b*logT -
172  (m_E + m_ecov)*recipT + m_mcov);
173  }
174 
175  //! Return the pre-exponential factor *A* (in m, kmol, s to powers depending
176  //! on the reaction order) accounting coverage dependence.
177  /*!
178  * Returns reaction pre-exponent accounting for both *a* and *m*.
179  */
180  doublereal preExponentialFactor() const {
181  return m_A * std::exp(std::log(10.0)*m_acov + m_mcov);
182  }
183 
184  //! Return effective temperature exponent
185  doublereal temperatureExponent() const {
186  return m_b;
187  }
188 
189  //! Return the activation energy divided by the gas constant (i.e. the
190  //! activation temperature) [K], accounting coverage dependence.
191  doublereal activationEnergy_R() const {
192  return m_E + m_ecov;
193  }
194 
195 protected:
196  doublereal m_b, m_E, m_A;
197  doublereal m_acov, m_ecov, m_mcov;
198  std::vector<size_t> m_sp, m_msp;
199  vector_fp m_ac, m_ec, m_mc;
200 };
201 
202 
203 //! Pressure-dependent reaction rate expressed by logarithmically interpolating
204 //! between Arrhenius rate expressions at various pressures.
205 /*!
206  * Given two rate expressions at two specific pressures:
207  *
208  * * \f$ P_1: k_1(T) = A_1 T^{b_1} e^{-E_1 / RT} \f$
209  * * \f$ P_2: k_2(T) = A_2 T^{b_2} e^{-E_2 / RT} \f$
210  *
211  * The rate at an intermediate pressure \f$ P_1 < P < P_2 \f$ is computed as
212  * \f[
213  * \log k(T,P) = \log k_1(T) + \bigl(\log k_2(T) - \log k_1(T)\bigr)
214  * \frac{\log P - \log P_1}{\log P_2 - \log P_1}
215  * \f]
216  * Multiple rate expressions may be given at the same pressure, in which case
217  * the rate used in the interpolation formula is the sum of all the rates given
218  * at that pressure. For pressures outside the given range, the rate expression
219  * at the nearest pressure is used.
220  */
221 class Plog
222 {
223 public:
224  //! return the rate coefficient type.
225  /*!
226  * @deprecated To be removed after Cantera 2.5.
227  */
228  static int type() {
229  warn_deprecated("Plog::type()",
230  "To be removed after Cantera 2.5.");
231  return PLOG_REACTION_RATECOEFF_TYPE;
232  }
233 
234  //! Default constructor.
235  Plog() {}
236 
237  //! Constructor from Arrhenius rate expressions at a set of pressures
238  explicit Plog(const std::multimap<double, Arrhenius>& rates);
239 
240  //! Update concentration-dependent parts of the rate coefficient.
241  //! @param c natural log of the pressure in Pa
242  void update_C(const doublereal* c) {
243  logP_ = c[0];
244  if (logP_ > logP1_ && logP_ < logP2_) {
245  return;
246  }
247 
248  auto iter = pressures_.upper_bound(c[0]);
249  AssertThrowMsg(iter != pressures_.end(), "Plog::update_C",
250  "Pressure out of range: {}", logP_);
251  AssertThrowMsg(iter != pressures_.begin(), "Plog::update_C",
252  "Pressure out of range: {}", logP_);
253 
254  // upper interpolation pressure
255  logP2_ = iter->first;
256  ihigh1_ = iter->second.first;
257  ihigh2_ = iter->second.second;
258 
259  // lower interpolation pressure
260  logP1_ = (--iter)->first;
261  ilow1_ = iter->second.first;
262  ilow2_ = iter->second.second;
263 
264  rDeltaP_ = 1.0 / (logP2_ - logP1_);
265  }
266 
267  /**
268  * Update the value the rate constant.
269  *
270  * This function returns the actual value of the rate constant.
271  */
272  doublereal updateRC(doublereal logT, doublereal recipT) const {
273  double log_k1, log_k2;
274  if (ilow1_ == ilow2_) {
275  log_k1 = rates_[ilow1_].updateLog(logT, recipT);
276  } else {
277  double k = 1e-300; // non-zero to make log(k) finite
278  for (size_t i = ilow1_; i < ilow2_; i++) {
279  k += rates_[i].updateRC(logT, recipT);
280  }
281  log_k1 = std::log(k);
282  }
283 
284  if (ihigh1_ == ihigh2_) {
285  log_k2 = rates_[ihigh1_].updateLog(logT, recipT);
286  } else {
287  double k = 1e-300; // non-zero to make log(k) finite
288  for (size_t i = ihigh1_; i < ihigh2_; i++) {
289  k += rates_[i].updateRC(logT, recipT);
290  }
291  log_k2 = std::log(k);
292  }
293 
294  return std::exp(log_k1 + (log_k2-log_k1) * (logP_-logP1_) * rDeltaP_);
295  }
296 
297  //! Check to make sure that the rate expression is finite over a range of
298  //! temperatures at each interpolation pressure. This is potentially an
299  //! issue when one of the Arrhenius expressions at a particular pressure
300  //! has a negative pre-exponential factor.
301  void validate(const std::string& equation);
302 
303  //! Return the pressures and Arrhenius expressions which comprise this
304  //! reaction.
305  std::vector<std::pair<double, Arrhenius> > rates() const;
306 
307 protected:
308  //! log(p) to (index range) in the rates_ vector
309  std::map<double, std::pair<size_t, size_t> > pressures_;
310 
311  // Rate expressions which are referenced by the indices stored in pressures_
312  std::vector<Arrhenius> rates_;
313 
314  double logP_; //!< log(p) at the current state
315  double logP1_, logP2_; //!< log(p) at the lower / upper pressure reference
316 
317  //! Indices to the ranges within rates_ for the lower / upper pressure, such
318  //! that rates_[ilow1_] through rates_[ilow2_] (inclusive) are the rates
319  //! expressions which are combined to form the rate at the lower reference
320  //! pressure.
321  size_t ilow1_, ilow2_, ihigh1_, ihigh2_;
322 
323  double rDeltaP_; //!< reciprocal of (logP2 - logP1)
324 };
325 
326 //! Pressure-dependent rate expression where the rate coefficient is expressed
327 //! as a bivariate Chebyshev polynomial in temperature and pressure.
328 /*!
329  * The rate constant can be written as:
330  * \f[
331  * \log k(T,P) = \sum_{t=1}^{N_T} \sum_{p=1}^{N_P} \alpha_{tp}
332  * \phi_t(\tilde{T}) \phi_p(\tilde{P})
333  * \f]
334  * where \f$\alpha_{tp}\f$ are the constants defining the rate, \f$\phi_n(x)\f$
335  * is the Chebyshev polynomial of the first kind of degree *n* evaluated at
336  * *x*, and
337  * \f[
338  * \tilde{T} \equiv \frac{2T^{-1} - T_\mathrm{min}^{-1} - T_\mathrm{max}^{-1}}
339  * {T_\mathrm{max}^{-1} - T_\mathrm{min}^{-1}}
340  * \f]
341  * \f[
342  * \tilde{P} \equiv \frac{2 \log P - \log P_\mathrm{min} - \log P_\mathrm{max}}
343  * {\log P_\mathrm{max} - \log P_\mathrm{min}}
344  * \f]
345  * are reduced temperature and reduced pressures which map the ranges
346  * \f$ (T_\mathrm{min}, T_\mathrm{max}) \f$ and
347  * \f$ (P_\mathrm{min}, P_\mathrm{max}) \f$ to (-1, 1).
348  *
349  * A Chebyshev rate expression is specified in terms of the coefficient matrix
350  * \f$ \alpha \f$ and the temperature and pressure ranges. Note that the
351  * Chebyshev polynomials are not defined outside the interval (-1,1), and
352  * therefore extrapolation of rates outside the range of temperatures and
353  * pressures for which they are defined is strongly discouraged.
354  */
356 {
357 public:
358  //! return the rate coefficient type.
359  /*!
360  * @deprecated To be removed after Cantera 2.5.
361  */
362  static int type() {
363  warn_deprecated("ChebyshevRate::type()",
364  "To be removed after Cantera 2.5.");
365  return CHEBYSHEV_REACTION_RATECOEFF_TYPE;
366  }
367 
368  //! Default constructor.
370 
371  //! Constructor directly from coefficient array
372  /*
373  * @param Tmin Minimum temperature [K]
374  * @param Tmax Maximum temperature [K]
375  * @param Pmin Minimum pressure [Pa]
376  * @param Pmax Maximum pressure [Pa]
377  * @param coeffs Coefficient array dimensioned `nT` by `nP` where `nT` and
378  * `nP` are the number of temperatures and pressures used in the fit,
379  * respectively.
380  */
381  ChebyshevRate(double Tmin, double Tmax, double Pmin, double Pmax,
382  const Array2D& coeffs);
383 
384  //! Update concentration-dependent parts of the rate coefficient.
385  //! @param c base-10 logarithm of the pressure in Pa
386  void update_C(const doublereal* c) {
387  double Pr = (2 * c[0] + PrNum_) * PrDen_;
388  double Cnm1 = Pr;
389  double Cn = 1;
390  double Cnp1;
391  for (size_t j = 0; j < nT_; j++) {
392  dotProd_[j] = chebCoeffs_[nP_*j];
393  }
394  for (size_t i = 1; i < nP_; i++) {
395  Cnp1 = 2 * Pr * Cn - Cnm1;
396  for (size_t j = 0; j < nT_; j++) {
397  dotProd_[j] += Cnp1 * chebCoeffs_[nP_*j + i];
398  }
399  Cnm1 = Cn;
400  Cn = Cnp1;
401  }
402  }
403 
404  /**
405  * Update the value the rate constant.
406  *
407  * This function returns the actual value of the rate constant.
408  */
409  doublereal updateRC(doublereal logT, doublereal recipT) const {
410  double Tr = (2 * recipT + TrNum_) * TrDen_;
411  double Cnm1 = Tr;
412  double Cn = 1;
413  double Cnp1;
414  double logk = dotProd_[0];
415  for (size_t i = 1; i < nT_; i++) {
416  Cnp1 = 2 * Tr * Cn - Cnm1;
417  logk += Cnp1 * dotProd_[i];
418  Cnm1 = Cn;
419  Cn = Cnp1;
420  }
421  return std::pow(10, logk);
422  }
423 
424  //! Minimum valid temperature [K]
425  double Tmin() const {
426  return Tmin_;
427  }
428 
429  //! Maximum valid temperature [K]
430  double Tmax() const {
431  return Tmax_;
432  }
433 
434  //! Minimum valid pressure [Pa]
435  double Pmin() const {
436  return Pmin_;
437  }
438 
439  //! Maximum valid pressure [Pa]
440  double Pmax() const {
441  return Pmax_;
442  }
443 
444  //! Number of points in the pressure direction
445  size_t nPressure() const {
446  return nP_;
447  }
448 
449  //! Number of points in the temperature direction
450  size_t nTemperature() const {
451  return nT_;
452  }
453 
454  //! Access the Chebyshev coefficients.
455  /*!
456  * \f$ \alpha_{t,p} = \mathrm{coeffs}[N_P*t + p] \f$ where
457  * \f$ 0 <= t < N_T \f$ and \f$ 0 <= p < N_P \f$.
458  */
459  const vector_fp& coeffs() const {
460  return chebCoeffs_;
461  }
462 
463 protected:
464  double Tmin_, Tmax_; //!< valid temperature range
465  double Pmin_, Pmax_; //!< valid pressure range
466  double TrNum_, TrDen_; //!< terms appearing in the reduced temperature
467  double PrNum_, PrDen_; //!< terms appearing in the reduced pressure
468 
469  size_t nP_; //!< number of points in the pressure direction
470  size_t nT_; //!< number of points in the temperature direction
471  vector_fp chebCoeffs_; //!< Chebyshev coefficients, length nP * nT
472  vector_fp dotProd_; //!< dot product of chebCoeffs with the reduced pressure polynomial
473 };
474 
475 }
476 
477 #endif
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:32
Arrhenius reaction rate type depends only on temperature.
Definition: RxnRates.h:32
static int type()
return the rate coefficient type.
Definition: RxnRates.h:38
void update_C(const doublereal *c)
Update concentration-dependent parts of the rate coefficient.
Definition: RxnRates.h:60
doublereal updateRC(doublereal logT, doublereal recipT) const
Update the value the rate constant.
Definition: RxnRates.h:76
doublereal updateLog(doublereal logT, doublereal recipT) const
Update the value of the natural logarithm of the rate constant.
Definition: RxnRates.h:66
double temperatureExponent() const
Return the temperature exponent b
Definition: RxnRates.h:87
doublereal activationEnergy_R() const
Return the activation energy divided by the gas constant (i.e.
Definition: RxnRates.h:93
Arrhenius()
Default constructor.
Definition: RxnRates.cpp:11
double preExponentialFactor() const
Return the pre-exponential factor A (in m, kmol, s to powers depending on the reaction order)
Definition: RxnRates.h:82
Pressure-dependent rate expression where the rate coefficient is expressed as a bivariate Chebyshev p...
Definition: RxnRates.h:356
double Tmax_
valid temperature range
Definition: RxnRates.h:464
ChebyshevRate()
Default constructor.
Definition: RxnRates.h:369
static int type()
return the rate coefficient type.
Definition: RxnRates.h:362
double TrDen_
terms appearing in the reduced temperature
Definition: RxnRates.h:466
void update_C(const doublereal *c)
Update concentration-dependent parts of the rate coefficient.
Definition: RxnRates.h:386
doublereal updateRC(doublereal logT, doublereal recipT) const
Update the value the rate constant.
Definition: RxnRates.h:409
double Pmin() const
Minimum valid pressure [Pa].
Definition: RxnRates.h:435
double Tmin() const
Minimum valid temperature [K].
Definition: RxnRates.h:425
double Tmax() const
Maximum valid temperature [K].
Definition: RxnRates.h:430
size_t nP_
number of points in the pressure direction
Definition: RxnRates.h:469
const vector_fp & coeffs() const
Access the Chebyshev coefficients.
Definition: RxnRates.h:459
double Pmax_
valid pressure range
Definition: RxnRates.h:465
size_t nT_
number of points in the temperature direction
Definition: RxnRates.h:470
vector_fp dotProd_
dot product of chebCoeffs with the reduced pressure polynomial
Definition: RxnRates.h:472
size_t nPressure() const
Number of points in the pressure direction.
Definition: RxnRates.h:445
double Pmax() const
Maximum valid pressure [Pa].
Definition: RxnRates.h:440
double PrDen_
terms appearing in the reduced pressure
Definition: RxnRates.h:467
vector_fp chebCoeffs_
Chebyshev coefficients, length nP * nT.
Definition: RxnRates.h:471
size_t nTemperature() const
Number of points in the temperature direction.
Definition: RxnRates.h:450
Pressure-dependent reaction rate expressed by logarithmically interpolating between Arrhenius rate ex...
Definition: RxnRates.h:222
static int type()
return the rate coefficient type.
Definition: RxnRates.h:228
void update_C(const doublereal *c)
Update concentration-dependent parts of the rate coefficient.
Definition: RxnRates.h:242
doublereal updateRC(doublereal logT, doublereal recipT) const
Update the value the rate constant.
Definition: RxnRates.h:272
std::vector< std::pair< double, Arrhenius > > rates() const
Return the pressures and Arrhenius expressions which comprise this reaction.
Definition: RxnRates.cpp:116
double rDeltaP_
reciprocal of (logP2 - logP1)
Definition: RxnRates.h:323
std::map< double, std::pair< size_t, size_t > > pressures_
log(p) to (index range) in the rates_ vector
Definition: RxnRates.h:309
Plog()
Default constructor.
Definition: RxnRates.h:235
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
double logP_
log(p) at the current state
Definition: RxnRates.h:314
size_t ilow1_
Indices to the ranges within rates_ for the lower / upper pressure, such that rates_[ilow1_] through ...
Definition: RxnRates.h:321
double logP2_
log(p) at the lower / upper pressure reference
Definition: RxnRates.h:315
An Arrhenius rate with coverage-dependent terms.
Definition: RxnRates.h:125
doublereal updateRC(doublereal logT, doublereal recipT) const
Update the value of the rate constant.
Definition: RxnRates.h:170
doublereal temperatureExponent() const
Return effective temperature exponent.
Definition: RxnRates.h:185
doublereal activationEnergy_R() const
Return the activation energy divided by the gas constant (i.e.
Definition: RxnRates.h:191
doublereal preExponentialFactor() const
Return the pre-exponential factor A (in m, kmol, s to powers depending on the reaction order) account...
Definition: RxnRates.h:180
void addCoverageDependence(size_t k, doublereal a, doublereal m, doublereal e)
Add a coverage dependency for species k, with exponential dependence a, power-law exponent m,...
Definition: RxnRates.cpp:51
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
This file contains definitions for utility functions and text for modules, inputfiles,...
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
Definition: ctexceptions.h:265
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
const double Tiny
Small number to compare differences of mole fractions against.
Definition: ct_defs.h:166
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:180
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
This file defines some constants used to specify reaction types.
Contains declarations for string manipulation functions within Cantera.