antioch-0.4.0
ideal_gas_internal_thermo_unit.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // Antioch - A Gas Dynamics Thermochemistry Library
5 //
6 // Copyright (C) 2014-2016 Paul T. Bauman, Benjamin S. Kirk,
7 // Sylvain Plessis, Roy H. Stonger
8 //
9 // Copyright (C) 2013 The PECOS Development Team
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the Version 2.1 GNU Lesser General
13 // Public License as published by the Free Software Foundation.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
23 // Boston, MA 02110-1301 USA
24 //
25 //-----------------------------------------------------------------------el-
26 
27 // C++
28 #include <cmath>
29 #include <limits>
30 
31 // Antioch
33 
36 #include "antioch/ideal_gas_internal_thermo.h"
37 #include "antioch/nasa_evaluator.h"
38 #include "antioch/cea_curve_fit.h"
40 
41 #include "antioch/vector_utils.h"
42 
43 template <typename Scalar>
44 bool test_zero(const Scalar val, const Scalar tol)
45 {
46  using std::abs;
47 
48  if( abs(val) > tol )
49  return false;
50  else
51  return true;
52 }
53 
54 template <typename Scalar>
55 int test_relative(const Scalar val, const Scalar truth, const Scalar tol, const std::string & words)
56 {
57  using std::abs;
58 
59  bool test = (test_zero(truth,tol))?!test_zero(val,tol):(abs( (val-truth)/truth ) > tol );
60  Scalar diff = (test_zero(truth,tol))?val:abs( (val-truth)/truth );
61  if(test)
62  {
63  std::cerr << std::scientific << std::setprecision(20);
64  std::cerr << "Error: Mismatch in " << words
65  << "\n Expected = " << truth
66  << "\n Computed = " << val
67  << "\n Relative diff = " << diff
68  << "\n Tolerance = " << tol
69  << std::endl;
70  return 1;
71  }else
72  {
73  return 0;
74  }
75 }
76 
77 template <typename Scalar>
78 int test_molecule(unsigned int spec, const Scalar & n_tr_dofs, const Scalar & R_spec,
79  const Scalar & cv_over_R, const Scalar & T,
80  const Antioch::IdealGasInternalThermo< Antioch::NASAEvaluator<Scalar, Antioch::CEACurveFit<Scalar> >,
81  Scalar
82  > & thermo,
83  const std::string & name)
84 {
85  const Scalar tol = (std::numeric_limits<Scalar>::epsilon() * 2 < 5e-17L)?5e-17L:
86  std::numeric_limits<Scalar>::epsilon() * 2;
87 
88  int return_flag = 0;
89  // values over R are:
90  // cv_tr / R = n_tr_dofs
91  // cv_trans / R = 1.5
92  // cv_rot / R = max(n_tr_dofs - 1.5,0)
93  // cv_vib / R = cp / R - 1 - n_tr_dofs
94 
95  Scalar cv_rot = (n_tr_dofs > Scalar(1.5))?n_tr_dofs - Scalar(1.5):Scalar(0.);
96  Scalar cv_vib = (n_tr_dofs < 2.)?0.L:cv_over_R - n_tr_dofs;
97 
98  return_flag = test_relative(thermo.cv_tr_over_R(spec), n_tr_dofs, tol, "cv_tr_over_R of " + name) || return_flag;
99  return_flag = test_relative(thermo.cv_tr(spec), R_spec * n_tr_dofs, tol, "cv_tr of " + name) || return_flag;
100  return_flag = test_relative(thermo.cv_trans_over_R(spec), Scalar(1.5), tol, "cv_trans_over_R of " + name) || return_flag;
101  return_flag = test_relative(thermo.cv_trans(spec), R_spec * Scalar(1.5), tol, "cv_trans of " + name) || return_flag;
102  return_flag = test_relative(thermo.cv_rot_over_R(spec), cv_rot, tol, "cv_rot_over_R of " + name) || return_flag;
103  return_flag = test_relative(thermo.cv_rot(spec), R_spec * cv_rot, tol, "cv_rot of " + name) || return_flag;
104 // vibration requires CEA fits, tolerance is somewhat loose...
105  return_flag = test_relative(thermo.cv_vib_over_R(spec,T), cv_vib, Scalar(200.L) * tol, "cv_vib_over_R of " + name) || return_flag;
106  return_flag = test_relative(thermo.cv_vib(spec,T), R_spec * cv_vib, Scalar(200.L) * tol, "cv_vib of " + name) || return_flag;
107 
108  return return_flag;
109 }
110 template <typename Scalar>
111 int tester()
112 {
113  const Scalar Mm_N = 14.008e-3; //in SI kg/mol
114  const Scalar Mm_O = 16e-3; //in SI kg/mol
115  const Scalar Mm_N2 = 2.L * Mm_N; //in SI kg/mol
116  const Scalar Mm_O2 = 2.L * Mm_O; //in SI kg/mol
117  const Scalar Mm_NO = Mm_O + Mm_N; //in SI kg/mol
118 
119  std::vector<std::string> species_str_list;
120  const unsigned int n_species = 5;
121  species_str_list.reserve(n_species);
122  species_str_list.push_back( "N2" );
123  species_str_list.push_back( "O2" );
124  species_str_list.push_back( "N" );
125  species_str_list.push_back( "O" );
126  species_str_list.push_back( "NO" );
127 
128  Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );
129 
130 // required for Cv, we take default CEA
134 
135  Antioch::IdealGasInternalThermo< Antioch::NASAEvaluator<Scalar, Antioch::CEACurveFit<Scalar> >,
136  Scalar > id_thermo( nasa_thermo, chem_mixture );
137 
138  // Mass fractions
139  std::vector<Scalar> mass_fractions( 5, 0.2 );
140  mass_fractions[0] = 0.5;
141  mass_fractions[1] = 0.2;
142  mass_fractions[2] = 0.1;
143  mass_fractions[3] = 0.1;
144  mass_fractions[4] = 0.1;
145 
146  const Scalar R_N2 = Antioch::Constants::R_universal<Scalar>() / Mm_N2;
147  const Scalar R_O2 = Antioch::Constants::R_universal<Scalar>() / Mm_O2;
148  const Scalar R_N = Antioch::Constants::R_universal<Scalar>() / Mm_N;
149  const Scalar R_O = Antioch::Constants::R_universal<Scalar>() / Mm_O;
150  const Scalar R_NO = Antioch::Constants::R_universal<Scalar>() / Mm_NO;
151 
152  int return_flag = 0;
153 
154  Scalar T = 300.1;
155 
156  // N2
157  return_flag = test_molecule(0,Scalar(2.5),R_N2,nasa_thermo.cv_over_R(Antioch::TempCache<Scalar>(T),0), T, id_thermo, "N2") || return_flag;
158  return_flag = test_molecule(1,Scalar(2.5),R_O2,nasa_thermo.cv_over_R(Antioch::TempCache<Scalar>(T),1), T, id_thermo, "O2") || return_flag;
159  return_flag = test_molecule(2,Scalar(1.5),R_N, nasa_thermo.cv_over_R(Antioch::TempCache<Scalar>(T),2), T, id_thermo, "N") || return_flag;
160  return_flag = test_molecule(3,Scalar(1.5),R_O, nasa_thermo.cv_over_R(Antioch::TempCache<Scalar>(T),3), T, id_thermo, "O") || return_flag;
161  return_flag = test_molecule(4,Scalar(2.5),R_NO,nasa_thermo.cv_over_R(Antioch::TempCache<Scalar>(T),4), T, id_thermo, "NO") || return_flag;
162 
163 
164  return return_flag;
165 }
166 
167 
168 int main()
169 {
170 
171  int ierr = (tester<double>() ||
172  tester<long double>() ||
173  tester<float>());
174 
175  return ierr;
176 }
bool test_zero(const Scalar val, const Scalar tol)
void read_nasa_mixture_data(NASAThermoMixture< NumericType, CurveType > &thermo, const std::string &filename=DefaultSourceFilename::thermo_data(), ParsingType=ASCII, bool verbose=true)
This class only differs from NASA9CurveFit in the construction.
Definition: ascii_parser.h:72
int test_relative(const Scalar val, const Scalar truth, const Scalar tol, const std::string &words)
static const std::string & thermo_data()
StateType cv_over_R(const TempCache< StateType > &cache, unsigned int species) const
Cv over R, from ideal gas,.
Class storing chemical mixture properties.
int test_molecule(unsigned int spec, const Scalar &n_tr_dofs, const Scalar &R_spec, const Scalar &cv_over_R, const Scalar &T, const Antioch::IdealGasInternalThermo< Antioch::NASAEvaluator< Scalar, Antioch::CEACurveFit< Scalar > >, Scalar > &thermo, const std::string &name)

Generated on Thu Jul 7 2016 11:09:46 for antioch-0.4.0 by  doxygen 1.8.8