https://mooseframework.inl.gov
Loading...
Searching...
No Matches
NASA7PolynomialsTest.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "gtest/gtest.h"
11
12#include "NASA7Polynomials.h"
13#include "ADReal.h"
14
15namespace
16{
18struct Reference
19{
20 std::string species;
21 Real cp_R;
22 Real h_RT;
23 Real s_R;
24};
25
31const Real tol = 1e-12;
32
33void
34expectCanteraValues(const Real T, const std::array<Reference, 7> & references)
35{
36 for (const auto & ref : references)
37 {
38 const auto & data = NASA7::speciesData(ref.species);
39 EXPECT_NEAR(NASA7::cpOverR(data, T), ref.cp_R, tol * std::abs(ref.cp_R)) << ref.species;
40 EXPECT_NEAR(NASA7::hOverRT(data, T), ref.h_RT, tol * std::abs(ref.h_RT)) << ref.species;
41 EXPECT_NEAR(NASA7::sOverR(data, T), ref.s_R, tol * std::abs(ref.s_R)) << ref.species;
42 }
43}
44}
45
46TEST(NASA7PolynomialsTest, canteraBelowMidpoint)
47{
48 // 923.15 K (650 C) is a typical operating temperature of solid oxide cells
49 expectCanteraValues(923.15,
50 {{{"H2", 3.613168165140949, 2.393557882983218, 19.70388492877914},
51 {"O2", 4.147314656442323, 2.611086604285082, 28.963169712215056},
52 {"H2O", 4.844876850286245, -28.52667487834571, 27.59941233403597},
53 {"CH4", 8.411873653444164, -5.402055033541204, 29.171138189568893},
54 {"CO", 3.9393320432028016, -11.904521875475112, 27.892178607608198},
55 {"CO2", 6.410478331025108, -47.455763652874914, 31.870172746438772},
56 {"N2", 3.883883836068483, 2.4714182404274005, 27.11985064871594}}});
57}
58
59TEST(NASA7PolynomialsTest, canteraAtMidpoint)
60{
61 // Cantera uses the low-temperature polynomial at the midpoint temperature itself
62 expectCanteraValues(1000.0,
63 {{{"H2", 3.6277926600000017, 2.4880181500000003, 19.99356155536211},
64 {"O2", 4.195457489999999, 2.7310016248333326, 29.296709192476225},
65 {"H2O", 4.9666161199999985, -25.957432841000003, 27.991587242388515},
66 {"CH4", 8.854050229999995, -4.323604100000004, 29.861079446444933},
67 {"CO", 3.9885755050000005, -10.6849246888, 28.209233158602412},
68 {"CO2", 6.533298272000001, -43.31136104626667, 32.38768755547865},
69 {"N2", 3.9403564, 2.5822312499999995, 27.43274636040696}}});
70}
71
72TEST(NASA7PolynomialsTest, canteraAboveMidpoint)
73{
74 expectCanteraValues(1500.0,
75 {{{"H2", 3.8822959451999997, 2.9101473592241667, 21.51235276622741},
76 {"O2", 4.3989938846625, 3.2555381173887485, 31.039298778830236},
77 {"H2O", 5.687841430574999, -15.524086927924582, 30.14793701207187},
78 {"CH4", 10.874274296875003, 0.43494356952083546, 33.86860929626944},
79 {"CO", 4.234951016024999, -5.748131851494999, 29.878586100354962},
80 {"CO2", 7.023470866475001, -26.605086887146665, 35.14116319971301},
81 {"N2", 4.1861203930625, 3.079423123570834, 29.081165481314585}}});
82}
83
84TEST(NASA7PolynomialsTest, molarMass)
85{
86 // Molecular weights reported by Cantera 3.2.0 for gri30.yaml [g/mol]
87 const std::array<std::pair<std::string, Real>, 7> molecular_weights = {{{"H2", 2.016},
88 {"O2", 31.998},
89 {"H2O", 18.015},
90 {"CH4", 16.043},
91 {"CO", 28.010},
92 {"CO2", 44.009},
93 {"N2", 28.014}}};
94
95 // The tolerance [kg/mol] only absorbs roundoff in the conversion from g/mol; it is far below the
96 // 1e-6 kg/mol resolution of the reported values
97 for (const auto & [species, molecular_weight] : molecular_weights)
98 EXPECT_NEAR(NASA7::speciesData(species).molar_mass, 1e-3 * molecular_weight, 1e-15) << species;
99}
100
101TEST(NASA7PolynomialsTest, consistentDerivatives)
102{
103 // The enthalpy and entropy polynomials are integrals of the heat capacity polynomial:
104 // d(h/R)/dT = cp/R and d(s/R)/dT = cp/(R T). Check this with automatic differentiation on both
105 // sides of the midpoint temperature.
106 DNDerivativeType dTdT;
107 Moose::derivInsert(dTdT, 0, 1);
108
109 for (const std::string species : {"H2", "O2", "H2O", "CH4", "CO", "CO2", "N2"})
110 for (const Real T_value : {600.0, 2000.0})
111 {
112 const auto & data = NASA7::speciesData(species);
113 const ADReal T(T_value, dTdT);
114
115 const Real cp_R = NASA7::cpOverR(data, T_value);
116 const ADReal h_R = T * NASA7::hOverRT(data, T);
117 const ADReal s_R = NASA7::sOverR(data, T);
118 EXPECT_NEAR(h_R.derivatives()[0], cp_R, tol * cp_R) << species << " at " << T_value;
119 EXPECT_NEAR(s_R.derivatives()[0], cp_R / T_value, tol * cp_R / T_value)
120 << species << " at " << T_value;
121 }
122}
DualNumber< Real, DNDerivativeType, true > ADReal
SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< MOOSE_AD_MAX_DOFS_PER_ELEM > > DNDerivativeType
const double tol
const double T
TEST(NASA7PolynomialsTest, canteraBelowMidpoint)
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N > > &derivs, libMesh::dof_id_type index, Real value)
CppType hOverRT(const SpeciesData &data, const CppType &T)
Standard-state molar enthalpy divided by the gas constant and temperature, h/(RT)
const SpeciesData & speciesData(const std::string &name)
Data of a built-in species.
CppType cpOverR(const SpeciesData &data, const CppType &T)
Standard-state molar isobaric heat capacity divided by the gas constant, cp/R.
CppType sOverR(const SpeciesData &data, const CppType &T)
Standard-state molar entropy divided by the gas constant, s/R, at the reference pressure of the data ...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real molar_mass
Molar mass [kg/mol].