Bug fix / clarification to importPhase()
Created a list of species early on in the new routine, formSpeciesXMLNodeList(). This list is the actual list of species that will make up the phase. This is done before the id of the SPeciesThermo or VPSSMgr is chosen, so that this id is chosen based on just the species to be included in the phase and not on all of the species that are in the database. The overall amount of code is reduced, and the code is clarified. Fixed an error in VPSSMgr_Water_HKFT.
This commit is contained in:
parent
7799f24724
commit
464fc1409d
6 changed files with 344 additions and 276 deletions
|
|
@ -50,44 +50,52 @@ namespace Cantera {
|
|||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Examine the types of species thermo parameterizations,
|
||||
* and return a flag indicating the type of parameterization
|
||||
* needed by the species.
|
||||
|
||||
//! Examine the types of species thermo parameterizations,
|
||||
//! and return a flag indicating the type of reference state thermo manager
|
||||
//! that will be needed in order to evaluate them all.
|
||||
/*!
|
||||
*
|
||||
* @param spData_node Species Data XML node. This node contains a list
|
||||
* of species XML nodes underneath it.
|
||||
* @param spDataNodeList, This vector contains a list
|
||||
* of species XML nodes that will be in the phase
|
||||
*
|
||||
* @todo Make sure that spDadta_node is species Data XML node by checking its name is speciesData
|
||||
*/
|
||||
static void getSpeciesThermoTypes(XML_Node* spData_node,
|
||||
static void getSpeciesThermoTypes(std::vector<XML_Node *> & spDataNodeList,
|
||||
int& has_nasa, int& has_shomate, int& has_simple,
|
||||
int &has_other) {
|
||||
const XML_Node& sparray = *spData_node;
|
||||
std::vector<XML_Node*> sp;
|
||||
|
||||
// get all of the species nodes
|
||||
sparray.getChildren("species",sp);
|
||||
size_t n, ns = sp.size();
|
||||
for (n = 0; n < ns; n++) {
|
||||
XML_Node* spNode = sp[n];
|
||||
size_t ns = spDataNodeList.size();
|
||||
for (size_t n = 0; n < ns; n++) {
|
||||
XML_Node* spNode = spDataNodeList[n];
|
||||
if (spNode->hasChild("thermo")) {
|
||||
const XML_Node& th = sp[n]->child("thermo");
|
||||
if (th.hasChild("NASA")) has_nasa = 1;
|
||||
if (th.hasChild("Shomate")) has_shomate = 1;
|
||||
if (th.hasChild("const_cp")) has_simple = 1;
|
||||
if (th.hasChild("poly")) {
|
||||
const XML_Node& th = spNode->child("thermo");
|
||||
if (th.hasChild("NASA")) {
|
||||
has_nasa = 1;
|
||||
} else if (th.hasChild("Shomate")) {
|
||||
has_shomate = 1;
|
||||
} else if (th.hasChild("const_cp")) {
|
||||
has_simple = 1;
|
||||
} else if (th.hasChild("poly")) {
|
||||
if (th.child("poly")["order"] == "1") has_simple = 1;
|
||||
else throw CanteraError("newSpeciesThermo",
|
||||
"poly with order > 1 not yet supported");
|
||||
}
|
||||
if (th.hasChild("Mu0")) has_other = 1;
|
||||
if (th.hasChild("NASA9")) has_other = 1;
|
||||
if (th.hasChild("NASA9MULTITEMP")) has_other = 1;
|
||||
if (th.hasChild("adsorbate")) has_other = 1;
|
||||
else if (th.hasChild("Mu0")) {
|
||||
has_other = 1;
|
||||
} else if (th.hasChild("NASA9")) {
|
||||
has_other = 1;
|
||||
} else if (th.hasChild("NASA9MULTITEMP")) {
|
||||
has_other = 1;
|
||||
} else if (th.hasChild("adsorbate")) {
|
||||
has_other = 1;
|
||||
} else {
|
||||
has_other = 1;
|
||||
//throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:",
|
||||
// spNode->attrib("name"), "missing");
|
||||
}
|
||||
} else {
|
||||
throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:",
|
||||
spNode->attrib("name"), "missing");
|
||||
throw CanteraError("getSpeciesThermoTypes:",
|
||||
spNode->attrib("name") + " is missing the thermo XML node");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,35 +105,16 @@ namespace Cantera {
|
|||
* Return a species thermo manager to handle the parameterizations
|
||||
* specified in a CTML phase specification.
|
||||
*/
|
||||
SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(XML_Node* spData_node) {
|
||||
SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(std::vector<XML_Node*> & spDataNodeList) {
|
||||
int inasa = 0, ishomate = 0, isimple = 0, iother = 0;
|
||||
try {
|
||||
getSpeciesThermoTypes(spData_node, inasa, ishomate, isimple, iother);
|
||||
getSpeciesThermoTypes(spDataNodeList, inasa, ishomate, isimple, iother);
|
||||
} catch (UnknownSpeciesThermoModel) {
|
||||
iother = 1;
|
||||
popError();
|
||||
}
|
||||
if (iother) {
|
||||
writelog("returning new GeneralSpeciesThermo");
|
||||
return new GeneralSpeciesThermo();
|
||||
}
|
||||
return newSpeciesThermo(NASA*inasa
|
||||
+ SHOMATE*ishomate + SIMPLE*isimple);
|
||||
}
|
||||
|
||||
SpeciesThermo* SpeciesThermoFactory::
|
||||
newSpeciesThermo(std::vector<XML_Node*> spData_nodes) {
|
||||
int n = static_cast<int>(spData_nodes.size());
|
||||
int inasa = 0, ishomate = 0, isimple = 0, iother = 0;
|
||||
for (int j = 0; j < n; j++) {
|
||||
try {
|
||||
getSpeciesThermoTypes(spData_nodes[j], inasa, ishomate, isimple, iother);
|
||||
} catch (UnknownSpeciesThermoModel) {
|
||||
iother = 1;
|
||||
popError();
|
||||
}
|
||||
}
|
||||
if (iother) {
|
||||
//writelog("returning new GeneralSpeciesThermo");
|
||||
return new GeneralSpeciesThermo();
|
||||
}
|
||||
return newSpeciesThermo(NASA*inasa
|
||||
|
|
@ -137,17 +126,15 @@ namespace Cantera {
|
|||
* @todo is this used?
|
||||
*/
|
||||
SpeciesThermo* SpeciesThermoFactory::
|
||||
newSpeciesThermoOpt(std::vector<XML_Node*> nodes) {
|
||||
int n = static_cast<int>(nodes.size());
|
||||
newSpeciesThermoOpt(std::vector<XML_Node*> & spDataNodeList) {
|
||||
int inasa = 0, ishomate = 0, isimple = 0, iother = 0;
|
||||
for (int j = 0; j < n; j++) {
|
||||
try {
|
||||
getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple, iother);
|
||||
} catch (UnknownSpeciesThermoModel) {
|
||||
iother = 1;
|
||||
popError();
|
||||
}
|
||||
try {
|
||||
getSpeciesThermoTypes(spDataNodeList, inasa, ishomate, isimple, iother);
|
||||
} catch (UnknownSpeciesThermoModel) {
|
||||
iother = 1;
|
||||
popError();
|
||||
}
|
||||
|
||||
if (iother) {
|
||||
return new GeneralSpeciesThermo();
|
||||
}
|
||||
|
|
@ -655,6 +642,80 @@ namespace Cantera {
|
|||
vp_ptr->createInstallPDSS(k, speciesNode, phaseNode_ptr);
|
||||
}
|
||||
|
||||
// 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 will look through species nodes. It will discover what
|
||||
* each species needs for its species property managers. Then,
|
||||
* it will malloc and return the proper species property manager to use.
|
||||
*
|
||||
* These functions allow using a different factory class that
|
||||
* derives from SpeciesThermoFactory.
|
||||
*
|
||||
* @param type Species thermo type.
|
||||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
*/
|
||||
SpeciesThermo* newSpeciesThermoMgr(int type, SpeciesThermoFactory* f) {
|
||||
if (f == 0) {
|
||||
f = SpeciesThermoFactory::factory();
|
||||
}
|
||||
SpeciesThermo* sptherm = f->newSpeciesThermo(type);
|
||||
return sptherm;
|
||||
}
|
||||
|
||||
// Function to return SpeciesThermo manager
|
||||
/*
|
||||
* This utility program will look through species nodes. It will discover what
|
||||
* each species needs for its species property managers. Then,
|
||||
* it will malloc and return the proper species property manager to use.
|
||||
*
|
||||
* These functions allow using a different factory class that
|
||||
* derives from SpeciesThermoFactory.
|
||||
*
|
||||
* @param spData_node Vector of XML_Nodes, each of which is a speciesData XML Node.
|
||||
* Each %speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
*/
|
||||
// SpeciesThermo* newSpeciesThermoMgr(XML_Node* spData_node,
|
||||
// SpeciesThermoFactory* f) {
|
||||
//if (f == 0) {
|
||||
// f = SpeciesThermoFactory::factory();
|
||||
//}
|
||||
//SpeciesThermo* sptherm = f->newSpeciesThermo(spData_node);
|
||||
//return sptherm;
|
||||
//}
|
||||
|
||||
//! Function to return SpeciesThermo manager
|
||||
/*!
|
||||
* This utility program will look through species nodes. It will discover what
|
||||
* each species needs for its species property managers. Then,
|
||||
* it will malloc and return the proper species property manager to use.
|
||||
*
|
||||
* These functions allow using a different factory class that
|
||||
* derives from SpeciesThermoFactory.
|
||||
*
|
||||
* @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node.
|
||||
* Each %speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
* @param opt Boolean defaults to false.
|
||||
*/
|
||||
SpeciesThermo* newSpeciesThermoMgr(std::vector<XML_Node*> spData_nodes,
|
||||
SpeciesThermoFactory* f, bool opt) {
|
||||
if (f == 0) {
|
||||
f = SpeciesThermoFactory::factory();
|
||||
}
|
||||
SpeciesThermo* sptherm;
|
||||
if (opt) {
|
||||
sptherm = f->newSpeciesThermoOpt(spData_nodes);
|
||||
} else {
|
||||
sptherm = f->newSpeciesThermo(spData_nodes);
|
||||
}
|
||||
return sptherm;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ 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
|
||||
|
|
@ -140,29 +139,16 @@ namespace Cantera {
|
|||
*/
|
||||
SpeciesThermo* newSpeciesThermoManager(std::string &stype);
|
||||
|
||||
//! Create a new species property manager.
|
||||
/*!
|
||||
* This routine will look through species nodes. It will discover what
|
||||
* each species needs for its species property managers. Then,
|
||||
* it will malloc and return the proper species property manager to use.
|
||||
*
|
||||
* @param spData_node Pointer to a speciesData XML Node.
|
||||
* Each speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
*/
|
||||
SpeciesThermo* newSpeciesThermo(XML_Node* spData_node);
|
||||
|
||||
//! Create a new species property manager for a group of species
|
||||
/*!
|
||||
* This routine will look through species nodes. It will discover what
|
||||
* each species needs for its species property managers. Then,
|
||||
* it will malloc and return the proper species property manager to use.
|
||||
*
|
||||
* @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node.
|
||||
* Each speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
*
|
||||
* @param spDataNodeList, This vector contains a list
|
||||
* of species XML nodes that will be in the phase
|
||||
*/
|
||||
SpeciesThermo* newSpeciesThermo(std::vector<XML_Node*> spData_nodes);
|
||||
SpeciesThermo* newSpeciesThermo(std::vector<XML_Node*> & spDataNodeList);
|
||||
|
||||
//! Create a new species property manager.
|
||||
/*!
|
||||
|
|
@ -171,13 +157,11 @@ namespace Cantera {
|
|||
* it will malloc and return the proper species property manager to use.
|
||||
*
|
||||
*
|
||||
* @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node.
|
||||
* Each %speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
*
|
||||
* @param spDataNodeList This vector contains a list
|
||||
* of species XML nodes that will be in the phase
|
||||
* @todo is this used?
|
||||
*/
|
||||
SpeciesThermo* newSpeciesThermoOpt(std::vector<XML_Node*> spData_nodes);
|
||||
SpeciesThermo* newSpeciesThermoOpt(std::vector<XML_Node*> & spDataNodeList);
|
||||
|
||||
//! Install a species thermodynamic property parameterization
|
||||
//! for the reference state for one species into a species thermo manager.
|
||||
|
|
@ -258,14 +242,7 @@ namespace Cantera {
|
|||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
*/
|
||||
inline SpeciesThermo* newSpeciesThermoMgr(int type,
|
||||
SpeciesThermoFactory* f=0) {
|
||||
if (f == 0) {
|
||||
f = SpeciesThermoFactory::factory();
|
||||
}
|
||||
SpeciesThermo* sptherm = f->newSpeciesThermo(type);
|
||||
return sptherm;
|
||||
}
|
||||
SpeciesThermo* newSpeciesThermoMgr(int type, SpeciesThermoFactory* f=0);
|
||||
|
||||
//! Create a new species thermo manager instance, by specifying
|
||||
//!the type and (optionally) a pointer to the factory to use to create it.
|
||||
|
|
@ -305,44 +282,27 @@ namespace Cantera {
|
|||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
*/
|
||||
inline SpeciesThermo* newSpeciesThermoMgr(XML_Node* spData_node,
|
||||
SpeciesThermoFactory* f=0) {
|
||||
if (f == 0) {
|
||||
f = SpeciesThermoFactory::factory();
|
||||
}
|
||||
SpeciesThermo* sptherm = f->newSpeciesThermo(spData_node);
|
||||
return sptherm;
|
||||
}
|
||||
// SpeciesThermo* newSpeciesThermoMgr(XML_Node* spData_node,
|
||||
// SpeciesThermoFactory* f=0);
|
||||
|
||||
//! Function to return SpeciesThermo manager
|
||||
/*!
|
||||
* This utility program will look through species nodes. It will discover what
|
||||
* each species needs for its species property managers. Then,
|
||||
* it will malloc and return the proper species property manager to use.
|
||||
* it will malloc and return the proper species reference state manager to use.
|
||||
*
|
||||
* These functions allow using a different factory class that
|
||||
* derives from SpeciesThermoFactory.
|
||||
*
|
||||
* @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node.
|
||||
* Each %speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
* @param spDataNodeList This vector contains a list
|
||||
* of species XML nodes that will be in the phase
|
||||
*
|
||||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
* @param opt Boolean defaults to false.
|
||||
*/
|
||||
inline SpeciesThermo* newSpeciesThermoMgr(std::vector<XML_Node*> spData_nodes,
|
||||
SpeciesThermoFactory* f=0, bool opt=false) {
|
||||
if (f == 0) {
|
||||
f = SpeciesThermoFactory::factory();
|
||||
}
|
||||
SpeciesThermo* sptherm;
|
||||
if (opt) {
|
||||
sptherm = f->newSpeciesThermoOpt(spData_nodes);
|
||||
} else {
|
||||
sptherm = f->newSpeciesThermo(spData_nodes);
|
||||
}
|
||||
return sptherm;
|
||||
}
|
||||
SpeciesThermo* newSpeciesThermoMgr(std::vector<XML_Node*> spDataNodeList,
|
||||
SpeciesThermoFactory* f=0, bool opt=false);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,6 +229,117 @@ namespace Cantera {
|
|||
return (ThermoPhase *) 0;
|
||||
}
|
||||
|
||||
|
||||
static void formSpeciesXMLNodeList(std::vector<XML_Node *> &spDataNodeList,
|
||||
std::vector<std::string> &spNamesList,
|
||||
std::vector<int> &spRuleList,
|
||||
const std::vector<XML_Node *> spArray_names,
|
||||
const std::vector<XML_Node *> spArray_dbases,
|
||||
const vector_int sprule) {
|
||||
|
||||
// used to check that each species is declared only once
|
||||
std::map<std::string, bool> declared;
|
||||
|
||||
int nspa = spArray_dbases.size();
|
||||
int nSpecies = 0;
|
||||
bool skip;
|
||||
|
||||
for (int jsp = 0; jsp < nspa; jsp++) {
|
||||
const XML_Node& speciesArray = *spArray_names[jsp];
|
||||
|
||||
// Get the top XML for the database
|
||||
const XML_Node *db = spArray_dbases[jsp];
|
||||
|
||||
// Get the array of species name strings and the count them
|
||||
std::vector<std::string> spnames;
|
||||
getStringArray(speciesArray, spnames);
|
||||
int nsp = static_cast<int>(spnames.size());
|
||||
|
||||
// if 'all' is specified as the one and only species in the
|
||||
// spArray_names field, then add all species
|
||||
// defined in the corresponding database to the phase
|
||||
if (nsp == 1 && spnames[0] == "all") {
|
||||
std::vector<XML_Node *> allsp;
|
||||
db->getChildren("species", allsp);
|
||||
nsp = static_cast<int>(allsp.size());
|
||||
spnames.resize(nsp);
|
||||
for (int nn = 0; nn < nsp; nn++) {
|
||||
string stemp = (*allsp[nn])["name"];
|
||||
bool skip = false;
|
||||
if (declared[stemp]) {
|
||||
if (sprule[jsp] >= 10) {
|
||||
skip = true;
|
||||
} else {
|
||||
throw CanteraError("ThermoFactory::formSpeciesXMLNodeList()",
|
||||
"duplicate species: \"" + stemp + "\"");
|
||||
}
|
||||
}
|
||||
if (!skip) {
|
||||
declared[stemp] = true;
|
||||
nSpecies++;
|
||||
spNamesList.resize(nSpecies);
|
||||
spDataNodeList.resize(nSpecies, 0);
|
||||
spRuleList.resize(nSpecies, 0);
|
||||
spNamesList[nSpecies-1] = stemp;
|
||||
spDataNodeList[nSpecies-1] = allsp[nn];
|
||||
spRuleList[nSpecies-1] = sprule[jsp];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nsp == 1 && spnames[0] == "unique") {
|
||||
std::vector<XML_Node *> allsp;
|
||||
db->getChildren("species", allsp);
|
||||
nsp = static_cast<int>(allsp.size());
|
||||
spnames.resize(nsp);
|
||||
for (int nn = 0; nn < nsp; nn++) {
|
||||
string stemp = (*allsp[nn])["name"];
|
||||
bool skip = false;
|
||||
if (declared[stemp]) {
|
||||
skip = true;
|
||||
}
|
||||
if (!skip) {
|
||||
declared[stemp] = true;
|
||||
nSpecies++;
|
||||
spNamesList.resize(nSpecies);
|
||||
spDataNodeList.resize(nSpecies, 0);
|
||||
spRuleList.resize(nSpecies, 0);
|
||||
spNamesList[nSpecies-1] = stemp;
|
||||
spDataNodeList[nSpecies-1] = allsp[nn];
|
||||
spRuleList[nSpecies-1] = sprule[jsp];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < nsp; k++) {
|
||||
string stemp = spnames[k];
|
||||
skip = false;
|
||||
if (declared[stemp]) {
|
||||
if (sprule[jsp] >= 10) {
|
||||
skip = true;
|
||||
} else {
|
||||
throw CanteraError("ThermoFactory::formSpeciesXMLNodeList()",
|
||||
"duplicate species: \"" + stemp + "\"");
|
||||
}
|
||||
}
|
||||
if (!skip) {
|
||||
declared[stemp] = true;
|
||||
// Find the species in the database by name.
|
||||
XML_Node* s = db->findByAttr("name", stemp);
|
||||
if (!s) {
|
||||
throw CanteraError("importPhase","no data for species, \""
|
||||
+ stemp + "\"");
|
||||
}
|
||||
nSpecies++;
|
||||
spNamesList.resize(nSpecies);
|
||||
spDataNodeList.resize(nSpecies, 0);
|
||||
spRuleList.resize(nSpecies, 0);
|
||||
spNamesList[nSpecies-1] = stemp;
|
||||
spDataNodeList[nSpecies-1] = s;
|
||||
spRuleList[nSpecies-1] = sprule[jsp];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Import a phase specification.
|
||||
|
|
@ -262,7 +373,8 @@ namespace Cantera {
|
|||
// phase.
|
||||
if (phase.name() != "phase") {
|
||||
throw CanteraError("importPhase",
|
||||
"Current const XML_Node named, " + phase.name() + ", is not a phase element.");
|
||||
"Current const XML_Node named, " + phase.name() +
|
||||
", is not a phase element.");
|
||||
}
|
||||
|
||||
// set the id attribute of the phase to the 'id' attribute
|
||||
|
|
@ -275,7 +387,8 @@ namespace Cantera {
|
|||
int idim = intValue(phase["dim"]);
|
||||
if (idim < 1 || idim > 3)
|
||||
throw CanteraError("importPhase",
|
||||
"phase, " + th->id() + ", has unphysical number of dimensions: " + phase["dim"]);
|
||||
"phase, " + th->id() +
|
||||
", has unphysical number of dimensions: " + phase["dim"]);
|
||||
th->setNDim(idim);
|
||||
}
|
||||
else {
|
||||
|
|
@ -290,7 +403,8 @@ namespace Cantera {
|
|||
th->setParametersFromXML(eos);
|
||||
} else {
|
||||
throw CanteraError("importPhase",
|
||||
" phase, " + th->id() + ", XML_Node does not have a \"thermo\" XML_Node");
|
||||
" phase, " + th->id() +
|
||||
", XML_Node does not have a \"thermo\" XML_Node");
|
||||
}
|
||||
|
||||
VPStandardStateTP *vpss_ptr = 0;
|
||||
|
|
@ -328,7 +442,8 @@ namespace Cantera {
|
|||
if (nspa == 0) {
|
||||
throw CanteraError("importPhase",
|
||||
"phase, " + th->id() + ", has zero \"speciesArray\" XML nodes.\n"
|
||||
+ " There must be at least one speciesArray nodes with one or more species");
|
||||
+ " There must be at least one speciesArray nodes "
|
||||
"with one or more species");
|
||||
}
|
||||
vector<XML_Node*> dbases;
|
||||
vector_int sprule(nspa,0);
|
||||
|
|
@ -336,15 +451,24 @@ namespace Cantera {
|
|||
// loop over the speciesArray elements
|
||||
for (jsp = 0; jsp < nspa; jsp++) {
|
||||
|
||||
const XML_Node& species = *sparrays[jsp];
|
||||
const XML_Node& speciesArray = *sparrays[jsp];
|
||||
|
||||
// If the speciesArray element has a child element
|
||||
//
|
||||
// <skip element="undeclared">
|
||||
//
|
||||
// then set sprule[jsp] to 1, so
|
||||
// that any species with an undeclared element will be
|
||||
// quietly skipped when importing species.
|
||||
if (species.hasChild("skip")) {
|
||||
const XML_Node& sk = species.child("skip");
|
||||
// Additionally, if the skip node has the following attribute:
|
||||
//
|
||||
// <skip species="duplicate">
|
||||
//
|
||||
// then duplicate species names will not cause Cantera to
|
||||
// throw an exception. Instead, the duplicate entry will
|
||||
// be discarded.
|
||||
if (speciesArray.hasChild("skip")) {
|
||||
const XML_Node& sk = speciesArray.child("skip");
|
||||
string eskip = sk["element"];
|
||||
if (eskip == "undeclared") {
|
||||
sprule[jsp] = 1;
|
||||
|
|
@ -357,19 +481,33 @@ namespace Cantera {
|
|||
|
||||
string fname, idstr;
|
||||
|
||||
// get a pointer to the node containing the species
|
||||
// Get a pointer to the node containing the species
|
||||
// definitions for the species declared in this
|
||||
// speciesArray element. This may be in the local file
|
||||
// containing the phase element, or may be in another
|
||||
// file.
|
||||
db = get_XML_Node(species["datasrc"], &phase.root());
|
||||
db = get_XML_Node(speciesArray["datasrc"], &phase.root());
|
||||
if (db == 0) {
|
||||
throw CanteraError("importPhase",
|
||||
" Can not find XML node for species database: "
|
||||
+ speciesArray["datasrc"]);
|
||||
}
|
||||
|
||||
// add this node to the list of species database nodes.
|
||||
dbases.push_back(db);
|
||||
}
|
||||
|
||||
// Now, collect all the species names and all the XML_Node * pointers
|
||||
// for those species in a single vector. This is where we decide what
|
||||
// species are to be included in the phase.
|
||||
// The logic is complicated enough that we put it in a separate routine.
|
||||
std::vector<XML_Node *> spDataNodeList;
|
||||
std::vector<std::string> spNamesList;
|
||||
std::vector<int> spRuleList;
|
||||
formSpeciesXMLNodeList(spDataNodeList, spNamesList, spRuleList,
|
||||
sparrays, dbases, sprule);
|
||||
|
||||
// if the phase has a species thermo manager already installed,
|
||||
// If the phase has a species thermo manager already installed,
|
||||
// delete it since we are adding new species.
|
||||
delete &th->speciesThermo();
|
||||
|
||||
|
|
@ -382,88 +520,28 @@ namespace Cantera {
|
|||
// to see what thermodynamic property parameterizations are
|
||||
// used, and selects a class that can handle the
|
||||
// parameterizations found.
|
||||
spth = newSpeciesThermoMgr(dbases);
|
||||
spth = newSpeciesThermoMgr(spDataNodeList);
|
||||
|
||||
// install it in the phase object
|
||||
th->setSpeciesThermo(spth);
|
||||
// SpeciesThermo& spthermo = th->speciesThermo();
|
||||
} else {
|
||||
vp_spth = newVPSSMgr(vpss_ptr, &phase, dbases);
|
||||
vp_spth = newVPSSMgr(vpss_ptr, &phase, spDataNodeList);
|
||||
vpss_ptr->setVPSSMgr(vp_spth);
|
||||
spth = vp_spth->SpeciesThermoMgr();
|
||||
th->setSpeciesThermo(spth);
|
||||
}
|
||||
|
||||
|
||||
// used to check that each species is declared only once
|
||||
map<string,bool> declared;
|
||||
int k = 0;
|
||||
|
||||
int i, k = 0;
|
||||
|
||||
// loop over the species arrays
|
||||
for (jsp = 0; jsp < nspa; jsp++) {
|
||||
|
||||
const XML_Node& species = *sparrays[jsp];
|
||||
db = dbases[jsp];
|
||||
|
||||
// Get the array of species name strings.
|
||||
vector<string> spnames;
|
||||
getStringArray(species, spnames);
|
||||
int nsp = static_cast<int>(spnames.size());
|
||||
|
||||
// if 'all' is specified, then add all species
|
||||
// defined in this database to the phase
|
||||
if (nsp == 1 && spnames[0] == "all") {
|
||||
vector<XML_Node*> allsp;
|
||||
db->getChildren("species",allsp);
|
||||
nsp = static_cast<int>(allsp.size());
|
||||
spnames.resize(nsp);
|
||||
for (int nn = 0; nn < nsp; nn++) {
|
||||
spnames[nn] = (*allsp[nn])["name"];
|
||||
}
|
||||
}
|
||||
else if (nsp == 1 && spnames[0] == "unique") {
|
||||
vector<XML_Node*> uniquesp;
|
||||
db->getChildren("species",uniquesp);
|
||||
nsp = static_cast<int>(uniquesp.size());
|
||||
spnames.clear();
|
||||
spnames.resize(nsp);
|
||||
string spnm;
|
||||
for (int nn = 0; nn < nsp; nn++) {
|
||||
spnm = (*uniquesp[nn])["name"];
|
||||
if (!declared[spnm]) spnames[nn] = spnm;
|
||||
}
|
||||
}
|
||||
|
||||
string name;
|
||||
bool skip;
|
||||
for (i = 0; i < nsp; i++) {
|
||||
name = spnames[i];
|
||||
skip = false;
|
||||
if (name == "") skip = true;
|
||||
// Check that every species is only declared once
|
||||
if (declared[name]) {
|
||||
if (sprule[jsp] >= 10)
|
||||
skip = true;
|
||||
else
|
||||
throw CanteraError("importPhase",
|
||||
"duplicate species: \"" + name + "\"");
|
||||
}
|
||||
if (!skip) {
|
||||
declared[name] = true;
|
||||
|
||||
// Find the species in the database by name.
|
||||
XML_Node* s = db->findByAttr("name",spnames[i]);
|
||||
if (s) {
|
||||
if (installSpecies(k, *s, *th, spth, sprule[jsp],
|
||||
&phase, vp_spth, spfactory))
|
||||
++k;
|
||||
}
|
||||
else {
|
||||
throw CanteraError("importPhase","no data for species, \""
|
||||
+ name + "\"");
|
||||
}
|
||||
}
|
||||
int nsp = spDataNodeList.size();
|
||||
for (int i = 0; i < nsp; i++) {
|
||||
XML_Node *s = spDataNodeList[i];
|
||||
AssertTrace(s != 0);
|
||||
bool ok = installSpecies(k, *s, *th, spth, spRuleList[i],
|
||||
&phase, vp_spth, spfactory);
|
||||
if (ok) {
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -474,6 +552,9 @@ namespace Cantera {
|
|||
|
||||
// Perform any required subclass-specific initialization.
|
||||
th->initThermo();
|
||||
|
||||
// Perform any required subclass-specific initialization
|
||||
// that requires the XML phase object
|
||||
string id = "";
|
||||
th->initThermoXML(phase, id);
|
||||
|
||||
|
|
|
|||
|
|
@ -70,24 +70,21 @@ namespace Cantera {
|
|||
*
|
||||
* @todo Make sure that spDadta_node is species Data XML node by checking its name is speciesData
|
||||
*/
|
||||
static void getVPSSMgrTypes(XML_Node* spData_node,
|
||||
int& has_nasa, int& has_shomate, int& has_simple,
|
||||
static void getVPSSMgrTypes(std::vector<XML_Node *> & spDataNodeList,
|
||||
int &has_nasa,
|
||||
int& has_shomate,
|
||||
int& has_simple,
|
||||
int &has_water,
|
||||
int &has_tpx,
|
||||
int &has_hptx,
|
||||
int &has_other) {
|
||||
|
||||
const XML_Node& sparray = *spData_node;
|
||||
std::vector<XML_Node*> sp;
|
||||
|
||||
// get all of the species nodes
|
||||
sparray.getChildren("species",sp);
|
||||
size_t n, ns = sp.size();
|
||||
for (n = 0; n < ns; n++) {
|
||||
|
||||
size_t ns = spDataNodeList.size();
|
||||
for (size_t n = 0; n < ns; n++) {
|
||||
bool ifound = false;
|
||||
XML_Node* spNode = sp[n];
|
||||
XML_Node* spNode = spDataNodeList[n];
|
||||
if (spNode->hasChild("standardState")) {
|
||||
const XML_Node& ssN = sp[n]->child("standardState");
|
||||
const XML_Node& ssN = spNode->child("standardState");
|
||||
string mm = ssN["model"];
|
||||
if (mm == "waterIAPWS" || mm == "waterPDSS") {
|
||||
has_water++;
|
||||
|
|
@ -100,7 +97,7 @@ namespace Cantera {
|
|||
}
|
||||
if (!ifound) {
|
||||
if (spNode->hasChild("thermo")) {
|
||||
const XML_Node& th = sp[n]->child("thermo");
|
||||
const XML_Node& th = spNode->child("thermo");
|
||||
if (th.hasChild("NASA")) {
|
||||
has_nasa++;
|
||||
ifound = true;
|
||||
|
|
@ -169,25 +166,13 @@ namespace Cantera {
|
|||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
// 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::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::vector<XML_Node*> & spDataNodeList) {
|
||||
|
||||
std::string ssManager="";
|
||||
std::string vpssManager="";
|
||||
|
|
@ -216,7 +201,7 @@ namespace Cantera {
|
|||
if (ssManager != "") {
|
||||
spth = newSpeciesThermoMgr(ssManager);
|
||||
} else {
|
||||
spth = newSpeciesThermoMgr(spData_nodes);
|
||||
spth = newSpeciesThermoMgr(spDataNodeList);
|
||||
}
|
||||
vp_ptr->setSpeciesThermo(spth);
|
||||
|
||||
|
|
@ -247,18 +232,17 @@ namespace Cantera {
|
|||
}
|
||||
|
||||
|
||||
int n = static_cast<int>(spData_nodes.size());
|
||||
int inasa = 0, ishomate = 0, isimple = 0, iwater = 0, itpx = 0, iother = 0;
|
||||
int ihptx = 0;
|
||||
for (int j = 0; j < n; j++) {
|
||||
try {
|
||||
getVPSSMgrTypes(spData_nodes[j], inasa, ishomate, isimple, iwater,
|
||||
itpx, ihptx, iother);
|
||||
} catch (UnknownSpeciesThermoModel) {
|
||||
iother = 1;
|
||||
popError();
|
||||
}
|
||||
|
||||
try {
|
||||
getVPSSMgrTypes(spDataNodeList, 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);
|
||||
|
|
@ -315,25 +299,15 @@ namespace Cantera {
|
|||
return vpsssptherm;
|
||||
}
|
||||
|
||||
VPSSMgr* newVPSSMgr(VPStandardStateTP *tp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
XML_Node* spData_node,
|
||||
VPSSMgrFactory* f) {
|
||||
if (f == 0) {
|
||||
f = VPSSMgrFactory::factory();
|
||||
}
|
||||
VPSSMgr* vpsssptherm = f->newVPSSMgr(tp_ptr, phaseNode_ptr, spData_node);
|
||||
return vpsssptherm;
|
||||
}
|
||||
|
||||
VPSSMgr* newVPSSMgr(VPStandardStateTP *tp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
std::vector<XML_Node*> spData_nodes,
|
||||
std::vector<XML_Node *> & spDataNodeList,
|
||||
VPSSMgrFactory* f) {
|
||||
if (f == 0) {
|
||||
f = VPSSMgrFactory::factory();
|
||||
}
|
||||
VPSSMgr* vpsssptherm = f->newVPSSMgr(tp_ptr, phaseNode_ptr, spData_nodes);
|
||||
VPSSMgr* vpsssptherm = f->newVPSSMgr(tp_ptr, phaseNode_ptr, spDataNodeList);
|
||||
return vpsssptherm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,9 +157,9 @@ namespace Cantera {
|
|||
* Each speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
*/
|
||||
virtual VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
XML_Node* spData_node);
|
||||
// virtual VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr,
|
||||
// XML_Node* phaseNode_ptr,
|
||||
// XML_Node* spData_node);
|
||||
|
||||
//! Create a new species property manager for a group of species
|
||||
/*!
|
||||
|
|
@ -175,9 +175,8 @@ namespace Cantera {
|
|||
* e.g., \<speciesData id="Species_Data"\>
|
||||
*/
|
||||
virtual VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
std::vector<XML_Node*> spData_nodes);
|
||||
|
||||
XML_Node* phaseNode_ptr,
|
||||
std::vector<XML_Node *> & spDataNodeList);
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -223,29 +222,6 @@ namespace Cantera {
|
|||
VPSSMgr* newVPSSMgr(VPSSMgr_enumType type,
|
||||
VPStandardStateTP *vp_ptr, VPSSMgrFactory* f=0);
|
||||
|
||||
//! Function to return VPSSMgr manager
|
||||
/*!
|
||||
* This utility program will look through species nodes. It will discover what
|
||||
* each species needs for its species property managers. Then,
|
||||
* it will malloc and return the proper species property manager to use.
|
||||
*
|
||||
* These functions allow using a different factory class that
|
||||
* derives from VPSSMgrFactory.
|
||||
*
|
||||
* @param vp_ptr Variable pressure standard state ThermoPhase object
|
||||
* that will be the owner.
|
||||
* @param phaseNode_ptr Pointer to the ThermoPhase phase XML Node
|
||||
* @param spData_node Vector of XML_Nodes, each of which is a speciesData XML Node.
|
||||
* Each %speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
*/
|
||||
VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
XML_Node* spData_node,
|
||||
VPSSMgrFactory* f=0);
|
||||
|
||||
//! Function to return VPSSMgr manager
|
||||
/*!
|
||||
* This utility program will look through species nodes. It will discover what
|
||||
|
|
@ -258,15 +234,16 @@ namespace Cantera {
|
|||
* @param vp_ptr Variable pressure standard state ThermoPhase object
|
||||
* that will be the owner.
|
||||
* @param phaseNode_ptr Pointer to the ThermoPhase phase XML Node
|
||||
* @param spData_nodes Vector of XML_Nodes, each of which is a speciesData XML Node.
|
||||
* Each %speciesData node contains a list of XML species elements
|
||||
* e.g., \<speciesData id="Species_Data"\>
|
||||
*
|
||||
* @param spDataNodeList This vector contains a list
|
||||
* of species XML nodes that will be in the phase
|
||||
*
|
||||
* @param f Pointer to a SpeciesThermoFactory. optional parameter.
|
||||
* Defautls to NULL.
|
||||
*/
|
||||
VPSSMgr* newVPSSMgr(VPStandardStateTP *vp_ptr,
|
||||
XML_Node* phaseNode_ptr,
|
||||
std::vector<XML_Node*> spData_nodes,
|
||||
std::vector<XML_Node *> & spDataNodeList,
|
||||
VPSSMgrFactory* f=0);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "VPStandardStateTP.h"
|
||||
#include "PDSS_Water.h"
|
||||
#include "PDSS_HKFT.h"
|
||||
#include "GeneralSpeciesThermo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -255,9 +256,17 @@ namespace Cantera {
|
|||
throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
|
||||
"wrong SS mode: " + model);
|
||||
}
|
||||
VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
|
||||
//VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
|
||||
if (m_waterSS) delete m_waterSS;
|
||||
m_waterSS = new PDSS_Water(m_vptp_ptr, 0);
|
||||
|
||||
GeneralSpeciesThermo *genSpthermo = dynamic_cast<GeneralSpeciesThermo *>(m_spthermo);
|
||||
if (!genSpthermo) {
|
||||
throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
|
||||
"failed dynamic cast");
|
||||
}
|
||||
genSpthermo->installPDSShandler(k, m_waterSS, this);
|
||||
|
||||
kPDSS = m_waterSS;
|
||||
} else {
|
||||
std::string model = (*ss)["model"];
|
||||
|
|
@ -269,6 +278,12 @@ namespace Cantera {
|
|||
|
||||
kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
|
||||
|
||||
GeneralSpeciesThermo *genSpthermo = dynamic_cast<GeneralSpeciesThermo *>(m_spthermo);
|
||||
if (!genSpthermo) {
|
||||
throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
|
||||
"failed dynamic cast");
|
||||
}
|
||||
genSpthermo->installPDSShandler(k, kPDSS, this);
|
||||
}
|
||||
return kPDSS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue