Cantera  3.1.0a1
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 
12 #include "cantera/base/global.h"
13 #include <iostream>
14 #include <limits>
15 
16 using namespace std;
17 
18 namespace Cantera {
19 
20 Species::Species(const string& name_, const Composition& comp_,
21  double charge_, double size_)
22  : name(name_)
23  , composition(comp_)
24  , charge(charge_)
25  , size(size_)
26 {
27 }
28 
30  if (m_molecularWeight == Undef) {
31  double weight = 0.0;
32  const auto& elements = elementWeights();
33  for (const auto& [eName, stoich] : composition) {
34  auto search = elements.find(eName);
35  if (search != elements.end()) {
36  if (search->second < 0) {
37  throw CanteraError("setMolecularWeight",
38  "element '{}' has no stable isotopes", eName);
39  }
40  weight += search->second * stoich;
41  }
42  }
43  setMolecularWeight(weight);
44  }
45  return m_molecularWeight;
46 }
47 
48 void Species::setMolecularWeight(double weight) {
49  if (m_molecularWeight != Undef) {
50  double maxWeight = max(weight, m_molecularWeight);
51  double weight_cmp = fabs(weight - m_molecularWeight) / maxWeight;
52  if (weight_cmp > 1.0e-9) {
53  warn_user(
54  "Species::setMolecularWeight",
55  "Molecular weight of species '{}' is changing from {} to {}.",
56  this->name,
58  weight
59  );
60  }
61  }
62 
63  m_molecularWeight = weight;
64 }
65 
66 AnyMap Species::parameters(const ThermoPhase* phase, bool withInput) const
67 {
68  AnyMap speciesNode;
69  speciesNode["name"] = name;
70  speciesNode["composition"] = composition;
71  speciesNode["composition"].setFlowStyle();
72 
73  if (charge != 0) {
74  speciesNode["charge"] = charge;
75  }
76  if (size != 1) {
77  speciesNode["size"] = size;
78  }
79  if (thermo) {
80  AnyMap thermoNode = thermo->parameters(withInput);
81  if (thermoNode.size()) {
82  speciesNode["thermo"] = std::move(thermoNode);
83  }
84  }
85  if (transport) {
86  speciesNode["transport"] = transport->parameters(withInput);
87  }
88  if (phase) {
89  phase->getSpeciesParameters(name, speciesNode);
90  }
91  if (withInput && input.hasKey("equation-of-state")) {
92  auto& eosIn = input["equation-of-state"].asVector<AnyMap>();
93  for (const auto& eos : eosIn) {
94  auto& out = speciesNode["equation-of-state"].getMapWhere(
95  "model", eos["model"].asString(), true);
96  out.update(eos);
97  }
98  }
99  if (withInput) {
100  speciesNode.update(input);
101  }
102  return speciesNode;
103 }
104 
105 unique_ptr<Species> newSpecies(const AnyMap& node)
106 {
107  auto s = make_unique<Species>(node["name"].asString(),
108  node["composition"].asMap<double>());
109 
110  if (node.hasKey("thermo")) {
111  s->thermo = newSpeciesThermo(node["thermo"].as<AnyMap>());
112  } else {
113  s->thermo = make_shared<SpeciesThermoInterpType>();
114  }
115 
116  s->size = node.getDouble("sites", 1.0);
117  if (s->composition.find("E") != s->composition.end()) {
118  s->charge = -s->composition["E"];
119  }
120 
121  if (node.hasKey("transport")) {
122  s->transport = newTransportData(node["transport"].as<AnyMap>());
123  s->transport->validate(*s);
124  }
125 
126  // Store input parameters in the "input" map, unless they are stored in a
127  // child object
128  const static set<string> known_keys{
129  "thermo", "transport"
130  };
131  s->input.setUnits(node.units());
132  for (const auto& [key, child] : node) {
133  if (known_keys.count(key) == 0) {
134  s->input[key] = child;
135  }
136  }
137  s->input.applyUnits();
138  s->input.copyMetadata(node);
139 
140  return s;
141 }
142 
143 vector<shared_ptr<Species>> getSpecies(const AnyValue& items)
144 {
145  vector<shared_ptr<Species>> all_species;
146  for (const auto& node : items.asVector<AnyMap>()) {
147  all_species.emplace_back(newSpecies(node));
148  }
149  return all_species;
150 }
151 
152 }
Contains the getElementWeight function and the definitions of element constraint types.
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:427
double getDouble(const string &key, double default_) const
If key exists, return it as a double, otherwise return default_.
Definition: AnyMap.cpp:1520
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1423
void setFlowStyle(bool flow=true)
Use "flow" style when outputting this AnyMap to YAML.
Definition: AnyMap.cpp:1726
const UnitSystem & units() const
Return the default units that should be used to convert stored values.
Definition: AnyMap.h:630
void update(const AnyMap &other, bool keepExisting=true)
Add items from other to this AnyMap.
Definition: AnyMap.cpp:1438
A wrapper for a variable whose type is determined at runtime.
Definition: AnyMap.h:86
const 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:109
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:66
double m_molecularWeight
The molecular weight of the species, in atomic mass units.
Definition: Species.h:89
Composition composition
The elemental composition of the species.
Definition: Species.h:45
string name
The name of the species.
Definition: Species.h:41
void setMolecularWeight(double weight)
Set the molecular weight of the species.
Definition: Species.cpp:48
double molecularWeight()
The molecular weight [amu] of the species.
Definition: Species.cpp:29
double charge
The electrical charge on the species, in units of the elementary charge.
Definition: Species.h:48
double size
The effective size of the species.
Definition: Species.h:52
shared_ptr< SpeciesThermoInterpType > thermo
Thermodynamic data for the species.
Definition: Species.h:80
AnyMap input
Input parameters used to define a species, for example from a YAML input file.
Definition: Species.h:83
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:390
virtual void getSpeciesParameters(const string &name, AnyMap &speciesNode) const
Get phase-specific parameters of a Species object such that an identical one could be reconstructed a...
Definition: ThermoPhase.h:1831
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition: global.h:267
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
const double Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
Definition: ct_defs.h:164
vector< shared_ptr< Species > > getSpecies(const AnyValue &items)
Generate Species objects for each item (an AnyMap) in items.
Definition: Species.cpp:143
unique_ptr< SpeciesThermoInterpType > newSpeciesThermo(const AnyMap &node)
Create a new SpeciesThermoInterpType object using the specified parameters.
unique_ptr< Species > newSpecies(const AnyMap &node)
Create a new Species object from an AnyMap specification.
Definition: Species.cpp:105
const map< string, double > & elementWeights()
Get a map with the element and isotope symbols and names as keys and weights as values.
Definition: Elements.cpp:246
unique_ptr< TransportData > newTransportData(const AnyMap &node)
Create a new TransportData object from an AnyMap specification.
map< string, double > Composition
Map from string names to doubles.
Definition: ct_defs.h:177
Contains declarations for string manipulation functions within Cantera.