Cantera  2.5.1
BinarySolutionTabulatedThermo.cpp
Go to the documentation of this file.
1 /**
2  * @file BinarySolutionTabulatedThermo.cpp Implementation file for an binary
3  * solution model with tabulated standard state thermodynamic data (see
4  * \ref thermoprops and class
5  * \link Cantera::BinarySolutionTabulatedThermo BinarySolutionTabulatedThermo\endlink).
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at https://cantera.org/license.txt for license and copyright information.
10 
12 #include "cantera/thermo/PDSS.h"
15 #include "cantera/base/ctml.h"
18 
19 namespace Cantera
20 {
21 
23  : m_kk_tab(npos)
24  , m_xlast(-1)
25 {
26 }
27 
29  const std::string& id_)
30  : m_kk_tab(npos)
31  , m_xlast(-1)
32 
33 {
34  initThermoFile(inputFile, id_);
35 }
36 
38  const std::string& id_)
39  : m_kk_tab(npos)
40  , m_xlast(-1)
41 {
42  importPhase(root, this);
43 }
44 
46 {
48  _updateThermo();
49 }
50 
52 {
53  double xnow = moleFraction(m_kk_tab);
54  bool x_changed = (m_xlast != xnow);
55 
56  if (x_changed) {
57  std::tie(m_h0_tab, m_s0_tab) = interpolate(xnow);
58  if (xnow == 0) {
60  } else if (xnow == 1) {
62  } else {
63  m_s0_tab += GasConstant*std::log(xnow/(1.0-xnow)) +
66  }
67  m_xlast = xnow;
68  }
69 
70  double tnow = temperature();
71  if (x_changed || m_tlast != tnow) {
72  // Update the thermodynamic functions of the reference state.
73  m_spthermo.update(tnow, m_cp0_R.data(), m_h0_RT.data(), m_s0_R.data());
74  double rrt = 1.0 / RT();
75  m_h0_RT[m_kk_tab] += m_h0_tab * rrt;
77  for (size_t k = 0; k < m_kk; k++) {
78  double deltaE = rrt * m_pe[k];
79  m_h0_RT[k] += deltaE;
80  m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
81  }
82  m_tlast = tnow;
83  }
84 }
85 
87 {
88  if (m_input.hasKey("tabulated-thermo")) {
89  m_kk_tab = speciesIndex(m_input["tabulated-species"].asString());
90  if (m_kk_tab == npos) {
91  throw InputFileError("BinarySolutionTabulatedThermo::initThermo",
92  m_input["tabulated-species"],
93  "Species '{}' is not in phase '{}'",
94  m_input["tabulated-species"].asString(), name());
95  }
96  const AnyMap& table = m_input["tabulated-thermo"].as<AnyMap>();
97  vector_fp x = table["mole-fractions"].asVector<double>();
98  size_t N = x.size();
99  vector_fp h = table.convertVector("enthalpy", "J/kmol", N);
100  vector_fp s = table.convertVector("entropy", "J/kmol/K", N);
101 
102  // Sort the x, h, s data in the order of increasing x
103  std::vector<std::pair<double,double>> x_h(N), x_s(N);
104  for(size_t i = 0; i < N; i++){
105  x_h[i] = {x[i], h[i]};
106  x_s[i] = {x[i], s[i]};
107  }
108  std::sort(x_h.begin(), x_h.end());
109  std::sort(x_s.begin(), x_s.end());
110 
111  // Store the sorted values in different arrays
112  m_molefrac_tab.resize(N);
113  m_enthalpy_tab.resize(N);
114  m_entropy_tab.resize(N);
115  for (size_t i = 0; i < N; i++) {
116  m_molefrac_tab[i] = x_h[i].first;
117  m_enthalpy_tab[i] = x_h[i].second;
118  m_entropy_tab[i] = x_s[i].second;
119  }
120  }
122 }
123 
124 void BinarySolutionTabulatedThermo::initThermoXML(XML_Node& phaseNode, const std::string& id_)
125 {
126  vector_fp x, h, s;
127  std::vector<std::pair<double,double>> x_h_temp, x_s_temp;
128 
129  if (id_.size() > 0) {
130  if (phaseNode.id() != id_) {
131  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
132  "phasenode and Id are incompatible");
133  }
134  }
135  if (nSpecies()!=2) {
136  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
137  "No. of species should be equal to 2!");
138  }
139  if (phaseNode.hasChild("thermo")) {
140  XML_Node& thermoNode = phaseNode.child("thermo");
141  std::string mString = thermoNode["model"];
142  if (!caseInsensitiveEquals(mString, "binarysolutiontabulatedthermo")) {
143  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
144  "Unknown thermo model: " + mString);
145  }
146  if (thermoNode.hasChild("tabulatedSpecies")) {
147  XML_Node& speciesNode = thermoNode.child("tabulatedSpecies");
148  std::string tabulated_species_name = speciesNode["name"];
149  m_kk_tab = speciesIndex(tabulated_species_name);
150  if (m_kk_tab == npos) {
151  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
152  "Species " + tabulated_species_name + " not found.");
153  }
154  }
155  if (thermoNode.hasChild("tabulatedThermo")) {
156  XML_Node& dataNode = thermoNode.child("tabulatedThermo");
157  getFloatArray(dataNode, x, true, "", "moleFraction");
158  getFloatArray(dataNode, h, true, "J/kmol", "enthalpy");
159  getFloatArray(dataNode, s, true, "J/kmol/K", "entropy");
160 
161  // Check for data length consistency
162  if ((x.size() != h.size()) || (x.size() != s.size()) || (h.size() != s.size())) {
163  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
164  "Species tabulated thermo data has different lengths.");
165  }
166  // Sort the x, h, s data in the order of increasing x
167  for(size_t i = 0; i < x.size(); i++){
168  x_h_temp.push_back(std::make_pair(x[i],h[i]));
169  x_s_temp.push_back(std::make_pair(x[i],s[i]));
170  }
171  std::sort(x_h_temp.begin(), x_h_temp.end());
172  std::sort(x_s_temp.begin(), x_s_temp.end());
173 
174  // Store the sorted values in different arrays
175  m_molefrac_tab.resize(x_h_temp.size());
176  m_enthalpy_tab.resize(x_h_temp.size());
177  m_entropy_tab.resize(x_h_temp.size());
178  for (size_t i = 0; i < x_h_temp.size(); i++) {
179  m_molefrac_tab[i] = x_h_temp[i].first;
180  m_enthalpy_tab[i] = x_h_temp[i].second;
181  m_entropy_tab[i] = x_s_temp[i].second;
182  }
183  } else {
184  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
185  "Unspecified tabulated species or thermo");
186  }
187  } else {
188  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
189  "Unspecified thermo model");
190  }
191 
192  /*
193  * Form of the standard concentrations. Must have one of:
194  *
195  * <standardConc model="unity" />
196  * <standardConc model="molar_volume" />
197  * <standardConc model="solvent_volume" />
198  */
199  if (phaseNode.hasChild("standardConc")) {
200  XML_Node& scNode = phaseNode.child("standardConc");
201  setStandardConcentrationModel(scNode.attrib("model"));
202  } else {
203  throw CanteraError("BinarySolutionTabulatedThermo::initThermoXML",
204  "Unspecified standardConc model");
205  }
206 
207  // Call the base initThermo, which handles setting the initial state
208  ThermoPhase::initThermoXML(phaseNode, id_);
209 }
210 
211 std::pair<double, double> BinarySolutionTabulatedThermo::interpolate(double x) const
212 {
213  std::pair<double, double> c;
214  // Check if x is out of bound
215  if (x > m_molefrac_tab.back()) {
216  c.first = m_enthalpy_tab.back();
217  c.second = m_entropy_tab.back();
218  return c;
219  }
220  if (x < m_molefrac_tab[0]) {
221  c.first = m_enthalpy_tab[0];
222  c.second = m_entropy_tab[0];
223  return c;
224  }
225  size_t i = std::distance(m_molefrac_tab.begin(),
226  std::lower_bound(m_molefrac_tab.begin(), m_molefrac_tab.end(), x));
227  c.first = m_enthalpy_tab[i-1] + (m_enthalpy_tab[i] - m_enthalpy_tab[i-1])
228  * (x - m_molefrac_tab[i-1])/(m_molefrac_tab[i]- m_molefrac_tab[i-1]);
229  c.second = m_entropy_tab[i-1] + (m_entropy_tab[i] - m_entropy_tab[i-1])
230  * (x - m_molefrac_tab[i-1])/(m_molefrac_tab[i]- m_molefrac_tab[i-1]);
231  return c;
232 }
233 
234 }
Header file for an binary solution model with tabulated standard state thermodynamic data (see Thermo...
Header for a general species thermodynamic property manager for a phase (see MultiSpeciesThermo).
Declarations for the virtual base class PDSS (pressure dependent standard state) which handles calcul...
Header for factory functions to build instances of classes that manage the standard-state thermodynam...
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.
Definition: AnyMap.h:360
size_t size() const
Returns the number of elements in this map.
Definition: AnyMap.h:484
vector_fp convertVector(const std::string &key, const std::string &units, size_t nMin=npos, size_t nMax=npos) const
Convert a vector of dimensional values.
Definition: AnyMap.cpp:1075
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:984
double m_xlast
Current tabulated species mole fraction.
BinarySolutionTabulatedThermo()
Default constructor for BinarySolutionTabulatedThermo.
double m_s0_tab
Tabulated contribution to s0[m_kk_tab] at the current composition.
vector_fp m_molefrac_tab
Vector for storing tabulated thermo.
size_t m_kk_tab
Current tabulated species index.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
std::pair< double, double > interpolate(double x) const
Species thermodynamics interpolation functions.
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id_)
Import and initialize a ThermoPhase object using an XML tree.
double m_h0_tab
Tabulated contribution to h0[m_kk_tab] at the current composition.
virtual void compositionChanged()
If the compositions have changed, update the tabulated thermo lookup.
virtual void _updateThermo() const
This function gets called for every call to functions in this class.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
vector_fp m_g0_RT
Vector containing the species reference Gibbs functions at T = m_tlast.
vector_fp m_cp0_R
Vector containing the species reference constant pressure heat capacities at T = m_tlast.
vector_fp m_h0_RT
Vector containing the species reference enthalpies at T = m_tlast.
vector_fp m_s0_R
Vector containing the species reference entropies at T = m_tlast.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
virtual doublereal standardConcentration(size_t k) const
The standard concentration used to normalize the generalized concentration.
vector_fp m_pe
Vector of potential energies for the species.
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
void setStandardConcentrationModel(const std::string &model)
Set the form for the standard and generalized concentrations.
Error thrown for problems processing information contained in an AnyMap or AnyValue.
Definition: AnyMap.h:539
virtual void update(doublereal T, doublereal *cp_R, doublereal *h_RT, doublereal *s_R) const
Compute the reference-state properties for all species.
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:84
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:285
size_t m_kk
Number of species in the phase.
Definition: Phase.h:942
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:577
doublereal temperature() const
Temperature (K).
Definition: Phase.h:667
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:201
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:776
doublereal m_tlast
last value of the temperature processed by reference state
Definition: ThermoPhase.h:1904
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
MultiSpeciesThermo m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
Definition: ThermoPhase.h:1870
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1874
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
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:538
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
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:188
const double Faraday
Faraday constant [C/kmol].
Definition: ct_defs.h:123
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:180
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:109
const double BigNumber
largest number to compare to inf.
Definition: ct_defs.h:151
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert, const std::string &unitsString, const std::string &nodeName)
This function reads the current node or a child node of the current node with the default name,...
Definition: ctml.cpp:256
Contains declarations for string manipulation functions within Cantera.