Cantera  2.0
RxnRates.h
Go to the documentation of this file.
1 /**
2  * @file RxnRates.h
3  *
4  */
5 // Copyright 2001 California Institute of Technology
6 
7 
8 #ifndef CT_RXNRATES_H
9 #define CT_RXNRATES_H
10 
11 #include "reaction_defs.h"
12 #include "ReactionData.h"
13 
16 
17 namespace Cantera
18 {
19 
20 //! Arrhenius reaction rate type depends only on temperature
21 /**
22  * A reaction rate coefficient of the following form.
23  *
24  * \f[
25  * k_f = A T^b \exp (-E/RT)
26  * \f]
27  *
28  */
29 class Arrhenius
30 {
31 public:
32  //! return the rate coefficient type.
33  static int type() {
34  return ARRHENIUS_REACTION_RATECOEFF_TYPE;
35  }
36 
37  //! Default constructor.
39  m_logA(-1.0E300),
40  m_b(0.0),
41  m_E(0.0),
42  m_A(0.0) {}
43 
44  //! Constructor from ReactionData.
45  explicit Arrhenius(const ReactionData& rdata) :
46  m_b(rdata.rateCoeffParameters[1]),
47  m_E(rdata.rateCoeffParameters[2]),
48  m_A(rdata.rateCoeffParameters[0]) {
49  if (m_A <= 0.0) {
50  m_logA = -1.0E300;
51  } else {
52  m_logA = std::log(m_A);
53  }
54  }
55 
56  /// Constructor.
57  /// @param A pre-exponential. The unit system is
58  /// (kmol, m, s). The actual units depend on the reaction
59  /// order and the dimensionality (surface or bulk).
60  /// @param b Temperature exponent. Non-dimensional.
61  /// @param E Activation energy in temperature units. Kelvin.
62  Arrhenius(doublereal A, doublereal b, doublereal E) :
63  m_b(b),
64  m_E(E),
65  m_A(A) {
66  if (m_A <= 0.0) {
67  m_logA = -1.0E300;
68  } else {
69  m_logA = log(m_A);
70  }
71  }
72 
73  //! Update concentration-dependent parts of the rate coefficient.
74  /*!
75  * For this class, there are no
76  * concentration-dependent parts, so this method does nothing.
77  */
78  void update_C(const doublereal* c) {
79  }
80 
81  /**
82  * Update the value of the logarithm of the rate constant.
83  *
84  * Note, this function should never be called for negative A values.
85  * If it does then it will produce a negative overflow result, and
86  * a zero net forwards reaction rate, instead of a negative reaction
87  * rate constant that is the expected result.
88  */
89  doublereal update(doublereal logT, doublereal recipT) const {
90  return m_logA + m_b*logT - m_E*recipT;
91  }
92 
93  /**
94  * Update the value the rate constant.
95  *
96  * This function returns the actual value of the rate constant.
97  * It can be safely called for negative values of the pre-exponential
98  * factor.
99  */
100  doublereal updateRC(doublereal logT, doublereal recipT) const {
101  return m_A * std::exp(m_b*logT - m_E*recipT);
102  }
103 
104 
105  void writeUpdateRHS(std::ostream& s) const {
106  s << " exp(" << m_logA;
107  if (m_b != 0.0) {
108  s << " + " << m_b << " * tlog";
109  }
110  if (m_E != 0.0) {
111  s << " - " << m_E << " * rt";
112  }
113  s << ");" << std::endl;
114  }
115 
116  doublereal activationEnergy_R() const {
117  return m_E;
118  }
119 
120  static bool alwaysComputeRate() {
121  return false;
122  }
123 
124 protected:
125  doublereal m_logA, m_b, m_E, m_A;
126 };
127 
128 //! @deprecated This class is not used.
130 {
131 
132 public:
133 
134  static int type() {
135  return ARRHENIUS_SUM_REACTION_RATECOEFF_TYPE;
136  }
137  ArrheniusSum() : m_nterms(0) {}
138 
139  void addArrheniusTerm(doublereal A, doublereal b, doublereal E) {
140  if (A > 0.0) {
141  m_terms.push_back(Arrhenius(A, b, E));
142  m_sign.push_back(1);
143  } else if (A < 0.0) {
144  m_terms.push_back(Arrhenius(-A, b, E));
145  m_sign.push_back(-1);
146  }
147  m_nterms++;
148  }
149 
150  void update_C(const doublereal* c) {}
151 
152  /**
153  * Update the value of the logarithm of the rate constant.
154  *
155  */
156  doublereal update(doublereal logT, doublereal recipT) const {
157  int n;
158  doublereal f, fsum = 0.0;
159  for (n = 0; n < m_nterms; n++) {
160  f = m_terms[n].updateRC(logT, recipT);
161  fsum += m_sign[n]*f;
162  }
163  return log(fsum);
164  }
165 
166  /**
167  * Update the value the rate constant.
168  *
169  * This function returns the actual value of the rate constant.
170  * It can be safely called for negative values of the pre-exponential
171  * factor.
172  */
173  doublereal updateRC(doublereal logT, doublereal recipT) const {
174  int n;
175  doublereal f, fsum = 0.0;
176  for (n = 0; n < m_nterms; n++) {
177  f = m_terms[n].updateRC(logT, recipT);
178  fsum += m_sign[n]*f;
179  }
180  return fsum;
181  }
182 
183  void writeUpdateRHS(std::ostream& s) const {
184  ;
185  }
186 
187  static bool alwaysComputeRate() {
188  return false;
189  }
190 
191 protected:
192  std::vector<Arrhenius> m_terms;
193  vector_int m_sign;
194  int m_nterms;
195 };
196 
197 
198 /**
199  * An Arrhenius rate with coverage-dependent terms.
200  */
202 {
203 
204 public:
205  static int type() {
206  return SURF_ARRHENIUS_REACTION_RATECOEFF_TYPE;
207  }
208 
209  SurfaceArrhenius() :
210  m_logA(-1.0E300),
211  m_b(0.0),
212  m_E(0.0),
213  m_A(0.0),
214  m_acov(0.0),
215  m_ecov(0.0),
216  m_mcov(0.0),
217  m_ncov(0),
218  m_nmcov(0) {
219  }
220 
221  explicit SurfaceArrhenius(const ReactionData& rdata) :
222  m_b(rdata.rateCoeffParameters[1]),
223  m_E(rdata.rateCoeffParameters[2]),
224  m_A(rdata.rateCoeffParameters[0]),
225  m_acov(0.0),
226  m_ecov(0.0),
227  m_mcov(0.0),
228  m_ncov(0),
229  m_nmcov(0)
230  {
231  if (m_A <= 0.0) {
232  m_logA = -1.0E300;
233  } else {
234  m_logA = std::log(m_A);
235  }
236 
237  const vector_fp& data = rdata.rateCoeffParameters;
238  if (data.size() >= 7) {
239  for (size_t n = 3; n < data.size()-3; n += 4) {
240  addCoverageDependence(size_t(data[n]), data[n+1],
241  data[n+2], data[n+3]);
242  }
243  }
244  }
245 
246  void addCoverageDependence(size_t k, doublereal a,
247  doublereal m, doublereal e) {
248  m_ncov++;
249  m_sp.push_back(k);
250  m_ac.push_back(a);
251  m_ec.push_back(e);
252  if (m != 0.0) {
253  m_msp.push_back(k);
254  m_mc.push_back(m);
255  m_nmcov++;
256  }
257  }
258 
259  void update_C(const doublereal* theta) {
260  m_acov = 0.0;
261  m_ecov = 0.0;
262  m_mcov = 0.0;
263  size_t k;
264  doublereal th;
265  for (size_t n = 0; n < m_ncov; n++) {
266  k = m_sp[n];
267  m_acov += m_ac[n] * theta[k];
268  m_ecov += m_ec[n] * theta[k];
269  }
270  for (size_t n = 0; n < m_nmcov; n++) {
271  k = m_msp[n];
272  // changed n to k, dgg 1/22/04
273  th = std::max(theta[k], Tiny);
274  // th = fmaxx(theta[n], Tiny);
275  m_mcov += m_mc[n]*std::log(th);
276  }
277  }
278 
279  /**
280  * Update the value of the logarithm of the rate constant.
281  *
282  * This calculation is not safe for negative values of
283  * the preexponential.
284  */
285  doublereal update(doublereal logT, doublereal recipT) const {
286  return m_logA + m_acov + m_b*logT
287  - (m_E + m_ecov)*recipT + m_mcov;
288  }
289 
290  /**
291  * Update the value the rate constant.
292  *
293  * This function returns the actual value of the rate constant.
294  * It can be safely called for negative values of the pre-exponential
295  * factor.
296  */
297  doublereal updateRC(doublereal logT, doublereal recipT) const {
298  return m_A * std::exp(m_acov + m_b*logT - (m_E + m_ecov)*recipT + m_mcov);
299  }
300 
301  doublereal activationEnergy_R() const {
302  return m_E + m_ecov;
303  }
304 
305  static bool alwaysComputeRate() {
306  return true;
307  }
308 
309 protected:
310  doublereal m_logA, m_b, m_E, m_A;
311  doublereal m_acov, m_ecov, m_mcov;
312  std::vector<size_t> m_sp, m_msp;
313  vector_fp m_ac, m_ec, m_mc;
314  size_t m_ncov, m_nmcov;
315 };
316 
317 
318 #ifdef INCL_TST
319 
320 class TST
321 {
322 
323 public:
324  static int type() {
325  return TSTRATE;
326  }
327  TST() {}
328  TST(const vector_fp& c) {
329  m_b.resize(10);
330  copy(c.begin(), c.begin() + 10, m_b.begin());
331  m_k = int(c[10]);
332  }
333 
334  void update_C(const vector_fp& c) {
335  doublereal ck = c[m_k];
336  delta_s0 = m_b[0] + m_b[1]*ck + m_b[2]*ck*ck;
337  delta_e0 = m_b[5] + m_b[6]*ck + m_b[7]*ck*ck;
338  }
339 
340  doublereal update(doublereal logT, doublereal recipT) const {
341  doublereal delta_s = delta_s0*(1.0 + m_b[3]*logT + m_b[4]*recipT);
342  doublereal delta_E = delta_e0*(1.0 + m_b[8]*logT + m_b[9]*recipT);
343  return logBoltz_Planck + logT + delta_s - delta_E*recipT;
344  }
345 
346  doublereal updateRC(doublereal logT, doublereal recipT) const {
347  doublereal lres = update(logT, recipT);
348  return exp(lres);
349  }
350 
351  void writeUpdateRHS(std::ostream& s) const {}
352 
353 protected:
354  doublereal delta_s0, delta_e0;
355  int m_k;
356  vector_fp m_b;
357 };
358 
359 #endif
360 
361 
362 
363 
364 //! Arrhenius reaction rate type depends only on temperature
365 /**
366  * A reaction rate coefficient of the following form.
367  *
368  * \f[
369  * k_f = A T^b \exp (-E/RT)
370  * \f]
371  *
372  */
374 {
375 public:
376 
377  //! return the rate coefficient type.
378  static int type() {
379  return EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE;
380  }
381 
382  //! Default constructor.
384  m_logA(-1.0E300),
385  m_b(0.0),
386  m_E(0.0),
387  m_A(0.0) {}
388 
389  //! Constructor with Arrhenius parameters from a ReactionData struct.
390  explicit ExchangeCurrent(const ReactionData& rdata) :
391  m_b(rdata.rateCoeffParameters[1]),
392  m_E(rdata.rateCoeffParameters[2]),
393  m_A(rdata.rateCoeffParameters[0]) {
394  if (m_A <= 0.0) {
395  m_logA = -1.0E300;
396  } else {
397  m_logA = std::log(m_A);
398  }
399  }
400 
401  /// Constructor.
402  /// @param A pre-exponential. The unit system is
403  /// (kmol, m, s). The actual units depend on the reaction
404  /// order and the dimensionality (surface or bulk).
405  /// @param b Temperature exponent. Non-dimensional.
406  /// @param E Activation energy in temperature units. Kelvin.
407  ExchangeCurrent(doublereal A, doublereal b, doublereal E) :
408  m_b(b),
409  m_E(E),
410  m_A(A) {
411  if (m_A <= 0.0) {
412  m_logA = -1.0E300;
413  } else {
414  m_logA = std::log(m_A);
415  }
416  }
417 
418  //! Update concentration-dependent parts of the rate coefficient.
419  /*!
420  * For this class, there are no
421  * concentration-dependent parts, so this method does nothing.
422  */
423  void update_C(const doublereal* c) {
424  }
425 
426  /**
427  * Update the value of the logarithm of the rate constant.
428  *
429  * Note, this function should never be called for negative A values.
430  * If it does then it will produce a negative overflow result, and
431  * a zero net forwards reaction rate, instead of a negative reaction
432  * rate constant that is the expected result.
433  */
434  doublereal update(doublereal logT, doublereal recipT) const {
435  return m_logA + m_b*logT - m_E*recipT;
436  }
437 
438  /**
439  * Update the value the rate constant.
440  *
441  * This function returns the actual value of the rate constant.
442  * It can be safely called for negative values of the pre-exponential
443  * factor.
444  */
445  doublereal updateRC(doublereal logT, doublereal recipT) const {
446  return m_A * std::exp(m_b*logT - m_E*recipT);
447  }
448 
449  void writeUpdateRHS(std::ostream& s) const {
450  s << " exp(" << m_logA;
451  if (m_b != 0.0) {
452  s << " + " << m_b << " * tlog";
453  }
454  if (m_E != 0.0) {
455  s << " - " << m_E << " * rt";
456  }
457  s << ");" << std::endl;
458  }
459 
460  doublereal activationEnergy_R() const {
461  return m_E;
462  }
463 
464  static bool alwaysComputeRate() {
465  return false;
466  }
467 
468 protected:
469  doublereal m_logA, m_b, m_E, m_A;
470 };
471 
472 
473 class Plog
474 {
475 public:
476  //! return the rate coefficient type.
477  static int type()
478  {
479  return PLOG_REACTION_RATECOEFF_TYPE;
480  }
481 
482  //! Default constructor.
483  Plog() {}
484 
485  //! Constructor from ReactionData.
486  explicit Plog(const ReactionData& rdata) :
487  logP1_(1000),
488  logP2_(-1000),
489  maxRates_(1)
490  {
491  typedef std::multimap<double, vector_fp>::const_iterator iter_t;
492 
493  size_t j = 0;
494  size_t rateCount = 0;
495  // Insert intermediate pressures
496  for (iter_t iter = rdata.plogParameters.begin();
497  iter != rdata.plogParameters.end();
498  iter++) {
499  double logp = std::log(iter->first);
500  if (pressures_.empty() || pressures_.rbegin()->first != logp) {
501  // starting a new group
502  pressures_[logp] = std::make_pair(j, j+1);
503  rateCount = 1;
504  } else {
505  // another rate expression at the same pressure
506  pressures_[logp].second = j+1;
507  rateCount++;
508  }
509  maxRates_ = std::max(rateCount, maxRates_);
510 
511  j++;
512  A_.push_back(iter->second[0]);
513  n_.push_back(iter->second[1]);
514  Ea_.push_back(iter->second[2]);
515  }
516 
517  // For pressures with only one Arrhenius expression, it is more
518  // efficient to work with log(A)
519  for (pressureIter iter = pressures_.begin();
520  iter != pressures_.end();
521  iter++) {
522  if (iter->second.first == iter->second.second - 1) {
523  A_[iter->second.first] = std::log(A_[iter->second.first]);
524  }
525  }
526 
527  // Duplicate the first and last groups to handle P < P_0 and P > P_N
528  pressures_.insert(std::make_pair(-1000.0, pressures_.begin()->second));
529  pressures_.insert(std::make_pair(1000.0, pressures_.rbegin()->second));
530 
531  // Resize work arrays
532  A1_.resize(maxRates_);
533  A2_.resize(maxRates_);
534  n1_.resize(maxRates_);
535  n2_.resize(maxRates_);
536  Ea1_.resize(maxRates_);
537  Ea2_.resize(maxRates_);
538 
539  if (rdata.validate) {
540  validate(rdata);
541  }
542  }
543 
544  //! Update concentration-dependent parts of the rate coefficient.
545  //! @param c natural log of the pressure in Pa
546  void update_C(const doublereal* c)
547  {
548  logP_ = c[0];
549  if (logP_ > logP1_ && logP_ < logP2_) {
550  return;
551  }
552 
553  pressureIter iter = pressures_.upper_bound(c[0]);
554  AssertThrowMsg(iter != pressures_.end(), "Plog::update_C",
555  "Pressure out of range: " + fp2str(logP_));
556  AssertThrowMsg(iter != pressures_.begin(), "Plog::update_C",
557  "Pressure out of range: " + fp2str(logP_));
558 
559  // upper interpolation pressure
560  logP2_ = iter->first;
561  size_t start = iter->second.first;
562  m2_ = iter->second.second - start;
563  for (size_t m = 0; m < m2_; m++) {
564  A2_[m] = A_[start+m];
565  n2_[m] = n_[start+m];
566  Ea2_[m] = Ea_[start+m];
567  }
568 
569  // lower interpolation pressure
570  logP1_ = (--iter)->first;
571  start = iter->second.first;
572  m1_ = iter->second.second - start;
573  for (size_t m = 0; m < m1_; m++) {
574  A1_[m] = A_[start+m];
575  n1_[m] = n_[start+m];
576  Ea1_[m] = Ea_[start+m];
577  }
578 
579  rDeltaP_ = 1.0 / (logP2_ - logP1_);
580  }
581 
582  /**
583  * Update the value of the logarithm of the rate constant.
584  */
585  doublereal update(doublereal logT, doublereal recipT) const
586  {
587  double log_k1, log_k2;
588  if (m1_ == 1) {
589  log_k1 = A1_[0] + n1_[0] * logT - Ea1_[0] * recipT;
590  } else {
591  double k = 1e-300; // non-zero to make log(k) finite
592  for (size_t m = 0; m < m1_; m++) {
593  k += A1_[m] * std::exp(n1_[m] * logT - Ea1_[m] * recipT);
594  }
595  log_k1 = std::log(k);
596  }
597 
598  if (m2_ == 1) {
599  log_k2 = A2_[0] + n2_[0] * logT - Ea2_[0] * recipT;
600  } else {
601  double k = 1e-300; // non-zero to make log(k) finite
602  for (size_t m = 0; m < m2_; m++) {
603  k += A2_[m] * std::exp(n2_[m] * logT - Ea2_[m] * recipT);
604  }
605  log_k2 = std::log(k);
606  }
607 
608  return log_k1 + (log_k2 - log_k1) * (logP_ - logP1_) * rDeltaP_;
609  }
610 
611  /**
612  * Update the value the rate constant.
613  *
614  * This function returns the actual value of the rate constant.
615  */
616  doublereal updateRC(doublereal logT, doublereal recipT) const {
617  return std::exp(update(logT, recipT));
618  }
619 
620  doublereal activationEnergy_R() const {
621  throw CanteraError("Plog::activationEnergy_R", "Not implemented");
622  }
623 
624  static bool alwaysComputeRate() {
625  return false;
626  }
627 
628  //! Check to make sure that the rate expression is finite over a range of
629  //! temperatures at each interpolation pressure. This is potentially an
630  //! issue when one of the Arrhenius expressions at a particular pressure
631  //! has a negative pre-exponential factor.
632  void validate(const ReactionData& rdata) {
633  double T[] = {1.0, 10.0, 100.0, 1000.0, 10000.0};
634  for (pressureIter iter = pressures_.begin();
635  iter->first < 1000;
636  iter++)
637  {
638  update_C(&iter->first);
639  for (size_t i=0; i < 5; i++) {
640  double k = updateRC(log(T[i]), 1.0/T[i]);
641  if (!(k >= 0)) {
642  // k is NaN. Increment the iterator so that the error
643  // message will correctly indicate that the problematic rate
644  // expression is at the higher of the adjacent pressures.
645  throw CanteraError("Plog::validate",
646  "Invalid rate coefficient for reaction #" +
647  int2str(rdata.number) + ":\n" + rdata.equation + "\n" +
648  "at P = " + fp2str(std::exp((++iter)->first)) +
649  ", T = " + fp2str(T[i]));
650  }
651  }
652  }
653  }
654 
655 protected:
656  //! log(p) to (index range) in A_, n, Ea vectors
657  std::map<double, std::pair<size_t, size_t> > pressures_;
658  typedef std::map<double, std::pair<size_t, size_t> >::iterator pressureIter;
659 
660  vector_fp A_; //!< Pre-exponential factor at each pressure (or log(A))
661  vector_fp n_; //!< Temperature exponent at each pressure [dimensionless]
662  vector_fp Ea_; //!< Activation energy at each pressure [K]
663 
664  double logP_; //!< log(p) at the current state
665  double logP1_, logP2_; //!< log(p) at the lower / upper pressure reference
666 
667  //! Pre-exponential factors at lower / upper pressure reference.
668  //! Stored as log(A) when there is only one at the corresponding pressure.
669  vector_fp A1_, A2_;
670  vector_fp n1_, n2_; //!< n at lower / upper pressure reference
671  vector_fp Ea1_, Ea2_; //!< Activation energy at lower / upper pressure reference
672 
673  //! Number of Arrhenius expressions at lower / upper pressure references
674  size_t m1_, m2_;
675  double rDeltaP_; //!< reciprocal of (logP2 - logP1)
676 
677  size_t maxRates_; //!< The maximum number of rates at any given pressure
678 };
679 
680 
681 class ChebyshevRate
682 {
683 public:
684  //! return the rate coefficient type.
685  static int type()
686  {
687  return CHEBYSHEV_REACTION_RATECOEFF_TYPE;
688  }
689 
690  //! Default constructor.
691  ChebyshevRate() {}
692 
693  //! Constructor from ReactionData.
694  explicit ChebyshevRate(const ReactionData& rdata) :
695  nP_(rdata.chebDegreeP),
696  nT_(rdata.chebDegreeT),
697  chebCoeffs_(rdata.chebCoeffs),
698  dotProd_(rdata.chebDegreeT)
699  {
700  double logPmin = std::log10(rdata.chebPmin);
701  double logPmax = std::log10(rdata.chebPmax);
702  double TminInv = 1.0 / rdata.chebTmin;
703  double TmaxInv = 1.0 / rdata.chebTmax;
704 
705  TrNum_ = - TminInv - TmaxInv;
706  TrDen_ = 1.0 / (TmaxInv - TminInv);
707  PrNum_ = - logPmin - logPmax;
708  PrDen_ = 1.0 / (logPmax - logPmin);
709  }
710 
711  //! Update concentration-dependent parts of the rate coefficient.
712  //! @param c base-10 logarithm of the pressure in Pa
713  void update_C(const doublereal* c)
714  {
715  double Pr = (2 * c[0] + PrNum_) * PrDen_;
716  double Cnm1 = 1;
717  double Cn = Pr;
718  double Cnp1;
719  for (size_t j = 0; j < nT_; j++) {
720  dotProd_[j] = chebCoeffs_[nP_*j] + Pr * chebCoeffs_[nP_*j+1];
721  }
722  for (size_t i = 2; i < nP_; i++) {
723  Cnp1 = 2 * Pr * Cn - Cnm1;
724  for (size_t j = 0; j < nT_; j++) {
725  dotProd_[j] += Cnp1 * chebCoeffs_[nP_*j + i];
726  }
727  Cnm1 = Cn;
728  Cn = Cnp1;
729  }
730  }
731 
732  /**
733  * Update the value of the base-10 logarithm of the rate constant.
734  */
735  doublereal update(doublereal logT, doublereal recipT) const
736  {
737  double Tr = (2 * recipT + TrNum_) * TrDen_;
738  double Cnm1 = 1;
739  double Cn = Tr;
740  double Cnp1;
741  double logk = dotProd_[0] + Tr * dotProd_[1];
742  for (size_t i = 2; i < nT_; i++) {
743  Cnp1 = 2 * Tr * Cn - Cnm1;
744  logk += Cnp1 * dotProd_[i];
745  Cnm1 = Cn;
746  Cn = Cnp1;
747  }
748  return logk;
749  }
750 
751  /**
752  * Update the value the rate constant.
753  *
754  * This function returns the actual value of the rate constant.
755  */
756  doublereal updateRC(doublereal logT, doublereal recipT) const {
757  return std::pow(10, update(logT, recipT));
758  }
759 
760  doublereal activationEnergy_R() const {
761  return 0.0;
762  }
763 
764  static bool alwaysComputeRate() {
765  return false;
766  }
767 
768 protected:
769  double TrNum_, TrDen_; //!< terms appearing in the reduced temperature
770  double PrNum_, PrDen_; //!< terms appearing in the reduced pressure
771 
772  size_t nP_; //!< number of points in the pressure direction
773  size_t nT_; //!< number of points in the temperature direction
774  vector_fp chebCoeffs_; //!< Chebyshev coefficients, length nP * nT
775  vector_fp dotProd_; //!< dot product of chebCoeffs with the reduced pressure polynomial
776 };
777 
778 // class LandauTeller {
779 
780 // public:
781 // static int type(){ return LANDAUTELLER; }
782 // LandauTeller(){}
783 // LandauTeller( const vector_fp& c ) : m_c(c) { m_c[0] = log(c[0]); }
784 
785 // doublereal update(doublereal logT, doublereal recipT) const {
786 // return m_c[0] + m_c[1]*tt[1] - m_c[2]*tt[2]
787 // + m_c[3]*tt[3] + m_c[4]*tt[4];
788 // }
789 
790 // //void writeUpdateRHS(ostream& s) const {
791 // // s << exp(m_logA);
792 // // s << " * exp(";
793 // // if (m_b != 0.0) s << m_b << " * tlog";
794 // // if (m_E != 0.0) s << " - " << m_E << " * rt";
795 // // if (m_E != 0.0) s << " - " << m_E << " * rt";
796 // // s << ");" << endl;
797 // // }
798 // //}
799 
800 // protected:
801 // doublereal m_logA, m_b, m_E;
802 // };
803 
804 //}
805 }
806 
807 #endif
808 
809