59 addAlias(
"ideal-surface",
"Surface");
66 addAlias(
"fixed-stoichiometry",
"StoichSubstance");
70 addAlias(
"compound-lattice",
"LatticeSolid");
73 reg(
"HMW-electrolyte", []() {
return new HMWSoln(); });
75 addAlias(
"HMW-electrolyte",
"HMWSoln");
77 addAlias(
"ideal-condensed",
"IdealSolidSolution");
78 addAlias(
"ideal-condensed",
"IdealSolidSoln");
80 addAlias(
"Debye-Huckel",
"DebyeHuckel");
82 addAlias(
"ideal-molal-solution",
"IdealMolalSolution");
83 addAlias(
"ideal-molal-solution",
"IdealMolalSoln");
86 addAlias(
"ideal-solution-VPSS",
"IdealSolnVPSS");
87 addAlias(
"ideal-solution-VPSS",
"IdealSolnGas");
88 addAlias(
"ideal-gas-VPSS",
"IdealGasVPSS");
91 addAlias(
"ions-from-neutral-molecule",
"IonsFromNeutralMolecule");
92 addAlias(
"ions-from-neutral-molecule",
"IonsFromNeutral");
94 addAlias(
"Redlich-Kister",
"RedlichKister");
96 addAlias(
"Redlich-Kwong",
"RedlichKwongMFTP");
97 addAlias(
"Redlich-Kwong",
"RedlichKwong");
99 addAlias(
"Maskell-solid-solution",
"MaskellSolidSolnPhase");
100 addAlias(
"Maskell-solid-solution",
"MaskellSolidsoln");
101 reg(
"liquid-water-IAPWS95", []() {
return new WaterSSTP(); });
102 addAlias(
"liquid-water-IAPWS95",
"PureLiquidWater");
103 addAlias(
"liquid-water-IAPWS95",
"Water");
105 addAlias(
"binary-solution-tabulated",
"BinarySolutionTabulatedThermo");
116 string model = xmlphase.
child(
"thermo")[
"model"];
124 if (!phaseNode.
hasKey(
"kinetics") && phaseNode.
hasKey(
"reactions")) {
126 "Phase entry includes a 'reactions' field but does not "
127 "specify a kinetics model.");
129 unique_ptr<ThermoPhase> t(
newThermoPhase(phaseNode[
"thermo"].asString()));
136 size_t dot = infile.find_last_of(
".");
145 if (extension ==
"yml" || extension ==
"yaml") {
147 AnyMap& phase = root[
"phases"].getMapWhere(
"name",
id);
148 return newPhase(phase, root).release();
154 "Couldn't find phase named \"" +
id +
"\" in file, " + infile);
176 std::vector<std::string> &spNamesList,
178 const std::vector<XML_Node*> spArray_names,
179 const std::vector<XML_Node*> spArray_dbases,
183 std::map<std::string, bool> declared;
185 for (
size_t jsp = 0; jsp < spArray_dbases.size(); jsp++) {
186 const XML_Node& speciesArray = *spArray_names[jsp];
189 const XML_Node* db = spArray_dbases[jsp];
192 std::vector<std::string> spnames;
194 size_t nsp = spnames.size();
199 if (nsp == 1 && spnames[0] ==
"all") {
200 std::vector<XML_Node*> allsp = db->
getChildren(
"species");
203 for (
size_t nn = 0; nn < nsp; nn++) {
204 string stemp = (*allsp[nn])[
"name"];
205 if (!declared[stemp] || sprule[jsp] < 10) {
206 declared[stemp] =
true;
207 spNamesList.push_back(stemp);
208 spDataNodeList.push_back(allsp[nn]);
209 spRuleList.push_back(sprule[jsp]);
212 }
else if (nsp == 1 && spnames[0] ==
"unique") {
213 std::vector<XML_Node*> allsp = db->
getChildren(
"species");
216 for (
size_t nn = 0; nn < nsp; nn++) {
217 string stemp = (*allsp[nn])[
"name"];
218 if (!declared[stemp]) {
219 declared[stemp] =
true;
220 spNamesList.push_back(stemp);
221 spDataNodeList.push_back(allsp[nn]);
222 spRuleList.push_back(sprule[jsp]);
226 std::map<std::string, XML_Node*> speciesNodes;
227 for (
size_t k = 0; k < db->
nChildren(); k++) {
229 speciesNodes[child[
"name"]] = &child;
231 for (
size_t k = 0; k < nsp; k++) {
232 string stemp = spnames[k];
233 if (!declared[stemp] || sprule[jsp] < 10) {
234 declared[stemp] =
true;
236 auto iter = speciesNodes.find(stemp);
237 if (iter == speciesNodes.end()) {
239 "no data for species, \"{}\"", stemp);
241 spNamesList.push_back(stemp);
242 spDataNodeList.push_back(iter->second);
243 spRuleList.push_back(sprule[jsp]);
253 if (phase.
name() !=
"phase") {
255 "Current const XML_Node named, " + phase.
name() +
256 ", is not a phase element.");
271 if (idim < 1 || idim > 3) {
273 "phase, " + th->
name() +
274 ", has unphysical number of dimensions: " + phase[
"dim"]);
289 " phase, " + th->
name() +
290 ", XML_Node does not have a \"thermo\" XML_Node");
299 "phase, " + th->
name() +
", was VPSS, but dynamic cast failed");
312 vector<XML_Node*> sparrays = phase.
getChildren(
"speciesArray");
315 "phase, " + th->
name() +
", has zero \"speciesArray\" XML nodes.\n"
316 +
" There must be at least one speciesArray nodes "
317 "with one or more species");
319 vector<XML_Node*> dbases;
327 for (
size_t jsp = 0; jsp < sparrays.size(); jsp++) {
328 const XML_Node& speciesArray = *sparrays[jsp];
342 if (speciesArray.
hasChild(
"skip")) {
344 string eskip = sk[
"element"];
345 if (eskip ==
"undeclared") {
348 string dskip = sk[
"species"];
349 if (dskip ==
"duplicate") {
360 "Can not find XML node for species database: {}",
361 speciesArray[
"datasrc"]);
365 dbases.push_back(db);
372 std::vector<XML_Node*> spDataNodeList;
373 std::vector<std::string> spNamesList;
376 sparrays, dbases, sprule);
378 size_t nsp = spDataNodeList.size();
380 throw CanteraError(
"importPhase",
"For Slave standard states, "
381 "number of species must be zero: {}", nsp);
383 for (
size_t k = 0; k < nsp; k++) {
392 std::string ss_model = (ss) ? ss->
attrib(
"model") :
"ideal-gas";
393 unique_ptr<PDSS> kPDSS(newPDSS(ss_model));
394 kPDSS->setParametersFromXML(*s);
410void addDefaultElements(ThermoPhase& thermo,
const vector<string>& element_names) {
411 for (
const auto& symbol : element_names) {
412 thermo.addElement(symbol);
416void addElements(ThermoPhase& thermo,
const vector<string>& element_names,
417 const AnyValue& elements,
bool allow_default)
419 const auto& local_elements = elements.asMap(
"symbol");
420 for (
const auto& symbol : element_names) {
421 if (local_elements.count(symbol)) {
422 auto& element = *local_elements.at(symbol);
423 double weight = element[
"atomic-weight"].asDouble();
424 long int number = element.getInt(
"atomic-number", 0);
426 thermo.addElement(symbol, weight, number, e298);
427 }
else if (allow_default) {
428 thermo.addElement(symbol);
430 throw InputFileError(
"addElements", elements,
431 "Element '{}' not found", symbol);
436void addSpecies(ThermoPhase& thermo,
const AnyValue& names,
const AnyValue& species)
438 if (names.is<vector<string>>()) {
440 const auto& species_nodes = species.asMap(
"name");
441 for (
const auto& name : names.asVector<
string>()) {
442 if (species_nodes.count(name)) {
443 thermo.addSpecies(
newSpecies(*species_nodes.at(name)));
445 throw InputFileError(
"addSpecies", names, species,
446 "Could not find a species named '{}'.", name);
449 }
else if (names ==
"all") {
451 for (
const auto& item : species.asVector<AnyMap>()) {
455 throw InputFileError(
"addSpecies", names,
456 "Could not parse species declaration of type '{}'", names.type_str());
462 thermo.
setName(phaseNode[
"name"].asString());
464 if (phaseNode.
hasKey(
"deprecated")) {
465 string msg = phaseNode[
"deprecated"].asString();
466 string filename = phaseNode.
getString(
"__file__",
467 rootNode.
getString(
"__file__",
"unknown file"));
468 string method = fmt::format(
"{}/{}", filename, phaseNode[
"name"].asString());
473 if (phaseNode.
hasKey(
"elements")) {
474 if (phaseNode.
getBool(
"skip-undeclared-elements",
false)) {
480 if (phaseNode[
"elements"].is<vector<string>>()) {
482 if (rootNode.
hasKey(
"elements")) {
483 addElements(thermo, phaseNode[
"elements"].asVector<string>(),
484 rootNode[
"elements"],
true);
486 addDefaultElements(thermo, phaseNode[
"elements"].asVector<string>());
488 }
else if (phaseNode[
"elements"].is<vector<AnyMap>>()) {
492 for (
const auto& elemNode : phaseNode[
"elements"].asVector<AnyMap>()) {
493 const string& source = elemNode.begin()->first;
494 const auto& names = elemNode.begin()->second.asVector<
string>();
495 const auto& slash = boost::ifind_last(source,
"/");
497 std::string fileName(source.begin(), slash.begin());
498 std::string node(slash.end(), source.end());
501 addElements(thermo, names, elements.
at(node),
false);
502 }
else if (rootNode.
hasKey(source)) {
503 addElements(thermo, names, rootNode.
at(source),
false);
504 }
else if (source ==
"default") {
505 addDefaultElements(thermo, names);
508 "Could not find elements section named '{}'", source);
513 "Could not parse elements declaration of type '{}'",
514 phaseNode[
"elements"].type_str());
523 if (phaseNode.
hasKey(
"species")) {
524 if (phaseNode[
"species"].is<vector<string>>()) {
527 addSpecies(thermo, phaseNode[
"species"], rootNode[
"species"]);
528 }
else if (phaseNode[
"species"].is<string>()) {
531 addSpecies(thermo, phaseNode[
"species"], rootNode[
"species"]);
532 }
else if (phaseNode[
"species"].is<vector<AnyMap>>()) {
536 for (
const auto& speciesNode : phaseNode[
"species"].asVector<AnyMap>()) {
537 const string& source = speciesNode.begin()->first;
538 const auto& names = speciesNode.begin()->second;
539 const auto& slash = boost::ifind_last(source,
"/");
542 std::string fileName(source.begin(), slash.begin());
543 std::string node(slash.end(), source.end());
546 addSpecies(thermo, names, species[node]);
547 }
else if (rootNode.
hasKey(source)) {
549 addSpecies(thermo, names, rootNode[source]);
552 "Could not find species section named '{}'", source);
557 "Could not parse species declaration of type '{}'",
558 phaseNode[
"species"].type_str());
560 }
else if (rootNode.
hasKey(
"species")) {
562 addSpecies(thermo,
AnyValue(
"all"), rootNode[
"species"]);
567 for (
size_t k = 0; k < thermo.
nSpecies(); k++) {
568 unique_ptr<PDSS> pdss;
569 if (thermo.
species(k)->input.hasKey(
"equation-of-state")) {
571 auto& eos = thermo.
species(k)->input[
"equation-of-state"];
573 for (
auto& node : eos.asVector<
AnyMap>()) {
574 string model = node[
"model"].asString();
575 if (PDSSFactory::factory()->exists(model)) {
576 pdss.reset(newPDSS(model));
577 pdss->setParameters(node);
584 "Could not find an equation-of-state specification "
585 "which defines a known PDSS model.");
588 pdss.reset(newPDSS(
"ideal-gas"));
590 vpssThermo->installPDSS(k, std::move(pdss));
597 if (phaseNode.
hasKey(
"state")) {
598 auto node = phaseNode[
"state"].as<
AnyMap>();
608 if (!phaseNode.
hasChild(
"elementArray")) {
610 "phase XML node doesn't have \"elementArray\" XML Node");
613 vector<string> enames;
617 string element_database =
"elements.xml";
619 element_database = elements[
"datasrc"];
628 local_db = &root.
child(
"elementData");
631 for (
size_t i = 0; i < enames.size(); i++) {
641 throw CanteraError(
"installElements",
"no data for element '{}'",
646 doublereal weight = 0.0;
654 string symbol = e->
attrib(
"name");
662 th.
addElement(symbol, weight, anum, entropy298);
669 if (!phaseSpeciesData) {
672 string jname = phaseSpeciesData->
name();
673 if (jname !=
"speciesData") {
675 "Unexpected phaseSpeciesData name: " + jname);
677 vector<XML_Node*> xspecies = phaseSpeciesData->
getChildren(
"species");
678 for (
size_t j = 0; j < xspecies.size(); j++) {
681 if (jname == kname) {
Header file for an binary solution model with tabulated standard state thermodynamic data (see Thermo...
Headers for the DebyeHuckel ThermoPhase object, which models dilute electrolyte solutions (see Thermo...
Declarations for the EdgePhase ThermoPhase object, which models the interface between two surfaces (s...
#define ENTROPY298_UNKNOWN
Number indicating we don't know the entropy of the element in its most stable state at 298....
Headers for the HMWSoln ThermoPhase object, which models concentrated electrolyte solutions (see Ther...
ThermoPhase object for the ideal gas equation of state - workhorse for Cantera (see Thermodynamic Pro...
ThermoPhase object for the ideal molal equation of state (see Thermodynamic Properties and class Idea...
Header file for an ideal solid solution model with incompressible thermodynamics (see Thermodynamic P...
Definition file for a derived class of ThermoPhase that assumes an ideal solution approximation and h...
Header for intermediate ThermoPhase object for phases which consist of ions whose thermodynamics is c...
Header for a simple thermodynamics model of a bulk phase derived from ThermoPhase,...
Header for a simple thermodynamics model of a bulk solid phase derived from ThermoPhase,...
(see Thermodynamic Properties and class MargulesVPSSTP).
Header file for a solid solution model following Maskell, Shaw, and Tye.
Header for a general species thermodynamic property manager for a phase (see MultiSpeciesThermo).
Header file for class PlasmaPhase.
Header for a ThermoPhase class for a pure fluid phase consisting of gas, liquid, mixed-gas-liquid and...
(see Thermodynamic Properties and class RedlichKisterVPSSTP).
Header for factory functions to build instances of classes that manage the standard-state thermodynam...
Declaration for class Cantera::Species.
Header file for the StoichSubstance class, which represents a fixed-composition incompressible substa...
Header for a simple thermodynamics model of a surface phase derived from ThermoPhase,...
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
A map of string keys to values whose type can vary at runtime.
const AnyValue & at(const std::string &key) const
Get the value of the item stored in key.
const std::string & getString(const std::string &key, const std::string &default_) const
If key exists, return it as a string, otherwise return default_.
bool getBool(const std::string &key, bool default_) const
If key exists, return it as a bool, otherwise return default_.
static AnyMap fromYamlFile(const std::string &name, const std::string &parent_name="")
Create an AnyMap from a YAML file.
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
A wrapper for a variable whose type is determined at runtime.
Overloads the virtual methods of class IdealSolidSolnPhase to implement tabulated standard state ther...
Base class for exceptions thrown by Cantera classes.
Class DebyeHuckel represents a dilute liquid electrolyte phase which obeys the Debye Huckel formulati...
A thermodynamic phase representing a one dimensional edge between two surfaces.
ThermoPhase * create(const std::string &name, Args... args)
Create an object using the object construction function corresponding to "name" and the provided cons...
void addAlias(const std::string &original, const std::string &alias)
Add an alias for an existing registered type.
void reg(const std::string &name, std::function< ThermoPhase *(Args...)> f)
Register a new object construction function.
Class HMWSoln represents a dilute or concentrated liquid electrolyte phase which obeys the Pitzer for...
Class IdealGasPhase represents low-density gases that obey the ideal gas equation of state.
This phase is based upon the mixing-rule assumption that all molality-based activity coefficients are...
Class IdealSolidSolnPhase represents a condensed phase ideal solution compound.
An ideal solution approximation of a phase.
A simple thermodynamic model for a bulk phase, assuming a lattice of solid atoms.
A phase that is comprised of a fixed additive combination of other lattice phases.
MargulesVPSSTP is a derived class of GibbsExcessVPSSTP that employs the Margules approximation for th...
Class MaskellSolidSolnPhase represents a condensed phase non-ideal solution with 2 species following ...
Implementation of a multi-species Peng-Robinson equation of state.
Class Phase is the base class for phases of matter, managing the species and elements in a phase,...
void setName(const std::string &nm)
Sets the string name for the phase.
size_t addElement(const std::string &symbol, doublereal weight=-12345.0, int atomicNumber=0, doublereal entropy298=ENTROPY298_UNKNOWN, int elem_type=CT_ELEM_TYPE_ABSPOS)
Add an element.
std::string name() const
Return the name of the phase.
size_t nSpecies() const
Returns the number of species in the phase.
void ignoreUndefinedElements()
Set behavior when adding a species containing undefined elements to just skip the species.
void addUndefinedElements()
Set behavior when adding a species containing undefined elements to add those elements to the phase.
void setNDim(size_t ndim)
Set the number of spatial dimensions (1, 2, or 3).
void setXMLdata(XML_Node &xmlPhase)
Stores the XML tree information for the current phase.
void throwUndefinedElements()
Set the behavior when adding a species containing undefined elements to throw an exception.
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
Base class for a phase with plasma properties.
This phase object consists of a single component that can be a gas, a liquid, a mixed gas-liquid flui...
RedlichKisterVPSSTP is a derived class of GibbsExcessVPSSTP that employs the Redlich-Kister approxima...
Implementation of a multi-species Redlich-Kwong equation of state.
Class StoichSubstance represents a stoichiometric (fixed composition) incompressible substance.
A simple thermodynamic model for a surface phase, assuming an ideal solution model.
ThermoFactory()
Private constructors prevents usage.
static std::mutex thermo_mutex
Decl for locking mutex for thermo factory singleton.
virtual ThermoPhase * newThermoPhase(const std::string &model)
Create a new thermodynamic property manager.
static ThermoFactory * s_factory
static member of a single instance
Base class for a phase with thermodynamic properties.
virtual bool addSpecies(shared_ptr< Species > spec)
virtual void setState_TP(doublereal t, doublereal p)
Set the temperature (K) and pressure (Pa)
virtual void setState(const AnyMap &state)
Set the state using an AnyMap containing any combination of properties supported by the thermodynamic...
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
void saveSpeciesData(const size_t k, const XML_Node *const data)
Store a reference pointer to the XML tree containing the species data for this phase.
virtual int standardStateConvention() const
This method returns the convention used in specification of the standard state, of which there are cu...
virtual void setParameters(int n, doublereal *const c)
Set the equation of state parameters.
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
This is a filter class for ThermoPhase that implements some preparatory steps for efficiently handlin...
void installPDSS(size_t k, std::unique_ptr< PDSS > &&pdss)
Install a PDSS object for species k
Class XML_Node is a tree-based representation of the contents of an XML file.
XML_Node * findByAttr(const std::string &attr, const std::string &val, int depth=100000) const
This routine carries out a recursive search for an XML node based on an attribute of each XML node.
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
std::string name() const
Returns the name of the XML node.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
std::string id() const
Return the id attribute, if present.
XML_Node & root() const
Return the root of the current XML_Node tree.
const XML_Node * findByName(const std::string &nm, int depth=100000) const
This routine carries out a recursive search for an XML node based on the name of the node.
std::vector< XML_Node * > getChildren(const std::string &name) const
Get a vector of pointers to XML_Node containing all of the children of the current node which match t...
size_t nChildren(bool discardComments=false) const
Return the number of children.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
#define AssertTrace(expr)
Assertion must be true or an error is thrown.
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
int intValue(const std::string &val)
Translate a string into one integer value.
void getStringArray(const XML_Node &node, std::vector< std::string > &v)
This function interprets the value portion of an XML element as a string.
XML_Node * get_XML_File(const std::string &file, int debug=0)
Return a pointer to the XML tree for a Cantera input file.
doublereal dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
const int cSS_CONVENTION_VPSS
Standard state uses the molality convention.
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
void setupPhase(ThermoPhase &phase, const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap())
Initialize a ThermoPhase object.
const double OneAtm
One atmosphere [Pa].
ThermoPhase * newThermoPhase(const std::string &model)
Create a new thermodynamic property manager.
shared_ptr< Species > newSpecies(const XML_Node &species_node)
Create a new Species object from a 'species' XML_Node.
XML_Node * get_XML_Node(const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
void warn_deprecated(const std::string &source, const AnyBase &node, const std::string &message)
A deprecation warning for syntax in an input file.
std::string toLowerCopy(const std::string &input)
Convert to lower case.
const XML_Node * speciesXML_Node(const std::string &kname, const XML_Node *phaseSpeciesData)
Search an XML tree for species data.
std::vector< int > vector_int
Vector of ints.
static void formSpeciesXMLNodeList(std::vector< XML_Node * > &spDataNodeList, std::vector< std::string > &spNamesList, vector_int &spRuleList, const std::vector< XML_Node * > spArray_names, const std::vector< XML_Node * > spArray_dbases, const vector_int sprule)
Gather a vector of pointers to XML_Nodes for a phase.
void installElements(Phase &th, const XML_Node &phaseNode)
Add the elements given in an XML_Node tree to the specified phase.
const int cSS_CONVENTION_SLAVE
Standard state thermodynamics is obtained from slave ThermoPhase objects.
doublereal fpValueCheck(const std::string &val)
Translate a string into one doublereal value, with error checking.
XML_Node * get_XML_NameID(const std::string &nameTarget, const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
Contains const definitions for types of species reference-state thermodynamics managers (see Species ...
Contains declarations for string manipulation functions within Cantera.