Cantera  2.5.1
Mu0Poly.cpp
Go to the documentation of this file.
1 /**
2  * @file Mu0Poly.cpp
3  * Definitions for a single-species standard state object derived
4  * from \link Cantera::SpeciesThermoInterpType SpeciesThermoInterpType\endlink based
5  * on a piecewise constant mu0 interpolation
6  * (see \ref spthermo and class \link Cantera::Mu0Poly Mu0Poly\endlink).
7  */
8 
9 // This file is part of Cantera. See License.txt in the top-level directory or
10 // at https://cantera.org/license.txt for license and copyright information.
11 
12 #include "cantera/thermo/Mu0Poly.h"
13 #include "cantera/base/ctml.h"
15 
16 using namespace std;
17 
18 namespace Cantera
19 {
20 Mu0Poly::Mu0Poly()
21  : SpeciesThermoInterpType(0.0, std::numeric_limits<double>::infinity(), 0.0)
22  , m_numIntervals(0)
23  , m_H298(0.0)
24 {
25 }
26 
27 Mu0Poly::Mu0Poly(double tlow, double thigh, double pref, const double* coeffs) :
28  SpeciesThermoInterpType(tlow, thigh, pref),
29  m_numIntervals(0),
30  m_H298(0.0)
31 {
32  std::map<double, double> T_mu;
33  size_t nPoints = (size_t) coeffs[0];
34  for (size_t i = 0; i < nPoints; i++) {
35  T_mu[coeffs[2*i+2]] = coeffs[2*i+3];
36  }
37  setParameters(coeffs[1], T_mu);
38 }
39 
40 void Mu0Poly::setParameters(double h0, const std::map<double, double>& T_mu)
41 {
42  size_t nPoints = T_mu.size();
43  if (nPoints < 2) {
44  throw CanteraError("Mu0Poly::setParameters", "nPoints must be >= 2");
45  }
46  m_numIntervals = nPoints - 1;
47  m_H298 = h0 / GasConstant;
48 
49  // Distribute the data into the internal arrays, and find the index of the
50  // point at 298.15 K.
51  size_t iT298 = npos;
52  for (const auto& row : T_mu) {
53  double T1 = row.first;
54  if (T1 == 298.15) {
55  iT298 = m_t0_int.size();
56  }
57  m_t0_int.push_back(T1);
58  m_mu0_R_int.push_back(row.second / GasConstant);
59  }
60  if (iT298 == npos) {
61  throw CanteraError("Mu0Poly::setParameters",
62  "One temperature has to be 298.15");
63  }
64 
65  // Resize according to the number of points
66  m_h0_R_int.resize(nPoints);
67  m_s0_R_int.resize(nPoints);
68  m_cp0_R_int.resize(nPoints);
69 
70  // Starting from the interval with T298, we go up
71  m_h0_R_int[iT298] = m_H298;
72  m_s0_R_int[iT298] = - (m_mu0_R_int[iT298] - m_h0_R_int[iT298]) / m_t0_int[iT298];
73  for (size_t i = iT298; i < m_numIntervals; i++) {
74  double T1 = m_t0_int[i];
75  double s1 = m_s0_R_int[i];
76  double T2 = m_t0_int[i+1];
77  double deltaMu = m_mu0_R_int[i+1] - m_mu0_R_int[i];
78  double deltaT = T2 - T1;
79  double cpi = (deltaMu - T1 * s1 + T2 * s1) / (deltaT - T2 * log(T2/T1));
80  m_cp0_R_int[i] = cpi;
81  m_h0_R_int[i+1] = m_h0_R_int[i] + cpi * deltaT;
82  m_s0_R_int[i+1] = s1 + cpi * log(T2/T1);
83  m_cp0_R_int[i+1] = cpi;
84  }
85 
86  // Starting from the interval with T298, we go down
87  if (iT298 != 0) {
88  m_h0_R_int[iT298] = m_H298;
89  m_s0_R_int[iT298] = - (m_mu0_R_int[iT298] - m_h0_R_int[iT298]) / m_t0_int[iT298];
90  for (size_t i = iT298 - 1; i != npos; i--) {
91  double T1 = m_t0_int[i];
92  double T2 = m_t0_int[i+1];
93  double s2 = m_s0_R_int[i+1];
94  double deltaMu = m_mu0_R_int[i+1] - m_mu0_R_int[i];
95  double deltaT = T2 - T1;
96  double cpi = (deltaMu - T1 * s2 + T2 * s2) / (deltaT - T1 * log(T2/T1));
97  m_cp0_R_int[i] = cpi;
98  m_h0_R_int[i] = m_h0_R_int[i+1] - cpi * deltaT;
99  m_s0_R_int[i] = s2 - cpi * log(T2/T1);
100  if (i == (m_numIntervals-1)) {
101  m_cp0_R_int[i+1] = cpi;
102  }
103  }
104  }
105 }
106 
107 void Mu0Poly::updateProperties(const doublereal* tt, doublereal* cp_R,
108  doublereal* h_RT, doublereal* s_R) const
109 {
110  size_t j = m_numIntervals;
111  double T = *tt;
112  for (size_t i = 0; i < m_numIntervals; i++) {
113  double T2 = m_t0_int[i+1];
114  if (T <=T2) {
115  j = i;
116  break;
117  }
118  }
119  double T1 = m_t0_int[j];
120  double cp_Rj = m_cp0_R_int[j];
121  *cp_R = cp_Rj;
122  *h_RT = (m_h0_R_int[j] + (T - T1) * cp_Rj)/T;
123  *s_R = m_s0_R_int[j] + cp_Rj * (log(T/T1));
124 }
125 
126 void Mu0Poly::updatePropertiesTemp(const doublereal T,
127  doublereal* cp_R,
128  doublereal* h_RT,
129  doublereal* s_R) const
130 {
131  updateProperties(&T, cp_R, h_RT, s_R);
132 }
133 
134 size_t Mu0Poly::nCoeffs() const
135 {
136  return 2*m_numIntervals + 4;
137 }
138 
139 void Mu0Poly::reportParameters(size_t& n, int& type,
140  doublereal& tlow, doublereal& thigh,
141  doublereal& pref,
142  doublereal* const coeffs) const
143 {
144  n = 0;
145  type = MU0_INTERP;
146  tlow = m_lowT;
147  thigh = m_highT;
148  pref = m_Pref;
149  coeffs[0] = int(m_numIntervals)+1;
150  coeffs[1] = m_H298 * GasConstant;
151  int j = 2;
152  for (size_t i = 0; i < m_numIntervals+1; i++) {
153  coeffs[j] = m_t0_int[i];
154  coeffs[j+1] = m_mu0_R_int[i] * GasConstant;
155  j += 2;
156  }
157 }
158 
160 {
161  bool dimensionlessMu0Values = false;
162 
163  doublereal h298 = 0.0;
164  if (Mu0Node.hasChild("H298")) {
165  h298 = getFloat(Mu0Node, "H298", "actEnergy");
166  }
167 
168  size_t numPoints = 1;
169  if (Mu0Node.hasChild("numPoints")) {
170  numPoints = getInteger(Mu0Node, "numPoints");
171  }
172 
173  vector_fp cValues(numPoints);
174  const XML_Node* valNode_ptr = getByTitle(Mu0Node, "Mu0Values");
175  if (!valNode_ptr) {
176  throw CanteraError("newMu0ThermoFromXML", "missing Mu0Values");
177  }
178  getFloatArray(*valNode_ptr, cValues, true, "actEnergy");
179 
180  // Check to see whether the Mu0's were input in a dimensionless form. If
181  // they were, then the assumed temperature needs to be adjusted from the
182  // assumed T = 273.15
183  if (valNode_ptr->attrib("units") == "Dimensionless") {
184  dimensionlessMu0Values = true;
185  }
186  if (cValues.size() != numPoints) {
187  throw CanteraError("newMu0ThermoFromXML", "numPoints inconsistent");
188  }
189 
190  vector_fp cTemperatures(numPoints);
191  const XML_Node* tempNode_ptr = getByTitle(Mu0Node, "Mu0Temperatures");
192  if (!tempNode_ptr) {
193  throw CanteraError("newMu0ThermoFromXML", "missing Mu0Temperatures");
194  }
195  getFloatArray(*tempNode_ptr, cTemperatures, false);
196  if (cTemperatures.size() != numPoints) {
197  throw CanteraError("newMu0ThermoFromXML", "numPoints inconsistent");
198  }
199 
200  // Fix up dimensionless Mu0 values if input
201  if (dimensionlessMu0Values) {
202  for (size_t i = 0; i < numPoints; i++) {
203  cValues[i] *= cTemperatures[i] / 273.15;
204  }
205  }
206 
207  vector_fp c(2 + 2 * numPoints);
208  c[0] = static_cast<double>(numPoints);
209  c[1] = h298;
210  for (size_t i = 0; i < numPoints; i++) {
211  c[2+i*2] = cTemperatures[i];
212  c[2+i*2+1] = cValues[i];
213  }
214 
215  return new Mu0Poly(fpValue(Mu0Node["Tmin"]), fpValue(Mu0Node["Tmax"]),
216  fpValue(Mu0Node["Pref"]), &c[0]);
217 }
218 
219 }
Header for a single-species standard state object derived from SpeciesThermoInterpType based on a pie...
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
The Mu0Poly class implements an interpolation of the Gibbs free energy based on a piecewise constant ...
Definition: Mu0Poly.h:74
doublereal m_H298
Value of the enthalpy at T = 298.15.
Definition: Mu0Poly.h:145
vector_fp m_mu0_R_int
Mu0's are primary input data.
Definition: Mu0Poly.h:152
vector_fp m_cp0_R_int
Heat capacity at the points.
Definition: Mu0Poly.h:161
void setParameters(double h0, const std::map< double, double > &T_mu)
Set parameters for .
Definition: Mu0Poly.cpp:40
virtual void updatePropertiesTemp(const doublereal temp, doublereal *cp_R, doublereal *h_RT, doublereal *s_R) const
Compute the reference-state property of one species.
Definition: Mu0Poly.cpp:126
virtual size_t nCoeffs() const
This utility function returns the number of coefficients for a given type of species parameterization...
Definition: Mu0Poly.cpp:134
virtual void reportParameters(size_t &n, int &type, doublereal &tlow, doublereal &thigh, doublereal &pref, doublereal *const coeffs) const
This utility function returns the type of parameterization and all of the parameters for the species.
Definition: Mu0Poly.cpp:139
vector_fp m_s0_R_int
Entropy at the points.
Definition: Mu0Poly.h:158
size_t m_numIntervals
Number of intervals in the interpolating linear approximation.
Definition: Mu0Poly.h:141
virtual void updateProperties(const doublereal *tt, doublereal *cp_R, doublereal *h_RT, doublereal *s_R) const
Update the properties for this species, given a temperature polynomial.
Definition: Mu0Poly.cpp:107
vector_fp m_t0_int
Points at which the standard state chemical potential are given.
Definition: Mu0Poly.h:148
vector_fp m_h0_R_int
Dimensionless Enthalpies at the temperature points.
Definition: Mu0Poly.h:155
Abstract Base class for the thermodynamic manager for an individual species' reference state.
doublereal m_lowT
lowest valid temperature
doublereal m_highT
Highest valid temperature.
doublereal m_Pref
Reference state pressure.
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
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
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
Mu0Poly * newMu0ThermoFromXML(const XML_Node &Mu0Node)
Install a Mu0 polynomial thermodynamic reference state.
Definition: Mu0Poly.cpp:159
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
XML_Node * getByTitle(const XML_Node &node, const std::string &title)
Search the child nodes of the current node for an XML Node with a Title attribute of a given name.
Definition: ctml.cpp:122
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
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
int getInteger(const XML_Node &parent, const std::string &name)
Get an integer value from a child element.
Definition: ctml.cpp:234
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
#define MU0_INTERP
piecewise interpolation of mu0.
Contains declarations for string manipulation functions within Cantera.