[Input] Parse YAML entries for NASA 7-coefficient polynomials

This commit is contained in:
Ray Speth 2018-12-14 17:42:31 -05:00
parent 3eaa32dea3
commit 2b41486850
3 changed files with 102 additions and 0 deletions

View file

@ -17,6 +17,8 @@ namespace Cantera
{
class XML_Node;
class AnyMap;
class UnitSystem;
//! Create a new SpeciesThermoInterpType object given a corresponding constant.
/*!
@ -50,6 +52,15 @@ SpeciesThermoInterpType* newSpeciesThermoInterpType(const std::string& type,
*/
SpeciesThermoInterpType* newSpeciesThermoInterpType(const XML_Node& thermoNode);
//! Create a new SpeciesThermoInterpType object using the specified parameters
/*!
* @param thermo_node An AnyMap specifying the model type (e.g. "NASA") and any
* model parameters necessary to instantiate the object
* @param units Specification for the unit system to convert from
*/
unique_ptr<SpeciesThermoInterpType> newSpeciesThermo(
const AnyMap& thermo_node, const UnitSystem& units);
}
#endif

View file

@ -20,6 +20,7 @@
#include "cantera/thermo/VPStandardStateTP.h"
#include "cantera/base/ctml.h"
#include "cantera/base/stringUtils.h"
#include "cantera/base/Units.h"
using namespace std;
@ -141,6 +142,39 @@ static SpeciesThermoInterpType* newNasaThermoFromXML(vector<XML_Node*> nodes)
return newSpeciesThermoInterpType(NASA, tmin, tmax, p0, &c[0]);
}
void setupSpeciesThermo(SpeciesThermoInterpType& thermo,
const AnyMap& node, const UnitSystem& units)
{
double Pref = OneAtm;
if (node.hasKey("reference-pressure")) {
Pref = units.convert(node.at("reference-pressure"), "Pa");
}
thermo.setRefPressure(Pref);
}
void setupNasaPoly(NasaPoly2& thermo, const AnyMap& node,
const UnitSystem& units)
{
setupSpeciesThermo(thermo, node, units);
vector_fp Tranges = units.convert(
node.at("temperature-ranges").asVector<AnyValue>(2, 3), "K");
const auto& data = node.at("data").asVector<vector_fp>(Tranges.size()-1);
for (const auto& poly : data) {
if (poly.size() != 7) {
throw CanteraError("setupNasaPoly", "Wrong number of coefficients "
"for NASA polynomial. Expected 7, but got {}", poly.size());
}
}
thermo.setMinTemp(Tranges.front());
thermo.setMaxTemp(Tranges.back());
if (Tranges.size() == 3) { // standard 2 temperature range polynomial
thermo.setParameters(Tranges[1], data[0], data[1]);
} else { // Repeat data for single temperature range for both ranges
thermo.setParameters(Tranges[1], data[0], data[0]);
}
}
//! Create a Shomate polynomial thermodynamic property parameterization for a
//! species
/*!
@ -339,4 +373,19 @@ SpeciesThermoInterpType* newSpeciesThermoInterpType(const XML_Node& thermo)
}
}
unique_ptr<SpeciesThermoInterpType> newSpeciesThermo(
const AnyMap& node, const UnitSystem& units)
{
std::string model = node.at("model").asString();
if (model == "NASA7") {
unique_ptr<NasaPoly2> thermo(new NasaPoly2());
setupNasaPoly(*thermo, node, units);
return unique_ptr<SpeciesThermoInterpType>(move(thermo));
} else {
throw CanteraError("newSpeciesThermo",
"Uknown thermo model '{}'", model);
}
}
}

View file

@ -1,11 +1,13 @@
#include "gtest/gtest.h"
#include "cantera/thermo/speciesThermoTypes.h"
#include "cantera/thermo/SpeciesThermoFactory.h"
#include "cantera/thermo/IdealGasPhase.h"
#include "cantera/thermo/ConstCpPoly.h"
#include "cantera/thermo/NasaPoly2.h"
#include "cantera/thermo/ShomatePoly.h"
#include "cantera/thermo/PDSS_HKFT.h"
#include "cantera/base/stringUtils.h"
#include "cantera/base/Units.h"
#include "thermo_data.h"
#include <sstream>
@ -121,3 +123,43 @@ TEST(Shomate, modifyOneHf298)
S.updatePropertiesTemp(298.15, &cp, &h, &s);
EXPECT_DOUBLE_EQ(hf, h * 298.15 * GasConstant);
}
TEST(SpeciesThermo, NasaPoly2FromYaml1) {
AnyMap data = AnyMap::fromYamlString(
"model: NASA7\n"
"reference-pressure: 1 atm\n"
"temperature-ranges: [200, 1000, 6000]\n"
"data:\n"
"- [3.944031200E+00, -1.585429000E-03, 1.665781200E-05, -2.047542600E-08,\n"
" 7.835056400E-12, 2.896617900E+03, 6.311991700E+00]\n"
"- [4.884754200E+00, 2.172395600E-03, -8.280690600E-07, 1.574751000E-10,\n"
" -1.051089500E-14, 2.316498300E+03, -1.174169500E-01]\n");
UnitSystem U;
double cp_R, h_RT, s_R;
auto st = newSpeciesThermo(data, U);
st->validate("NO2");
st->updatePropertiesTemp(300, &cp_R, &h_RT, &s_R);
EXPECT_DOUBLE_EQ(st->refPressure(), OneAtm);
EXPECT_DOUBLE_EQ(cp_R, 4.47823303484);
EXPECT_DOUBLE_EQ(h_RT, 13.735827875868003);
EXPECT_DOUBLE_EQ(s_R, 28.913447733267262);
}
TEST(SpeciesThermo, NasaPoly2FromYaml2) {
AnyMap data = AnyMap::fromYamlString(
"model: NASA7\n"
"reference-pressure: 1 atm\n"
"temperature-ranges: [200 K, 1000 K]\n"
"data:\n"
"- [3.944031200E+00, -1.585429000E-03, 1.665781200E-05, -2.047542600E-08,\n"
" 7.835056400E-12, 2.896617900E+03, 6.311991700E+00]\n");
UnitSystem U;
double cp_R, h_RT, s_R;
auto st = newSpeciesThermo(data, U);
st->validate("NO2");
st->updatePropertiesTemp(300, &cp_R, &h_RT, &s_R);
EXPECT_DOUBLE_EQ(st->maxTemp(), 1000);
EXPECT_DOUBLE_EQ(cp_R, 4.47823303484);
EXPECT_DOUBLE_EQ(h_RT, 13.735827875868003);
EXPECT_DOUBLE_EQ(s_R, 28.913447733267262);
}