Cantera  2.3.0
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 http://www.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() : m_numIntervals(0),
21  m_H298(0.0)
22 {
23  warn_deprecated("Mu0Poly::Mu0Poly()",
24  "Default constructor to be removed after Cantera 2.3.");
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  processCoeffs(coeffs);
33 }
34 
36 {
37  return new Mu0Poly(*this);
38 }
39 
40 void Mu0Poly::updateProperties(const doublereal* tt, doublereal* cp_R,
41  doublereal* h_RT, doublereal* s_R) const
42 {
43  size_t j = m_numIntervals;
44  double T = *tt;
45  for (size_t i = 0; i < m_numIntervals; i++) {
46  double T2 = m_t0_int[i+1];
47  if (T <=T2) {
48  j = i;
49  break;
50  }
51  }
52  double T1 = m_t0_int[j];
53  double cp_Rj = m_cp0_R_int[j];
54  *cp_R = cp_Rj;
55  *h_RT = (m_h0_R_int[j] + (T - T1) * cp_Rj)/T;
56  *s_R = m_s0_R_int[j] + cp_Rj * (log(T/T1));
57 }
58 
59 void Mu0Poly::updatePropertiesTemp(const doublereal T,
60  doublereal* cp_R,
61  doublereal* h_RT,
62  doublereal* s_R) const
63 {
64  updateProperties(&T, cp_R, h_RT, s_R);
65 }
66 
67 void Mu0Poly::reportParameters(size_t& n, int& type,
68  doublereal& tlow, doublereal& thigh,
69  doublereal& pref,
70  doublereal* const coeffs) const
71 {
72  n = 0;
73  type = MU0_INTERP;
74  tlow = m_lowT;
75  thigh = m_highT;
76  pref = m_Pref;
77  coeffs[0] = int(m_numIntervals)+1;
78  coeffs[1] = m_H298 * GasConstant;
79  int j = 2;
80  for (size_t i = 0; i < m_numIntervals+1; i++) {
81  coeffs[j] = m_t0_int[i];
82  coeffs[j+1] = m_mu0_R_int[i] * GasConstant;
83  j += 2;
84  }
85 }
86 
87 void Mu0Poly::modifyParameters(doublereal* coeffs)
88 {
89  warn_deprecated("Mu0Poly::modifyParameters", "To be removed after "
90  "Cantera 2.3. Use MultiSpeciesThermo::modifySpecies instead.");
91  processCoeffs(coeffs);
92 }
93 
95 {
96  bool dimensionlessMu0Values = false;
97 
98  doublereal h298 = 0.0;
99  if (Mu0Node.hasChild("H298")) {
100  h298 = getFloat(Mu0Node, "H298", "actEnergy");
101  }
102 
103  size_t numPoints = 1;
104  if (Mu0Node.hasChild("numPoints")) {
105  numPoints = getInteger(Mu0Node, "numPoints");
106  }
107 
108  vector_fp cValues(numPoints);
109  const XML_Node* valNode_ptr = getByTitle(Mu0Node, "Mu0Values");
110  if (!valNode_ptr) {
111  throw CanteraError("installMu0ThermoFromXML", "missing Mu0Values");
112  }
113  getFloatArray(*valNode_ptr, cValues, true, "actEnergy");
114 
115  // Check to see whether the Mu0's were input in a dimensionless form. If
116  // they were, then the assumed temperature needs to be adjusted from the
117  // assumed T = 273.15
118  if (valNode_ptr->attrib("units") == "Dimensionless") {
119  dimensionlessMu0Values = true;
120  }
121  if (cValues.size() != numPoints) {
122  throw CanteraError("installMu0ThermoFromXML", "numPoints inconsistent");
123  }
124 
125  vector_fp cTemperatures(numPoints);
126  const XML_Node* tempNode_ptr = getByTitle(Mu0Node, "Mu0Temperatures");
127  if (!tempNode_ptr) {
128  throw CanteraError("installMu0ThermoFromXML",
129  "missing Mu0Temperatures");
130  }
131  getFloatArray(*tempNode_ptr, cTemperatures, false);
132  if (cTemperatures.size() != numPoints) {
133  throw CanteraError("installMu0ThermoFromXML", "numPoints inconsistent");
134  }
135 
136  // Fix up dimensionless Mu0 values if input
137  if (dimensionlessMu0Values) {
138  for (size_t i = 0; i < numPoints; i++) {
139  cValues[i] *= cTemperatures[i] / 273.15;
140  }
141  }
142 
143  vector_fp c(2 + 2 * numPoints);
144  c[0] = static_cast<double>(numPoints);
145  c[1] = h298;
146  for (size_t i = 0; i < numPoints; i++) {
147  c[2+i*2] = cTemperatures[i];
148  c[2+i*2+1] = cValues[i];
149  }
150 
151  return new Mu0Poly(fpValue(Mu0Node["Tmin"]), fpValue(Mu0Node["Tmax"]),
152  fpValue(Mu0Node["Pref"]), &c[0]);
153 }
154 
155 void Mu0Poly::processCoeffs(const doublereal* coeffs)
156 {
157  size_t nPoints = (size_t) coeffs[0];
158  if (nPoints < 2) {
159  throw CanteraError("Mu0Poly",
160  "nPoints must be >= 2");
161  }
162  m_numIntervals = nPoints - 1;
163  m_H298 = coeffs[1] / GasConstant;
164  size_t iT298 = 0;
165 
166  // Resize according to the number of points
167  m_t0_int.resize(nPoints);
168  m_h0_R_int.resize(nPoints);
169  m_s0_R_int.resize(nPoints);
170  m_cp0_R_int.resize(nPoints);
171  m_mu0_R_int.resize(nPoints);
172 
173  // Calculate the T298 interval and make sure that the temperatures are
174  // strictly monotonic. Also distribute the data into the internal arrays.
175  bool ifound = false;
176  for (size_t i = 0, iindex = 2; i < nPoints; i++) {
177  double T1 = coeffs[iindex];
178  m_t0_int[i] = T1;
179  m_mu0_R_int[i] = coeffs[iindex+1] / GasConstant;
180  if (T1 == 298.15) {
181  iT298 = i;
182  ifound = true;
183  }
184  if (i < nPoints - 1 && coeffs[iindex+2] <= T1) {
185  throw CanteraError("Mu0Poly",
186  "Temperatures are not monotonic increasing");
187  }
188  iindex += 2;
189  }
190  if (!ifound) {
191  throw CanteraError("Mu0Poly",
192  "One temperature has to be 298.15");
193  }
194 
195  // Starting from the interval with T298, we go up
196  m_h0_R_int[iT298] = m_H298;
197  m_s0_R_int[iT298] = - (m_mu0_R_int[iT298] - m_h0_R_int[iT298]) / m_t0_int[iT298];
198  for (size_t i = iT298; i < m_numIntervals; i++) {
199  double T1 = m_t0_int[i];
200  double s1 = m_s0_R_int[i];
201  double T2 = m_t0_int[i+1];
202  double deltaMu = m_mu0_R_int[i+1] - m_mu0_R_int[i];
203  double deltaT = T2 - T1;
204  double cpi = (deltaMu - T1 * s1 + T2 * s1) / (deltaT - T2 * log(T2/T1));
205  m_cp0_R_int[i] = cpi;
206  m_h0_R_int[i+1] = m_h0_R_int[i] + cpi * deltaT;
207  m_s0_R_int[i+1] = s1 + cpi * log(T2/T1);
208  m_cp0_R_int[i+1] = cpi;
209  }
210 
211  // Starting from the interval with T298, we go down
212  if (iT298 != 0) {
213  m_h0_R_int[iT298] = m_H298;
214  m_s0_R_int[iT298] = - (m_mu0_R_int[iT298] - m_h0_R_int[iT298]) / m_t0_int[iT298];
215  for (size_t i = iT298 - 1; i != npos; i--) {
216  double T1 = m_t0_int[i];
217  double T2 = m_t0_int[i+1];
218  double s2 = m_s0_R_int[i+1];
219  double deltaMu = m_mu0_R_int[i+1] - m_mu0_R_int[i];
220  double deltaT = T2 - T1;
221  double cpi = (deltaMu - T1 * s2 + T2 * s2) / (deltaT - T1 * log(T2/T1));
222  m_cp0_R_int[i] = cpi;
223  m_h0_R_int[i] = m_h0_R_int[i+1] - cpi * deltaT;
224  m_s0_R_int[i] = s2 - cpi * log(T2/T1);
225  if (i == (m_numIntervals-1)) {
226  m_cp0_R_int[i+1] = cpi;
227  }
228  }
229  }
230 }
231 
232 }
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
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:299
Header for a single-species standard state object derived from SpeciesThermoInterpType based on a pie...
Abstract Base class for the thermodynamic manager for an individual species&#39; reference state...
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
vector_fp m_s0_R_int
Entropy at the points.
Definition: Mu0Poly.h:155
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
Mu0Poly()
Constructor.
Definition: Mu0Poly.cpp:20
size_t m_numIntervals
Number of intervals in the interpolating linear approximation.
Definition: Mu0Poly.h:138
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
vector_fp m_cp0_R_int
Heat capacity at the points.
Definition: Mu0Poly.h:158
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
STL namespace.
The Mu0Poly class implements an interpolation of the Gibbs free energy based on a piecewise constant ...
Definition: Mu0Poly.h:73
doublereal m_H298
Value of the enthalpy at T = 298.15.
Definition: Mu0Poly.h:142
#define MU0_INTERP
piecewise interpolation of mu0.
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:59
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:40
doublereal m_highT
Highest valid temperature.
vector_fp m_mu0_R_int
Mu0&#39;s are primary input data.
Definition: Mu0Poly.h:149
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
virtual void modifyParameters(doublereal *coeffs)
Definition: Mu0Poly.cpp:87
doublereal m_lowT
lowest valid temperature
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:536
int getInteger(const XML_Node &parent, const std::string &name)
Get an integer value from a child element.
Definition: ctml.cpp:277
virtual void reportParameters(size_t &n, int &type, doublereal &tlow, doublereal &thigh, doublereal &pref, doublereal *const coeffs) const
This utility function reports back the type of parameterization and all of the parameters for the spe...
Definition: Mu0Poly.cpp:67
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:500
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:136
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:157
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
vector_fp m_t0_int
Points at which the standard state chemical potential are given.
Definition: Mu0Poly.h:145
Contains declarations for string manipulation functions within Cantera.
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:178
virtual SpeciesThermoInterpType * duplMyselfAsSpeciesThermoInterpType() const
Definition: Mu0Poly.cpp:35
vector_fp m_h0_R_int
Dimensionless Enthalpies at the temperature points.
Definition: Mu0Poly.h:152
doublereal m_Pref
Reference state pressure.
Namespace for the Cantera kernel.
Definition: application.cpp:29
Mu0Poly * newMu0ThermoFromXML(const XML_Node &Mu0Node)
Install a Mu0 polynomial thermodynamic reference state.
Definition: Mu0Poly.cpp:94
void processCoeffs(const doublereal *coeffs)
process the coefficients
Definition: Mu0Poly.cpp:155