From 0b3a150ec15505b533efdb15c01312879e51781b Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 5 Mar 2019 14:34:12 -0500 Subject: [PATCH 1/3] [Thermo] Fix overriding of IdealSolidSolnPhase::_updateThermo Since IdealSolidSolnPhase::_updateThermo wasn't a virtual method, and the signatures didn't match (const vs non-const), calls to this method from IdealSolidSolnPhase weren't being overridden by BinarySolutionTabulatedThermo::_updateThermo as expected. --- include/cantera/thermo/BinarySolutionTabulatedThermo.h | 4 ++-- include/cantera/thermo/IdealSolidSolnPhase.h | 2 +- src/thermo/BinarySolutionTabulatedThermo.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/cantera/thermo/BinarySolutionTabulatedThermo.h b/include/cantera/thermo/BinarySolutionTabulatedThermo.h index 671b22a9ec..11c2e9d7f7 100644 --- a/include/cantera/thermo/BinarySolutionTabulatedThermo.h +++ b/include/cantera/thermo/BinarySolutionTabulatedThermo.h @@ -156,7 +156,7 @@ class BinarySolutionTabulatedThermo : public IdealSolidSolnPhase size_t m_kk_tab; //! Current tabulated species mole fraction - double m_xlast; + mutable double m_xlast; //! Vector for storing tabulated thermo vector_fp m_molefrac_tab; @@ -164,7 +164,7 @@ class BinarySolutionTabulatedThermo : public IdealSolidSolnPhase vector_fp m_entropy_tab; private: - void _updateThermo(); + virtual void _updateThermo() const; }; } diff --git a/include/cantera/thermo/IdealSolidSolnPhase.h b/include/cantera/thermo/IdealSolidSolnPhase.h index 05316b5c0a..adf632e696 100644 --- a/include/cantera/thermo/IdealSolidSolnPhase.h +++ b/include/cantera/thermo/IdealSolidSolnPhase.h @@ -681,7 +681,7 @@ class IdealSolidSolnPhase : public ThermoPhase * the temperature has changed, the species thermo manager is called to * recalculate G, Cp, H, and S at the current temperature. */ - void _updateThermo() const; + virtual void _updateThermo() const; //@} }; diff --git a/src/thermo/BinarySolutionTabulatedThermo.cpp b/src/thermo/BinarySolutionTabulatedThermo.cpp index e054ce1c0d..a902857956 100644 --- a/src/thermo/BinarySolutionTabulatedThermo.cpp +++ b/src/thermo/BinarySolutionTabulatedThermo.cpp @@ -48,7 +48,7 @@ void BinarySolutionTabulatedThermo::compositionChanged() _updateThermo(); } -void BinarySolutionTabulatedThermo::_updateThermo() +void BinarySolutionTabulatedThermo::_updateThermo() const { double tnow = temperature(); double xnow = moleFraction(m_kk_tab); From af58f91c4c37c3405f119d4bcf588796ba6a02eb Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 5 Mar 2019 14:34:40 -0500 Subject: [PATCH 2/3] [Thermo] Fix BinarySolutionTabulatedThermo updates when only T changes In the case where temperature changes but the mole fractions are the same, we still need to apply the enthalpy and entropy offsets to the tabulated species. --- .../thermo/BinarySolutionTabulatedThermo.h | 6 +++ src/thermo/BinarySolutionTabulatedThermo.cpp | 49 ++++++------------- .../BinarySolutionTabulatedThermo_Test.cpp | 9 +++- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/include/cantera/thermo/BinarySolutionTabulatedThermo.h b/include/cantera/thermo/BinarySolutionTabulatedThermo.h index 11c2e9d7f7..973164efa1 100644 --- a/include/cantera/thermo/BinarySolutionTabulatedThermo.h +++ b/include/cantera/thermo/BinarySolutionTabulatedThermo.h @@ -158,6 +158,12 @@ class BinarySolutionTabulatedThermo : public IdealSolidSolnPhase //! Current tabulated species mole fraction mutable double m_xlast; + //! Tabulated contribution to h0[m_kk_tab] at the current composition + mutable double m_h0_tab; + + //! Tabulated contribution to s0[m_kk_tab] at the current composition + mutable double m_s0_tab; + //! Vector for storing tabulated thermo vector_fp m_molefrac_tab; vector_fp m_enthalpy_tab; diff --git a/src/thermo/BinarySolutionTabulatedThermo.cpp b/src/thermo/BinarySolutionTabulatedThermo.cpp index a902857956..166192a032 100644 --- a/src/thermo/BinarySolutionTabulatedThermo.cpp +++ b/src/thermo/BinarySolutionTabulatedThermo.cpp @@ -50,53 +50,36 @@ void BinarySolutionTabulatedThermo::compositionChanged() void BinarySolutionTabulatedThermo::_updateThermo() const { - double tnow = temperature(); double xnow = moleFraction(m_kk_tab); - std::pair d; - double dS_corr = 0.0; - - if (m_xlast != xnow) { - d = interpolate(xnow); - if (xnow == 0) - { - dS_corr = -BigNumber; - } else if (xnow == 1) - { - dS_corr = BigNumber; - } else - { - dS_corr = GasConstant*std::log(xnow/(1.0-xnow)) + + bool x_changed = (m_xlast != xnow); + + if (x_changed) { + std::tie(m_h0_tab, m_s0_tab) = interpolate(xnow); + if (xnow == 0) { + m_s0_tab = -BigNumber; + } else if (xnow == 1) { + m_s0_tab = BigNumber; + } else { + m_s0_tab += GasConstant*std::log(xnow/(1.0-xnow)) + GasConstant/Faraday*std::log(standardConcentration(1-m_kk_tab) /standardConcentration(m_kk_tab)); } + m_xlast = xnow; + } + double tnow = temperature(); + if (x_changed || m_tlast != tnow) { // Update the thermodynamic functions of the reference state. m_spthermo.update(tnow, m_cp0_R.data(), m_h0_RT.data(), m_s0_R.data()); - m_tlast = tnow; double rrt = 1.0 / RT(); - double rr = 1.0 / GasConstant; + m_h0_RT[m_kk_tab] += m_h0_tab * rrt; + m_s0_R[m_kk_tab] += m_s0_tab / GasConstant; for (size_t k = 0; k < m_kk; k++) { double deltaE = rrt * m_pe[k]; m_h0_RT[k] += deltaE; m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k]; } - m_h0_RT[m_kk_tab] += d.first*rrt; - m_s0_R[m_kk_tab] += (d.second + dS_corr)*rr; - m_g0_RT[m_kk_tab] = m_h0_RT[m_kk_tab] - m_s0_R[m_kk_tab]; - m_tlast = tnow; - m_xlast = xnow; - } else if (m_tlast != tnow) { - // Update the thermodynamic functions of the reference state. - m_spthermo.update(tnow, m_cp0_R.data(), m_h0_RT.data(), m_s0_R.data()); - m_tlast = tnow; - double rrt = 1.0 / RT(); - for (size_t k = 0; k < m_kk; k++) { - double deltaE = rrt * m_pe[k]; - m_h0_RT[k] += deltaE; - m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k]; - } - m_tlast = tnow; } } diff --git a/test/thermo/BinarySolutionTabulatedThermo_Test.cpp b/test/thermo/BinarySolutionTabulatedThermo_Test.cpp index fb9f414363..6145907f21 100644 --- a/test/thermo/BinarySolutionTabulatedThermo_Test.cpp +++ b/test/thermo/BinarySolutionTabulatedThermo_Test.cpp @@ -52,6 +52,10 @@ TEST_F(BinarySolutionTabulatedThermo_Test,interp_h) { set_defect_X(xmin + i*dx); EXPECT_NEAR(expected_result[i], test_phase->enthalpy_mole(), 1.e-6); + // enthalpy is temperature-independent in test data file (all species + // use constant cp model with cp = 0) + test_phase->setState_TP(310, 101325); + EXPECT_NEAR(expected_result[i], test_phase->enthalpy_mole(), 1.e-6); } } @@ -78,7 +82,10 @@ TEST_F(BinarySolutionTabulatedThermo_Test,interp_s) for (int i = 0; i < 9; ++i) { set_defect_X(xmin + i*dx); - + EXPECT_NEAR(expected_result[i], test_phase->entropy_mole(), 1.e-6); + // entropy is temperature-independent in test data file (all species use + // constant cp model with cp = 0) + test_phase->setState_TP(330.0, 101325); EXPECT_NEAR(expected_result[i], test_phase->entropy_mole(), 1.e-6); } } From 3c97fa07d430f357d0d0ce0064f265eb20fa005b Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 5 Mar 2019 23:22:07 -0500 Subject: [PATCH 3/3] [Thermo] Fix BinarySolutionTabulatedThermo initial mole fraction thermo The value of m_xlast should only be set to a valid value by _updateThermo, after it has calculated values for the tabulated enthalpy and entropy. --- src/thermo/BinarySolutionTabulatedThermo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/thermo/BinarySolutionTabulatedThermo.cpp b/src/thermo/BinarySolutionTabulatedThermo.cpp index 166192a032..fa87dc735c 100644 --- a/src/thermo/BinarySolutionTabulatedThermo.cpp +++ b/src/thermo/BinarySolutionTabulatedThermo.cpp @@ -113,7 +113,6 @@ void BinarySolutionTabulatedThermo::initThermoXML(XML_Node& phaseNode, const std throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML", "Species " + tabulated_species_name + " not found."); } - m_xlast = moleFraction(m_kk_tab); } if (thermoNode.hasChild("tabulatedThermo")) { XML_Node& dataNode = thermoNode.child("tabulatedThermo");