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 #ifndef ANTIOCH_CHEMKIN_PARSER_H
27 #define ANTIOCH_CHEMKIN_PARSER_H
28 
29 //Antioch
30 #include "antioch/antioch_asserts.h"
31 #include "antioch/string_utils.h"
32 #include "antioch/parser_base.h"
33 #include "antioch/parsing_enum.h"
34 #include "antioch/units.h"
35 #include "antioch/chemkin_definitions.h"
36 
37 //C++
38 #include <fstream>
39 #include <string>
40 #include <vector>
41 #include <map>
42 
43 namespace Antioch{
44 
45 
46   template <typename NumericType>
47   class ChemicalMixture;
48 
49   template <typename NumericType, typename CurveType>
50   class NASAThermoMixture;
51 
52   template <typename NumericType>
53   class NASA7CurveFit;
54 
55   template <typename NumericType>
56   class NASA9CurveFit;
57 
58   // backward compatibility
59   template <typename NumericType>
60   class CEACurveFit;
61 
62   /*! ChemKin format file reader
63    *
64    * defaults unit:
65    *  - A: cm-molecule or cm-mol (see read_reaction_set_data.h for addition of s-1)
66    *  - beta: no units
67    *  - Ea: cal/mol
68    *
69    * There are no other kinetics paramters for rate constant. Chemical processes
70    * are:
71    *  - Elementary
72    *  - Duplicate
73    *  - Three-Body
74    *  - Lindemann falloff
75    *  - Troe falloff
76    *  - SRI falloff (not supported)
77    */
78   template <typename NumericType = double>
79   class ChemKinParser: public ParserBase<NumericType>
80   {
81         public:
82           ChemKinParser(const std::string &filename, bool verbose = true);
83           ~ChemKinParser();
84 
85          void change_file(const std::string & filename);
86 
87 ////////////// species
88 
89          /*! read SPECIES block*/
90          const std::vector<std::string> species_list();
91 
92         // reads the mandatory data, not valid yet in ChemKin
93 //        void read_chemical_species(ChemicalMixture<NumericType> & chem_mixture);
94 
95         // reads the vibrational data, not valid yet in ChemKin
96 //        void read_vibrational_data(ChemicalMixture<NumericType> & chem_mixture);
97 
98         // reads the electronic data, not valid yet in ChemKin
99 //        void read_electronic_data(ChemicalMixture<NumericType> & chem_mixture);
100 
101 ////////////////// thermo
102 
103 //global overload
104 // it seems that they're all linked in
105 // a way so they shadow themselves
106 // => we need to implement all or nothing
107 
108     //! reads the thermo, NASA generalist, no templates for virtual
read_thermodynamic_data(NASAThermoMixture<NumericType,NASA7CurveFit<NumericType>> & thermo)109     void read_thermodynamic_data(NASAThermoMixture<NumericType, NASA7CurveFit<NumericType> >& thermo)
110     {this->read_thermodynamic_data_root(thermo);}
111 
112     //! reads the thermo, NASA generalist, no templates for virtual
read_thermodynamic_data(NASAThermoMixture<NumericType,NASA9CurveFit<NumericType>> &)113     void read_thermodynamic_data(NASAThermoMixture<NumericType, NASA9CurveFit<NumericType> >& /*thermo*/)
114     {antioch_error_msg("ERROR: ChemKin Parsing only supports parsing for NASA7CurveFit!");}
115 
116     //! reads the thermo, NASA generalist, no templates for virtual
read_thermodynamic_data(NASAThermoMixture<NumericType,CEACurveFit<NumericType>> &)117     void read_thermodynamic_data(NASAThermoMixture<NumericType, CEACurveFit<NumericType> >& /*thermo*/)
118     {antioch_error_msg("ERROR: ChemKin Parsing only supports parsing for NASA7CurveFit!");}
119 
120 
121 ///////////////// kinetics
122 
123          /*! Read header of file, go to interesting part*/
124          bool initialize();
125 
126          /*! go to next reaction*/
127          bool reaction();
128 
129          /*! go to next rate constant*/
130          bool rate_constant(const std::string & /* kinetics_model */);
131 
132          /*! return true if there's a Troe block*/
133          bool Troe() const;
134 
135          /*! return reaction id, 0 if not provided*/
136          const std::string reaction_id() const;
137 
138          /*! return reaction equation */
139          const std::string reaction_equation() const;
140 
141          /*! return reaction chemical process*/
142          const std::string reaction_chemical_process() const;
143 
144          /*! return reaction kinetics model*/
145          const std::string reaction_kinetics_model(const std::vector<std::string> & /*kinetics_models*/) const;
146 
147          /*! return reversible state*/
148          bool reaction_reversible() const;
149 
150          /*! return pairs of reactants and stoichiometric coefficients*/
151          bool reactants_pairs(std::vector<std::pair<std::string,int> > & reactants_pair) const;
152 
153          /*! return pairs of products and stoichiometric coefficients*/
154          bool products_pairs(std::vector<std::pair<std::string,int> > & products_pair) const;
155 
156          /*! return a map between reactants' name and found partial orders */
157          const std::map<std::string,NumericType> reactants_orders() const;
158 
159          /*! return a map between products' name and found partial orders */
160          const std::map<std::string,NumericType> products_orders() const;
161 
162          /*! return true if "name" attribute is found with value "k0"*/
163          bool is_k0(unsigned int nrc, const std::string & kin_model) const;
164 
165          /*! return index of k0 (0 or 1)*/
166          unsigned int where_is_k0(const std::string & /*kin_model*/) const;
167 
168          /*! return true if pre exponentiel coefficient*/
169          bool rate_constant_preexponential_parameter(    NumericType & A,    std::string & A_unit,    std::string & def_unit) const;
170 
171          /*! return true if beta coefficient*/
172          bool rate_constant_power_parameter(             NumericType & b,    std::string & b_unit,    std::string & def_unit) const;
173 
174          /*! return true if activation energie*/
175          bool rate_constant_activation_energy_parameter(NumericType & Ea,   std::string & Ea_unit,   std::string & def_unit) const;
176 
177          /*! return true if D coefficient*/
178          bool rate_constant_Berthelot_coefficient_parameter(NumericType & D,    std::string & D_unit,    std::string & def_unit) const;
179 
180          /*! return true if Tref*/
181          bool rate_constant_Tref_parameter(              NumericType & Tref, std::string & Tref_unit, std::string & def_unit) const;
182 
183          /*! return true if lambda*/
184          bool rate_constant_lambda_parameter(       std::vector<NumericType> & lambda, std::string & lambda_unit, std::string & def_unit) const;
185 
186          /*! return true if sigma*/
187          bool rate_constant_cross_section_parameter(std::vector<NumericType> & sigma,  std::string & sigma_unit,  std::string & def_unit) const;
188 
189          /*! return true if a Kooij is called Arrhenuis*/
190          bool verify_Kooij_in_place_of_Arrhenius() const;
191 
192          /*! return true if efficiencies are found*/
193          bool efficiencies(std::vector<std::pair<std::string,NumericType> > & par_values) const;
194 
195          /*! return true is alpha*/
196          bool Troe_alpha_parameter(NumericType & alpha, std::string & alpha_unit, std::string & def_unit) const;
197 
198          /*! return true is alpha*/
199          bool Troe_T1_parameter(   NumericType & T1,    std::string & T1_unit,    std::string & def_unit) const;
200 
201          /*! return true is alpha*/
202          bool Troe_T2_parameter(   NumericType & T2,    std::string & T2_unit,    std::string & def_unit) const;
203 
204          /*! return true is alpha*/
205          bool Troe_T3_parameter(   NumericType & T3,    std::string & T3_unit,    std::string & def_unit) const;
206 
207         private:
208 
209           //! reads the thermo, NASA generalist
210           template <typename CurveType>
211           void read_thermodynamic_data_root(NASAThermoMixture<NumericType, CurveType >& thermo);
212 
213           /*! Convenient method */
214           void parse_a_line(const std::string & line);
215 
216           /*! Convenient method */
217           void parse_equation_coef(const std::string & line);
218 
219           /*! Convenient method */
220           void parse_reversible_parameters(const std::string & line);
221 
222           /*! Convenient method */
223           void parse_equation(std::string &equation);
224 
225           /*! Convenient method */
226           void parse_coefficients_line(const std::string &line);
227 
228           /*! Convenient method */
229           void parse_forward_orders(const std::string & line);
230 
231           /*! Convenient method */
232           void parse_backward_orders(const std::string & line);
233 
234           /*! Convenient method */
235           void parse_orders(const std::string & line, std::vector<std::pair<std::string, NumericType> > & reaction_orders);
236 
237           /*! Convenient method */
238           std::pair<std::string,NumericType> parse_molecule(const std::string & molecule);
239 
240           /*! Convenient method */
241           bool is_real_number(const char & c) const;
242 
243           /*! if stoichiometry is real, make them integer*/
244           void rescale_stoichiometry();
245 
246           /*! check if the stoichiometric coef is an integer */
247           bool after_coma_digits(NumericType number) const;
248 
249           /*! look for q when given r = p / q*/
250           unsigned int factor_to_int(NumericType number) const;
251 
252           /*! verify if line is a new reaction*/
253           bool next_reaction(const std::string & line);
254 
255           /*! finding next line that might be a reaction */
256           bool next_meaningful_line(std::string & line);
257 
258           /*! Never use default constructor*/
259           ChemKinParser();
260           std::ifstream                    _doc;
261 
262 
263           bool                             _reversible;
264           unsigned int                     _nrates; // total number of rates
265           unsigned int                     _crates; // current place
266 
267           unsigned int                     _pow_unit; // for A unit
268 
269           // ChemKin allows real stoichiometric coefficients
270           std::vector<std::pair<std::string,NumericType> > _reactants;
271           std::vector<std::pair<std::string,NumericType> > _products;
272 
273           std::vector<std::pair<std::string,NumericType> > _reactants_orders;
274           std::vector<std::pair<std::string,NumericType> > _products_orders;
275 
276           std::string                      _equation;
277           std::string                      _chemical_process;
278           std::string                      _kinetics_model;
279 
280           std::vector<NumericType>         _A;
281           std::vector<NumericType>         _b;
282           std::vector<NumericType>         _Ea;
283           std::vector<NumericType>         _D;     // ChemKin don't use it, but whatever, let's generalize, just in case
284 
285           std::vector<std::pair<std::string,NumericType> > _efficiencies;
286 
287           NumericType                      _Tref;  // ChemKin don't use it, but whatever, let's generalize, just in case
288           NumericType                      _Troe_alpha;
289           NumericType                      _Troe_T1;
290           NumericType                      _Troe_T2;
291           NumericType                      _Troe_T3;
292 
293           std::map<ParsingKey,std::string> _map;
294           std::map<ParsingKey,std::string> _default_unit;
295 
296           std::map<std::string,std::string> _unit_custom_ea;
297           std::map<std::string,std::string> _unit_custom_A;
298 
299           std::string _cached_line;
300           bool        _duplicate_process;
301           bool        _next_is_reverse;
302 
303           const ChemKinDefinitions _spec;
304 
305   };
306 
307   template <typename NumericType>
308   inline
Troe()309   bool ChemKinParser<NumericType>::Troe() const
310   {
311       return (_chemical_process.find("TroeFalloff") != std::string::npos);
312   }
313 
314   template <typename NumericType>
315   inline
reaction_id()316   const std::string ChemKinParser<NumericType>::reaction_id() const
317   {
318      return _equation;
319   }
320 
321   template <typename NumericType>
322   inline
reaction_equation()323   const std::string ChemKinParser<NumericType>::reaction_equation() const
324   {
325      return _equation;
326   }
327 
328   template <typename NumericType>
329   inline
reaction_chemical_process()330   const std::string ChemKinParser<NumericType>::reaction_chemical_process() const
331   {
332       return _chemical_process;
333   }
334 
335   template <typename NumericType>
336   inline
reaction_reversible()337   bool ChemKinParser<NumericType>::reaction_reversible() const
338   {
339      return _reversible;
340   }
341 
342   template <typename NumericType>
343   inline
reaction_kinetics_model(const std::vector<std::string> &)344   const std::string ChemKinParser<NumericType>::reaction_kinetics_model(const std::vector<std::string> & /*kinetics_models*/) const
345   {
346       return _kinetics_model;
347   }
348 
349   template <typename NumericType>
350   inline
is_k0(unsigned int nrc,const std::string &)351   bool ChemKinParser<NumericType>::is_k0(unsigned int nrc, const std::string & /*kin_model*/) const
352   {
353     // k0 is always the first, explicit in ChemKin
354       return (nrc == 0);
355   }
356 
357   template <typename NumericType>
358   inline
where_is_k0(const std::string &)359   unsigned int ChemKinParser<NumericType>::where_is_k0(const std::string & /*kin_model*/) const
360   {
361      return 0;
362   }
363 
364   template <typename NumericType>
365   inline
rate_constant_Berthelot_coefficient_parameter(NumericType &,std::string &,std::string &)366   bool ChemKinParser<NumericType>::rate_constant_Berthelot_coefficient_parameter(NumericType & /*D*/, std::string & /*D_unit*/, std::string & /*def_unit*/) const
367   {
368       return false; //not a chemkin model
369   }
370 
371   template <typename NumericType>
372   inline
rate_constant_lambda_parameter(std::vector<NumericType> &,std::string &,std::string &)373   bool ChemKinParser<NumericType>::rate_constant_lambda_parameter(std::vector<NumericType> & /*lambda*/, std::string & /*lambda_unit*/, std::string & /*def_unit*/) const
374   {
375       return false; //not a supported chemkin model yet
376   }
377 
378   template <typename NumericType>
379   inline
rate_constant_cross_section_parameter(std::vector<NumericType> &,std::string &,std::string &)380   bool ChemKinParser<NumericType>::rate_constant_cross_section_parameter(std::vector<NumericType> & /*sigma*/, std::string & /*sigma_unit*/, std::string & /*def_unit*/) const
381   {
382       return false; //not a supported chemkin model yet
383   }
384 
385   template <typename NumericType>
386   inline
verify_Kooij_in_place_of_Arrhenius()387   bool ChemKinParser<NumericType>::verify_Kooij_in_place_of_Arrhenius() const
388   {
389       return false;
390   }
391 
392 }//end namespace Antioch
393 
394 #endif
395