[Thermo] Allow instantiation of IdealSolnGasVPSS without XML

This is also the first test of PDSS_IdealGas that doesn't use XML
This commit is contained in:
Ray Speth 2017-02-19 16:32:28 -05:00
parent 3ea2a6caf3
commit 5efea12959
3 changed files with 80 additions and 26 deletions

View file

@ -45,6 +45,19 @@ public:
return "IdealSolnGas";
}
//! Set this phase to represent an ideal gas
void setGasMode() { m_idealGas = true; }
//! Set this phase to represent an ideal liquid or solid solution
void setSolnMode() { m_idealGas = false; }
//! Set the standard concentration model
/*
* Does not apply to the ideal gas case. Must be one of 'unity',
* 'molar_volume', or 'solvent_volume'.
*/
void setStandardConcentrationModel(const std::string& model);
//! @}
//! @name Molar Thermodynamic Properties
//! @{
@ -134,6 +147,7 @@ public:
virtual bool addSpecies(shared_ptr<Species> spec);
virtual void setParametersFromXML(const XML_Node& thermoNode);
virtual void initThermo();
virtual void setToEquilState(const doublereal* lambda_RT);
virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
@ -149,7 +163,7 @@ protected:
//! form of the generalized concentrations
/*!
* - 0 unity
* - 0 unity (default)
* - 1 1/V_k
* - 2 1/V_0
*/

View file

@ -22,7 +22,7 @@ namespace Cantera
{
IdealSolnGasVPSS::IdealSolnGasVPSS() :
m_idealGas(0),
m_idealGas(-1),
m_formGC(0)
{
}
@ -43,6 +43,25 @@ IdealSolnGasVPSS::IdealSolnGasVPSS(const std::string& infile, std::string id_) :
importPhase(*xphase, this);
}
void IdealSolnGasVPSS::setStandardConcentrationModel(const std::string& model)
{
if (m_idealGas) {
throw CanteraError("IdealSolnGasVPSS::setStandardConcentrationModel",
"Standard concentration model not applicable for ideal gas");
}
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("IdealSolnGasVPSS::setStandardConcentrationModel",
"Unknown standard concentration model '{}'", model);
}
}
// ------------Molar Thermodynamic Properties -------------------------
doublereal IdealSolnGasVPSS::enthalpy_mole() const
@ -234,15 +253,24 @@ bool IdealSolnGasVPSS::addSpecies(shared_ptr<Species> spec)
return added;
}
void IdealSolnGasVPSS::initThermo()
{
VPStandardStateTP::initThermo();
if (m_idealGas == -1) {
throw CanteraError("IdealSolnGasVPSS::initThermo",
"solution / gas mode not set");
}
}
void IdealSolnGasVPSS::initThermoXML(XML_Node& phaseNode, const std::string& id_)
{
if (phaseNode.hasChild("thermo")) {
XML_Node& thermoNode = phaseNode.child("thermo");
std::string model = thermoNode["model"];
if (model == "IdealGasVPSS") {
m_idealGas = 1;
setGasMode();
} else if (model == "IdealSolnVPSS") {
m_idealGas = 0;
setSolnMode();
} else {
throw CanteraError("IdealSolnGasVPSS::initThermoXML",
"Unknown thermo model : " + model);
@ -255,27 +283,11 @@ void IdealSolnGasVPSS::initThermoXML(XML_Node& phaseNode, const std::string& id_
// <standardConc model="molar_volume" />
// <standardConc model="solvent_volume" />
if (phaseNode.hasChild("standardConc")) {
if (m_idealGas) {
throw CanteraError("IdealSolnGasVPSS::initThermoXML",
"standardConc node for ideal gas");
}
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("initThermoXML",
"Unknown standardConc model: " + formString);
}
} else {
if (!m_idealGas) {
throw CanteraError("initThermoXML",
"Unspecified standardConc model");
}
setStandardConcentrationModel(scNode.attrib("model"));
} else if (!m_idealGas) {
throw CanteraError("IdealSolnGasVPSS::initThermoXML",
"Unspecified standardConc model");
}
VPStandardStateTP::initThermoXML(phaseNode, id_);
@ -286,9 +298,9 @@ void IdealSolnGasVPSS::setParametersFromXML(const XML_Node& thermoNode)
VPStandardStateTP::setParametersFromXML(thermoNode);
std::string model = thermoNode["model"];
if (model == "IdealGasVPSS") {
m_idealGas = 1;
setGasMode();
} else if (model == "IdealSolnVPSS") {
m_idealGas = 0;
setSolnMode();
} else {
throw CanteraError("IdealSolnGasVPSS::initThermoXML",
"Unknown thermo model : " + model);

View file

@ -1,10 +1,12 @@
#include "gtest/gtest.h"
#include "cantera/thermo/ThermoFactory.h"
#include "cantera/thermo/PDSSFactory.h"
#include "cantera/thermo/FixedChemPotSSTP.h"
#include "cantera/thermo/PureFluidPhase.h"
#include "cantera/thermo/WaterSSTP.h"
#include "cantera/thermo/RedlichKwongMFTP.h"
#include "cantera/thermo/IonsFromNeutralVPSSTP.h"
#include "cantera/thermo/IdealSolnGasVPSS.h"
#include "cantera/thermo/NasaPoly2.h"
#include "cantera/thermo/ShomatePoly.h"
#include "cantera/thermo/IdealGasPhase.h"
@ -224,6 +226,32 @@ TEST_F(ConstructFromScratch, RedlichKwongMFTP)
EXPECT_NEAR(p.enthalpy_mole(), -404848642.3797, 1e-3);
}
TEST_F(ConstructFromScratch, IdealSolnGasVPSS_gas)
{
IdealSolnGasVPSS p;
p.addUndefinedElements();
p.addSpecies(sH2O);
p.addSpecies(sH2);
p.addSpecies(sO2);
std::unique_ptr<PDSS> pH2O(newPDSS("ideal-gas"));
std::unique_ptr<PDSS> pH2(newPDSS("ideal-gas"));
std::unique_ptr<PDSS> pO2(newPDSS("ideal-gas"));
p.installPDSS(0, std::move(pH2O));
p.installPDSS(1, std::move(pH2));
p.installPDSS(2, std::move(pO2));
p.setGasMode();
EXPECT_THROW(p.setStandardConcentrationModel("unity"), CanteraError);
p.initThermo();
p.setState_TPX(400, 5*OneAtm, "H2:0.01, O2:0.99");
p.equilibrate("HP");
EXPECT_NEAR(p.temperature(), 479.929, 1e-3); // based on h2o2.cti
EXPECT_NEAR(p.moleFraction("H2O"), 0.01, 1e-4);
EXPECT_NEAR(p.moleFraction("H2"), 0.0, 1e-4);
}
TEST(PureFluidFromScratch, CarbonDioxide)
{
PureFluidPhase p;