[Thermo] Extract 'newSpecies(XML_Node&) from thermo initialization
VPStandardStateTP phases now use the same pathway for adding species as other phase in importPhase. Deprecate the now-unused 'installSpecies' function.
This commit is contained in:
parent
d27b9ef9b1
commit
2ca603838d
7 changed files with 67 additions and 76 deletions
|
|
@ -11,6 +11,7 @@ namespace Cantera
|
|||
|
||||
class SpeciesThermoInterpType;
|
||||
class TransportData;
|
||||
class XML_Node;
|
||||
|
||||
//! Contains data about a single chemical species
|
||||
/*!
|
||||
|
|
@ -49,6 +50,9 @@ public:
|
|||
shared_ptr<SpeciesThermoInterpType> thermo;
|
||||
};
|
||||
|
||||
//! Create a new Species object from a 'species' XML_Node.
|
||||
shared_ptr<Species> newSpecies(const XML_Node& species_node);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -274,8 +274,8 @@ void installElements(Phase& th, const XML_Node& phaseNode);
|
|||
* state thermo properties
|
||||
* @param factory Pointer to the SpeciesThermoFactory .
|
||||
* (defaults to 0)
|
||||
* @deprecated The 'factory' argument is unused and will be removed after
|
||||
* Cantera 2.2.
|
||||
* @deprecated Use newSpecies and addSpecies. For VPStandardStateTP phases, call
|
||||
* createInstallPDSS as well. To be removed after Cantera 2.2.
|
||||
* @return
|
||||
* Returns true if everything is ok, false otherwise.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -491,6 +491,8 @@ public:
|
|||
*/
|
||||
virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
|
||||
|
||||
using Phase::addSpecies;
|
||||
virtual bool addSpecies(shared_ptr<Species> spec);
|
||||
|
||||
//! set the VPSS Mgr
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
#include "cantera/thermo/Species.h"
|
||||
|
||||
#include "cantera/thermo/SpeciesThermoInterpType.h"
|
||||
#include "cantera/thermo/SpeciesThermoFactory.h"
|
||||
#include "cantera/transport/TransportData.h"
|
||||
#include "cantera/base/stringUtils.h"
|
||||
#include "cantera/base/ctexceptions.h"
|
||||
#include "cantera/base/ctml.h"
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
using namespace ctml;
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
Species::Species()
|
||||
|
|
@ -55,4 +60,26 @@ Species& Species::operator=(const Species& other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
shared_ptr<Species> newSpecies(const XML_Node& species_node)
|
||||
{
|
||||
std::string name = species_node["name"];
|
||||
compositionMap comp = parseCompString(species_node.child("atomArray").value());
|
||||
shared_ptr<Species> s(new Species(name, comp));
|
||||
if (species_node.hasChild("charge")) {
|
||||
s->charge = getFloat(species_node, "charge");
|
||||
}
|
||||
if (species_node.hasChild("size")) {
|
||||
s->size = getFloat(species_node, "size");
|
||||
}
|
||||
s->thermo.reset(newSpeciesThermoInterpType(species_node.child("thermo")));
|
||||
|
||||
// Read transport data, if provided
|
||||
if (species_node.hasChild("transport")) {
|
||||
s->transport = newTransportData(species_node.child("transport"));
|
||||
s->transport->validate(*s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -625,7 +625,8 @@ SpeciesThermoInterpType* newSpeciesThermoInterpType(const XML_Node& thermo)
|
|||
"Too many regions in thermo parameterization.");
|
||||
}
|
||||
|
||||
if (thermo["model"] == "MineralEQ3") {
|
||||
std::string model = lowercase(thermo["model"]);
|
||||
if (model == "mineraleq3") {
|
||||
if (thermoType != "mineq3") {
|
||||
throw CanteraError("SpeciesThermoFactory::installThermoForSpecies",
|
||||
"confused: expected MinEQ3");
|
||||
|
|
@ -645,6 +646,11 @@ SpeciesThermoInterpType* newSpeciesThermoInterpType(const XML_Node& thermo)
|
|||
return newAdsorbateThermoFromXML(*tp[0]);
|
||||
} else if (thermoType == "statmech") {
|
||||
return newStatMechThermoFromXML(*tp[0]);
|
||||
} else if (model == "hkft" || model == "ionfromneutral") {
|
||||
// Some PDSS species use the 'thermo' node, but don't specify a
|
||||
// SpeciesThermoInterpType parameterization. This function needs to just
|
||||
// ignore this data.
|
||||
return 0;
|
||||
} else {
|
||||
throw CanteraError("newSpeciesThermoInterpType",
|
||||
"Unknown species thermo model '" + thermoType + "'.");
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "cantera/thermo/ThermoFactory.h"
|
||||
|
||||
#include "cantera/thermo/Species.h"
|
||||
#include "cantera/thermo/speciesThermoTypes.h"
|
||||
#include "cantera/thermo/SpeciesThermoFactory.h"
|
||||
#include "cantera/thermo/GeneralSpeciesThermo.h"
|
||||
|
|
@ -52,8 +53,6 @@
|
|||
#include "cantera/thermo/MixedSolventElectrolyte.h"
|
||||
#include "cantera/thermo/IdealSolnGasVPSS.h"
|
||||
|
||||
#include "cantera/transport/TransportData.h"
|
||||
|
||||
#include "cantera/base/stringUtils.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -454,17 +453,12 @@ bool importPhase(XML_Node& phase, ThermoPhase* th,
|
|||
sparrays, dbases, sprule);
|
||||
|
||||
// Decide whether the the phase has a variable pressure ss or not
|
||||
SpeciesThermo* spth = &th->speciesThermo();
|
||||
VPSSMgr* vp_spth = 0;
|
||||
if (ssConvention == cSS_CONVENTION_VPSS) {
|
||||
vp_spth = newVPSSMgr(vpss_ptr, &phase, spDataNodeList);
|
||||
VPSSMgr* vp_spth = newVPSSMgr(vpss_ptr, &phase, spDataNodeList);
|
||||
vpss_ptr->setVPSSMgr(vp_spth);
|
||||
spth = vp_spth->SpeciesThermoMgr();
|
||||
th->setSpeciesThermo(spth);
|
||||
th->setSpeciesThermo(vp_spth->SpeciesThermoMgr());
|
||||
}
|
||||
|
||||
size_t k = 0;
|
||||
|
||||
size_t nsp = spDataNodeList.size();
|
||||
if (ssConvention == cSS_CONVENTION_SLAVE) {
|
||||
if (nsp > 0) {
|
||||
|
|
@ -472,15 +466,17 @@ bool importPhase(XML_Node& phase, ThermoPhase* th,
|
|||
+ int2str(nsp));
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < nsp; i++) {
|
||||
XML_Node* s = spDataNodeList[i];
|
||||
for (size_t k = 0; k < nsp; k++) {
|
||||
XML_Node* s = spDataNodeList[k];
|
||||
AssertTrace(s != 0);
|
||||
bool ok = installSpecies(k, *s, *th, spth, spRuleList[i],
|
||||
&phase, vp_spth, spfactory);
|
||||
if (ok) {
|
||||
th->saveSpeciesData(k, s);
|
||||
++k;
|
||||
if (spRuleList[k]) {
|
||||
th->ignoreUndefinedElements();
|
||||
}
|
||||
th->addSpecies(newSpecies(*s));
|
||||
if (vpss_ptr) {
|
||||
vpss_ptr->createInstallPDSS(k, *s, &phase);
|
||||
}
|
||||
th->saveSpeciesData(k, s);
|
||||
}
|
||||
|
||||
if (ssConvention == cSS_CONVENTION_SLAVE) {
|
||||
|
|
@ -572,65 +568,14 @@ bool installSpecies(size_t k, const XML_Node& s, thermo_t& th,
|
|||
VPSSMgr* vpss_ptr,
|
||||
SpeciesThermoFactory* factory)
|
||||
{
|
||||
std::string xname = s.name();
|
||||
if (xname != "species") {
|
||||
throw CanteraError("installSpecies",
|
||||
"Unexpected XML name of species XML_Node: " + xname);
|
||||
}
|
||||
|
||||
if (rule) {
|
||||
th.ignoreUndefinedElements();
|
||||
}
|
||||
|
||||
// get the composition of the species
|
||||
const XML_Node& a = s.child("atomArray");
|
||||
map<string,string> comp;
|
||||
getMap(a, comp);
|
||||
|
||||
// construct a vector of atom numbers for each element in phase th. Elements
|
||||
// not declared in the species (i.e., not in map comp) will have zero
|
||||
// entries in the vector.
|
||||
size_t nel = th.nElements();
|
||||
vector_fp ecomp(nel, 0.0);
|
||||
compositionMap comp_map = parseCompString(a.value());
|
||||
for (size_t m = 0; m < nel; m++) {
|
||||
std::string& es = comp[th.elementName(m)];
|
||||
if (!es.empty()) {
|
||||
ecomp[m] = fpValueCheck(es);
|
||||
}
|
||||
}
|
||||
|
||||
// get the species charge, if any. Note that the charge need
|
||||
// not be explicitly specified if special element 'E'
|
||||
// (electron) is one of the elements.
|
||||
doublereal chrg = 0.0;
|
||||
if (s.hasChild("charge")) {
|
||||
chrg = getFloat(s, "charge");
|
||||
}
|
||||
|
||||
// get the species size, if any. (This is used by surface
|
||||
// phases to represent how many sites a species occupies.)
|
||||
doublereal sz = 1.0;
|
||||
if (s.hasChild("size")) {
|
||||
sz = getFloat(s, "size");
|
||||
}
|
||||
|
||||
if (vpss_ptr) {
|
||||
th.addUniqueSpecies(s["name"], &ecomp[0], chrg, sz);
|
||||
VPStandardStateTP* vp_ptr = dynamic_cast<VPStandardStateTP*>(&th);
|
||||
warn_deprecated("installSpecies", "Use newSpecies and addSpecies. For"
|
||||
" VPStandardStateTP phases, call createInstallPDSS as well."
|
||||
" To be removed after Cantera 2.2.");
|
||||
th.addSpecies(newSpecies(s));
|
||||
VPStandardStateTP* vp_ptr = dynamic_cast<VPStandardStateTP*>(&th);
|
||||
if (vp_ptr) {
|
||||
vp_ptr->createInstallPDSS(k, s, phaseNode_ptr);
|
||||
} else {
|
||||
shared_ptr<Species> sp(new Species(s["name"], comp_map, chrg, sz));
|
||||
sp->thermo.reset(newSpeciesThermoInterpType(s.child("thermo")));
|
||||
|
||||
// Read gas-phase transport data, if provided
|
||||
if (s.hasChild("transport")) {
|
||||
sp->transport = newTransportData(s.child("transport"));
|
||||
sp->transport->validate(*sp);
|
||||
}
|
||||
th.addSpecies(sp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,13 @@ void VPStandardStateTP::setVPSSMgr(VPSSMgr* vp_ptr)
|
|||
m_VPSS_ptr = vp_ptr;
|
||||
}
|
||||
|
||||
bool VPStandardStateTP::addSpecies(shared_ptr<Species> spec)
|
||||
{
|
||||
// Specifically skip ThermoPhase::addSpecies since the Species object
|
||||
// doesn't have an associated SpeciesThermoInterpType object
|
||||
return Phase::addSpecies(spec);
|
||||
}
|
||||
|
||||
void VPStandardStateTP::setTemperature(const doublereal temp)
|
||||
{
|
||||
setState_TP(temp, m_Pcurrent);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue