Implemented Chebyshev rate expressions
This commit is contained in:
parent
8cbc083854
commit
7bfd094eaf
3 changed files with 110 additions and 13 deletions
|
|
@ -660,27 +660,61 @@ public:
|
||||||
ChebyshevRate() {}
|
ChebyshevRate() {}
|
||||||
|
|
||||||
//! Constructor from ReactionData.
|
//! Constructor from ReactionData.
|
||||||
explicit ChebyshevRate(const ReactionData& rdata)
|
explicit ChebyshevRate(const ReactionData& rdata) :
|
||||||
|
nP_(rdata.chebDegreeP),
|
||||||
|
nT_(rdata.chebDegreeT),
|
||||||
|
chebCoeffs_(rdata.chebCoeffs),
|
||||||
|
dotProd_(rdata.chebDegreeT)
|
||||||
{
|
{
|
||||||
|
double logPmin = log10(rdata.chebPmin);
|
||||||
|
double logPmax = log10(rdata.chebPmax);
|
||||||
|
double TminInv = 1.0 / rdata.chebTmin;
|
||||||
|
double TmaxInv = 1.0 / rdata.chebTmax;
|
||||||
|
|
||||||
|
TrNum_ = - TminInv - TmaxInv;
|
||||||
|
TrDen_ = 1.0 / (TmaxInv - TminInv);
|
||||||
|
PrNum_ = - logPmin - logPmax;
|
||||||
|
PrDen_ = 1.0 / (logPmax - logPmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Update concentration-dependent parts of the rate coefficient.
|
//! Update concentration-dependent parts of the rate coefficient.
|
||||||
//! @param c natural log of the pressure in Pa
|
//! @param c base-10 logarithm of the pressure in Pa
|
||||||
void update_C(const doublereal* c)
|
void update_C(const doublereal* c)
|
||||||
{
|
{
|
||||||
|
double Pr = (2 * c[0] + PrNum_) * PrDen_;
|
||||||
|
double Cnm1 = 1;
|
||||||
|
double Cn = Pr;
|
||||||
|
double Cnp1;
|
||||||
|
for (size_t j = 0; j < nT_; j++) {
|
||||||
|
dotProd_[j] = chebCoeffs_[nP_*j] + Pr * chebCoeffs_[nP_*j+1];
|
||||||
|
}
|
||||||
|
for (size_t i = 2; i < nP_; i++) {
|
||||||
|
Cnp1 = 2 * Pr * Cn - Cnm1;
|
||||||
|
for (size_t j = 0; j < nT_; j++) {
|
||||||
|
dotProd_[j] += Cnp1 * chebCoeffs_[nP_*j + i];
|
||||||
|
}
|
||||||
|
Cnm1 = Cn;
|
||||||
|
Cn = Cnp1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the value of the logarithm of the rate constant.
|
* Update the value of the base-10 logarithm of the rate constant.
|
||||||
*
|
|
||||||
* Note, this function should never be called for negative A values.
|
|
||||||
* If it does then it will produce a negative overflow result, and
|
|
||||||
* a zero net forwards reaction rate, instead of a negative reaction
|
|
||||||
* rate constant that is the expected result.
|
|
||||||
*/
|
*/
|
||||||
doublereal update(doublereal logT, doublereal recipT) const
|
doublereal update(doublereal logT, doublereal recipT) const
|
||||||
{
|
{
|
||||||
return 0.0;
|
double Tr = (2 * recipT + TrNum_) * TrDen_;
|
||||||
|
double Cnm1 = 1;
|
||||||
|
double Cn = Tr;
|
||||||
|
double Cnp1;
|
||||||
|
double logk = dotProd_[0] + Tr * dotProd_[1];
|
||||||
|
for (size_t i = 2; i < nT_; i++) {
|
||||||
|
Cnp1 = 2 * Tr * Cn - Cnm1;
|
||||||
|
logk += Cnp1 * dotProd_[i];
|
||||||
|
Cnm1 = Cn;
|
||||||
|
Cn = Cnp1;
|
||||||
|
}
|
||||||
|
return logk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -689,7 +723,7 @@ public:
|
||||||
* This function returns the actual value of the rate constant.
|
* This function returns the actual value of the rate constant.
|
||||||
*/
|
*/
|
||||||
doublereal updateRC(doublereal logT, doublereal recipT) const {
|
doublereal updateRC(doublereal logT, doublereal recipT) const {
|
||||||
return exp(update(logT, recipT));
|
return pow(10, update(logT, recipT));
|
||||||
}
|
}
|
||||||
|
|
||||||
doublereal activationEnergy_R() const {
|
doublereal activationEnergy_R() const {
|
||||||
|
|
@ -701,6 +735,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
double TrNum_, TrDen_; //!< terms appearing in the reduced temperature
|
||||||
|
double PrNum_, PrDen_; //!< terms appearing in the reduced pressure
|
||||||
|
|
||||||
|
size_t nP_; //!< number of points in the pressure direction
|
||||||
|
size_t nT_; //!< number of points in the temperature direction
|
||||||
|
vector_fp chebCoeffs_; //!< Chebyshev coefficients, length nP * nT
|
||||||
|
vector_fp dotProd_; //!< dot product of chebCoeffs with the reduced pressure polynomial
|
||||||
};
|
};
|
||||||
|
|
||||||
// class LandauTeller {
|
// class LandauTeller {
|
||||||
|
|
|
||||||
|
|
@ -206,16 +206,16 @@ _update_rates_C()
|
||||||
m_falloff_concm.update(m_conc, ctot, &concm_falloff_values[0]);
|
m_falloff_concm.update(m_conc, ctot, &concm_falloff_values[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
double logP = log(thermo().pressure());
|
|
||||||
|
|
||||||
// P-log reactions
|
// P-log reactions
|
||||||
if (m_plog_rates.nReactions()) {
|
if (m_plog_rates.nReactions()) {
|
||||||
|
double logP = log(thermo().pressure());
|
||||||
m_plog_rates.update_C(&logP);
|
m_plog_rates.update_C(&logP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chebyshev reactions
|
// Chebyshev reactions
|
||||||
if (m_cheb_rates.nReactions()) {
|
if (m_cheb_rates.nReactions()) {
|
||||||
m_cheb_rates.update_C(&logP);
|
double log10P = log10(thermo().pressure());
|
||||||
|
m_cheb_rates.update_C(&log10P);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ROP_ok = false;
|
m_ROP_ok = false;
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,62 @@ TEST_F(PdepTest, PlogIntermediatePressure3) {
|
||||||
EXPECT_NEAR(2.224601e+07, ropf[2], 1e+3);
|
EXPECT_NEAR(2.224601e+07, ropf[2], 1e+3);
|
||||||
EXPECT_NEAR(1.007440e+07, ropf[3], 1e+3);
|
EXPECT_NEAR(1.007440e+07, ropf[3], 1e+3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PdepTest, ChebyshevIntermediate1) {
|
||||||
|
// Test Chebyshev rates in the normal interpolation region
|
||||||
|
vector_fp kf(6);
|
||||||
|
|
||||||
|
set_TP(1100.0, 20 * 101325);
|
||||||
|
kin_->getFwdRateConstants(&kf[0]);
|
||||||
|
// Expected rates computed using RMG-py
|
||||||
|
EXPECT_NEAR(3.130698657e+06, kf[4], 1e-1);
|
||||||
|
EXPECT_NEAR(1.187949573e+00, kf[5], 1e-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PdepTest, ChebyshevIntermediate2) {
|
||||||
|
// Test Chebyshev rates in the normal interpolation region
|
||||||
|
vector_fp kf(6);
|
||||||
|
|
||||||
|
set_TP(400.0, 0.1 * 101325);
|
||||||
|
kin_->getFwdRateConstants(&kf[0]);
|
||||||
|
// Expected rates computed using RMG-py
|
||||||
|
EXPECT_NEAR(1.713599902e+05, kf[4], 1e-3);
|
||||||
|
EXPECT_NEAR(9.581780687e-24, kf[5], 1e-31);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PdepTest, ChebyshevIntermediateROP) {
|
||||||
|
set_TP(1100.0, 30 * 101325);
|
||||||
|
vector_fp ropf(6);
|
||||||
|
// Expected rates computed using Chemkin
|
||||||
|
kin_->getFwdRatesOfProgress(&ropf[0]);
|
||||||
|
EXPECT_NEAR(4.552930e+03, ropf[4], 1e-1);
|
||||||
|
EXPECT_NEAR(4.877390e-02, ropf[5], 1e-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PdepTest, ChebyshevEdgeCases) {
|
||||||
|
vector_fp kf(6);
|
||||||
|
|
||||||
|
// Minimum P
|
||||||
|
set_TP(500.0, 1000.0);
|
||||||
|
kin_->getFwdRateConstants(&kf[0]);
|
||||||
|
EXPECT_NEAR(1.225785655e+06, kf[4], 1e-2);
|
||||||
|
|
||||||
|
// Maximum P
|
||||||
|
set_TP(500.0, 1.0e7);
|
||||||
|
kin_->getFwdRateConstants(&kf[0]);
|
||||||
|
EXPECT_NEAR(1.580981157e+03, kf[4], 1e-5);
|
||||||
|
|
||||||
|
// Minimum T
|
||||||
|
set_TP(300.0, 101325);
|
||||||
|
kin_->getFwdRateConstants(&kf[0]);
|
||||||
|
EXPECT_NEAR(5.405987017e+03, kf[4], 1e-5);
|
||||||
|
|
||||||
|
// Maximum T
|
||||||
|
set_TP(2000.0, 101325);
|
||||||
|
kin_->getFwdRateConstants(&kf[0]);
|
||||||
|
EXPECT_NEAR(3.354054351e+07, kf[4], 1e-1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Cantera
|
} // namespace Cantera
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue