From b7a5aff900470e5d4283fc2c10ac06c33a4846ef Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Fri, 17 Jul 2015 18:18:03 -0400 Subject: [PATCH] [Thermo] Convert Shomate coefficients when creating objects Do conversion to nondimensional units once when creating the ShomatePoly object, instead of every time that properties are calculated. --- include/cantera/thermo/ShomatePoly.h | 78 ++++++++----------------- test/thermo/thermoParameterizations.cpp | 27 +++++++++ 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/include/cantera/thermo/ShomatePoly.h b/include/cantera/thermo/ShomatePoly.h index e904161036..96c9bb89ff 100644 --- a/include/cantera/thermo/ShomatePoly.h +++ b/include/cantera/thermo/ShomatePoly.h @@ -72,8 +72,11 @@ class ShomatePoly : public SpeciesThermoInterpType */ ShomatePoly(double tlow, double thigh, double pref, const double* coeffs) : SpeciesThermoInterpType(tlow, thigh, pref), - m_coeff(coeffs, coeffs + 7) + m_coeff(7) { + for (size_t i = 0; i < 7; i++) { + m_coeff[i] = coeffs[i] * 1000 / GasConstant; + } } virtual SpeciesThermoInterpType* @@ -85,7 +88,7 @@ class ShomatePoly : public SpeciesThermoInterpType return SHOMATE; } - virtual size_t temperaturePolySize() const { return 7; } + virtual size_t temperaturePolySize() const { return 6; } virtual void updateTemperaturePoly(double T, double* T_poly) const { doublereal tt = 1.e-3*T; @@ -94,8 +97,7 @@ class ShomatePoly : public SpeciesThermoInterpType T_poly[2] = T_poly[1] * tt; T_poly[3] = 1.0/T_poly[1]; T_poly[4] = std::log(tt); - T_poly[5] = 1.0/GasConstant; - T_poly[6] = 1.0/(GasConstant * T); + T_poly[5] = 1.0/tt; } //! Update the properties for this species, given a temperature polynomial @@ -105,14 +107,13 @@ class ShomatePoly : public SpeciesThermoInterpType * pointers to arrays where the computed property values should be * written. This method updates only one value in each array. * - * - `tt` is T/1000. - * - `m_t[0] = tt` - * - `m_t[1] = tt*tt` - * - `m_t[2] = m_t[1]*tt` - * - `m_t[3] = 1.0/m_t[1]` - * - `m_t[4] = log(tt)` - * - `m_t[5] = 1.0/GasConstant` - * - `m_t[6] = 1.0/(GasConstant * T)` + * - `t` is T/1000. + * - `t[0] = t` + * - `t[1] = t*t` + * - `t[2] = t[1]*t` + * - `t[3] = 1.0/t[1]` + * - `t[4] = log(t)` + * - `t[5] = 1.0/t; * * @param tt Vector of temperature polynomials * @param cp_R Vector of Dimensionless heat capacities. (length m_kk). @@ -128,32 +129,18 @@ class ShomatePoly : public SpeciesThermoInterpType doublereal Ct2 = m_coeff[2]*tt[1]; doublereal Dt3 = m_coeff[3]*tt[2]; doublereal Etm2 = m_coeff[4]*tt[3]; - doublereal F = m_coeff[5]; + doublereal Ftm1 = m_coeff[5]*tt[5]; doublereal G = m_coeff[6]; - doublereal cp, h, s; - cp = A + Bt + Ct2 + Dt3 + Etm2; - h = tt[0]*(A + 0.5*Bt + 1.0/3.0*Ct2 + 0.25*Dt3 - Etm2) + F; - s = A*tt[4] + Bt + 0.5*Ct2 + 1.0/3.0*Dt3 - 0.5*Etm2 + G; - - /* - * Shomate polynomials parameterizes assuming units of - * J/(gmol*K) for cp_r and s_R and kJ/(gmol) for h. - * However, Cantera assumes default MKS units of - * J/(kmol*K). This requires us to multiply cp and s - * by 1.e3 and h by 1.e6, before we then nondimensionalize - * the results by dividing by (GasConstant * T), - * where GasConstant has units of J/(kmol * K). - */ - *cp_R = 1.e3 * cp * tt[5]; - *h_RT = 1.e6 * h * tt[6]; - *s_R = 1.e3 * s * tt[5]; + *cp_R = A + Bt + Ct2 + Dt3 + Etm2; + *h_RT = A + 0.5*Bt + 1.0/3.0*Ct2 + 0.25*Dt3 - Etm2 + Ftm1; + *s_R = A*tt[4] + Bt + 0.5*Ct2 + 1.0/3.0*Dt3 - 0.5*Etm2 + G; } virtual void updatePropertiesTemp(const doublereal temp, doublereal* cp_R, doublereal* h_RT, doublereal* s_R) const { - double tPoly[7]; + double tPoly[6]; updateTemperaturePoly(temp, tPoly); updateProperties(tPoly, cp_R, h_RT, s_R); } @@ -168,7 +155,7 @@ class ShomatePoly : public SpeciesThermoInterpType thigh = m_highT; pref = m_Pref; for (int i = 0; i < 7; i++) { - coeffs[i] = m_coeff[i]; + coeffs[i] = m_coeff[i] * GasConstant / 1000; } } @@ -178,36 +165,21 @@ class ShomatePoly : public SpeciesThermoInterpType * parameters for the standard state. */ virtual void modifyParameters(doublereal* coeffs) { - if (m_coeff.size() != 7) { - throw CanteraError("modifyParameters", - "modifying something that hasn't been initialized"); + for (size_t i = 0; i < 7; i++) { + m_coeff[i] = coeffs[i] * 1000 / GasConstant; } - std::copy(coeffs, coeffs + 7, m_coeff.begin()); } virtual doublereal reportHf298(doublereal* const h298 = 0) const { - double tPoly[7]; - updateTemperaturePoly(298.15, tPoly); - doublereal A = m_coeff[0]; - doublereal Bt = m_coeff[1]*tPoly[0]; - doublereal Ct2 = m_coeff[2]*tPoly[1]; - doublereal Dt3 = m_coeff[3]*tPoly[2]; - doublereal Etm2 = m_coeff[4]*tPoly[3]; - doublereal F = m_coeff[5]; - - doublereal h = tPoly[0]*(A + 0.5*Bt + 1.0/3.0*Ct2 + 0.25*Dt3 - Etm2) + F; - - double hh = 1.e6 * h; - if (h298) { - *h298 = 1.e6 * h; - } - return hh; + double cp_R, h_RT, s_R; + updatePropertiesTemp(298.15, &cp_R, &h_RT, &s_R); + return h_RT * GasConstant * 298.15; } virtual void modifyOneHf298(const size_t k, const doublereal Hf298New) { doublereal hnow = reportHf298(); doublereal delH = Hf298New - hnow; - m_coeff[5] += delH / 1.0E6; + m_coeff[5] += delH / (1e3 * GasConstant); } protected: diff --git a/test/thermo/thermoParameterizations.cpp b/test/thermo/thermoParameterizations.cpp index a316290db7..370d525b47 100644 --- a/test/thermo/thermoParameterizations.cpp +++ b/test/thermo/thermoParameterizations.cpp @@ -103,3 +103,30 @@ TEST_F(SpeciesThermoInterpTypeTest, install_shomate) EXPECT_DOUBLE_EQ(p2.entropy_mass(), p.entropy_mass()); EXPECT_DOUBLE_EQ(p2.cp_mass(), p.cp_mass()); } + +TEST(Shomate, modifyParameters) +{ + ShomatePoly2 S1(200, 6000, 101325, co2_shomate_coeffs); + ShomatePoly2 S2(200, 6000, 101325, co_shomate_coeffs); + + S2.modifyParameters((double*) co2_shomate_coeffs); + double cp1, cp2, h1, h2, s1, s2; + S1.updatePropertiesTemp(500, &cp1, &h1, &s1); + S2.updatePropertiesTemp(500, &cp2, &h2, &s2); + EXPECT_DOUBLE_EQ(cp1, cp2); + EXPECT_DOUBLE_EQ(h1, h2); + EXPECT_DOUBLE_EQ(s1, s2); +} + +TEST(Shomate, modifyOneHf298) +{ + ShomatePoly2 S(200, 6000, 101325, co2_shomate_coeffs); + + EXPECT_NEAR(-393.5224e6, S.reportHf298(), 1e4); + double Htest = -400e6; + S.modifyOneHf298(npos, Htest); + double cp, h, s; + S.updatePropertiesTemp(298.15, &cp, &h, &s); + EXPECT_DOUBLE_EQ(Htest, h * 298.15 * GasConstant); + EXPECT_DOUBLE_EQ(Htest, S.reportHf298()); +}