Cantera 2.6.0
Species.cpp
1// This file is part of Cantera. See License.txt in the top-level directory or
2// at https://cantera.org/license.txt for license and copyright information.
3
11#include "cantera/base/ctml.h"
12#include "cantera/base/global.h"
13#include <iostream>
14#include <limits>
15#include <set>
16
17namespace Cantera {
18
19Species::Species()
20 : charge(0.0)
21 , size(1.0)
22{
23}
24
25Species::Species(const std::string& name_, const compositionMap& comp_,
26 double charge_, double size_)
27 : name(name_)
28 , composition(comp_)
29 , charge(charge_)
30 , size(size_)
31{
32}
33
34Species::~Species()
35{
36}
37
38AnyMap Species::parameters(const ThermoPhase* phase, bool withInput) const
39{
40 AnyMap speciesNode;
41 speciesNode["name"] = name;
42 speciesNode["composition"] = composition;
43 speciesNode["composition"].setFlowStyle();
44
45 if (charge != 0) {
46 speciesNode["charge"] = charge;
47 }
48 if (size != 1) {
49 speciesNode["size"] = size;
50 }
51 if (thermo) {
52 AnyMap thermoNode = thermo->parameters(withInput);
53 if (thermoNode.size()) {
54 speciesNode["thermo"] = std::move(thermoNode);
55 }
56 }
57 if (transport) {
58 speciesNode["transport"] = transport->parameters(withInput);
59 }
60 if (phase) {
61 phase->getSpeciesParameters(name, speciesNode);
62 }
63 if (withInput && input.hasKey("equation-of-state")) {
64 auto& eosIn = input["equation-of-state"].asVector<AnyMap>();
65 for (const auto& eos : eosIn) {
66 auto& out = speciesNode["equation-of-state"].getMapWhere(
67 "model", eos["model"].asString(), true);
68 out.update(eos);
69 }
70 }
71 if (withInput) {
72 speciesNode.update(input);
73 }
74 return speciesNode;
75}
76
77shared_ptr<Species> newSpecies(const XML_Node& species_node)
78{
79 std::string name = species_node["name"];
80 compositionMap comp = parseCompString(species_node.child("atomArray").value());
81 auto s = make_shared<Species>(name, comp);
82 if (species_node.hasChild("charge")) {
83 s->charge = getFloat(species_node, "charge");
84 }
85 if (species_node.hasChild("size")) {
86 s->size = getFloat(species_node, "size");
87 }
88 if (species_node.hasChild("thermo")) {
89 s->thermo.reset(newSpeciesThermoInterpType(species_node.child("thermo")));
90 } else {
91 s->thermo.reset(new SpeciesThermoInterpType());
92 }
93
94 // Read transport data, if provided
95 if (species_node.hasChild("transport")) {
96 s->transport = newTransportData(species_node.child("transport"));
97 s->transport->validate(*s);
98 }
99
100 // Extra data used for electrolyte species in Debye-Huckel model
101 if (species_node.hasChild("stoichIsMods")) {
102 s->input["Debye-Huckel"]["weak-acid-charge"] =
103 getFloat(species_node, "stoichIsMods");
104 }
105
106 if (species_node.hasChild("electrolyteSpeciesType")) {
107 s->input["Debye-Huckel"]["electrolyte-species-type"] =
108 species_node.child("electrolyteSpeciesType").value();
109 }
110
111 // Extra data optionally used by LatticePhase
112 const XML_Node* stdstate = species_node.findByName("standardState");
113 if (stdstate && stdstate->findByName("molarVolume")) {
114 s->input["molar_volume"] = getFloat(*stdstate, "molarVolume", "toSI");
115 }
116
117 // Extra data possibly used by IonsFromNeutralVPSSTP
118 const XML_Node* thermo = species_node.findByName("thermo");
119 if (thermo && thermo->attrib("model") == "IonFromNeutral") {
120 if (thermo->hasChild("specialSpecies")) {
121 auto& eos = s->input["equation-of-state"].getMapWhere(
122 "model", "ions-from-neutral-molecule", true);
123 eos["special-species"] = true;
124 }
125 }
126
127 return s;
128}
129
130unique_ptr<Species> newSpecies(const AnyMap& node)
131{
132 unique_ptr<Species> s(new Species(node["name"].asString(),
133 node["composition"].asMap<double>()));
134
135 if (node.hasKey("thermo")) {
136 s->thermo = newSpeciesThermo(node["thermo"].as<AnyMap>());
137 } else {
138 s->thermo.reset(new SpeciesThermoInterpType());
139 }
140
141 s->size = node.getDouble("sites", 1.0);
142 if (s->composition.find("E") != s->composition.end()) {
143 s->charge = -s->composition["E"];
144 }
145
146 if (node.hasKey("transport")) {
147 s->transport = newTransportData(node["transport"].as<AnyMap>());
148 s->transport->validate(*s);
149 }
150
151 // Store input parameters in the "input" map, unless they are stored in a
152 // child object
153 const static std::set<std::string> known_keys{
154 "thermo", "transport"
155 };
156 s->input.setUnits(node.units());
157 for (const auto& item : node) {
158 if (known_keys.count(item.first) == 0) {
159 s->input[item.first] = item.second;
160 }
161 }
162 s->input.applyUnits();
163 s->input.copyMetadata(node);
164
165 return s;
166}
167
168std::vector<shared_ptr<Species> > getSpecies(const XML_Node& node)
169{
170 std::vector<shared_ptr<Species> > all_species;
171 for (const auto& spnode : node.child("speciesData").getChildren("species")) {
172 all_species.push_back(newSpecies(*spnode));
173 }
174 return all_species;
175}
176
177std::vector<shared_ptr<Species>> getSpecies(const AnyValue& items)
178{
179 std::vector<shared_ptr<Species> > all_species;
180 for (const auto& node : items.asVector<AnyMap>()) {
181 all_species.emplace_back(newSpecies(node));
182 }
183 return all_species;
184}
185
186}
Header for factory functions to build instances of classes that manage the standard-state thermodynam...
Pure Virtual Base class for individual species reference state thermodynamic managers and text for th...
Declaration for class Cantera::Species.
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:399
const UnitSystem & units() const
Return the default units that should be used to convert stored values.
Definition: AnyMap.h:598
double getDouble(const std::string &key, double default_) const
If key exists, return it as a double, otherwise return default_.
Definition: AnyMap.cpp:1492
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1406
void update(const AnyMap &other, bool keepExisting=true)
Add items from other to this AnyMap.
Definition: AnyMap.cpp:1421
A wrapper for a variable whose type is determined at runtime.
Definition: AnyMap.h:84
const std::vector< T > & asVector(size_t nMin=npos, size_t nMax=npos) const
Return the held value, if it is a vector of type T.
Definition: AnyMap.inl.h:72
Abstract Base class for the thermodynamic manager for an individual species' reference state.
Contains data about a single chemical species.
Definition: Species.h:26
compositionMap composition
The elemental composition of the species.
Definition: Species.h:46
std::string name
The name of the species.
Definition: Species.h:42
double charge
The electrical charge on the species, in units of the elementary charge.
Definition: Species.h:49
double size
The effective size of the species.
Definition: Species.h:53
shared_ptr< SpeciesThermoInterpType > thermo
Thermodynamic data for the species.
Definition: Species.h:58
AnyMap input
Input parameters used to define a species, for example from a YAML input file.
Definition: Species.h:61
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:493
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:529
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.
Definition: xml.cpp:680
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...
Definition: xml.cpp:712
std::string value() const
Return the value of an XML node as a string.
Definition: xml.cpp:442
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:547
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
This file contains definitions for utility functions and text for modules, inputfiles,...
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type="")
Get a floating-point value from a child element.
Definition: ctml.cpp:166
unique_ptr< SpeciesThermoInterpType > newSpeciesThermo(const AnyMap &thermo_node)
Create a new SpeciesThermoInterpType object using the specified parameters.
shared_ptr< Species > newSpecies(const XML_Node &species_node)
Create a new Species object from a 'species' XML_Node.
Definition: Species.cpp:77
std::vector< shared_ptr< Species > > getSpecies(const XML_Node &node)
Generate Species objects for all <species> nodes in an XML document.
Definition: Species.cpp:168
std::map< std::string, double > compositionMap
Map connecting a string name with a double.
Definition: ct_defs.h:176
shared_ptr< TransportData > newTransportData(const XML_Node &transport_node)
Create a new TransportData object from a 'transport' XML_Node.
compositionMap parseCompString(const std::string &ss, const std::vector< std::string > &names=std::vector< std::string >())
Parse a composition string into a map consisting of individual key:composition pairs.
Definition: stringUtils.cpp:59
SpeciesThermoInterpType * newSpeciesThermoInterpType(int type, double tlow, double thigh, double pref, const double *coeffs)
Create a new SpeciesThermoInterpType object given a corresponding constant.
Contains declarations for string manipulation functions within Cantera.