antioch-0.4.0
kinetics_regression.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 // $Id$
28 //
29 //--------------------------------------------------------------------------
30 //--------------------------------------------------------------------------
31 
32 // C++
33 #include <limits>
34 #include <string>
35 #include <vector>
36 
37 // Antioch
38 #include "antioch/vector_utils.h"
39 
43 #include "antioch/reaction_set.h"
45 #include "antioch/cea_thermo.h"
47 
48 
49 template <typename Scalar>
50 int checker(const Scalar & theory, const Scalar & computed, const std::string& words)
51 {
52 
53  int return_flag(0);
54  const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 500;
55 
56  const Scalar rel_error = std::abs( (computed - theory)/theory);
57  if( rel_error > tol )
58  {
59  std::cerr << "Error: Mismatch between theory and regression values in test " << words << std::endl;
60  std::cout << std::scientific << std::setprecision(16)
61  << "theory value = " << theory << std::endl
62  << "computed value = " << computed << std::endl
63  << "relative difference = " << rel_error << std::endl
64  << "tolerance = " << tol << std::endl << std::endl;
65  return_flag = 1;
66  }
67 
68  return return_flag;
69 }
70 
71 
72 template <typename Scalar>
73 int tester(const std::string& input_name)
74 {
75  using std::abs;
76 
77  std::vector<std::string> species_str_list;
78  const unsigned int n_species = 5;
79  species_str_list.reserve(n_species);
80  species_str_list.push_back( "N2" );
81  species_str_list.push_back( "O2" );
82  species_str_list.push_back( "N" );
83  species_str_list.push_back( "O" );
84  species_str_list.push_back( "NO" );
85 
86  Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );
87  Antioch::ReactionSet<Scalar> reaction_set( chem_mixture );
88  Antioch::CEAThermodynamics<Scalar> thermo( chem_mixture );
89 
90  Antioch::read_reaction_set_data_xml<Scalar>( input_name, true, reaction_set );
91 
92  const Scalar T = 1500.0; // K
93  const Scalar P = 1.0e5; // Pa
94  const Antioch::KineticsConditions<Scalar> conditions(T);
95 
96  // Mass fractions
97  std::vector<Scalar> Y(n_species,0.2);
98 
99  const Scalar R_mix = chem_mixture.R(Y); // get R_tot in J.kg-1.K-1
100 
101  const Scalar rho = P/(R_mix*T); // kg.m-3
102 
103  std::vector<Scalar> molar_densities(n_species,0.0);
104  chem_mixture.molar_densities(rho,Y,molar_densities);
105 
106  std::vector<Scalar> h_RT_minus_s_R(n_species);
107  std::vector<Scalar> dh_RT_minus_s_R_dT(n_species);
108 
109  typedef typename Antioch::CEAThermodynamics<Scalar>::template Cache<Scalar> Cache;
110  thermo.h_RT_minus_s_R(Cache(T),h_RT_minus_s_R);
111  thermo.dh_RT_minus_s_R_dT(Cache(T),dh_RT_minus_s_R_dT);
112 
113  Antioch::KineticsEvaluator<Scalar> kinetics( reaction_set, 0 );
114 
115  std::vector<Scalar> omega_dot(n_species);
116  std::vector<Scalar> omega_dot_2(n_species);
117  std::vector<Scalar> omega_dot_3(n_species);
118  std::vector<Scalar> omega_dot_4(n_species);
119  std::vector<Scalar> domega_dot_dT(n_species);
120  std::vector<Scalar> domega_dot_dT_2(n_species);
121 
122  std::vector<std::vector<Scalar> > domega_dot_drho_s(n_species);
123  std::vector<std::vector<Scalar> > domega_dot_drho_s_2(n_species);
124  for( unsigned int s = 0; s < n_species; s++ )
125  {
126  domega_dot_drho_s[s].resize(n_species);
127  domega_dot_drho_s_2[s].resize(n_species);
128  }
129 
130 // backward compatibility
131 
132  kinetics.compute_mass_sources( T , molar_densities, h_RT_minus_s_R, omega_dot);
133 
134  kinetics.compute_mass_sources_and_derivs( T , molar_densities, h_RT_minus_s_R, dh_RT_minus_s_R_dT,
135  omega_dot_2, domega_dot_dT, domega_dot_drho_s );
136 
137 // kinetics conditions
138 
139  kinetics.compute_mass_sources( conditions , molar_densities, h_RT_minus_s_R, omega_dot_3);
140 
141  kinetics.compute_mass_sources_and_derivs( conditions , molar_densities, h_RT_minus_s_R, dh_RT_minus_s_R_dT,
142  omega_dot_4, domega_dot_dT_2, domega_dot_drho_s_2 );
143 
144  for( unsigned int s = 0; s < n_species; s++)
145  {
146  std::cout << std::scientific << std::setprecision(16)
147  << "domega_dot_dT(" << chem_mixture.chemical_species()[s]->species() << ") = "
148  << domega_dot_dT[s] << std::endl;
149  }
150 
151  for( unsigned int s = 0; s < n_species; s++)
152  {
153  for( unsigned int t = 0; t < n_species; t++)
154  {
155  std::cout << std::scientific << std::setprecision(16)
156  << "domega_dot_drho_s(" << chem_mixture.chemical_species()[s]->species()
157  << ", " << chem_mixture.chemical_species()[t]->species() << ") = "
158  << domega_dot_drho_s[s][t] << std::endl;
159  }
160  }
161 
162  int return_flag = 0;
163 
164  // Regression values for omega_dot
165  std::vector<Scalar> omega_dot_reg(n_species);
166  omega_dot_reg[0] = 9.1623705357123753e+04;
167  omega_dot_reg[1] = -3.3462025680272243e+05;
168  omega_dot_reg[2] = -2.1139216712069495e+05;
169  omega_dot_reg[3] = 1.9782018625609628e+05;
170  omega_dot_reg[4] = 2.5656853231019735e+05;
171 
172 
173 // omega_dots tests
174  for( unsigned int s = 0; s < n_species; s++)
175  {
176  return_flag = checker(omega_dot_reg[s],omega_dot_2[s],"omega dot2 of species " + chem_mixture.chemical_species()[s]->species()) || return_flag;
177  return_flag = checker(omega_dot_reg[s],omega_dot_3[s],"omega dot3 of species " + chem_mixture.chemical_species()[s]->species()) || return_flag;
178  return_flag = checker(omega_dot_reg[s],omega_dot_4[s],"omega dot4 of species " + chem_mixture.chemical_species()[s]->species()) || return_flag;
179  }
180 
181  // Regression values for domega_dot_dT
182  std::vector<Scalar> domega_dot_reg_dT(n_species);
183  domega_dot_reg_dT[0] = 1.8014990183270937e+02;
184  domega_dot_reg_dT[1] = -5.2724437115534380e+02;
185  domega_dot_reg_dT[2] = -3.0930094476883017e+02;
186  domega_dot_reg_dT[3] = 3.7972747459781005e+02;
187  domega_dot_reg_dT[4] = 2.7666793949365456e+02;
188 
189  for( unsigned int s = 0; s < n_species; s++)
190  {
191  return_flag = checker(domega_dot_reg_dT[s],domega_dot_dT[s],"domega_dot_dT of species " + chem_mixture.chemical_species()[s]->species()) || return_flag;
192  return_flag = checker(domega_dot_reg_dT[s],domega_dot_dT_2[s],"domega_dot_dT2 of species " + chem_mixture.chemical_species()[s]->species()) || return_flag;
193  }
194 
195  // Regression values for domega_dot_drho_s
196  std::vector<std::vector<Scalar> > domega_dot_reg_drhos(n_species);
197  for( unsigned int s = 0; s < n_species; s++)
198  {
199  domega_dot_reg_drhos[s].resize(n_species);
200  }
201 
202  domega_dot_reg_drhos[0][0] = 1.9675775188085109e+04;
203  domega_dot_reg_drhos[0][1] = 1.7226141262419737e+04;
204  domega_dot_reg_drhos[0][2] = 3.2159299284723610e+06;
205  domega_dot_reg_drhos[0][3] = 1.4765214711933021e+05;
206  domega_dot_reg_drhos[0][4] = 2.3225053279918131e+06;
207 
208  domega_dot_reg_drhos[1][0] = 8.8927385505978492e+03;
209  domega_dot_reg_drhos[1][1] = -9.9560178070099482e+06;
210  domega_dot_reg_drhos[1][2] = -9.8748760140991123e+06;
211  domega_dot_reg_drhos[1][3] = 4.6143036700500813e+05;
212  domega_dot_reg_drhos[1][4] = 8.3487375168772399e+03;
213 
214  domega_dot_reg_drhos[2][0] = -2.2420842426881281e+04;
215  domega_dot_reg_drhos[2][1] = -4.3812843857644886e+06;
216  domega_dot_reg_drhos[2][2] = -6.8343593463263955e+06;
217  domega_dot_reg_drhos[2][3] = -5.4143671040862988e+05;
218  domega_dot_reg_drhos[2][4] = -1.2267997668149246e+06;
219 
220  domega_dot_reg_drhos[3][0] = -1.2028166578920147e+04;
221  domega_dot_reg_drhos[3][1] = 4.9713710400172938e+06;
222  domega_dot_reg_drhos[3][2] = 5.7418898143800552e+06;
223  domega_dot_reg_drhos[3][3] = -9.1121284934572734e+05;
224  domega_dot_reg_drhos[3][4] = 1.2431710353864791e+06;
225 
226  domega_dot_reg_drhos[4][0] = 5.8804952671184686e+03;
227  domega_dot_reg_drhos[4][1] = 9.3487050114947233e+06;
228  domega_dot_reg_drhos[4][2] = 7.7514156175730915e+06;
229  domega_dot_reg_drhos[4][3] = 8.4356704563001888e+05;
230  domega_dot_reg_drhos[4][4] = -2.3472253340802449e+06;
231 
232  for( unsigned int s = 0; s < n_species; s++)
233  {
234  for( unsigned int t = 0; t < n_species; t++)
235  {
236  return_flag = checker(domega_dot_reg_drhos[s][t],domega_dot_drho_s[s][t] , "domega_dot_drhos of species "
237  + chem_mixture.chemical_species()[s]->species()
238  + " with respect to species "
239  + chem_mixture.chemical_species()[t]->species()) || return_flag;
240  return_flag = checker(domega_dot_reg_drhos[s][t],domega_dot_drho_s_2[s][t], "domega_dot_drhos of species "
241  + chem_mixture.chemical_species()[s]->species()
242  + " with respect to species "
243  + chem_mixture.chemical_species()[t]->species()) || return_flag;
244  }
245  }
246 
247 // now some resetting and verifying omega_dot
248  std::string reaction_id("0001");
249  std::vector<std::string> keywords;
250  keywords.push_back("A");
251  Scalar new_value(6e15L); //SI, original is 7e15
252  reaction_set.set_parameter_of_reaction(reaction_id,keywords,new_value);
253  reaction_id = "0002";
254  keywords[0] = "efficiencies";
255  keywords.push_back("O2");
256  new_value = 1.2L;
257  reaction_set.set_parameter_of_reaction(reaction_id,keywords,new_value);
258 
259 //recomputing
260  Antioch::set_zero(omega_dot);
261  kinetics.compute_mass_sources( conditions , molar_densities, h_RT_minus_s_R, omega_dot);
262 
263 // new values, SI
264  omega_dot_reg[0] = 8.9806036413183845e4;
265  omega_dot_reg[1] = -3.3456693672788515e5;
266  omega_dot_reg[2] = -2.0957449817675504e5;
267  omega_dot_reg[3] = 1.9776686618125900e5;
268  omega_dot_reg[4] = 2.5656853231019735e5;
269 
270  for( unsigned int s = 0; s < n_species; s++)
271  {
272  return_flag = checker(omega_dot_reg[s],omega_dot[s] ,"resetted omega dot of species " + chem_mixture.chemical_species()[s]->species()) || return_flag;
273  }
274 
275 // and now a get/set loop
276  reaction_id = "0004";
277  const Scalar val(1.1L);
278  keywords.clear();
279  keywords.push_back("E");
280 // keywords.push_back("cal/mol"); // no, you only get SI
281  reaction_set.set_parameter_of_reaction(reaction_id,keywords,
282  val * reaction_set.get_parameter_of_reaction(reaction_id,keywords) );
283 
284 //recomputing
285  Antioch::set_zero(omega_dot);
286  kinetics.compute_mass_sources( conditions , molar_densities, h_RT_minus_s_R, omega_dot);
287 
288 // new values, SI
289  omega_dot_reg[0] = 1.541307374714467399842142e4;
290  omega_dot_reg[1] = -3.345669367278851525665733e5;
291  omega_dot_reg[2] = -1.723780168437354542966397e5;
292  omega_dot_reg[3] = 1.552808795073360031682657e5;
293  omega_dot_reg[4] = 3.362510003171399296965259e5;
294 
295  for( unsigned int s = 0; s < n_species; s++)
296  {
297  return_flag = checker(omega_dot_reg[s],omega_dot[s] ,"loop-resetted omega dot of species " + chem_mixture.chemical_species()[s]->species()) || return_flag;
298  }
299 
300  return return_flag;
301 }
302 
303 int main(int argc, char* argv[])
304 {
305  // Check command line count.
306  if( argc < 2 )
307  {
308  // TODO: Need more consistent error handling.
309  std::cerr << "Error: Must specify reaction set XML input file." << std::endl;
310  antioch_error();
311  }
312 
313  return (tester<float>(std::string(argv[1])) ||
314  tester<double>(std::string(argv[1])) /* ||
315  tester<long double>(std::string(argv[1]))*/
316  );
317 }
This class encapsulates all the reaction mechanisms considered in a chemical nonequilibrium simulatio...
CoeffType R(const unsigned int s) const
Gas constant for species s in [J/kg-K].
void compute_mass_sources(const KC &conditions, const VectorStateType &molar_densities, const VectorStateType &h_RT_minus_s_R, VectorStateType &mass_sources)
Compute species production/destruction rates per unit volume.
void set_parameter_of_reaction(const std::string &reaction_id, const std::vector< std::string > &keywords, ParamType value)
change a parameter of a reaction
Definition: reaction_set.h:512
#define antioch_error()
int main(int argc, char *argv[])
int tester(const std::string &input_name)
StateType dh_RT_minus_s_R_dT(const Cache< StateType > &cache, unsigned int species) const
We currently need different specializations for scalar vs vector inputs here.
Definition: cea_thermo.h:487
int checker(const Scalar &theory, const Scalar &computed, const std::string &words)
CoeffType get_parameter_of_reaction(const std::string &reaction_id, const std::vector< std::string > &keywords) const
Definition: reaction_set.h:462
void set_zero(_Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &a)
Definition: eigen_utils.h:217
Class to handle computing mass source terms for a given ReactionSet.
X(const unsigned int species, const StateType &M, const StateType &mass_fraction) const template< typename VectorStateType > void X(typename Antioch VectorStateType void molar_densities(const StateType &rho, const VectorStateType &mass_fractions, VectorStateType &molar_densities) const
Class storing chemical mixture properties.
StateType h_RT_minus_s_R(const Cache< StateType > &cache, unsigned int species) const
We currently need different specializations for scalar vs vector inputs here.
Definition: cea_thermo.h:420
void compute_mass_sources_and_derivs(const KC &conditions, const VectorStateType &molar_densities, const VectorStateType &h_RT_minus_s_R, const VectorStateType &dh_RT_minus_s_R_dT, VectorStateType &mass_sources, VectorStateType &dmass_dT, std::vector< VectorStateType > &dmass_drho_s)
Compute species production/destruction rate derivatives.
const std::vector< ChemicalSpecies< CoeffType > * > & chemical_species() const
This class contains the conditions of the chemistry.
We parse the file here, with an exhaustive unit management.

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