Cantera 2.6.0
SpeciesThermoFactory.cpp
Go to the documentation of this file.
1/**
2 * @file SpeciesThermoFactory.cpp
3 * Definitions for factory functions to build instances of classes that
4 * manage the standard-state thermodynamic properties of a set of species
5 * (see \ref spthermo);
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
21#include "cantera/base/ctml.h"
23#include "cantera/base/Units.h"
24
25using namespace std;
26
27namespace Cantera
28{
29
31 double thigh, double pref, const double* coeffs)
32{
33 switch (type) {
34 case NASA1:
35 return new NasaPoly1(tlow, thigh, pref, coeffs);
36 case SHOMATE1:
37 return new ShomatePoly(tlow, thigh, pref, coeffs);
38 case CONSTANT_CP:
39 case SIMPLE:
40 return new ConstCpPoly(tlow, thigh, pref, coeffs);
41 case MU0_INTERP:
42 return new Mu0Poly(tlow, thigh, pref, coeffs);
43 case SHOMATE2:
44 return new ShomatePoly2(tlow, thigh, pref, coeffs);
45 case NASA2:
46 return new NasaPoly2(tlow, thigh, pref, coeffs);
47 case NASA9MULTITEMP:
48 return new Nasa9PolyMultiTempRegion(tlow, thigh, pref, coeffs);
49 default:
50 throw CanteraError("newSpeciesThermoInterpType",
51 "Unknown species thermo type: {}.", type);
52 }
53}
54
56 double tlow, double thigh, double pref, const double* coeffs)
57{
58 int itype = -1;
59 std::string type = toLowerCopy(stype);
60 if (type == "nasa2" || type == "nasa") {
61 itype = NASA2; // two-region 7-coefficient NASA polynomials
62 } else if (type == "const_cp" || type == "simple") {
63 itype = CONSTANT_CP;
64 } else if (type == "shomate" || type == "shomate1") {
65 itype = SHOMATE1; // single-region Shomate polynomial
66 } else if (type == "shomate2") {
67 itype = SHOMATE2; // two-region Shomate polynomials
68 } else if (type == "nasa1") {
69 itype = NASA1; // single-region, 7-coefficient NASA polynomial
70 } else if (type == "nasa9") {
71 itype = NASA9; // single-region, 9-coefficient NASA polynomial
72 } else if (type == "nasa9multi") {
73 itype = NASA9MULTITEMP; // multi-region, 9-coefficient NASA polynomials
74 } else if (type == "mu0") {
75 itype = MU0_INTERP;
76 } else {
77 throw CanteraError("newSpeciesThermoInterpType",
78 "Unknown species thermo type: '" + stype + "'.");
79 }
80 return newSpeciesThermoInterpType(itype, tlow, thigh, pref, coeffs);
81}
82
83//! Create a NASA polynomial thermodynamic property parameterization for a
84//! species from a set ! of XML nodes
85/*!
86 * This is called if a 'NASA' node is found in the XML input.
87 *
88 * @param nodes vector of 1 or 2 'NASA' XML_Nodes, each defining the
89 * coefficients for a temperature range
90 */
91static SpeciesThermoInterpType* newNasaThermoFromXML(vector<XML_Node*> nodes)
92{
93 const XML_Node& f0 = *nodes[0];
94 bool dualRange = (nodes.size() > 1);
95 double tmin0 = fpValue(f0["Tmin"]);
96 double tmax0 = fpValue(f0["Tmax"]);
97
98 doublereal p0 = OneAtm;
99 if (f0.hasAttrib("P0")) {
100 p0 = fpValue(f0["P0"]);
101 }
102 if (f0.hasAttrib("Pref")) {
103 p0 = fpValue(f0["Pref"]);
104 }
105 p0 = OneAtm;
106
107 double tmin1 = tmax0;
108 double tmax1 = tmin1 + 0.0001;
109 if (dualRange) {
110 tmin1 = fpValue(nodes[1]->attrib("Tmin"));
111 tmax1 = fpValue(nodes[1]->attrib("Tmax"));
112 }
113
114 vector_fp c0, c1;
115 doublereal tmin, tmid, tmax;
116 if (fabs(tmax0 - tmin1) < 0.01) {
117 // f0 has the lower T data, and f1 the higher T data
118 tmin = tmin0;
119 tmid = tmax0;
120 tmax = tmax1;
121 getFloatArray(f0.child("floatArray"), c0, false);
122 if (dualRange) {
123 getFloatArray(nodes[1]->child("floatArray"), c1, false);
124 } else {
125 // if there is no higher range data, then copy c0 to c1.
126 c1 = c0;
127 }
128 } else if (fabs(tmax1 - tmin0) < 0.01) {
129 // f1 has the lower T data, and f0 the higher T data
130 tmin = tmin1;
131 tmid = tmax1;
132 tmax = tmax0;
133 getFloatArray(nodes[1]->child("floatArray"), c0, false);
134 getFloatArray(f0.child("floatArray"), c1, false);
135 } else {
136 throw CanteraError("newNasaThermoFromXML",
137 "non-continuous temperature ranges.");
138 }
139
140 vector_fp c(15);
141 c[0] = tmid;
142 copy(c1.begin(), c1.begin()+7, c.begin() + 1); // high-T coefficients
143 copy(c0.begin(), c0.begin()+7, c.begin() + 8); // low-T coefficients
144 return newSpeciesThermoInterpType(NASA, tmin, tmax, p0, &c[0]);
145}
146
147void setupSpeciesThermo(SpeciesThermoInterpType& thermo,
148 const AnyMap& node)
149{
150 double Pref = node.convert("reference-pressure", "Pa", OneAtm);
151 thermo.setRefPressure(Pref);
152 thermo.input() = node;
153}
154
155void setupNasaPoly(NasaPoly2& thermo, const AnyMap& node)
156{
157 setupSpeciesThermo(thermo, node);
158 vector_fp Tranges = node.convertVector("temperature-ranges", "K", 2, 3);
159 const auto& data = node["data"].asVector<vector_fp>(Tranges.size()-1);
160 for (const auto& poly : data) {
161 if (poly.size() != 7) {
162 throw CanteraError("setupNasaPoly", "Wrong number of coefficients "
163 "for NASA polynomial. Expected 7, but got {}", poly.size());
164 }
165 }
166 thermo.setMinTemp(Tranges.front());
167 thermo.setMaxTemp(Tranges.back());
168 if (Tranges.size() == 3) { // standard 2 temperature range polynomial
169 thermo.setParameters(Tranges[1], data[0], data[1]);
170 } else { // Repeat data for single temperature range for both ranges
171 thermo.setParameters(Tranges[1], data[0], data[0]);
172 }
173}
174
175
176//! Create a Shomate polynomial thermodynamic property parameterization for a
177//! species
178/*!
179 * This is called if a 'Shomate' node is found in the XML input.
180 *
181 * @param nodes vector of 1 or 2 'Shomate' XML_Nodes, each defining the
182 * coefficients for a temperature range
183 */
185 vector<XML_Node*>& nodes)
186{
187 bool dualRange = false;
188 if (nodes.size() == 2) {
189 dualRange = true;
190 }
191 double tmin0 = fpValue(nodes[0]->attrib("Tmin"));
192 double tmax0 = fpValue(nodes[0]->attrib("Tmax"));
193
194 doublereal p0 = OneAtm;
195 if (nodes[0]->hasAttrib("P0")) {
196 p0 = fpValue(nodes[0]->attrib("P0"));
197 }
198 if (nodes[0]->hasAttrib("Pref")) {
199 p0 = fpValue(nodes[0]->attrib("Pref"));
200 }
201 p0 = OneAtm;
202
203 double tmin1 = tmax0;
204 double tmax1 = tmin1 + 0.0001;
205 if (dualRange) {
206 tmin1 = fpValue(nodes[1]->attrib("Tmin"));
207 tmax1 = fpValue(nodes[1]->attrib("Tmax"));
208 }
209
210 vector_fp c0, c1;
211 doublereal tmin, tmid, tmax;
212 if (fabs(tmax0 - tmin1) < 0.01) {
213 tmin = tmin0;
214 tmid = tmax0;
215 tmax = tmax1;
216 getFloatArray(nodes[0]->child("floatArray"), c0, false);
217 if (dualRange) {
218 getFloatArray(nodes[1]->child("floatArray"), c1, false);
219 } else {
220 if(c0.size() != 7)
221 {
222 throw CanteraError("newShomateThermoFromXML",
223 "Shomate thermo requires 7 coefficients in float array.");
224 }
225 c1.resize(7,0.0);
226 copy(c0.begin(), c0.begin()+7, c1.begin());
227 }
228 } else if (fabs(tmax1 - tmin0) < 0.01) {
229 tmin = tmin1;
230 tmid = tmax1;
231 tmax = tmax0;
232 getFloatArray(nodes[1]->child("floatArray"), c0, false);
233 getFloatArray(nodes[0]->child("floatArray"), c1, false);
234 } else {
235 throw CanteraError("newShomateThermoFromXML",
236 "non-continuous temperature ranges.");
237 }
238 if(c0.size() != 7 || c1.size() != 7)
239 {
240 throw CanteraError("newShomateThermoFromXML",
241 "Shomate thermo requires 7 coefficients in float array.");
242 }
243 vector_fp c(15);
244 c[0] = tmid;
245 copy(c0.begin(), c0.begin()+7, c.begin() + 1);
246 copy(c1.begin(), c1.begin()+7, c.begin() + 8);
247 return newSpeciesThermoInterpType(SHOMATE, tmin, tmax, p0, &c[0]);
248}
249
250
251void setupShomatePoly(ShomatePoly2& thermo, const AnyMap& node)
252{
253 setupSpeciesThermo(thermo, node);
254 vector_fp Tranges = node.convertVector("temperature-ranges", "K", 2, 3);
255 const auto& data = node["data"].asVector<vector_fp>(Tranges.size()-1);
256 for (const auto& poly : data) {
257 if (poly.size() != 7) {
258 throw CanteraError("setupShomatePoly", "Wrong number of coefficients "
259 "for Shomate polynomial. Expected 7, but got {}", poly.size());
260 }
261 }
262 thermo.setMinTemp(Tranges.front());
263 thermo.setMaxTemp(Tranges.back());
264 if (Tranges.size() == 3) { // standard 2 temperature range polynomial
265 thermo.setParameters(Tranges[1], data[0], data[1]);
266 } else { // Repeat data for single temperature range for both ranges
267 thermo.setParameters(Tranges[1], data[0], data[0]);
268 }
269}
270
271
272//! Create a "simple" constant heat capacity thermodynamic property
273//! parameterization for a ! species
274/*!
275 * This is called if a 'const_cp' XML node is found
276 *
277 * @param f 'const_cp' XML node
278 */
280{
281 double tmin = fpValue(f["Tmin"]);
282 double tmax = fpValue(f["Tmax"]);
283 if (tmax == 0.0) {
284 tmax = 1.0e30;
285 }
286
287 vector_fp c(4);
288 c[0] = getFloat(f, "t0", "toSI");
289 c[1] = getFloat(f, "h0", "toSI");
290 c[2] = getFloat(f, "s0", "toSI");
291 c[3] = getFloat(f, "cp0", "toSI");
292 doublereal p0 = OneAtm;
293 return newSpeciesThermoInterpType(CONSTANT_CP, tmin, tmax, p0, &c[0]);
294}
295
296void setupConstCp(ConstCpPoly& thermo, const AnyMap& node)
297{
298 setupSpeciesThermo(thermo, node);
299 if (node.hasKey("T-min")) {
300 thermo.setMinTemp(node.convert("T-min", "K"));
301 }
302 if (node.hasKey("T-max")) {
303 thermo.setMaxTemp(node.convert("T-max", "K"));
304 }
305 double T0 = node.convert("T0", "K", 298.15);
306 double h0 = node.convert("h0", "J/kmol", 0.0);
307 double s0 = node.convert("s0", "J/kmol/K", 0.0);
308 double cp0 = node.convert("cp0", "J/kmol/K", 0.0);
309 thermo.setParameters(T0, h0, s0, cp0);
310}
311
312//! Create a NASA9 polynomial thermodynamic property parameterization for a
313//! species
314/*!
315 * This is called if a 'NASA9' Node is found in the XML input.
316 *
317 * @param tp Vector of XML Nodes that make up the parameterization
318 */
320 const std::vector<XML_Node*>& tp)
321{
322 int nRegions = 0;
323 vector_fp cPoly;
324 std::vector<Nasa9Poly1*> regionPtrs;
325 doublereal pref = OneAtm;
326 // Loop over all of the possible temperature regions
327 for (size_t i = 0; i < tp.size(); i++) {
328 const XML_Node& fptr = *tp[i];
329 if (fptr.name() == "NASA9" && fptr.hasChild("floatArray")) {
330 double tmin = fpValue(fptr["Tmin"]);
331 double tmax = fpValue(fptr["Tmax"]);
332 if (fptr.hasAttrib("P0")) {
333 pref = fpValue(fptr["P0"]);
334 }
335 if (fptr.hasAttrib("Pref")) {
336 pref = fpValue(fptr["Pref"]);
337 }
338
339 getFloatArray(fptr.child("floatArray"), cPoly, false);
340 if (cPoly.size() != 9) {
341 throw CanteraError("newNasa9ThermoFromXML",
342 "Expected 9 coeff polynomial");
343 }
344 regionPtrs.push_back(new Nasa9Poly1(tmin, tmax, pref, &cPoly[0]));
345 nRegions++;
346 }
347 }
348 if (nRegions == 0) {
349 throw CanteraError("newNasa9ThermoFromXML", "zero regions found");
350 } else if (nRegions == 1) {
351 return regionPtrs[0];
352 } else {
353 return new Nasa9PolyMultiTempRegion(regionPtrs);
354 }
355}
356
357
358void setupNasa9Poly(Nasa9PolyMultiTempRegion& thermo, const AnyMap& node)
359{
360 setupSpeciesThermo(thermo, node);
361 vector_fp Tranges = node.convertVector("temperature-ranges", "K", 2, 999);
362 const auto& data = node["data"].asVector<vector_fp>(Tranges.size()-1);
363 map<double, vector_fp> regions;
364 for (size_t i = 0; i < data.size(); i++) {
365 if (data[i].size() != 9) {
366 throw CanteraError("setupNasa9Poly", "Wrong number of coefficients "
367 "for NASA9 polynomial. Expected 9, but got {}", data[i].size());
368 }
369 regions[Tranges[i]] = data[i];
370 }
371 thermo.setMinTemp(Tranges.front());
372 thermo.setMaxTemp(Tranges.back());
373 thermo.setParameters(regions);
374}
375
376
377void setupMu0(Mu0Poly& thermo, const AnyMap& node)
378{
379 setupSpeciesThermo(thermo, node);
380 if (node.hasKey("T-min")) {
381 thermo.setMinTemp(node.convert("T-min", "K"));
382 }
383 if (node.hasKey("T-max")) {
384 thermo.setMaxTemp(node.convert("T-max", "K"));
385 }
386 bool dimensionless = node.getBool("dimensionless", false);
387 double h0 = node.convert("h0", "J/kmol", 0.0);
388 map<double, double> T_mu;
389 for (const auto& item : node["data"]) {
390 double T = node.units().convertTo(fpValueCheck(item.first), "K");
391 if (dimensionless) {
392 T_mu[T] = item.second.asDouble() * GasConstant * T;
393 } else {
394 T_mu[T] = node.units().convert(item.second, "J/kmol");
395 }
396 }
397 thermo.setParameters(h0, T_mu);
398}
399
401{
402 std::string model = toLowerCopy(thermo["model"]);
403 if (model == "hkft" || model == "ionfromneutral") {
404 // Some PDSS species use the 'thermo' node, but don't specify a
405 // SpeciesThermoInterpType parameterization. This function needs to
406 // just ignore this data.
407 return 0;
408 }
409
410 // Get the children of the thermo XML node. In the next bit of code we take
411 // out the comments that may have been children of the thermo XML node by
412 // doing a selective copy. These shouldn't interfere with the algorithm at
413 // any point.
414 const std::vector<XML_Node*>& tpWC = thermo.children();
415 std::vector<XML_Node*> tp;
416 for (size_t i = 0; i < tpWC.size(); i++) {
417 if (!tpWC[i]->isComment()) {
418 tp.push_back(tpWC[i]);
419 }
420 }
421
422 std::string thermoType = toLowerCopy(tp[0]->name());
423
424 for (size_t i = 1; i < tp.size(); i++) {
425 if (!caseInsensitiveEquals(tp[i]->name(), thermoType)) {
426 throw CanteraError("newSpeciesThermoInterpType",
427 "Encountered unsupported mixed species thermo "
428 "parameterizations, '{}' and '{}'", tp[i]->name(), thermoType);
429 }
430 }
431 if ((tp.size() > 2 && thermoType != "nasa9") ||
432 (tp.size() > 1 && (thermoType == "const_cp" ||
433 thermoType == "mu0"))) {
434 throw CanteraError("newSpeciesThermoInterpType",
435 "Too many regions in thermo parameterization.");
436 }
437
438 if (thermoType == "shomate") {
439 return newShomateThermoFromXML(tp);
440 } else if (thermoType == "const_cp") {
441 return newConstCpThermoFromXML(*tp[0]);
442 } else if (thermoType == "nasa") {
443 return newNasaThermoFromXML(tp);
444 } else if (thermoType == "mu0") {
445 return newMu0ThermoFromXML(*tp[0]);
446 } else if (thermoType == "nasa9") {
447 return newNasa9ThermoFromXML(tp);
448 } else {
449 throw CanteraError("newSpeciesThermoInterpType",
450 "Unknown species thermo model '" + thermoType + "'.");
451 }
452}
453
454
455unique_ptr<SpeciesThermoInterpType> newSpeciesThermo(const AnyMap& node)
456{
457 std::string model = node["model"].asString();
458 if (model == "NASA7") {
459 unique_ptr<NasaPoly2> thermo(new NasaPoly2());
460 setupNasaPoly(*thermo, node);
461 return unique_ptr<SpeciesThermoInterpType>(move(thermo));
462 } else if (model == "Shomate") {
463 unique_ptr<ShomatePoly2> thermo(new ShomatePoly2());
464 setupShomatePoly(*thermo, node);
465 return unique_ptr<SpeciesThermoInterpType>(move(thermo));
466 } else if (model == "NASA9") {
467 unique_ptr<Nasa9PolyMultiTempRegion> thermo(new Nasa9PolyMultiTempRegion());
468 setupNasa9Poly(*thermo, node);
469 return unique_ptr<SpeciesThermoInterpType>(move(thermo));
470 } else if (model == "constant-cp") {
471 unique_ptr<ConstCpPoly> thermo(new ConstCpPoly());
472 setupConstCp(*thermo, node);
473 return unique_ptr<SpeciesThermoInterpType>(move(thermo));
474 } else if (model == "piecewise-Gibbs") {
475 unique_ptr<Mu0Poly> thermo(new Mu0Poly());
476 setupMu0(*thermo, node);
477 return unique_ptr<SpeciesThermoInterpType>(move(thermo));
478 } else {
479 throw CanteraError("newSpeciesThermo",
480 "Unknown thermo model '{}'", model);
481 }
482}
483
484}
Headers for the SpeciesThermoInterpType object that employs a constant heat capacity assumption (see ...
Header for a single-species standard state object derived from SpeciesThermoInterpType based on a pie...
Header for a general species thermodynamic property manager for a phase (see MultiSpeciesThermo).
Header for a single-species standard state object derived from SpeciesThermoInterpType based on the N...
Header for a single-species standard state object derived from SpeciesThermoInterpType based on the N...
Header for a single-species standard state object derived from SpeciesThermoInterpType based on the N...
Header for a single-species standard state object derived from SpeciesThermoInterpType based on the S...
Header for factory functions to build instances of classes that manage the standard-state thermodynam...
Header for unit conversion utilities, which are used to translate user input from input files (See In...
Header file for a derived class of ThermoPhase that handles variable pressure standard state methods ...
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:399
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
A constant-heat capacity species thermodynamic property manager class.
Definition: ConstCpPoly.h:45
The Mu0Poly class implements an interpolation of the Gibbs free energy based on a piecewise constant ...
Definition: Mu0Poly.h:75
The NASA 9 polynomial parameterization for one temperature range.
Definition: Nasa9Poly1.h:63
The NASA 9 polynomial parameterization for a single species encompassing multiple temperature regions...
The NASA polynomial parameterization for one temperature range.
Definition: NasaPoly1.h:48
The NASA polynomial parameterization for two temperature ranges.
Definition: NasaPoly2.h:49
The Shomate polynomial parameterization for two temperature ranges for one species.
Definition: ShomatePoly.h:237
The Shomate polynomial parameterization for one temperature range for one species.
Definition: ShomatePoly.h:59
Abstract Base class for the thermodynamic manager for an individual species' reference state.
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
std::string name() const
Returns the name of the XML node.
Definition: xml.h:371
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:529
const std::vector< XML_Node * > & children() const
Return an unchangeable reference to the vector of children of the current node.
Definition: xml.cpp:552
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:547
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
Definition: xml.cpp:534
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
Mu0Poly * newMu0ThermoFromXML(const XML_Node &Mu0Node)
Install a Mu0 polynomial thermodynamic reference state.
Definition: Mu0Poly.cpp:181
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
static SpeciesThermoInterpType * newNasa9ThermoFromXML(const std::vector< XML_Node * > &tp)
Create a NASA9 polynomial thermodynamic property parameterization for a species.
static SpeciesThermoInterpType * newNasaThermoFromXML(vector< XML_Node * > nodes)
Create a NASA polynomial thermodynamic property parameterization for a species from a set !...
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:166
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
const double OneAtm
One atmosphere [Pa].
Definition: ct_defs.h:81
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
unique_ptr< SpeciesThermoInterpType > newSpeciesThermo(const AnyMap &thermo_node)
Create a new SpeciesThermoInterpType object using the specified parameters.
std::string toLowerCopy(const std::string &input)
Convert to lower case.
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:184
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:113
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert=true, const std::string &unitsString="", const std::string &nodeName="floatArray")
This function reads the current node or a child node of the current node with the default name,...
Definition: ctml.cpp:258
static SpeciesThermoInterpType * newConstCpThermoFromXML(XML_Node &f)
Create a "simple" constant heat capacity thermodynamic property parameterization for a !...
doublereal fpValueCheck(const std::string &val)
Translate a string into one doublereal value, with error checking.
static SpeciesThermoInterpType * newShomateThermoFromXML(vector< XML_Node * > &nodes)
Create a Shomate polynomial thermodynamic property parameterization for a species.
SpeciesThermoInterpType * newSpeciesThermoInterpType(int type, double tlow, double thigh, double pref, const double *coeffs)
Create a new SpeciesThermoInterpType object given a corresponding constant.
Contains const definitions for types of species reference-state thermodynamics managers (see Species ...
#define NASA1
7 coefficient NASA Polynomials This is implemented in the class NasaPoly1 in NasaPoly1....
#define CONSTANT_CP
Constant Cp.
#define MU0_INTERP
piecewise interpolation of mu0.
#define SHOMATE1
one region of Shomate Polynomials used in NIST database This is implemented in the NIST database.
#define NASA9MULTITEMP
9 coefficient NASA Polynomials in multiple temperature regions This is implemented in the class Nasa9...
#define SHOMATE
Two regions of Shomate Polynomials.
#define NASA9
9 coefficient NASA Polynomials This is implemented in the class Nasa9Poly1 in Nasa9Poly1....
#define SHOMATE2
Two regions of Shomate Polynomials.
#define NASA
Two regions of 7 coefficient NASA Polynomials This is implemented in the class NasaPoly2 in NasaPoly2...
#define SIMPLE
Constant Cp thermo.
#define NASA2
Two regions of 7 coefficient NASA Polynomials This is implemented in the class NasaPoly2 in NasaPoly2...
Contains declarations for string manipulation functions within Cantera.