diff --git a/src/thermo/MargulesVPSSTP.cpp b/src/thermo/MargulesVPSSTP.cpp index 443ea17a0..c440e57fc 100644 --- a/src/thermo/MargulesVPSSTP.cpp +++ b/src/thermo/MargulesVPSSTP.cpp @@ -200,6 +200,26 @@ void MargulesVPSSTP::getPartialMolarVolumes(doublereal* vbar) const void MargulesVPSSTP::initThermo() { initLengths(); + if (m_input.hasKey("interactions")) { + for (auto& item : m_input["interactions"].asVector()) { + auto& species = item["species"].asVector(2); + vector_fp h(2), s(2), vh(2), vs(2); + if (item.hasKey("excess-enthalpy")) { + h = item.convertVector("excess-enthalpy", "J/kmol", 2); + } + if (item.hasKey("excess-entropy")) { + s = item.convertVector("excess-entropy", "J/kmol/K", 2); + } + if (item.hasKey("excess-volume-enthalpy")) { + vh = item.convertVector("excess-volume-enthalpy", "m^3/kmol/K", 2); + } + if (item.hasKey("excess-volume-entropy")) { + vs = item.convertVector("excess-volume-entropy", "m^3/kmol/K", 2); + } + addBinaryInteraction(species[0], species[1], + h[0], h[1], s[0], s[1], vh[0], vh[1], vs[0], vs[1]); + } + } GibbsExcessVPSSTP::initThermo(); } diff --git a/src/thermo/PDSSFactory.cpp b/src/thermo/PDSSFactory.cpp index 303accba6..3a57c9fa0 100644 --- a/src/thermo/PDSSFactory.cpp +++ b/src/thermo/PDSSFactory.cpp @@ -22,6 +22,7 @@ PDSSFactory::PDSSFactory() reg("ideal-gas", []() { return new PDSS_IdealGas(); }); reg("constant-incompressible", []() { return new PDSS_ConstVol(); }); m_synonyms["constant_incompressible"] = "constant-incompressible"; + m_synonyms["constant-volume"] = "constant-incompressible"; reg("water", []() { return new PDSS_Water(); }); m_synonyms["waterPDSS"] = m_synonyms["waterIAPWS"] = "water"; reg("ions-from-neutral", []() { return new PDSS_IonsFromNeutral(); }); diff --git a/src/thermo/PDSS_ConstVol.cpp b/src/thermo/PDSS_ConstVol.cpp index 22d45a946..f9653d169 100644 --- a/src/thermo/PDSS_ConstVol.cpp +++ b/src/thermo/PDSS_ConstVol.cpp @@ -40,6 +40,9 @@ void PDSS_ConstVol::setParametersFromXML(const XML_Node& speciesNode) void PDSS_ConstVol::initThermo() { PDSS::initThermo(); + if (m_input.hasKey("molar-volume")) { + setMolarVolume(m_input.convert("molar-volume", "m^3/kmol")); + } m_minTemp = m_spthermo->minTemp(); m_maxTemp = m_spthermo->maxTemp(); m_p0 = m_spthermo->refPressure(); diff --git a/test/data/thermo-models.yaml b/test/data/thermo-models.yaml index 8f726733e..d23901d11 100644 --- a/test/data/thermo-models.yaml +++ b/test/data/thermo-models.yaml @@ -19,6 +19,16 @@ phases: species: [Li] chemical-potential: -2.3e7 J/kmol +- name: molten-salt-Margules + thermo: Margules + species: [KCl(l), LiCl(l)] + state: {T: 900, P: 101325, X: {KCl(l): 0.3, LiCl(l): 0.7}} + units: {quantity: gmol} + interactions: + - species: [KCl(l), LiCl(l)] + excess-enthalpy: [-17570, -377] + excess-entropy: [-7.627, 4.958] + species: - name: NaCl(s) composition: {Na: 1, Cl: 1} @@ -50,3 +60,25 @@ species: - name: Li composition: {Li: 1} + +- name: KCl(l) + composition: {K: 1, Cl: 1} + thermo: + model: Shomate + temperature-ranges: [700, 2000] + data: + - [73.59698, 0.0, 0.0, 0.0, 0.0, -443.7341, 175.7209] + equation-of-state: + model: constant-volume + molar-volume: 37.57 cm^3/gmol + +- name: LiCl(l) + composition: {Li: 1, Cl: 1} + thermo: + model: Shomate + temperature-ranges: [700, 2000] + data: + - [73.18025, -9.047232, -0.316390, 0.079587, 0.013594, -417.1314, 157.6711] + equation-of-state: + model: constant-volume + molar-volume: 20.304 cm^3/gmol diff --git a/test/thermo/thermoFromYaml.cpp b/test/thermo/thermoFromYaml.cpp index fd641b0e6..397100eb3 100644 --- a/test/thermo/thermoFromYaml.cpp +++ b/test/thermo/thermoFromYaml.cpp @@ -113,3 +113,16 @@ TEST(ThermoFromYaml, FixedChemPot) thermo->getChemPotentials(&mu); EXPECT_DOUBLE_EQ(mu, -2.3e7); } + +TEST(ThermoFromYaml, Margules) +{ + AnyMap infile = AnyMap::fromYamlFile("thermo-models.yaml"); + auto phaseNodes = infile["phases"].asMap("name"); + auto thermo = newPhase(*phaseNodes.at("molten-salt-Margules"), infile); + EXPECT_EQ(thermo->type(), "Margules"); + + // Regression test based on LiKCl_liquid.xml + EXPECT_NEAR(thermo->density(), 2042.1165603245981, 1e-9); + EXPECT_NEAR(thermo->gibbs_mass(), -9682981.421693124, 1e-5); + EXPECT_NEAR(thermo->cp_mole(), 67478.48085733457, 1e-8); +}