32 #include "antioch_config.h"
36 #ifdef ANTIOCH_HAVE_EIGEN
37 #include "Eigen/Dense"
40 #ifdef ANTIOCH_HAVE_METAPHYSICL
41 #include "metaphysicl/numberarray.h"
44 #ifdef ANTIOCH_HAVE_VEXCL
45 #include "vexcl/vexcl.hpp"
64 #ifdef ANTIOCH_HAVE_GRVY
67 GRVY::GRVY_Timer_Class gt;
74 template <
typename Scalar,
typename TrioScalars>
75 int test_cp(
const std::string& species_name,
unsigned int species,
76 TrioScalars cp_exact, TrioScalars T,
78 const std::string& testname )
84 const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 25;
87 template Cache<TrioScalars> Cache;
89 #ifdef ANTIOCH_HAVE_GRVY
90 gt.BeginTimer(testname);
93 const TrioScalars
cp = thermo.
cp(Cache(T), species);
95 #ifdef ANTIOCH_HAVE_GRVY
96 gt.EndTimer(testname);
100 const TrioScalars diff = cp_exact -
cp;
101 const TrioScalars rel_cp_error = abs(diff/cp_exact);
105 std::cerr <<
"Error: Mismatch in species specific heat."
107 (std::numeric_limits<Scalar>::digits10 + 1)
108 <<
"\nspecies = " << species_name
110 <<
"\ncp_exact = " << cp_exact
111 <<
"\ndifference = " << diff
112 <<
"\nrelative = " << rel_cp_error
113 <<
"\ntolerance = " << tol
114 <<
"\nT = " << T << std::endl;
122 template <
typename Scalar>
123 Scalar
cp( Scalar T, Scalar a0, Scalar a1, Scalar a2,
124 Scalar a3, Scalar a4, Scalar a5, Scalar a6 )
129 return a0/(T*T) + a1/T + a2 + a3*T + a4*(T*T) + a5*(T*T*T) + a6*(T*T*T*T);
133 template <
typename TrioScalars>
134 int vectester(
const TrioScalars& example,
const std::string& testname)
138 std::vector<std::string> species_str_list;
139 const unsigned int n_species = 5;
140 species_str_list.reserve(n_species);
141 species_str_list.push_back(
"N2" );
142 species_str_list.push_back(
"O2" );
143 species_str_list.push_back(
"N" );
144 species_str_list.push_back(
"O" );
145 species_str_list.push_back(
"NO" );
147 const Scalar Mm_N = 14.008e-3L;
148 const Scalar Mm_O = 16.000e-3L;
149 const Scalar Mm_N2 = 2.L * Mm_N;
150 const Scalar Mm_O2 = 2.L * Mm_O;
151 const Scalar Mm_NO = Mm_N + Mm_O;
158 TrioScalars T = example;
159 for (
unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
162 T[3*tuple+1] = 1500.0;
163 T[3*tuple+2] = 10000.0;
166 const Scalar R_N2 = Antioch::Constants::R_universal<Scalar>()/Mm_N2;
167 const Scalar R_O2 = Antioch::Constants::R_universal<Scalar>()/Mm_O2;
168 const Scalar R_N = Antioch::Constants::R_universal<Scalar>()/Mm_N;
169 const Scalar R_O = Antioch::Constants::R_universal<Scalar>()/Mm_O;
170 const Scalar R_NO = Antioch::Constants::R_universal<Scalar>()/Mm_NO;
176 unsigned int index = 0;
177 TrioScalars cp_N2 = example;
178 for (
unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
180 cp_N2[3*tuple ] = R_N2*
cp( Scalar(T[0]), Scalar(2.21037122e+04), Scalar(-3.81846145e+02), Scalar(6.08273815e+00),
181 Scalar(-8.53091381e-03), Scalar(1.38464610e-05), Scalar(-9.62579293e-09), Scalar(2.51970560e-12));
183 cp_N2[3*tuple+1] = R_N2*
cp( Scalar(T[1]), Scalar(5.87709908e+05), Scalar(-2.23924255e+03), Scalar(6.06694267e+00),
184 Scalar(-6.13965296e-04), Scalar(1.49179819e-07), Scalar(-1.92309442e-11), Scalar(1.06194871e-15) );
186 cp_N2[3*tuple+2] = R_N2*
cp( Scalar(T[2]), Scalar(8.30971200e+08), Scalar(-6.42048187e+05), Scalar(2.02020507e+02), Scalar(-3.06501961e-02),
187 Scalar(2.48685558e-06), Scalar(-9.70579208e-11), Scalar(1.43751673e-15));
193 int return_flag_temp = 0;
194 return_flag_temp =
test_cp( species_name, index, cp_N2, T, thermo, testname );
195 if( return_flag_temp != 0 ) return_flag = 1;
200 unsigned int index = 1;
201 TrioScalars cp_O2 = example;
202 for (
unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
204 cp_O2[3*tuple ] = R_O2*
cp( Scalar(T[0]), Scalar(-3.42556269e+04), Scalar(4.84699986e+02), Scalar(1.11901159e+00),
205 Scalar(4.29388743e-03), Scalar(-6.83627313e-07), Scalar(-2.02337478e-09) , Scalar(1.03904064e-12) );
207 cp_O2[3*tuple+1] = R_O2*
cp( Scalar(T[1]), Scalar(-1.03793994e+06), Scalar(2.34483275e+03), Scalar(1.81972949e+00), Scalar(1.26784887e-03),
208 Scalar(-2.18807142e-07), Scalar(2.05372411e-11), Scalar(-8.19349062e-16) );
210 cp_O2[3*tuple+2] = R_O2*
cp( Scalar(T[2]), Scalar(4.97515261e+08), Scalar(-2.86602339e+05), Scalar(6.69015464e+01), Scalar(-6.16971869e-03),
211 Scalar(3.01623757e-07), Scalar(-7.42087888e-12), Scalar(7.27744063e-17));
217 int return_flag_temp = 0;
218 return_flag_temp =
test_cp( species_name, index, cp_O2, T, thermo, testname );
219 if( return_flag_temp != 0 ) return_flag = 1;
224 unsigned int index = 2;
225 TrioScalars cp_N = example;
226 for (
unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
228 cp_N[3*tuple ] = R_N*
cp( Scalar(T[0]), Scalar(0.00000000e+00), Scalar(0.00000000e+00), Scalar(2.50000000e+00), Scalar(0.00000000e+00),
229 Scalar(0.00000000e+00), Scalar(0.00000000e+00), Scalar(0.00000000e+00));
231 cp_N[3*tuple+1] = R_N*
cp( Scalar(T[1]), Scalar(8.87650138e+04), Scalar(-1.07123150e+02), Scalar(2.36218829e+00), Scalar(2.91672008e-04),
232 Scalar(-1.72951510e-07), Scalar(4.01265788e-11), Scalar(-2.67722757e-15) );
234 cp_N[3*tuple+2] = R_N*
cp( Scalar(T[2]), Scalar(5.47518105e+08), Scalar(-3.10757498e+05), Scalar(6.91678274e+01), Scalar(-6.84798813e-03),
235 Scalar(3.82757240e-07), Scalar(-1.09836771e-11), Scalar(1.27798602e-16));
241 int return_flag_temp = 0;
242 return_flag_temp =
test_cp( species_name, index, cp_N, T, thermo, testname );
243 if( return_flag_temp != 0 ) return_flag = 1;
249 unsigned int index = 3;
250 TrioScalars cp_O = example;
251 for (
unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
253 cp_O[3*tuple ] = R_O*
cp( Scalar(T[0]), Scalar(-7.95361130e+03) , Scalar(1.60717779e+02), Scalar(1.96622644e+00), Scalar(1.01367031e-03),
254 Scalar(-1.11041542e-06), Scalar(6.51750750e-10), Scalar(-1.58477925e-13) );
256 cp_O[3*tuple+1] = R_O*
cp( Scalar(T[1]), Scalar(2.61902026e+05), Scalar(-7.29872203e+02), Scalar(3.31717727e+00), Scalar(-4.28133436e-04),
257 Scalar(1.03610459e-07), Scalar(-9.43830433e-12), Scalar(2.72503830e-16) );
259 cp_O[3*tuple+2] = R_O*
cp( Scalar(T[2]), Scalar(1.77900426e+08), Scalar(-1.08232826e+05), Scalar(2.81077837e+01), Scalar(-2.97523226e-03),
260 Scalar(1.85499753e-07), Scalar(-5.79623154e-12), Scalar(7.19172016e-17) );
266 int return_flag_temp = 0;
267 return_flag_temp =
test_cp( species_name, index, cp_O, T, thermo, testname );
268 if( return_flag_temp != 0 ) return_flag = 1;
274 unsigned int index = 4;
275 TrioScalars cp_NO = example;
276 for (
unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
278 cp_NO[3*tuple ] = R_NO*
cp( Scalar(T[0]), Scalar(-1.14391658e+04), Scalar(1.53646774e+02), Scalar(3.43146865e+00), Scalar(-2.66859213e-03),
279 Scalar(8.48139877e-06), Scalar(-7.68511079e-09), Scalar(2.38679758e-12) );
281 cp_NO[3*tuple+1] = R_NO*
cp( Scalar(T[1]), Scalar(2.23903708e+05), Scalar(-1.28965624e+03), Scalar(5.43394039e+00), Scalar(-3.65605546e-04),
282 Scalar(9.88101763e-08), Scalar(-1.41608327e-11), Scalar(9.38021642e-16) );
284 cp_NO[3*tuple+2] = R_NO*
cp( Scalar(T[2]), Scalar(-9.57530764e+08), Scalar(5.91243671e+05), Scalar(-1.38456733e+02), Scalar(1.69433998e-02),
285 Scalar(-1.00735146e-06), Scalar(2.91258526e-11), Scalar(-3.29511091e-16) );
291 int return_flag_temp = 0;
292 return_flag_temp =
test_cp( species_name, index, cp_NO, T, thermo, testname );
293 if( return_flag_temp != 0 ) return_flag = 1;
304 returnval = returnval ||
305 vectester (std::valarray<float>(3*ANTIOCH_N_TUPLES),
"valarray<float>");
306 returnval = returnval ||
307 vectester (std::valarray<double>(3*ANTIOCH_N_TUPLES),
"valarray<double>");
312 #ifdef ANTIOCH_HAVE_EIGEN
313 returnval = returnval ||
314 vectester (Eigen::Array<float, 3*ANTIOCH_N_TUPLES, 1>(),
"Eigen::ArrayXf");
315 returnval = returnval ||
316 vectester (Eigen::Array<double, 3*ANTIOCH_N_TUPLES, 1>(),
"Eigen::ArrayXd");
320 #ifdef ANTIOCH_HAVE_METAPHYSICL
321 returnval = returnval ||
322 vectester (MetaPhysicL::NumberArray<3*ANTIOCH_N_TUPLES, float> (0),
"NumberArray<float>");
323 returnval = returnval ||
324 vectester (MetaPhysicL::NumberArray<3*ANTIOCH_N_TUPLES, double> (0),
"NumberArray<double>");
328 #ifdef ANTIOCH_HAVE_VEXCL
329 vex::Context ctx_f (vex::Filter::All);
331 returnval = returnval ||
332 vectester (vex::vector<float> (ctx_f, 3*ANTIOCH_N_TUPLES),
"vex::vector<float>");
334 vex::Context ctx_d (vex::Filter::DoublePrecision);
336 returnval = returnval ||
337 vectester (vex::vector<double> (ctx_d, 3*ANTIOCH_N_TUPLES),
"vex::vector<double>");
340 #ifdef ANTIOCH_HAVE_GRVY
Antioch::enable_if_c< is_eigen< T >::value, typename value_type< T >::type >::type max(const T &in)
int vectester(const TrioScalars &example, const std::string &testname)
const std::vector< Species > & species_list() const
const std::map< Species, std::string > & species_inverse_name_map() const
int test_cp(const std::string &species_name, unsigned int species, TrioScalars cp_exact, TrioScalars T, const Antioch::CEAThermodynamics< Scalar > &thermo, const std::string &testname)
Class storing chemical mixture properties.
Scalar cp(Scalar T, Scalar a0, Scalar a1, Scalar a2, Scalar a3, Scalar a4, Scalar a5, Scalar a6)
StateType cp(const Cache< StateType > &cache, unsigned int species) const
We currently need different specializations for scalar vs vector inputs here.