Cantera  2.5.1
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 
10 #include "cantera/base/ctml.h"
11 #include <iostream>
12 #include <limits>
13 #include <set>
14 
15 namespace Cantera {
16 
17 Species::Species()
18  : charge(0.0)
19  , size(1.0)
20 {
21 }
22 
23 Species::Species(const std::string& name_, const compositionMap& comp_,
24  double charge_, double size_)
25  : name(name_)
26  , composition(comp_)
27  , charge(charge_)
28  , size(size_)
29 {
30 }
31 
32 Species::~Species()
33 {
34 }
35 
36 shared_ptr<Species> newSpecies(const XML_Node& species_node)
37 {
38  std::string name = species_node["name"];
39  compositionMap comp = parseCompString(species_node.child("atomArray").value());
40  auto s = make_shared<Species>(name, comp);
41  if (species_node.hasChild("charge")) {
42  s->charge = getFloat(species_node, "charge");
43  }
44  if (species_node.hasChild("size")) {
45  s->size = getFloat(species_node, "size");
46  }
47  if (species_node.hasChild("thermo")) {
48  s->thermo.reset(newSpeciesThermoInterpType(species_node.child("thermo")));
49  } else {
50  s->thermo.reset(new SpeciesThermoInterpType());
51  }
52 
53  // Read transport data, if provided
54  if (species_node.hasChild("transport")) {
55  s->transport = newTransportData(species_node.child("transport"));
56  s->transport->validate(*s);
57  }
58 
59  // Extra data used for electrolyte species in Debye-Huckel model
60  if (species_node.hasChild("stoichIsMods")) {
61  s->input["Debye-Huckel"]["weak-acid-charge"] =
62  getFloat(species_node, "stoichIsMods");
63  }
64 
65  if (species_node.hasChild("electrolyteSpeciesType")) {
66  s->input["Debye-Huckel"]["electrolyte-species-type"] =
67  species_node.child("electrolyteSpeciesType").value();
68  }
69 
70  // Extra data optionally used by LatticePhase
71  const XML_Node* stdstate = species_node.findByName("standardState");
72  if (stdstate && stdstate->findByName("molarVolume")) {
73  s->extra["molar_volume"] = getFloat(*stdstate, "molarVolume", "toSI");
74  }
75 
76  // Extra data possibly used by IonsFromNeutralVPSSTP
77  const XML_Node* thermo = species_node.findByName("thermo");
78  if (thermo && thermo->attrib("model") == "IonFromNeutral") {
79  if (thermo->hasChild("specialSpecies")) {
80  auto& eos = s->input["equation-of-state"].getMapWhere(
81  "model", "ions-from-neutral-molecule", true);
82  eos["special-species"] = true;
83  }
84  }
85 
86  return s;
87 }
88 
89 unique_ptr<Species> newSpecies(const AnyMap& node)
90 {
91  unique_ptr<Species> s(new Species(node["name"].asString(),
92  node["composition"].asMap<double>()));
93 
94  if (node.hasKey("thermo")) {
95  s->thermo = newSpeciesThermo(node["thermo"].as<AnyMap>());
96  } else {
97  s->thermo.reset(new SpeciesThermoInterpType());
98  }
99 
100  s->size = node.getDouble("sites", 1.0);
101  if (s->composition.find("E") != s->composition.end()) {
102  s->charge = -s->composition["E"];
103  }
104 
105  if (node.hasKey("transport")) {
106  s->transport = newTransportData(node["transport"].as<AnyMap>());
107  s->transport->validate(*s);
108  }
109 
110  // Store input parameters in the "input" map, unless they are stored in a
111  // child object
112  const static std::set<std::string> known_keys{
113  "transport"
114  };
115  s->input.applyUnits(node.units());
116  for (const auto& item : node) {
117  if (known_keys.count(item.first) == 0) {
118  s->input[item.first] = item.second;
119  }
120  }
121 
122  return s;
123 }
124 
125 std::vector<shared_ptr<Species> > getSpecies(const XML_Node& node)
126 {
127  std::vector<shared_ptr<Species> > all_species;
128  for (const auto& spnode : node.child("speciesData").getChildren("species")) {
129  all_species.push_back(newSpecies(*spnode));
130  }
131  return all_species;
132 }
133 
134 std::vector<shared_ptr<Species>> getSpecies(const AnyValue& items)
135 {
136  std::vector<shared_ptr<Species> > all_species;
137  for (const auto& node : items.asVector<AnyMap>()) {
138  all_species.emplace_back(newSpecies(node));
139  }
140  return all_species;
141 }
142 
143 }
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.
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:360
double getDouble(const std::string &key, double default_) const
If key exists, return it as a double, otherwise return default_.
Definition: AnyMap.cpp:1039
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:984
const UnitSystem & units() const
Return the default units that should be used to convert stored values.
Definition: AnyMap.h:492
A wrapper for a variable whose type is determined at runtime.
Definition: AnyMap.h:77
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:73
Abstract Base class for the thermodynamic manager for an individual species' reference state.
Contains data about a single chemical species.
Definition: Species.h:25
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:104
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:492
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:528
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:679
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:711
std::string value() const
Return the value of an XML node as a string.
Definition: xml.cpp:441
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:546
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.
std::map< std::string, double > compositionMap
Map connecting a string name with a double.
Definition: ct_defs.h:172
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
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:164
unique_ptr< SpeciesThermoInterpType > newSpeciesThermo(const AnyMap &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:36
std::vector< shared_ptr< Species > > getSpecies(const XML_Node &node)
Generate Species objects for all <species> nodes in an XML document.
Definition: Species.cpp:125
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)
Parse a composition string into a map consisting of individual key:composition pairs.
Definition: stringUtils.cpp:60
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.