diff --git a/include/cantera/thermo/MaskellSolidSolnPhase.h b/include/cantera/thermo/MaskellSolidSolnPhase.h index 22b2b7e1d..483d3cf8e 100644 --- a/include/cantera/thermo/MaskellSolidSolnPhase.h +++ b/include/cantera/thermo/MaskellSolidSolnPhase.h @@ -123,6 +123,9 @@ public: virtual void initThermoXML(XML_Node& phaseNode, const std::string& id); void set_h_mix(const doublereal hmix) { h_mixing = hmix; } + + //! Set the product Species. Must be called after species have been added. + void setProductSpecies(const std::string& name); //@} private: diff --git a/src/thermo/MaskellSolidSolnPhase.cpp b/src/thermo/MaskellSolidSolnPhase.cpp index 7f58c373a..8f2a34fd5 100644 --- a/src/thermo/MaskellSolidSolnPhase.cpp +++ b/src/thermo/MaskellSolidSolnPhase.cpp @@ -24,8 +24,8 @@ MaskellSolidSolnPhase::MaskellSolidSolnPhase() : m_g0_RT(2), m_s0_R(2), h_mixing(0.0), - product_species_index(0), - reactant_species_index(1) + product_species_index(-1), + reactant_species_index(-1) { } @@ -209,17 +209,9 @@ void MaskellSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string } if (thNode.hasChild("product_species")) { - std::string product_species_name = thNode.child("product_species").value(); - product_species_index = static_cast(speciesIndex(product_species_name)); - if (product_species_index == -1) { - throw CanteraError("MaskellSolidSolnPhase::initThermoXML", - "Species " + product_species_name + " not found."); - } - if (product_species_index == 0) { - reactant_species_index = 1; - } else { - reactant_species_index = 0; - } + setProductSpecies(thNode.child("product_species").value()); + } else { + setProductSpecies(speciesName(0)); // default } } else { throw CanteraError("MaskellSolidSolnPhase::initThermoXML", @@ -236,6 +228,16 @@ void MaskellSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string VPStandardStateTP::initThermoXML(phaseNode, id_); } +void MaskellSolidSolnPhase::setProductSpecies(const std::string& name) +{ + product_species_index = static_cast(speciesIndex(name)); + if (product_species_index == -1) { + throw CanteraError("MaskellSolidSolnPhase::setProductSpecies", + "Species '{}' not found", name); + } + reactant_species_index = (product_species_index == 0) ? 1 : 0; +} + void MaskellSolidSolnPhase::_updateThermo() const { assert(m_kk == 2); diff --git a/test/thermo/MaskellSolidSolnPhase_Test.cpp b/test/thermo/MaskellSolidSolnPhase_Test.cpp index e56ea356e..abf592923 100644 --- a/test/thermo/MaskellSolidSolnPhase_Test.cpp +++ b/test/thermo/MaskellSolidSolnPhase_Test.cpp @@ -1,6 +1,9 @@ #include "gtest/gtest.h" #include "cantera/thermo/MaskellSolidSolnPhase.h" #include "cantera/thermo/ThermoFactory.h" +#include "cantera/thermo/PDSS_ConstVol.h" +#include "cantera/thermo/ConstCpPoly.h" +#include "cantera/base/stringUtils.h" #include namespace Cantera @@ -8,8 +11,6 @@ namespace Cantera class MaskellSolidSolnPhase_Test : public testing::Test { -protected: - std::unique_ptr test_phase; public: void initializeTestPhaseWithXML(const std::string & filename) { @@ -35,6 +36,11 @@ public: EXPECT_NEAR(1000.+expected_result[i], chemPotentials[1], 1.e-6); } } + + std::unique_ptr test_phase; + const double expected_result_0[9] = {1.2338461168724738e7, 8.011774549216799e6, 4.990989640314685e6, 2.415973128783114e6, 0., -2.415973128783114e6, -4.99098964031469e6, -8.0117745492168e6, -1.2338461168724738e7}; + const double expected_result_5000[9] = { 1.233625377465302e7, 8.00995666545047e6, 4.989677478024063e6, 2.41528026460977e6, 0., -2.415280264609771e6, -4.989677478024068e6, -8.00995666545047e6, -1.233625377465302e7 }; + const double expected_result_minus_5000[9] = { 1.2340671035887627e7, 8.013594700219031e6, 4.992303607179179e6, 2.4166670154679064e6, 0., -2.4166670154679064e6, -4.9923036071791835e6, -8.013594700219034e6, -1.2340671035887627e7}; }; TEST_F(MaskellSolidSolnPhase_Test, construct_from_xml) @@ -58,15 +64,12 @@ TEST_F(MaskellSolidSolnPhase_Test, chem_potentials) MaskellSolidSolnPhase* maskell_phase = dynamic_cast(test_phase.get()); maskell_phase->set_h_mix(0.); - const double expected_result_0[9] = {1.2338461168724738e7, 8.011774549216799e6, 4.990989640314685e6, 2.415973128783114e6, 0., -2.415973128783114e6, -4.99098964031469e6, -8.0117745492168e6, -1.2338461168724738e7}; check_chemPotentials(expected_result_0); maskell_phase->set_h_mix(5000.); - const double expected_result_5000[9] = { 1.233625377465302e7, 8.00995666545047e6, 4.989677478024063e6, 2.41528026460977e6, 0., -2.415280264609771e6, -4.989677478024068e6, -8.00995666545047e6, -1.233625377465302e7 }; check_chemPotentials(expected_result_5000); maskell_phase->set_h_mix(-5000.); - const double expected_result_minus_5000[9] = { 1.2340671035887627e7, 8.013594700219031e6, 4.992303607179179e6, 2.4166670154679064e6, 0., -2.4166670154679064e6, -4.9923036071791835e6, -8.013594700219034e6, -1.2340671035887627e7}; check_chemPotentials(expected_result_minus_5000); } @@ -137,4 +140,47 @@ TEST_F(MaskellSolidSolnPhase_Test, activityConcentrations) } } +TEST_F(MaskellSolidSolnPhase_Test, fromScratch) { + auto sH = make_shared("H(s)", parseCompString("H:1 He:2")); + double coeffs1[] = {1.0, 0.0, 0.0, 0.0}; + sH->thermo.reset(new ConstCpPoly(250, 800, 1e5, coeffs1)); + + auto sHe = make_shared("He(s)", parseCompString("He:1")); + double coeffs2[] = {1.0, 1000.0, 0.0, 0.0}; + sHe->thermo.reset(new ConstCpPoly(250, 800, 1e5, coeffs2)); + + MaskellSolidSolnPhase* p = new MaskellSolidSolnPhase(); + test_phase.reset(p); + + p->addUndefinedElements(); + p->addSpecies(sH); + p->addSpecies(sHe); + + std::unique_ptr ssH(new PDSS_ConstVol()); + ssH->setMolarVolume(0.005); + p->installPDSS(0, std::move(ssH)); + + std::unique_ptr ssHe(new PDSS_ConstVol()); + ssHe->setMolarVolume(0.01); + p->installPDSS(1, std::move(ssHe)); + + p->set_h_mix(5000); + p->setProductSpecies("H(s)"); + + p->initThermo(); + p->setState_TPX(298, 1, "H(s):0.90 He(s):0.10"); + + vector_fp pmv(2); + p->getPartialMolarVolumes(&pmv[0]); + EXPECT_EQ(0.005, pmv[0]); + EXPECT_EQ(0.01, pmv[1]); + + // Compare with XML chem_potentials test + p->set_h_mix(5000.); + check_chemPotentials(expected_result_5000); + + p->set_h_mix(-5000.); + check_chemPotentials(expected_result_minus_5000); +} + };