34 return ARRHENIUS_REACTION_RATECOEFF_TYPE;
46 m_b(rdata.rateCoeffParameters[1]),
47 m_E(rdata.rateCoeffParameters[2]),
48 m_A(rdata.rateCoeffParameters[0]) {
52 m_logA = std::log(m_A);
62 Arrhenius(doublereal A, doublereal b, doublereal E) :
89 doublereal
update(doublereal logT, doublereal recipT)
const {
90 return m_logA + m_b*logT - m_E*recipT;
100 doublereal
updateRC(doublereal logT, doublereal recipT)
const {
101 return m_A * std::exp(m_b*logT - m_E*recipT);
105 void writeUpdateRHS(std::ostream& s)
const {
106 s <<
" exp(" << m_logA;
108 s <<
" + " << m_b <<
" * tlog";
111 s <<
" - " << m_E <<
" * rt";
113 s <<
");" << std::endl;
116 doublereal activationEnergy_R()
const {
120 static bool alwaysComputeRate() {
125 doublereal m_logA, m_b, m_E, m_A;
135 return ARRHENIUS_SUM_REACTION_RATECOEFF_TYPE;
139 void addArrheniusTerm(doublereal A, doublereal b, doublereal E) {
143 }
else if (A < 0.0) {
145 m_sign.push_back(-1);
150 void update_C(
const doublereal* c) {}
156 doublereal
update(doublereal logT, doublereal recipT)
const {
158 doublereal f, fsum = 0.0;
159 for (n = 0; n < m_nterms; n++) {
160 f = m_terms[n].updateRC(logT, recipT);
173 doublereal
updateRC(doublereal logT, doublereal recipT)
const {
175 doublereal f, fsum = 0.0;
176 for (n = 0; n < m_nterms; n++) {
177 f = m_terms[n].updateRC(logT, recipT);
183 void writeUpdateRHS(std::ostream& s)
const {
187 static bool alwaysComputeRate() {
192 std::vector<Arrhenius> m_terms;
206 return SURF_ARRHENIUS_REACTION_RATECOEFF_TYPE;
222 m_b(rdata.rateCoeffParameters[1]),
223 m_E(rdata.rateCoeffParameters[2]),
224 m_A(rdata.rateCoeffParameters[0]),
234 m_logA = std::log(m_A);
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]);
246 void addCoverageDependence(
size_t k, doublereal a,
247 doublereal m, doublereal e) {
259 void update_C(
const doublereal* theta) {
265 for (
size_t n = 0; n < m_ncov; n++) {
267 m_acov += m_ac[n] * theta[k];
268 m_ecov += m_ec[n] * theta[k];
270 for (
size_t n = 0; n < m_nmcov; n++) {
275 m_mcov += m_mc[n]*std::log(th);
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;
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);
301 doublereal activationEnergy_R()
const {
305 static bool alwaysComputeRate() {
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;
314 size_t m_ncov, m_nmcov;
330 copy(c.begin(), c.begin() + 10, m_b.begin());
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;
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);
346 doublereal updateRC(doublereal logT, doublereal recipT)
const {
347 doublereal lres = update(logT, recipT);
351 void writeUpdateRHS(std::ostream& s)
const {}
354 doublereal delta_s0, delta_e0;
379 return EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE;
391 m_b(rdata.rateCoeffParameters[1]),
392 m_E(rdata.rateCoeffParameters[2]),
393 m_A(rdata.rateCoeffParameters[0]) {
397 m_logA = std::log(m_A);
414 m_logA = std::log(m_A);
434 doublereal
update(doublereal logT, doublereal recipT)
const {
435 return m_logA + m_b*logT - m_E*recipT;
445 doublereal
updateRC(doublereal logT, doublereal recipT)
const {
446 return m_A * std::exp(m_b*logT - m_E*recipT);
449 void writeUpdateRHS(std::ostream& s)
const {
450 s <<
" exp(" << m_logA;
452 s <<
" + " << m_b <<
" * tlog";
455 s <<
" - " << m_E <<
" * rt";
457 s <<
");" << std::endl;
460 doublereal activationEnergy_R()
const {
464 static bool alwaysComputeRate() {
469 doublereal m_logA, m_b, m_E, m_A;
479 return PLOG_REACTION_RATECOEFF_TYPE;
486 explicit Plog(
const ReactionData& rdata) :
491 typedef std::multimap<double, vector_fp>::const_iterator iter_t;
494 size_t rateCount = 0;
496 for (iter_t iter = rdata.plogParameters.begin();
497 iter != rdata.plogParameters.end();
499 double logp = std::log(iter->first);
500 if (pressures_.empty() || pressures_.rbegin()->first != logp) {
502 pressures_[logp] = std::make_pair(j, j+1);
506 pressures_[logp].second = j+1;
509 maxRates_ =
std::max(rateCount, maxRates_);
512 A_.push_back(iter->second[0]);
513 n_.push_back(iter->second[1]);
514 Ea_.push_back(iter->second[2]);
519 for (pressureIter iter = pressures_.begin();
520 iter != pressures_.end();
522 if (iter->second.first == iter->second.second - 1) {
523 A_[iter->second.first] = std::log(A_[iter->second.first]);
528 pressures_.insert(std::make_pair(-1000.0, pressures_.begin()->second));
529 pressures_.insert(std::make_pair(1000.0, pressures_.rbegin()->second));
532 A1_.resize(maxRates_);
533 A2_.resize(maxRates_);
534 n1_.resize(maxRates_);
535 n2_.resize(maxRates_);
536 Ea1_.resize(maxRates_);
537 Ea2_.resize(maxRates_);
539 if (rdata.validate) {
546 void update_C(
const doublereal* c)
549 if (logP_ > logP1_ && logP_ < logP2_) {
553 pressureIter iter = pressures_.upper_bound(c[0]);
555 "Pressure out of range: " +
fp2str(logP_));
557 "Pressure out of range: " +
fp2str(logP_));
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];
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];
579 rDeltaP_ = 1.0 / (logP2_ - logP1_);
585 doublereal update(doublereal logT, doublereal recipT)
const
587 double log_k1, log_k2;
589 log_k1 = A1_[0] + n1_[0] * logT - Ea1_[0] * recipT;
592 for (
size_t m = 0; m < m1_; m++) {
593 k += A1_[m] * std::exp(n1_[m] * logT - Ea1_[m] * recipT);
595 log_k1 = std::log(k);
599 log_k2 = A2_[0] + n2_[0] * logT - Ea2_[0] * recipT;
602 for (
size_t m = 0; m < m2_; m++) {
603 k += A2_[m] * std::exp(n2_[m] * logT - Ea2_[m] * recipT);
605 log_k2 = std::log(k);
608 return log_k1 + (log_k2 - log_k1) * (logP_ - logP1_) * rDeltaP_;
616 doublereal updateRC(doublereal logT, doublereal recipT)
const {
617 return std::exp(update(logT, recipT));
620 doublereal activationEnergy_R()
const {
621 throw CanteraError(
"Plog::activationEnergy_R",
"Not implemented");
624 static bool alwaysComputeRate() {
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();
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]);
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)) +
657 std::map<double, std::pair<size_t, size_t> > pressures_;
658 typedef std::map<double, std::pair<size_t, size_t> >::iterator pressureIter;
665 double logP1_, logP2_;
687 return CHEBYSHEV_REACTION_RATECOEFF_TYPE;
694 explicit ChebyshevRate(
const ReactionData& rdata) :
695 nP_(rdata.chebDegreeP),
696 nT_(rdata.chebDegreeT),
697 chebCoeffs_(rdata.chebCoeffs),
698 dotProd_(rdata.chebDegreeT)
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;
705 TrNum_ = - TminInv - TmaxInv;
706 TrDen_ = 1.0 / (TmaxInv - TminInv);
707 PrNum_ = - logPmin - logPmax;
708 PrDen_ = 1.0 / (logPmax - logPmin);
713 void update_C(
const doublereal* c)
715 double Pr = (2 * c[0] + PrNum_) * PrDen_;
719 for (
size_t j = 0; j < nT_; j++) {
720 dotProd_[j] = chebCoeffs_[nP_*j] + Pr * chebCoeffs_[nP_*j+1];
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];
735 doublereal update(doublereal logT, doublereal recipT)
const
737 double Tr = (2 * recipT + TrNum_) * TrDen_;
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];
756 doublereal updateRC(doublereal logT, doublereal recipT)
const {
757 return std::pow(10, update(logT, recipT));
760 doublereal activationEnergy_R()
const {
764 static bool alwaysComputeRate() {
769 double TrNum_, TrDen_;
770 double PrNum_, PrDen_;