[Thermo] Allow instantiation of IdealSolidSolnPhase without XML

This commit is contained in:
Ray Speth 2017-07-31 22:23:24 -04:00
parent 8a4142d4bc
commit aa02d24235
3 changed files with 62 additions and 34 deletions

View file

@ -578,6 +578,22 @@ public:
virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
virtual void setToEquilState(const doublereal* lambda_RT);
//! Set the form for the standard and generalized concentrations
/*!
* Must be one of 'unity', 'molar_volume', or 'solvent_volume'.
* The default is 'unity'.
*
* | m_formGC | GeneralizedConc | StandardConc |
* | ----------- | --------------- | ------------ |
* | unity | X_k | 1.0 |
* | molar_volume | X_k / V_k | 1.0 / V_k |
* | solvent_volume | X_k / V_N | 1.0 / V_N |
*
* The value and form of the generalized concentration will affect
* reaction rate constants involving species in this phase.
*/
void setStandardConcentrationModel(const std::string& model);
/**
* Report the molar volume of species k
*
@ -603,16 +619,9 @@ protected:
virtual void compositionChanged();
/**
* Format for the generalized concentrations.
*
* | m_formGC | GeneralizedConc | StandardConc |
* | ----------- | --------------- | ------------ |
* | 0 (default) | X_k | 1.0 |
* | 1 | X_k / V_k | 1.0 / V_k |
* | 2 | X_k / V_N | 1.0 / V_N |
*
* The value and form of the generalized concentration will affect
* reaction rate constants involving species in this phase.
* The standard concentrations can have one of three different forms:
* 0 = 'unity', 1 = 'molar_volume', 2 = 'solvent_volume'. See
* setStandardConcentrationModel().
*/
int m_formGC;

View file

@ -359,7 +359,12 @@ bool IdealSolidSolnPhase::addSpecies(shared_ptr<Species> spec)
m_s0_R.push_back(0.0);
m_pe.push_back(0.0);;
m_pp.push_back(0.0);
m_speciesMolarVolume.push_back(0.0);
if (spec->extra.hasKey("molar_volume")) {
m_speciesMolarVolume.push_back(spec->extra["molar_volume"].asDouble());
} else {
throw CanteraError("IdealSolidSolnPhase::addSpecies",
"Molar volume not specified for species '{}'", spec->name);
}
}
return added;
}
@ -391,34 +396,12 @@ void IdealSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string&
// <standardConc model="molar_volume" />
// <standardConc model="solvent_volume" />
if (phaseNode.hasChild("standardConc")) {
XML_Node& scNode = phaseNode.child("standardConc");
string formString = scNode.attrib("model");
if (ba::iequals(formString, "unity")) {
m_formGC = 0;
} else if (ba::iequals(formString, "molar_volume")) {
m_formGC = 1;
} else if (ba::iequals(formString, "solvent_volume")) {
m_formGC = 2;
} else {
throw CanteraError("IdealSolidSolnPhase::initThermoXML",
"Unknown standardConc model: " + formString);
}
setStandardConcentrationModel(phaseNode.child("standardConc")["model"]);
} else {
throw CanteraError("IdealSolidSolnPhase::initThermoXML",
"Unspecified standardConc model");
}
// Now go get the molar volumes
XML_Node& speciesList = phaseNode.child("speciesArray");
XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
&phaseNode.root());
for (size_t k = 0; k < m_kk; k++) {
XML_Node* s = speciesDB->findByAttr("name", speciesName(k));
XML_Node* ss = s->findByName("standardState");
m_speciesMolarVolume[k] = getFloat(*ss, "molarVolume", "toSI");
}
// Call the base initThermo, which handles setting the initial state.
ThermoPhase::initThermoXML(phaseNode, id_);
}
@ -440,6 +423,20 @@ void IdealSolidSolnPhase::setToEquilState(const doublereal* lambda_RT)
setState_PX(pres, &m_pp[0]);
}
void IdealSolidSolnPhase::setStandardConcentrationModel(const std::string& model)
{
if (ba::iequals(model, "unity")) {
m_formGC = 0;
} else if (ba::iequals(model, "molar_volume")) {
m_formGC = 1;
} else if (ba::iequals(model, "solvent_volume")) {
m_formGC = 2;
} else {
throw CanteraError("IdealSolidSolnPhase::setStandardConcentrationModel",
"Unknown standard concentration model '{}'", model);
}
}
double IdealSolidSolnPhase::speciesMolarVolume(int k) const
{
return m_speciesMolarVolume[k];

View file

@ -15,6 +15,8 @@
#include "cantera/thermo/LatticePhase.h"
#include "cantera/thermo/StoichSubstance.h"
#include "cantera/thermo/LatticeSolidPhase.h"
#include "cantera/thermo/IdealSolidSolnPhase.h"
#include "cantera/thermo/NasaPoly2.h"
#include "cantera/thermo/ConstCpPoly.h"
#include "cantera/thermo/ShomatePoly.h"
@ -479,4 +481,24 @@ TEST(LatticeSolidPhase, fromScratch)
}
}
TEST(IdealSolidSolnPhase, fromScratch)
{
// Regression test based fictitious XML input file
IdealSolidSolnPhase p;
p.addUndefinedElements();
auto sp1 = make_species("sp1", "C:2, H:2", o2_nasa_coeffs);
sp1->extra["molar_volume"] = 1.5;
auto sp2 = make_species("sp2", "C:1", h2o_nasa_coeffs);
sp2->extra["molar_volume"] = 1.3;
auto sp3 = make_species("sp3", "H:2", h2_nasa_coeffs);
sp3->extra["molar_volume"] = 0.1;
for (auto& s : {sp1, sp2, sp3}) {
p.addSpecies(s);
}
p.setState_TPX(500, 2e5, "sp1:0.1, sp2:0.89, sp3:0.01");
EXPECT_NEAR(p.density(), 10.1786978, 1e-6);
EXPECT_NEAR(p.enthalpy_mass(), -15642803.3884617, 1e-4);
EXPECT_NEAR(p.gibbs_mole(), -313642293.1654253, 1e-4);
}
} // namespace Cantera