Bug fixes for liquid electrolyte thermo capability.
thermo XML node now takes a couple of extra XML nodes that can specify explicitly which standardStateManager and which variblePressureStandardState manager to use. These are : <standardStateManager model="provide_specific_model_here"> and <variablePressureStandardStateManager model="provide_specific_model_here"> Previously, these were being determined implicitly by querying the input deck. However, it seems a no brainer to put the capability for putting explicit instructions in.
This commit is contained in:
parent
4dcb746101
commit
c884917c95
15 changed files with 260 additions and 161 deletions
|
|
@ -32,6 +32,8 @@ namespace Cantera {
|
|||
m_temp(-1.0),
|
||||
m_pres(-1.0),
|
||||
m_p0(-1.0),
|
||||
m_minTemp(-1.0),
|
||||
m_maxTemp(10000.0),
|
||||
m_tp(0),
|
||||
m_vpssmgr_ptr(0),
|
||||
m_mw(0.0),
|
||||
|
|
@ -55,6 +57,8 @@ namespace Cantera {
|
|||
m_temp(-1.0),
|
||||
m_pres(-1.0),
|
||||
m_p0(-1.0),
|
||||
m_minTemp(-1.0),
|
||||
m_maxTemp(10000.0),
|
||||
m_tp(tp),
|
||||
m_vpssmgr_ptr(0),
|
||||
m_mw(0.0),
|
||||
|
|
@ -87,6 +91,8 @@ namespace Cantera {
|
|||
m_temp(-1.0),
|
||||
m_pres(-1.0),
|
||||
m_p0(-1.0),
|
||||
m_minTemp(-1.0),
|
||||
m_maxTemp(10000.0),
|
||||
m_tp(0),
|
||||
m_vpssmgr_ptr(0),
|
||||
m_mw(b.m_mw),
|
||||
|
|
@ -121,6 +127,8 @@ namespace Cantera {
|
|||
m_temp = b.m_temp;
|
||||
m_pres = b.m_pres;
|
||||
m_p0 = b.m_p0;
|
||||
m_minTemp = b.m_minTemp;
|
||||
m_maxTemp = b.m_maxTemp;
|
||||
m_tp = b.m_tp;
|
||||
m_vpssmgr_ptr = b.m_vpssmgr_ptr;
|
||||
m_mw = b.m_mw;
|
||||
|
|
@ -158,10 +166,12 @@ namespace Cantera {
|
|||
|
||||
|
||||
void PDSS::initThermoXML(const XML_Node& phaseNode, std::string& id) {
|
||||
AssertThrow(m_tp != 0, "PDSS::initThermoXML()");
|
||||
m_vpssmgr_ptr = m_tp->provideVPSSMgr();
|
||||
}
|
||||
|
||||
void PDSS::initThermo() {
|
||||
AssertThrow(m_tp != 0, "PDSS::initThermo()");
|
||||
m_vpssmgr_ptr = m_tp->provideVPSSMgr();
|
||||
initPtrs();
|
||||
}
|
||||
|
|
@ -361,7 +371,6 @@ namespace Cantera {
|
|||
return(cp_mole() - GasConstant * tmp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the pressure (Pascals), given the temperature and density
|
||||
* Temperature: kelvin
|
||||
|
|
|
|||
|
|
@ -279,6 +279,17 @@ namespace Cantera {
|
|||
return m_p0;
|
||||
}
|
||||
|
||||
//! return the minimum temperature
|
||||
doublereal minTemp() const {
|
||||
return m_minTemp;
|
||||
}
|
||||
|
||||
|
||||
//! return the minimum temperature
|
||||
doublereal maxTemp() const {
|
||||
return m_maxTemp;
|
||||
}
|
||||
|
||||
//! Return the molar gibbs free energy divided by RT at reference pressure
|
||||
/*!
|
||||
* Returns the species reference state gibbs free energy divided by RT at the
|
||||
|
|
@ -486,6 +497,12 @@ namespace Cantera {
|
|||
//! reference state pressure of the species.
|
||||
doublereal m_p0;
|
||||
|
||||
//! minimum temperature
|
||||
doublereal m_minTemp;
|
||||
|
||||
//! maximum temperature
|
||||
doublereal m_maxTemp;
|
||||
|
||||
//! Thermophase which this species belongs to.
|
||||
/*!
|
||||
* Note, in some
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ namespace Cantera {
|
|||
// Ok we may change this evaluation method in the future.
|
||||
double GG = gibbs_mole();
|
||||
double SS = entropy_mole();
|
||||
double h = GG - m_temp * SS;
|
||||
double h = GG + m_temp * SS;
|
||||
return h;
|
||||
}
|
||||
|
||||
|
|
@ -483,8 +483,8 @@ namespace Cantera {
|
|||
const XML_Node& speciesNode,
|
||||
const XML_Node& phaseNode, bool spInstalled) {
|
||||
PDSS::initThermo();
|
||||
SpeciesThermo &sp = m_tp->speciesThermo();
|
||||
m_p0 = sp.refPressure(m_spindex);
|
||||
|
||||
// m_p0 = OneAtm;
|
||||
|
||||
if (!spInstalled) {
|
||||
throw CanteraError("PDSS_HKFT::constructPDSSXML", "spInstalled false not handled");
|
||||
|
|
@ -507,6 +507,23 @@ namespace Cantera {
|
|||
"no Thermo::HKFT Node for species " + speciesNode.name());
|
||||
}
|
||||
|
||||
// go get the attributes
|
||||
m_p0 = OneAtm;
|
||||
std::string p0string = (*hh)["Pref"];
|
||||
if (p0string != "") {
|
||||
m_p0 = strSItoDbl(p0string);
|
||||
}
|
||||
|
||||
std::string minTstring = (*hh)["Tmin"];
|
||||
if (minTstring != "") {
|
||||
m_minTemp = atofCheck(minTstring.c_str());
|
||||
}
|
||||
|
||||
std::string maxTstring = (*hh)["Tmax"];
|
||||
if (maxTstring != "") {
|
||||
m_maxTemp = atofCheck(maxTstring.c_str());
|
||||
}
|
||||
|
||||
if (hh->hasChild("DG0_f_Pr_Tr")) {
|
||||
double val = getFloat(*hh, "DG0_f_Pr_Tr");
|
||||
m_deltaG_formation_tr_pr = val;
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ namespace Cantera {
|
|||
PDSS_Water::PDSS_Water() :
|
||||
PDSS(),
|
||||
m_sub(0),
|
||||
m_temp(0.0),
|
||||
m_dens(1000.0),
|
||||
m_iState(-3000),
|
||||
m_iState(WATER_LIQUID),
|
||||
EW_Offset(0.0),
|
||||
SW_Offset(0.0),
|
||||
m_verbose(0),
|
||||
|
|
@ -40,14 +39,15 @@ namespace Cantera {
|
|||
m_sub = new WaterPropsIAPWS();
|
||||
m_spthermo = 0;
|
||||
constructSet();
|
||||
m_minTemp = 200.;
|
||||
m_maxTemp = 10000.;
|
||||
}
|
||||
|
||||
PDSS_Water::PDSS_Water(VPStandardStateTP *tp, int spindex) :
|
||||
PDSS(tp, spindex),
|
||||
m_sub(0),
|
||||
m_temp(0.0),
|
||||
m_dens(1000.0),
|
||||
m_iState(-3000),
|
||||
m_iState(WATER_LIQUID),
|
||||
EW_Offset(0.0),
|
||||
SW_Offset(0.0),
|
||||
m_verbose(0),
|
||||
|
|
@ -57,6 +57,8 @@ namespace Cantera {
|
|||
m_sub = new WaterPropsIAPWS();
|
||||
m_spthermo = 0;
|
||||
constructSet();
|
||||
m_minTemp = 200.;
|
||||
m_maxTemp = 10000.;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -64,9 +66,8 @@ namespace Cantera {
|
|||
std::string inputFile, std::string id) :
|
||||
PDSS(tp, spindex),
|
||||
m_sub(0),
|
||||
m_temp(0.0),
|
||||
m_dens(1000.0),
|
||||
m_iState(-3000),
|
||||
m_iState(WATER_LIQUID),
|
||||
EW_Offset(0.0),
|
||||
SW_Offset(0.0),
|
||||
m_verbose(0),
|
||||
|
|
@ -76,6 +77,8 @@ namespace Cantera {
|
|||
m_sub = new WaterPropsIAPWS();
|
||||
constructPDSSFile(tp, spindex, inputFile, id);
|
||||
m_spthermo = 0;
|
||||
m_minTemp = 200.;
|
||||
m_maxTemp = 10000.;
|
||||
}
|
||||
|
||||
PDSS_Water::PDSS_Water(VPStandardStateTP *tp, int spindex,
|
||||
|
|
@ -83,9 +86,8 @@ namespace Cantera {
|
|||
const XML_Node& phaseRoot, bool spInstalled) :
|
||||
PDSS(tp, spindex),
|
||||
m_sub(0),
|
||||
m_temp(0.0),
|
||||
m_dens(1000.0),
|
||||
m_iState(-3000),
|
||||
m_iState(WATER_LIQUID),
|
||||
EW_Offset(0.0),
|
||||
SW_Offset(0.0),
|
||||
m_verbose(0),
|
||||
|
|
@ -97,6 +99,8 @@ namespace Cantera {
|
|||
constructPDSSXML(tp, spindex, phaseRoot, id) ;
|
||||
initThermo();
|
||||
m_spthermo = 0;
|
||||
m_minTemp = 200.;
|
||||
m_maxTemp = 10000.;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -104,9 +108,8 @@ namespace Cantera {
|
|||
PDSS_Water::PDSS_Water(const PDSS_Water &b) :
|
||||
PDSS(),
|
||||
m_sub(0),
|
||||
m_temp(0.0),
|
||||
m_dens(1000.0),
|
||||
m_iState(-3000),
|
||||
m_iState(WATER_LIQUID),
|
||||
EW_Offset(b.EW_Offset),
|
||||
SW_Offset(b.SW_Offset),
|
||||
m_verbose(b.m_verbose),
|
||||
|
|
@ -131,7 +134,6 @@ namespace Cantera {
|
|||
PDSS::operator=(b);
|
||||
|
||||
m_sub->operator=(*(b.m_sub));
|
||||
m_temp = b.m_temp;
|
||||
m_dens = b.m_dens;
|
||||
m_iState = b.m_iState;
|
||||
EW_Offset = b.EW_Offset;
|
||||
|
|
@ -375,9 +377,7 @@ namespace Cantera {
|
|||
if (T > m_sub->Tcrit()) {
|
||||
waterState = WATER_SUPERCRIT;
|
||||
}
|
||||
if (p < 1.0) {
|
||||
waterState = WATER_GAS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_HKM
|
||||
//printf("waterPDSS: set pres = %g t = %g, waterState = %d\n",
|
||||
|
|
@ -393,8 +393,14 @@ namespace Cantera {
|
|||
m_dens = dd;
|
||||
m_pres = p;
|
||||
|
||||
// We are only putting the phase check here because of speed considerations.
|
||||
m_iState = m_sub->phaseState(true);
|
||||
|
||||
if (! m_allowGasPhase) {
|
||||
if (m_iState != WATER_SUPERCRIT && m_iState != WATER_LIQUID && m_iState != WATER_UNSTABLELIQUID) {
|
||||
throw CanteraError("PDSS_Water::setPressure",
|
||||
"Water State isn't liquid or crit");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the volumetric thermal expansion coefficient. Units: 1/K.
|
||||
|
|
@ -467,13 +473,10 @@ namespace Cantera {
|
|||
|
||||
// saturation pressure
|
||||
doublereal PDSS_Water::satPressure(doublereal t){
|
||||
doublereal pp = m_sub->psat(t);
|
||||
doublereal dens = m_dens;
|
||||
doublereal pp = m_sub->psat(t, WATER_LIQUID);
|
||||
m_dens = m_sub->density();
|
||||
m_temp = t;
|
||||
m_dens = dens;
|
||||
return pp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -486,11 +486,6 @@ namespace Cantera {
|
|||
*/
|
||||
mutable WaterPropsIAPWS *m_sub;
|
||||
|
||||
/**
|
||||
* state of the system (temperature and density);
|
||||
*/
|
||||
doublereal m_temp;
|
||||
|
||||
//! State of the system - density
|
||||
/*!
|
||||
* Density is the independent variable here, but it's hidden behind the
|
||||
|
|
@ -525,6 +520,7 @@ namespace Cantera {
|
|||
//! Verbose flag - used?
|
||||
bool m_verbose;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Since this phase represents a liquid phase, it's an error to
|
||||
* return a gas-phase answer. However, if the below is true, then
|
||||
|
|
@ -537,6 +533,3 @@ namespace Cantera {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -155,10 +155,7 @@ namespace Cantera {
|
|||
+ SHOMATE*ishomate + SIMPLE*isimple);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(int type) {
|
||||
|
||||
switch (type) {
|
||||
case NASA:
|
||||
return new NasaThermo;
|
||||
|
|
@ -173,12 +170,36 @@ namespace Cantera {
|
|||
case SHOMATE + SIMPLE:
|
||||
return new SpeciesThermoDuo<ShomateThermo, SimpleThermo>;
|
||||
default:
|
||||
throw UnknownSpeciesThermo(
|
||||
"SpeciesThermoFactory::newSpeciesThermo",type);
|
||||
throw UnknownSpeciesThermo("SpeciesThermoFactory::newSpeciesThermo",
|
||||
type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SpeciesThermo* SpeciesThermoFactory::newSpeciesThermoManager(std::string &stype) {
|
||||
std::string ltype = lowercase(stype);
|
||||
if (ltype == "nasa") {
|
||||
return new NasaThermo;
|
||||
} else if (ltype == "shomate") {
|
||||
return new ShomateThermo;
|
||||
} else if (ltype == "simple" || ltype == "constant_cp") {
|
||||
return new SimpleThermo;
|
||||
} else if (ltype == "nasa_shomate_duo") {
|
||||
return new SpeciesThermoDuo<NasaThermo, ShomateThermo>;
|
||||
} else if (ltype == "nasa_simple_duo") {
|
||||
return new SpeciesThermoDuo<NasaThermo, SimpleThermo>;
|
||||
} else if (ltype == "shomate_simple_duo") {
|
||||
return new SpeciesThermoDuo<ShomateThermo, SimpleThermo>;
|
||||
} else if (ltype == "general") {
|
||||
return new GeneralSpeciesThermo();
|
||||
} else if (ltype == "") {
|
||||
return (SpeciesThermo*) 0;
|
||||
} else {
|
||||
throw UnknownSpeciesThermo("SpeciesThermoFactory::newSpeciesThermoManager",
|
||||
stype);
|
||||
}
|
||||
return (SpeciesThermo*) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the continuity of properties at the midpoint
|
||||
|
|
@ -186,7 +207,6 @@ namespace Cantera {
|
|||
*/
|
||||
void NasaThermo::checkContinuity(std::string name, double tmid, const doublereal* clow,
|
||||
doublereal* chigh) {
|
||||
|
||||
// heat capacity
|
||||
doublereal cplow = poly4(tmid, clow);
|
||||
doublereal cphigh = poly4(tmid, chigh);
|
||||
|
|
|
|||
|
|
@ -130,6 +130,16 @@ namespace Cantera {
|
|||
*/
|
||||
SpeciesThermo* newSpeciesThermo(int type);
|
||||
|
||||
|
||||
//! Create a new species thermo property manager given a string
|
||||
/*!
|
||||
* Create a new species thermo property manager, given a
|
||||
* string.
|
||||
*
|
||||
* @param stype String name for the species thermo type
|
||||
*/
|
||||
SpeciesThermo* newSpeciesThermoManager(std::string &stype);
|
||||
|
||||
//! Create a new species property manager.
|
||||
/*!
|
||||
* This routine will look through species nodes. It will discover what
|
||||
|
|
@ -257,6 +267,29 @@ namespace Cantera {
|
|||
return sptherm;
|
||||
}
|
||||
|
||||
//! Create a new species thermo manager instance, by specifying
|
||||
//!the type and (optionally) a pointer to the factory to use to create it.
|
||||
/*!
|
||||
* This utility program is a basic factory operation for spawning a
|
||||
* new species reference-state thermo mananger
|
||||
*
|
||||
* These functions allows for using a different factory class that
|
||||
* derives from SpeciesThermoFactory. However, no applications of this
|
||||
* have been done yet.
|
||||
*
|
||||
* @param type Species thermo type.
|
||||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
*/
|
||||
inline SpeciesThermo* newSpeciesThermoMgr(std::string &stype,
|
||||
SpeciesThermoFactory* f=0) {
|
||||
if (f == 0) {
|
||||
f = SpeciesThermoFactory::factory();
|
||||
}
|
||||
SpeciesThermo* sptherm = f->newSpeciesThermoManager(stype);
|
||||
return sptherm;
|
||||
}
|
||||
|
||||
//! Function to return SpeciesThermo manager
|
||||
/*!
|
||||
* This utility program will look through species nodes. It will discover what
|
||||
|
|
|
|||
|
|
@ -72,15 +72,13 @@ namespace Cantera {
|
|||
//! Returns the minimum temperature that the thermo
|
||||
//! parameterization is valid
|
||||
doublereal STITbyPDSS::minTemp() const {
|
||||
// This concept needs to be put into PDSS
|
||||
return 0.0;
|
||||
return m_PDSS_ptr->minTemp();
|
||||
}
|
||||
|
||||
//! Returns the maximum temperature that the thermo
|
||||
//! parameterization is valid
|
||||
doublereal STITbyPDSS::maxTemp() const {
|
||||
// This concept needs to be put into PDSS
|
||||
return 0.0;
|
||||
return m_PDSS_ptr->maxTemp();
|
||||
}
|
||||
|
||||
//! Returns the reference pressure (Pa)
|
||||
|
|
|
|||
|
|
@ -133,6 +133,10 @@ namespace Cantera {
|
|||
UnknownSpeciesThermo(std::string proc, int type) :
|
||||
CanteraError(proc, "Specified species parameterization type (" + int2str(type)
|
||||
+ ") does not match any known type.") {}
|
||||
|
||||
UnknownSpeciesThermo(std::string proc, std::string stype) :
|
||||
CanteraError(proc, "Specified species parameterization type (" + stype
|
||||
+ ") does not match any known type.") {}
|
||||
//! destructor
|
||||
virtual ~UnknownSpeciesThermo() {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -377,14 +377,14 @@ namespace Cantera {
|
|||
SpeciesThermo* spth = 0;
|
||||
VPSSMgr* vp_spth = 0;
|
||||
if (ssConvention == cSS_CONVENTION_TEMPERATURE) {
|
||||
// Create a new species thermo manager. Function
|
||||
// 'newSpeciesThermoMgr' looks at the species in the database
|
||||
// to see what thermodynamic property parameterizations are
|
||||
// used, and selects a class that can handle the
|
||||
// parameterizations found.
|
||||
// Create a new species thermo manager. Function
|
||||
// 'newSpeciesThermoMgr' looks at the species in the database
|
||||
// to see what thermodynamic property parameterizations are
|
||||
// used, and selects a class that can handle the
|
||||
// parameterizations found.
|
||||
spth = newSpeciesThermoMgr(dbases);
|
||||
|
||||
// install it in the phase object
|
||||
|
||||
// install it in the phase object
|
||||
th->setSpeciesThermo(spth);
|
||||
// SpeciesThermo& spthermo = th->speciesThermo();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace Cantera {
|
|||
m_plast(-1.0),
|
||||
m_p0(-1.0),
|
||||
m_minTemp(-1.0),
|
||||
m_maxTemp(-1.0),
|
||||
m_maxTemp(1.0E8),
|
||||
m_useTmpRefStateStorage(false),
|
||||
m_useTmpStandardStateStorage(false)
|
||||
{
|
||||
|
|
@ -67,7 +67,7 @@ namespace Cantera {
|
|||
m_plast(-1.0),
|
||||
m_p0(-1.0),
|
||||
m_minTemp(-1.0),
|
||||
m_maxTemp(-1.0),
|
||||
m_maxTemp(1.0E8),
|
||||
m_useTmpRefStateStorage(false),
|
||||
m_useTmpStandardStateStorage(false)
|
||||
{
|
||||
|
|
@ -399,9 +399,7 @@ namespace Cantera {
|
|||
|
||||
PDSS * VPSSMgr::createInstallPDSS(int k, const XML_Node& s,
|
||||
const XML_Node *phaseNode_ptr) {
|
||||
// VPSSMgr_enumType tt = reportVPSSMgrType();
|
||||
//string ttt = "createInstallPDSS: " + int2str(int(tt));
|
||||
err( "createInstallPDSS: ");
|
||||
err("VPSSMgr::createInstallPDSS");
|
||||
return (PDSS *) 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,18 +150,19 @@ namespace Cantera {
|
|||
|
||||
VPSSMgr_enumType
|
||||
VPSSMgrFactory::VPSSMgr_StringConversion(std::string ssModel) const {
|
||||
std::string lssModel = lowercase(ssModel);
|
||||
VPSSMgr_enumType type;
|
||||
if (ssModel == "IdealGas") {
|
||||
if (lssModel == "idealgas") {
|
||||
type = cVPSSMGR_IDEALGAS;
|
||||
} else if (ssModel == "ConstVol") {
|
||||
} else if (lssModel == "constvol") {
|
||||
type = cVPSSMGR_CONSTVOL;
|
||||
} else if (ssModel == "PureFuild") {
|
||||
} else if (lssModel == "purefuild") {
|
||||
type = cVPSSMGR_PUREFLUID;
|
||||
} else if (ssModel == "Water_ConstVol") {
|
||||
} else if (lssModel == "water_constvol") {
|
||||
type = cVPSSMGR_WATER_CONSTVOL;
|
||||
} else if (ssModel == "Water_HKFT") {
|
||||
} else if (lssModel == "water_hkft") {
|
||||
type = cVPSSMGR_WATER_HKFT;
|
||||
} else if (ssModel == "General") {
|
||||
} else if (lssModel == "general") {
|
||||
type = cVPSSMGR_GENERAL;
|
||||
} else {
|
||||
type = cVPSSMGR_UNDEF;
|
||||
|
|
@ -169,108 +170,65 @@ namespace Cantera {
|
|||
return type;
|
||||
}
|
||||
|
||||
// Stub out of new capabilities.
|
||||
|
||||
// Chose the variable pressure standard state manager
|
||||
// and the reference standard state manager
|
||||
VPSSMgr*
|
||||
VPSSMgrFactory::newVPSSMgr(VPStandardStateTP *vp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
XML_Node* spData_node) {
|
||||
std::string ssModel="";
|
||||
VPSSMgr *vpss = 0;
|
||||
// First look for any explicit instructions within the XML Data
|
||||
if (phaseNode_ptr) {
|
||||
if (phaseNode_ptr->hasChild("thermo")) {
|
||||
const XML_Node& thermoNode = phaseNode_ptr->child("thermo");
|
||||
if (thermoNode.hasChild("standardState")) {
|
||||
const XML_Node& ssNode = thermoNode.child("standardState");
|
||||
ssModel = ssNode["model"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// first get the reference state handler
|
||||
SpeciesThermo *spth = newSpeciesThermoMgr(spData_node);
|
||||
vp_ptr->setSpeciesThermo(spth);
|
||||
|
||||
if (ssModel != "") {
|
||||
VPSSMgr_enumType type = VPSSMgr_StringConversion(ssModel);
|
||||
vpss = newVPSSMgr(type, vp_ptr);
|
||||
return vpss;
|
||||
}
|
||||
|
||||
// If it comes back as general, then there may be some unknown
|
||||
// parameterizations to the SpeciesThermo factory routine.
|
||||
bool haveSomeUnknowns = true;
|
||||
GeneralSpeciesThermo *ttmp = dynamic_cast<GeneralSpeciesThermo *>(spth);
|
||||
if (ttmp == 0) {
|
||||
haveSomeUnknowns = false;
|
||||
}
|
||||
|
||||
|
||||
if (vp_ptr->eosType() == cVPSS_IdealGas) {
|
||||
vpss = new VPSSMgr_IdealGas(vp_ptr, spth);
|
||||
|
||||
}
|
||||
|
||||
if (vp_ptr->eosType() == cVPSS_ConstVol) {
|
||||
vpss = new VPSSMgr_ConstVol(vp_ptr, spth);
|
||||
}
|
||||
|
||||
int inasa = 0, ishomate = 0, isimple = 0, iwater = 0, itpx = 0, iother = 0;
|
||||
int ihptx = 0;
|
||||
|
||||
try {
|
||||
getVPSSMgrTypes(spData_node, inasa, ishomate, isimple, iwater,
|
||||
itpx, ihptx, iother);
|
||||
} catch (UnknownSpeciesThermoModel) {
|
||||
iother = 1;
|
||||
popError();
|
||||
}
|
||||
|
||||
if (iwater == 1) {
|
||||
if (ihptx == 0) {
|
||||
vpss = new VPSSMgr_Water_ConstVol(vp_ptr, spth);
|
||||
} else {
|
||||
vpss = new VPSSMgr_Water_HKFT(vp_ptr, spth);
|
||||
}
|
||||
}
|
||||
// The default here is to fall back to use the completely
|
||||
// general representation.
|
||||
if (vpss == 0) {
|
||||
vpss = new VPSSMgr_General(vp_ptr, spth);
|
||||
}
|
||||
return vpss;
|
||||
std::vector<XML_Node*> spData_nodes;
|
||||
spData_nodes.push_back(spData_node);
|
||||
VPSSMgr *vv = newVPSSMgr(vp_ptr, phaseNode_ptr, spData_nodes);
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
// Chose the variable pressure standard state manager
|
||||
// and the reference standard state manager
|
||||
VPSSMgr*
|
||||
VPSSMgrFactory::newVPSSMgr(VPStandardStateTP *vp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
std::vector<XML_Node*> spData_nodes) {
|
||||
|
||||
std::string ssModel="";
|
||||
std::string ssManager="";
|
||||
std::string vpssManager="";
|
||||
VPSSMgr *vpss = 0;
|
||||
// First look for any explicit instructions within the XML Data
|
||||
|
||||
// First look for any explicit instructions within the XML Database
|
||||
// for the standard state manager and the variable pressure
|
||||
// standard state manager
|
||||
if (phaseNode_ptr) {
|
||||
if (phaseNode_ptr->hasChild("thermo")) {
|
||||
const XML_Node& thermoNode = phaseNode_ptr->child("thermo");
|
||||
if (thermoNode.hasChild("standardState")) {
|
||||
const XML_Node& ssNode = thermoNode.child("standardState");
|
||||
ssModel = ssNode["model"];
|
||||
if (thermoNode.hasChild("standardStateManager")) {
|
||||
const XML_Node& ssNode = thermoNode.child("standardStateManager");
|
||||
ssManager = ssNode["model"];
|
||||
}
|
||||
if (thermoNode.hasChild("variablePressureStandardStateManager")) {
|
||||
const XML_Node& vpssNode = thermoNode.child("variablePressureStandardStateManager");
|
||||
vpssManager = vpssNode["model"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// first get the reference state handler
|
||||
SpeciesThermo *spth = newSpeciesThermoMgr(spData_nodes);
|
||||
// first get the reference state handler. If we have explicit instructions,
|
||||
// use them to spawn the object.
|
||||
SpeciesThermo *spth = 0;
|
||||
if (ssManager != "") {
|
||||
spth = newSpeciesThermoMgr(ssManager);
|
||||
} else {
|
||||
spth = newSpeciesThermoMgr(spData_nodes);
|
||||
}
|
||||
vp_ptr->setSpeciesThermo(spth);
|
||||
|
||||
if (ssModel != "") {
|
||||
VPSSMgr_enumType type = VPSSMgr_StringConversion(ssModel);
|
||||
// Next, if we have specific directions, use them to get the VPSSSMgr object
|
||||
// and return immediately
|
||||
if (vpssManager != "") {
|
||||
VPSSMgr_enumType type = VPSSMgr_StringConversion(vpssManager);
|
||||
vpss = newVPSSMgr(type, vp_ptr);
|
||||
return vpss;
|
||||
}
|
||||
|
||||
|
||||
// If it comes back as general, then there may be some unknown
|
||||
// parameterizations to the SpeciesThermo factory routine.
|
||||
bool haveSomeUnknowns = true;
|
||||
|
|
@ -278,14 +236,16 @@ namespace Cantera {
|
|||
if (ttmp == 0) {
|
||||
haveSomeUnknowns = false;
|
||||
}
|
||||
|
||||
if (vp_ptr->eosType() == cIdealSolnGasVPSS) {
|
||||
|
||||
// Handle special cases based on the VPStandardState types
|
||||
if (vp_ptr->eosType() == cVPSS_IdealGas) {
|
||||
vpss = new VPSSMgr_IdealGas(vp_ptr, spth);
|
||||
return vpss;
|
||||
} else if (vp_ptr->eosType() == cVPSS_ConstVol) {
|
||||
vpss = new VPSSMgr_ConstVol(vp_ptr, spth);
|
||||
return vpss;
|
||||
}
|
||||
|
||||
if (vp_ptr->eosType() == cIdealSolnGasVPSS_iscv) {
|
||||
vpss = new VPSSMgr_ConstVol(vp_ptr, spth);
|
||||
}
|
||||
|
||||
int n = static_cast<int>(spData_nodes.size());
|
||||
int inasa = 0, ishomate = 0, isimple = 0, iwater = 0, itpx = 0, iother = 0;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "PDSS_Water.h"
|
||||
#include "PDSS_ConstVol.h"
|
||||
#include "PDSS_HKFT.h"
|
||||
#include "GeneralSpeciesThermo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -75,20 +76,20 @@ namespace Cantera {
|
|||
}
|
||||
|
||||
|
||||
|
||||
void VPSSMgr_General::_updateRefStateThermo() const
|
||||
{
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
PDSS *kPDSS = m_PDSS_ptrs[k];
|
||||
kPDSS->setState_TP(m_tlast, m_plast);
|
||||
m_h0_RT[k] = kPDSS->enthalpy_RT_ref();
|
||||
m_s0_R[k] = kPDSS->entropy_R_ref();
|
||||
m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
|
||||
m_cp0_R[k] = kPDSS->cp_R_ref();
|
||||
m_V0[k] = kPDSS->molarVolume_ref();
|
||||
if (m_useTmpRefStateStorage) {
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
PDSS *kPDSS = m_PDSS_ptrs[k];
|
||||
kPDSS->setState_TP(m_tlast, m_plast);
|
||||
m_h0_RT[k] = kPDSS->enthalpy_RT_ref();
|
||||
m_s0_R[k] = kPDSS->entropy_R_ref();
|
||||
m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
|
||||
m_cp0_R[k] = kPDSS->cp_R_ref();
|
||||
m_V0[k] = kPDSS->molarVolume_ref();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VPSSMgr_General::_updateStandardStateThermo()
|
||||
{
|
||||
|
|
@ -120,7 +121,9 @@ namespace Cantera {
|
|||
const XML_Node *phaseNode_ptr, bool &doST) {
|
||||
PDSS *kPDSS = 0;
|
||||
doST = true;
|
||||
|
||||
GeneralSpeciesThermo *genSpthermo = dynamic_cast<GeneralSpeciesThermo *>(m_spthermo);
|
||||
|
||||
|
||||
const XML_Node * const ss = speciesNode.findByName("standardState");
|
||||
if (!ss) {
|
||||
VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
|
||||
|
|
@ -131,12 +134,23 @@ namespace Cantera {
|
|||
if (model == "constant_incompressible") {
|
||||
VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
|
||||
kPDSS = new PDSS_ConstVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
|
||||
} else if (model == "waterIAPWS" || model == "waterPDSS") {
|
||||
doST = false;
|
||||
kPDSS = new PDSS_Water();
|
||||
} else if (model == "waterIAPWS" || model == "waterPDSS") {
|
||||
// VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
|
||||
kPDSS = new PDSS_Water(m_vptp_ptr, 0);
|
||||
if (!genSpthermo) {
|
||||
throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
|
||||
"failed dynamic cast");
|
||||
}
|
||||
genSpthermo->installPDSShandler(k, kPDSS, this);
|
||||
m_useTmpRefStateStorage = false;
|
||||
} else if (model == "HKFT") {
|
||||
doST = false;
|
||||
kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
|
||||
if (!genSpthermo) {
|
||||
throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
|
||||
"failed dynamic cast");
|
||||
}
|
||||
genSpthermo->installPDSShandler(k, kPDSS, this);
|
||||
} else {
|
||||
throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
|
||||
"unknown");
|
||||
|
|
@ -153,8 +167,26 @@ namespace Cantera {
|
|||
if ((int) m_PDSS_ptrs.size() < k+1) {
|
||||
m_PDSS_ptrs.resize(k+1, 0);
|
||||
}
|
||||
|
||||
m_PDSS_ptrs[k] = kPDSS;
|
||||
if ((k+1) >= m_kk) {
|
||||
m_kk = k+1;
|
||||
}
|
||||
|
||||
doublereal minTemp = kPDSS->minTemp();
|
||||
if (minTemp > m_minTemp) {
|
||||
m_minTemp = minTemp;
|
||||
}
|
||||
|
||||
doublereal maxTemp = kPDSS->maxTemp();
|
||||
if (maxTemp < m_maxTemp) {
|
||||
m_maxTemp = maxTemp;
|
||||
}
|
||||
|
||||
doublereal p0 = kPDSS->refPressure();
|
||||
if (k == 0) {
|
||||
m_p0 = p0;
|
||||
}
|
||||
|
||||
return kPDSS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -406,9 +406,15 @@ corr1(doublereal temperature, doublereal pressure, doublereal &densLiq,
|
|||
* p : Pascals : Newtons/m**2
|
||||
*/
|
||||
static int method = 1;
|
||||
doublereal WaterPropsIAPWS::psat(doublereal temperature) {
|
||||
|
||||
doublereal WaterPropsIAPWS::psat(doublereal temperature, int waterState) {
|
||||
doublereal densLiq = -1.0, densGas = -1.0, delGRT = 0.0;
|
||||
doublereal dp, pcorr;
|
||||
if (temperature >= T_c) {
|
||||
densGas = density(temperature, P_c, WATER_SUPERCRIT);
|
||||
setState_TR(temperature, densGas);
|
||||
return P_c;
|
||||
}
|
||||
doublereal p = psat_est(temperature);
|
||||
bool conv = false;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
|
|
@ -432,6 +438,15 @@ doublereal WaterPropsIAPWS::psat(doublereal temperature) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Put the fluid in the desired end condition
|
||||
if (waterState == WATER_LIQUID) {
|
||||
setState_TR(temperature, densLiq);
|
||||
} else if (waterState == WATER_GAS) {
|
||||
setState_TR(temperature, densGas);
|
||||
} else {
|
||||
throw Cantera::CanteraError("WaterPropsIAPWS::psat",
|
||||
"unknown water state input: " + Cantera::int2str(waterState));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ public:
|
|||
* Returns the saturation pressure
|
||||
* units = Pascal
|
||||
*/
|
||||
doublereal psat(doublereal temperature);
|
||||
doublereal psat(doublereal temperature, int waterState = WATER_LIQUID);
|
||||
|
||||
//! Return the value of the density at the water spinodal point
|
||||
//! for the current temperature.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue