From b7f40b209806f7489f8c0e70ff5bce5fc344bfb2 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Mon, 14 Mar 2022 16:38:25 -0400 Subject: [PATCH 1/2] [Thermo] Remove incorrect partialMolarCp from RedlichKwong --- include/cantera/thermo/RedlichKwongMFTP.h | 4 ++- .../cython/cantera/test/test_convert.py | 35 ++++++++++++------- src/thermo/RedlichKwongMFTP.cpp | 6 ---- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/include/cantera/thermo/RedlichKwongMFTP.h b/include/cantera/thermo/RedlichKwongMFTP.h index 4eb4e151ff..9d89bf8ba8 100644 --- a/include/cantera/thermo/RedlichKwongMFTP.h +++ b/include/cantera/thermo/RedlichKwongMFTP.h @@ -117,7 +117,9 @@ class RedlichKwongMFTP : public MixtureFugacityTP virtual void getPartialMolarEnthalpies(doublereal* hbar) const; virtual void getPartialMolarEntropies(doublereal* sbar) const; virtual void getPartialMolarIntEnergies(doublereal* ubar) const; - virtual void getPartialMolarCp(doublereal* cpbar) const; + virtual void getPartialMolarCp(double* cpbar) const { + throw NotImplementedError("RedlichKwongMFTP::getPartialMolarCp"); + } virtual void getPartialMolarVolumes(doublereal* vbar) const; //! @} diff --git a/interfaces/cython/cantera/test/test_convert.py b/interfaces/cython/cantera/test/test_convert.py index ebf939be90..472c8c6b45 100644 --- a/interfaces/cython/cantera/test/test_convert.py +++ b/interfaces/cython/cantera/test/test_convert.py @@ -663,12 +663,16 @@ def checkConversion(self, basename, cls=ct.Solution, ctiphases=(), return ctiPhase, yamlPhase - def checkThermo(self, ctiPhase, yamlPhase, temperatures, tol=1e-7): + def checkThermo(self, ctiPhase, yamlPhase, temperatures, tol=1e-7, check_cp=True): for T in temperatures: ctiPhase.TP = T, ct.one_atm yamlPhase.TP = T, ct.one_atm - cp_cti = ctiPhase.partial_molar_cp - cp_yaml = yamlPhase.partial_molar_cp + if check_cp: + cp_cti = ctiPhase.partial_molar_cp + cp_yaml = yamlPhase.partial_molar_cp + else: + with pytest.raises(ct.CanteraError): + yamlPhase.partial_molar_cp h_cti = ctiPhase.partial_molar_enthalpies h_yaml = yamlPhase.partial_molar_enthalpies s_cti = ctiPhase.partial_molar_entropies @@ -676,7 +680,8 @@ def checkThermo(self, ctiPhase, yamlPhase, temperatures, tol=1e-7): self.assertNear(ctiPhase.density, yamlPhase.density) for i in range(ctiPhase.n_species): message = ' for species {0} at T = {1}'.format(i, T) - self.assertNear(cp_cti[i], cp_yaml[i], tol, msg='cp'+message) + if check_cp: + self.assertNear(cp_cti[i], cp_yaml[i], tol, msg='cp'+message) self.assertNear(h_cti[i], h_yaml[i], tol, msg='h'+message) self.assertNear(s_cti[i], s_yaml[i], tol, msg='s'+message) @@ -779,13 +784,13 @@ def test_Redlich_Kwong_CO2(self): ctiGas, yamlGas = self.checkConversion('co2_RK_example') for P in [1e5, 2e6, 1.3e7]: yamlGas.TP = ctiGas.TP = 300, P - self.checkThermo(ctiGas, yamlGas, [300, 400, 500]) + self.checkThermo(ctiGas, yamlGas, [300, 400, 500], check_cp=False) @utilities.slow_test def test_Redlich_Kwong_ndodecane(self): self.convert("nDodecane_Reitz", self.cantera_data_path) ctiGas, yamlGas = self.checkConversion('nDodecane_Reitz') - self.checkThermo(ctiGas, yamlGas, [300, 400, 500]) + self.checkThermo(ctiGas, yamlGas, [300, 400, 500], check_cp=False) self.checkKinetics(ctiGas, yamlGas, [300, 500, 1300], [1e5, 2e6, 1.4e7], 1e-6) @@ -889,12 +894,17 @@ def checkConversion(self, basename, cls=ct.Solution, ctmlphases=(), return ctmlPhase, yamlPhase - def checkThermo(self, ctmlPhase, yamlPhase, temperatures, pressure=ct.one_atm, tol=1e-7): + def checkThermo(self, ctmlPhase, yamlPhase, temperatures, pressure=ct.one_atm, + tol=1e-7, check_cp=True): for T in temperatures: ctmlPhase.TP = T, pressure yamlPhase.TP = T, pressure - cp_ctml = ctmlPhase.partial_molar_cp - cp_yaml = yamlPhase.partial_molar_cp + if check_cp: + cp_ctml = ctmlPhase.partial_molar_cp + cp_yaml = yamlPhase.partial_molar_cp + else: + with pytest.raises(ct.CanteraError): + yamlPhase.partial_molar_cp h_ctml = ctmlPhase.partial_molar_enthalpies h_yaml = yamlPhase.partial_molar_enthalpies s_ctml = ctmlPhase.partial_molar_entropies @@ -902,7 +912,8 @@ def checkThermo(self, ctmlPhase, yamlPhase, temperatures, pressure=ct.one_atm, t self.assertNear(ctmlPhase.density, yamlPhase.density) for i in range(ctmlPhase.n_species): message = ' for species {0} at T = {1}'.format(ctmlPhase.species_names[i], T) - self.assertNear(cp_ctml[i], cp_yaml[i], tol, msg='cp'+message) + if check_cp: + self.assertNear(cp_ctml[i], cp_yaml[i], tol, msg='cp'+message) self.assertNear(h_ctml[i], h_yaml[i], tol, msg='h'+message) self.assertNear(s_ctml[i], s_yaml[i], tol, msg='s'+message) @@ -1002,13 +1013,13 @@ def test_Redlich_Kwong_CO2(self): ctmlGas, yamlGas = self.checkConversion('co2_RK_example') for P in [1e5, 2e6, 1.3e7]: yamlGas.TP = ctmlGas.TP = 300, P - self.checkThermo(ctmlGas, yamlGas, [300, 400, 500]) + self.checkThermo(ctmlGas, yamlGas, [300, 400, 500], check_cp=False) @utilities.slow_test def test_Redlich_Kwong_ndodecane(self): self.convert("nDodecane_Reitz", self.cantera_data_path) ctmlGas, yamlGas = self.checkConversion('nDodecane_Reitz') - self.checkThermo(ctmlGas, yamlGas, [300, 400, 500]) + self.checkThermo(ctmlGas, yamlGas, [300, 400, 500], check_cp=False) self.checkKinetics(ctmlGas, yamlGas, [300, 500, 1300], [1e5, 2e6, 1.4e7], 1e-6) diff --git a/src/thermo/RedlichKwongMFTP.cpp b/src/thermo/RedlichKwongMFTP.cpp index bd88331ccb..011a2f1dab 100644 --- a/src/thermo/RedlichKwongMFTP.cpp +++ b/src/thermo/RedlichKwongMFTP.cpp @@ -341,12 +341,6 @@ void RedlichKwongMFTP::getPartialMolarIntEnergies(doublereal* ubar) const scale(ubar, ubar+m_kk, ubar, RT()); } -void RedlichKwongMFTP::getPartialMolarCp(doublereal* cpbar) const -{ - getCp_R(cpbar); - scale(cpbar, cpbar+m_kk, cpbar, GasConstant); -} - void RedlichKwongMFTP::getPartialMolarVolumes(doublereal* vbar) const { for (size_t k = 0; k < m_kk; k++) { From c72f095ff7524a271dd60b44c2759addc5834bb0 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Mon, 14 Mar 2022 17:13:52 -0400 Subject: [PATCH 2/2] [Thermo] Correct RedlichKwong::getPartialMolarIntEnergies Fixes #998 --- src/thermo/RedlichKwongMFTP.cpp | 9 +++++++-- test/thermo/RedlichKwongMFTP_Test.cpp | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/thermo/RedlichKwongMFTP.cpp b/src/thermo/RedlichKwongMFTP.cpp index 011a2f1dab..981aaae30a 100644 --- a/src/thermo/RedlichKwongMFTP.cpp +++ b/src/thermo/RedlichKwongMFTP.cpp @@ -337,8 +337,13 @@ void RedlichKwongMFTP::getPartialMolarEntropies(doublereal* sbar) const void RedlichKwongMFTP::getPartialMolarIntEnergies(doublereal* ubar) const { - getIntEnergy_RT(ubar); - scale(ubar, ubar+m_kk, ubar, RT()); + // u_k = h_k - P * v_k + getPartialMolarVolumes(m_partialMolarVolumes.data()); + getPartialMolarEnthalpies(ubar); + double p = pressure(); + for (size_t k = 0; k < nSpecies(); k++) { + ubar[k] -= p * m_partialMolarVolumes[k]; + } } void RedlichKwongMFTP::getPartialMolarVolumes(doublereal* vbar) const diff --git a/test/thermo/RedlichKwongMFTP_Test.cpp b/test/thermo/RedlichKwongMFTP_Test.cpp index 9ae4c86baa..7c1d962843 100644 --- a/test/thermo/RedlichKwongMFTP_Test.cpp +++ b/test/thermo/RedlichKwongMFTP_Test.cpp @@ -204,4 +204,22 @@ TEST_F(RedlichKwongMFTP_Test, localCritProperties) EXPECT_NEAR(test_phase->critPressure(), 22.064e6, 1e-4); } +TEST_F(RedlichKwongMFTP_Test, partialMolarIntEnergy) +{ + // Check that sum(X_k * u) = u + set_r(0.4); + test_phase->setState_TP(400, 1.3e7); + double u_ref = test_phase->intEnergy_mole(); + size_t kk = test_phase->nSpecies(); + vector_fp uk(kk); + vector_fp X(kk); + test_phase->getMoleFractions(X.data()); + test_phase->getPartialMolarIntEnergies(uk.data()); + double u_test = 0; + for (size_t k = 0; k < kk; k++) { + u_test += uk[k] * X[k]; + } + EXPECT_NEAR(u_ref, u_test, 1e-13 * std::abs(u_ref)); +} + };