32 #include "antioch_config.h"
37 #ifdef ANTIOCH_HAVE_EIGEN
57 template <
typename Scalar>
58 bool test_relative(
const Scalar val,
const Scalar truth,
const Scalar tol)
62 if( abs( (val-truth)/truth ) > tol )
68 template <
typename Scalar>
79 template <
typename Scalar>
84 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Eigen::ColMajor> VectorXr;
86 std::vector<std::string> species_str_list;
87 const unsigned int n_species = 5;
88 species_str_list.reserve(n_species);
89 species_str_list.push_back(
"N2" );
90 species_str_list.push_back(
"O2" );
91 species_str_list.push_back(
"N" );
92 species_str_list.push_back(
"O" );
93 species_str_list.push_back(
"NO" );
95 const Scalar Mm_N = 14.008e-3;
96 const Scalar Mm_O = 16e-3;
97 const Scalar Mm_N2 = 2.L * Mm_N;
98 const Scalar Mm_O2 = 2.L * Mm_O;
99 const Scalar Mm_NO = Mm_O + Mm_N;
107 VectorXr mass_fractions(n_species);
108 mass_fractions[0] = 0.5;
109 mass_fractions[1] = 0.2;
110 mass_fractions[2] = 0.1;
111 mass_fractions[3] = 0.1;
112 mass_fractions[4] = 0.1;
114 Scalar cv_tr_mix = 0.0;
116 const Scalar R_N2 = Antioch::Constants::R_universal<Scalar>()/Mm_N2;
117 const Scalar R_O2 = Antioch::Constants::R_universal<Scalar>()/Mm_O2;
118 const Scalar R_N = Antioch::Constants::R_universal<Scalar>()/Mm_N;
119 const Scalar R_O = Antioch::Constants::R_universal<Scalar>()/Mm_O;
120 const Scalar R_NO = Antioch::Constants::R_universal<Scalar>()/Mm_NO;
124 Scalar tol = std::numeric_limits<Scalar>::epsilon() * 2;
128 Scalar cv_N2 = sm_thermo.
cv_tr(0);
132 std::cerr << std::scientific << std::setprecision(20);
133 std::cerr <<
"Error: Mismatch in cv_tr for N2."
134 <<
"\n Expected = " << R_N2*Scalar(2.5)
135 <<
"\n Computed = " << cv_N2
136 <<
"\n Diff = " << cv_N2 - R_N2*Scalar(2.5)
141 cv_tr_mix += cv_N2*mass_fractions[0];
146 Scalar cv_O2 = sm_thermo.
cv_tr(1);
150 std::cerr << std::scientific << std::setprecision(20);
151 std::cerr <<
"Error: Mismatch in cv_tr for O2."
152 <<
"\n Expected = " << R_O2*Scalar(2.5)
153 <<
"\n Computed = " << cv_O2
154 <<
"\n Diff = " << cv_O2 - R_O2*Scalar(2.5)
159 cv_tr_mix += cv_O2*mass_fractions[1];
164 Scalar cv_N = sm_thermo.
cv_tr(2);
168 std::cerr << std::scientific << std::setprecision(20);
169 std::cerr <<
"Error: Mismatch in cv_tr for N."
170 <<
"\n Expected = " << R_N*Scalar(1.5)
171 <<
"\n Computed = " << cv_N
172 <<
"\n Diff = " << cv_N - R_N*Scalar(2.5)
177 cv_tr_mix += cv_N*mass_fractions[2];
182 Scalar cv_O = sm_thermo.
cv_tr(3);
186 std::cerr << std::scientific << std::setprecision(20);
187 std::cerr <<
"Error: Mismatch in cv_tr for O."
188 <<
"\n Expected = " << R_O*Scalar(1.5)
189 <<
"\n Computed = " << cv_O
190 <<
"\n Diff = " << cv_O - R_O*Scalar(2.5)
195 cv_tr_mix += cv_O*mass_fractions[3];
200 Scalar cv_NO = sm_thermo.
cv_tr(4);
204 std::cerr << std::scientific << std::setprecision(20);
205 std::cerr <<
"Error: Mismatch in cv_tr for NO."
206 <<
"\n Expected = " << R_NO*Scalar(2.5)
207 <<
"\n Computed = " << cv_NO
208 <<
"\n Diff = " << cv_NO - R_NO*Scalar(2.5)
213 cv_tr_mix += cv_NO*mass_fractions[4];
218 Scalar cv = sm_thermo.
cv_tr(mass_fractions);
222 std::cerr << std::scientific << std::setprecision(20);
223 std::cerr <<
"Error: Mismatch in mixture cv_tr."
224 <<
"\n Expected = " << cv_tr_mix
225 <<
"\n Computed = " << cv
226 <<
"\n Diff = " << cv - cv_tr_mix
235 template <
typename Scalar>
241 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Eigen::ColMajor> VectorXr;
243 std::vector<std::string> species_str_list;
244 const unsigned int n_species = 5;
245 species_str_list.reserve(n_species);
246 species_str_list.push_back(
"N2" );
247 species_str_list.push_back(
"O2" );
248 species_str_list.push_back(
"N" );
249 species_str_list.push_back(
"O" );
250 species_str_list.push_back(
"NO" );
252 const Scalar Mm_N = 14.008e-3;
253 const Scalar Mm_O = 16e-3;
254 const Scalar Mm_N2 = 2.L * Mm_N;
255 const Scalar Mm_O2 = 2.L * Mm_O;
256 const Scalar Mm_NO = Mm_O + Mm_N;
264 VectorXr mass_fractions(n_species);
265 mass_fractions[0] = 0.5;
266 mass_fractions[1] = 0.2;
267 mass_fractions[2] = 0.1;
268 mass_fractions[3] = 0.1;
269 mass_fractions[4] = 0.1;
271 const Scalar R_N2 = Antioch::Constants::R_universal<Scalar>() / Mm_N2;
272 const Scalar R_O2 = Antioch::Constants::R_universal<Scalar>() / Mm_O2;
273 const Scalar R_NO = Antioch::Constants::R_universal<Scalar>() / Mm_NO;
275 const Scalar th0_N2 = 3.39500e+03;
276 const Scalar th0_O2 = 2.23900e+03;
277 const Scalar th0_NO = 2.81700e+03;
280 const Scalar Tv = 1000.0;
282 const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 2;
283 const Scalar ztol = std::numeric_limits<Scalar>::epsilon();
287 Scalar cv_vib_mix = 0.0;
291 Scalar cv_vib_N2 = sm_thermo.
cv_vib (0, Tv);
293 const Scalar expv = exp(th0_N2/Tv);
294 const Scalar expvmi = expv - Scalar(1.0);
295 Scalar cv_vib_N2_true = R_N2*th0_N2*th0_N2*expv/expvmi/expvmi/Tv/Tv;
299 std::cerr << std::scientific << std::setprecision(20);
300 std::cerr <<
"Error: Mismatch in cv_vib for N2."
301 <<
"\n Expected = " << cv_vib_N2_true
302 <<
"\n Computed = " << cv_vib_N2
303 <<
"\n Diff = " << cv_vib_N2_true - cv_vib_N2
308 cv_vib_mix += mass_fractions[0]*cv_vib_N2_true;
313 Scalar cv_vib_O2 = sm_thermo.
cv_vib (1, Tv);
315 const Scalar expv = exp(th0_O2/Tv);
316 const Scalar expvmi = expv - Scalar(1.0);
317 Scalar cv_vib_O2_true = R_O2*th0_O2*th0_O2*expv/expvmi/expvmi/Tv/Tv;
321 std::cerr << std::scientific << std::setprecision(20);
322 std::cerr <<
"Error: Mismatch in cv_vib for O2."
323 <<
"\n Expected = " << cv_vib_O2_true
324 <<
"\n Computed = " << cv_vib_O2
325 <<
"\n Diff = " << cv_vib_O2_true - cv_vib_O2
330 cv_vib_mix += mass_fractions[1]*cv_vib_O2_true;
335 Scalar cv_vib_O = sm_thermo.
cv_vib (2, Tv);
339 std::cerr << std::scientific << std::setprecision(20);
340 std::cerr <<
"Error: Mismatch in cv_vib for O."
341 <<
"\n Expected = " << Scalar(0.0)
342 <<
"\n Computed = " << cv_vib_O
343 <<
"\n Diff = " << cv_vib_O
353 Scalar cv_vib_N = sm_thermo.
cv_vib (3, Tv);
357 std::cerr << std::scientific << std::setprecision(20);
358 std::cerr <<
"Error: Mismatch in cv_vib for N."
359 <<
"\n Expected = " << Scalar(0.0)
360 <<
"\n Computed = " << cv_vib_N
361 <<
"\n Diff = " << cv_vib_N
371 Scalar cv_vib_NO = sm_thermo.
cv_vib (4, Tv);
373 const Scalar expv = exp(th0_NO/Tv);
374 const Scalar expvmi = expv - Scalar(1.0);
375 Scalar cv_vib_NO_true = R_NO*th0_NO*th0_NO*expv/expvmi/expvmi/Tv/Tv;
379 std::cerr << std::scientific << std::setprecision(20);
380 std::cerr <<
"Error: Mismatch in cv_vib for NO."
381 <<
"\n Expected = " << cv_vib_NO_true
382 <<
"\n Computed = " << cv_vib_NO
383 <<
"\n Diff = " << cv_vib_NO_true - cv_vib_NO
388 cv_vib_mix += mass_fractions[4]*cv_vib_NO_true;
393 Scalar cv = sm_thermo.
cv_vib(Tv, mass_fractions);
397 std::cerr << std::scientific << std::setprecision(20);
398 std::cerr <<
"Error: Mismatch in mixture cv_vib."
399 <<
"\n Expected = " << cv_vib_mix
400 <<
"\n Computed = " << cv
401 <<
"\n Diff = " << cv - cv_vib_mix
410 template <
typename Scalar>
412 const Scalar Rs,
const Scalar Te,
unsigned int N )
418 Scalar num=0.0, den=0.0, dnum=0.0, dden=0.0;
420 for (
unsigned int i=0; i<N; ++i)
422 num += theta[i]*
static_cast<Scalar
>(g[i])*exp(-theta[i]/Te);
423 dnum += theta[i]*
static_cast<Scalar
>(g[i])*exp(-theta[i]/Te)*(theta[i]/Te/Te);
425 den +=
static_cast<Scalar
>(g[i])*exp(-theta[i]/Te);
426 dden +=
static_cast<Scalar
>(g[i])*exp(-theta[i]/Te)*(theta[i]/Te/Te);
429 cv = Rs*(dnum/den - num*dden/den/den);
434 template <
typename Scalar>
440 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Eigen::ColMajor> VectorXr;
442 std::vector<std::string> species_str_list;
443 const unsigned int n_species = 2;
444 species_str_list.reserve(n_species);
445 species_str_list.push_back(
"O2" );
446 species_str_list.push_back(
"O" );
448 const Scalar Mm_O = 16.000e-3L;
449 const Scalar Mm_O2 = 2.L * Mm_O;
457 VectorXr mass_fractions( n_species );
458 mass_fractions[0] = 0.9;
459 mass_fractions[1] = 0.1;
461 const Scalar R_O2 = Antioch::Constants::R_universal<Scalar>() / Mm_O2;
462 const Scalar R_O = Antioch::Constants::R_universal<Scalar>() / Mm_O;
465 unsigned int g_O[5] = {5, 3, 1, 5, 1};
466 Scalar theta_O[5] = {0.00000e+00,
472 unsigned int g_O2[7] = {3, 2, 1, 1, 6, 3, 3};
473 Scalar theta_O2[7] = {0.00000e+00,
481 const Scalar Te = 1000.0;
483 const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 8;
485 Scalar cv_el_mix_true = 0.0;
491 Scalar cv_el_O2 = sm_thermo.
cv_el (0, Te);
492 Scalar cv_el_O2_true =
cv_el_compare(g_O2, theta_O2, R_O2, Te, 7);
496 std::cerr << std::scientific << std::setprecision(20);
497 std::cerr <<
"Error: Mismatch in cv_el for O2."
498 <<
"\n Expected = " << cv_el_O2_true
499 <<
"\n Computed = " << cv_el_O2
500 <<
"\n Diff = " << cv_el_O2_true - cv_el_O2
501 <<
"\n Tol = " << tol
506 cv_el_mix_true += mass_fractions[0]*cv_el_O2_true;
511 Scalar cv_el_O = sm_thermo.
cv_el (1, Te);
512 Scalar cv_el_O_true =
cv_el_compare(g_O, theta_O, R_O, Te, 5);
516 std::cerr << std::scientific << std::setprecision(20);
517 std::cerr <<
"Error: Mismatch in cv_el for O."
518 <<
"\n Expected = " << cv_el_O_true
519 <<
"\n Computed = " << cv_el_O
520 <<
"\n Diff = " << cv_el_O_true - cv_el_O
521 <<
"\n Tol = " << tol
526 cv_el_mix_true += mass_fractions[1]*cv_el_O_true;
531 Scalar cv_el = sm_thermo.
cv_el (Te, mass_fractions);
535 std::cerr << std::scientific << std::setprecision(20);
536 std::cerr <<
"Error: Mismatch in cv_el for mixture."
537 <<
"\n Expected = " << cv_el_mix_true
538 <<
"\n Computed = " << cv_el
539 <<
"\n Diff = " << cv_el_mix_true - cv_el
540 <<
"\n Tol = " << tol
550 template <
typename Scalar>
555 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Eigen::ColMajor> VectorXr;
557 std::vector<std::string> species_str_list;
558 const unsigned int n_species = 5;
559 species_str_list.reserve(n_species);
560 species_str_list.push_back(
"N2" );
561 species_str_list.push_back(
"O2" );
562 species_str_list.push_back(
"N" );
563 species_str_list.push_back(
"O" );
564 species_str_list.push_back(
"NO" );
572 VectorXr mass_fractions(5);
573 mass_fractions[0] = 0.5;
574 mass_fractions[1] = 0.2;
575 mass_fractions[2] = 0.1;
576 mass_fractions[3] = 0.1;
577 mass_fractions[4] = 0.1;
583 const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 100;
587 const Scalar Texact = 300.0;
590 const Scalar e_tot = sm_thermo.
e_tot(Texact, mass_fractions);
593 const Scalar T = sm_thermo.
T_from_e_tot(e_tot, mass_fractions);
597 std::cerr << std::scientific << std::setprecision(20);
598 std::cerr <<
"Error: Mismatch in T_from_e_tot."
599 <<
"\n Expected = " << Texact
600 <<
"\n Computed = " << T
601 <<
"\n Diff = " << Texact - T
602 <<
"\n Tol = " << tol
610 const Scalar Texact = 1000.0;
613 const Scalar e_tot = sm_thermo.
e_tot(Texact, mass_fractions);
616 const Scalar T = sm_thermo.
T_from_e_tot(e_tot, mass_fractions);
620 std::cerr << std::scientific << std::setprecision(20);
621 std::cerr <<
"Error: Mismatch in T_from_e_tot."
622 <<
"\n Expected = " << Texact
623 <<
"\n Computed = " << T
624 <<
"\n Diff = " << Texact - T
625 <<
"\n Tol = " << tol
633 const Scalar Texact = 5010.0;
636 const Scalar e_tot = sm_thermo.
e_tot(Texact, mass_fractions);
639 const Scalar T = sm_thermo.
T_from_e_tot(e_tot, mass_fractions);
643 std::cerr << std::scientific << std::setprecision(20);
644 std::cerr <<
"Error: Mismatch in T_from_e_tot."
645 <<
"\n Expected = " << Texact
646 <<
"\n Computed = " << T
647 <<
"\n Diff = " << Texact - T
648 <<
"\n Tol = " << tol
661 int ierr = (test_cv_tr<double>() ||
663 test_cv_tr<float>());
666 ierr += (test_cv_vib<double>() ||
668 test_cv_vib<float>());
671 ierr += (test_cv_el<double>() ||
673 test_cv_el<float>());
676 ierr += (test_T_from_e_tot<double>() ||
678 test_T_from_e_tot<float>());
683 #else // don't have eigen
689 #endif // ANTIOCH_HAVE_EIGEN
CoeffType cv_tr(const unsigned int species) const
enable_if_c< has_size< VectorStateType >::value, typename Antioch::value_type< VectorStateType >::type >::type T_from_e_tot(const typename Antioch::value_type< VectorStateType >::type &e_tot, const VectorStateType &mass_fractions, typename Antioch::value_type< VectorStateType >::type T=-1) const
Scalar cv_el_compare(const unsigned int g[], const Scalar theta[], const Scalar Rs, const Scalar Te, unsigned int N)
StateType cv_el(const unsigned int species, const StateType &Te) const
bool test_relative(const Scalar val, const Scalar truth, const Scalar tol)
StateType e_tot(const unsigned int species, const StateType &T, const StateType &Tv) const
bool test_zero(const Scalar val, const Scalar tol)
StateType cv_vib(const unsigned int species, const StateType &Tv) const
Class storing chemical mixture properties.
Scalar g(const std::vector< Scalar > &thermo, const Scalar &T)