41 template <
typename NumericType>
43 :
ParserBase<NumericType>(
"ChemKin",filename,verbose,
"!"),
44 _doc(filename.c_str()),
45 _duplicate_process(false),
46 _next_is_reverse(false)
50 std::cerr <<
"ERROR: unable to load ChemKin file " << filename << std::endl;
54 if(this->
verbose())std::cout <<
"Having opened file " << filename << std::endl;
98 template <
typename NumericType>
104 template <
typename NumericType>
108 _doc.open(filename.c_str());
112 std::cerr <<
"ERROR: unable to load ChemKin file " << filename << std::endl;
116 if(this->verbose())std::cout <<
"Having opened file " << filename << std::endl;
119 template <
typename NumericType>
135 std::vector<std::string> keywords;
137 if(nw == 0)keywords.push_back(line);
138 for(
unsigned int k = 1; k < keywords.size(); k++)
140 if(_unit_custom_ea.count(keywords[k]))
143 }
else if(_unit_custom_A.count(keywords[k]))
148 antioch_parsing_error(
"ChemKin parser: I don't have ChemKin supporting this word as a unit:\n" + keywords[k]);
156 template <
typename NumericType>
171 std::vector<std::string> species;
173 while(line.find(_spec.end_tag()) == std::string::npos)
175 std::vector<std::string> tmp;
179 species.push_back(line);
182 for(
unsigned int i = 0; i < tmp.size(); i++)
184 species.push_back(tmp[i]);
193 template <
typename NumericType>
198 if(!_next_is_reverse)
203 _duplicate_process =
false;
207 _kinetics_model =
"Kooij";
208 _chemical_process =
"Elementary";
211 _efficiencies.clear();
215 _reactants_orders.clear();
216 _products_orders.clear();
219 _next_is_reverse =
false;
223 _duplicate_process =
false;
227 _kinetics_model =
"Kooij";
228 _chemical_process =
"Elementary";
231 _efficiencies.clear();
234 std::vector<std::pair<std::string,NumericType> > tmp(_reactants);
235 std::vector<std::pair<std::string,NumericType> > tmp_o(_reactants_orders);
236 _reactants = _products;
237 _reactants_orders = _products_orders;
239 _products_orders = tmp_o;
243 std::string str_delim = _spec.delim().at(delim);
244 std::size_t lim = _equation.find(str_delim);
245 std::string reac_to_prod = _equation.substr(0,lim);
246 std::string prod_to_reac = _equation.substr(lim + str_delim.size(), std::string::npos);
247 _equation = prod_to_reac + str_delim + reac_to_prod;
264 if(_cached_line.empty())
266 reac = this->next_meaningful_line(line);
275 while(!this->next_reaction(line))
277 if(line.find(_spec.end_tag()) != std::string::npos || _doc.eof())
283 if(line.find(_spec.comment()) != std::string::npos)line.erase(line.find(_spec.comment()),std::string::npos);
285 this->parse_a_line(line);
287 this->next_meaningful_line(line);
294 template <
typename NumericType>
298 return (_crates <= _nrates);
301 template <
typename NumericType>
304 reactants_pair.clear();
305 reactants_pair.resize(_reactants.size());
307 for(
unsigned int i = 0; i < _reactants.size(); i++)
309 reactants_pair[i] = std::make_pair(_reactants[i].first,(
int)_reactants[i].second);
312 return !(_reactants.empty());
315 template <
typename NumericType>
318 products_pair.clear();
319 products_pair.resize(_products.size());
320 for(
unsigned int i = 0; i < _products.size(); i++)
322 products_pair[i] = std::make_pair(_products[i].first,(
int)_products[i].second);
324 return !(_products.empty());
327 template <
typename NumericType>
330 std::map<std::string,NumericType> orders;
331 for(
unsigned int s = 0; s < _reactants_orders.size(); s++)
333 orders.insert(_reactants_orders[s]);
338 template <
typename NumericType>
341 std::map<std::string,NumericType> orders;
342 for(
unsigned int s = 0; s < _products_orders.size(); s++)
344 orders.insert(_products_orders[s]);
349 template <
typename NumericType>
352 if(_crates <= _A.size())
361 int mult = (_chemical_process.find(
"Falloff") != std::string::npos && _crates == 1)?_pow_unit+1:_pow_unit;
372 return (_crates <= _A.size());
375 template <
typename NumericType>
378 if(_crates <= _b.size())
386 return (_crates <= _b.size());
389 template <
typename NumericType>
392 if(_crates <= _Ea.size())
400 return (_crates <= _Ea.size());
403 template <
typename NumericType>
408 def_unit = Tref_unit;
409 return (_crates <= _b.size());
412 template <
typename NumericType>
415 par_values = _efficiencies;
416 return !_efficiencies.empty();
419 template <
typename NumericType>
424 def_unit = alpha_unit;
429 template <
typename NumericType>
439 template <
typename NumericType>
446 return (_Troe_T2 > 0.);
449 template <
typename NumericType>
459 template <
typename NumericType>
462 std::string capital_line(line);
463 std::transform(capital_line.begin(),capital_line.end(), capital_line.begin(),::toupper);
466 if(line.find(_spec.delim().at(_spec.REVERSIBLE)) != std::string::npos)
468 this->parse_equation_coef(line);
472 }
else if(capital_line.find(_spec.reversible()) != std::string::npos)
477 this->parse_reversible_parameters(line);
478 _next_is_reverse =
false;
481 _next_is_reverse =
true;
485 }
else if(capital_line.find(_spec.duplicate()) != std::string::npos)
487 _chemical_process =
"Duplicate";
488 _duplicate_process =
true;
493 this->parse_forward_orders(line);
497 this->parse_backward_orders(line);
499 }
else if(line.find(_spec.parser()) != std::string::npos)
501 if(_chemical_process.find(
"Falloff") != std::string::npos &&
502 _chemical_process.find(
"ThreeBody") == std::string::npos)_chemical_process +=
"ThreeBody";
503 this->parse_coefficients_line(line);
510 template <
typename NumericType>
514 std::vector<std::string> out;
516 if(out.size() < 4)
antioch_parsing_error(
"ChemKin parser: unrecognized reaction input line:\n" + line);
519 _Ea.push_back(std::atof(out[out.size()-1].c_str()));
520 _b.push_back( std::atof(out[out.size()-2].c_str()));
521 _A.push_back( std::atof(out[out.size()-3].c_str()));
525 std::string equation;
526 for(
unsigned int i = 0; i < out.size() - 3; i++)
533 if(_reactants.empty())this->parse_equation(equation);
536 template <
typename NumericType>
541 std::vector<std::string> out;
543 if(out.size() < 2)
antioch_parsing_error(
"ChemKin parser: unrecognized reversible reaction parameters input line:\n" + line);
545 std::vector<std::string> pars;
547 if(pars.size() < 3)
antioch_parsing_error(
"ChemKin parser: unrecognized reversible reaction parameters input line:\n" + line);
550 _A.push_back( std::atof(pars[0].c_str()));
551 _b.push_back( std::atof(pars[1].c_str()));
552 _Ea.push_back(std::atof(pars[2].c_str()));
555 template <
typename NumericType>
558 _equation = equation;
566 _chemical_process =
"LindemannFalloff";
574 std::vector<std::string> out;
582 equation.insert(equation.find(_spec.delim().at(delim)) + _spec.delim().at(delim).size(),_spec.delim().at(
ChemKinDefinitions::PLUS));
586 if(out.size() < 3)
antioch_parsing_error(
"ChemKin parser: unrecognized reaction equation:\n" + equation);
594 for(
unsigned int i = 0; i < out.size(); i++)
596 if(out[i] == _spec.delim().at(delim))
603 if(_chemical_process.find(
"Falloff") != std::string::npos)
604 std::cerr <<
"WARNING: ChemKin parser: it seems you want both a falloff and a three-body reaction in your equation:\n" << equation << std::endl;
606 _chemical_process =
"ThreeBody";
616 while(out[i+j].empty())
623 (prod)?_products.push_back(this->parse_molecule(out[i]))
625 _reactants.push_back(this->parse_molecule(out[i]));
632 for(
unsigned int i = 0; i < _reactants.size(); i++)
634 if(this->after_coma_digits(_reactants[i].second))
642 for(
unsigned int i = 0; i < _products.size(); i++)
644 if(this->after_coma_digits(_products[i].second))
652 if(real)this->rescale_stoichiometry();
655 _reactants_orders = _reactants;
656 _products_orders = _products;
659 for(
unsigned int r = 0; r < _reactants.size(); r++)
661 _pow_unit += (
unsigned int)_reactants[r].second;
664 if(_chemical_process ==
"ThreeBody")_pow_unit++;
667 template <
typename NumericType>
672 while(this->is_real_number(molecule[pos]))pos++;
674 NumericType stoi = (pos == 0)?1.:std::atof(molecule.substr(0,pos+1).c_str());
676 return std::make_pair(molecule.substr(pos,std::string::npos),stoi);
679 template <
typename NumericType>
682 return (c ==
'0' || c ==
'1' || c ==
'2' ||
683 c ==
'3' || c ==
'4' || c ==
'5' ||
684 c ==
'6' || c ==
'7' || c ==
'8' ||
685 c ==
'9' || c ==
'.');
689 template <
typename NumericType>
693 std::vector<std::string> out;
695 out.erase(out.begin());
697 std::vector< std::pair<std::string, NumericType> > orders;
698 for(
unsigned int i = 0; i < out.size(); i++)
700 std::vector<std::string> you;
703 NumericType order = std::atof(you[1].c_str());
704 orders.push_back(std::make_pair(you[0],order));
708 for(
unsigned int s = 0; s < reaction_orders.size(); s++)
712 for(i = 0; i < orders.size(); i++)
714 if(orders[i].first == reaction_orders[s].first)
716 reaction_orders[s] = orders[i];
723 template <
typename NumericType>
726 this->parse_orders(line, _reactants_orders);
729 template <
typename NumericType>
732 this->parse_orders(line, _products_orders);
735 template <
typename NumericType>
738 std::vector<std::string> out;
746 std::vector<std::string> troe_par;
748 if(troe_par.size() < 3)
antioch_parsing_error(
"ChemKin parser: Troe parameters error while reading:\n" + line);
750 _Troe_alpha = std::atof(troe_par[0].c_str());
751 _Troe_T3 = std::atof(troe_par[1].c_str());
752 _Troe_T1 = std::atof(troe_par[2].c_str());
753 _Troe_T2 = (troe_par.size() == 4)?std::atof(troe_par[3].c_str()):-1.L;
755 _chemical_process =
"TroeFalloff";
760 std::vector<std::string> k0_par;
762 if(k0_par.size() != 3)
antioch_parsing_error(
"ChemKin parser: Falloff k0 parameters error while reading:\n" + line);
764 _A.insert( _A.begin(),std::atof( k0_par[0].c_str()));
765 _b.insert( _b.begin(),std::atof( k0_par[1].c_str()));
766 _Ea.insert(_Ea.begin(),std::atof(k0_par[2].c_str()));
770 }
else if(_chemical_process.find(
"ThreeBody") != std::string::npos)
773 for(
unsigned int i = 0; i < out.size(); i++)
776 out[i].erase(out[i].begin(), std::find_if(out[i].begin(), out[i].end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
778 out[i].erase(std::find_if(out[i].rbegin(), out[i].rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), out[i].end());
782 out.erase(out.begin() + i);
787 for(
unsigned int c = 0; c < out.size(); c += 2)
789 _efficiencies.push_back(std::make_pair( out[c], std::atof(out[c+1].c_str())));
795 template <
typename NumericType>
801 std::vector<unsigned int> not_int_factor;
802 for(
unsigned int i = 0; i < _reactants.size(); i++)
804 if(this->after_coma_digits(_reactants[i].second))
806 unsigned int fac = this->factor_to_int(_reactants[i].second);
808 for(i = 0; i < not_int_factor.size(); i++)
810 if(fac == not_int_factor[i])
break;
812 if(i < not_int_factor.size() - 1)not_int_factor.push_back(fac);
815 for(
unsigned int i = 0; i < _products.size(); i++)
817 if(this->after_coma_digits(_products[i].second))
819 unsigned int fac = this->factor_to_int(_products[i].second);
821 for(i = 0; i < not_int_factor.size(); i++)
823 if(fac == not_int_factor[i])
break;
825 if(i < not_int_factor.size() - 1)not_int_factor.push_back(fac);
832 unsigned int factor(1);
833 for(
unsigned int i = 0; i < not_int_factor.size(); i++)
835 factor *= not_int_factor[i];
839 for(
unsigned int i = 0; i < _reactants.size(); i++)
841 _reactants[i].second *= (NumericType)factor;
843 for(
unsigned int i = 0; i < _products.size(); i++)
845 _products[i].second *= (NumericType)factor;
849 template <
typename NumericType>
853 unsigned int down(2);
854 const unsigned int limit(150);
855 while(this->after_coma_digits(number * (NumericType) down))
860 std::stringstream os;
861 os <<
"real is " << number <<
" and multiplicative factor limit is " << limit;
869 template <
typename NumericType>
873 const NumericType eps(1e-3);
874 return (std::abs(number - std::floor(number)) > eps);
877 template <
typename NumericType>
882 input_line.find(_spec.end_tag()) != std::string::npos) out =
true;
884 if(_next_is_reverse) out =
true;
886 if(input_line == _cached_line || _cached_line.empty()) out =
false;
891 std::vector<std::string> inputs;
893 if(inputs.size() < 4)
antioch_parsing_error(
"ChemKin parser: unrecognized reaction input line:\n" + input_line);
896 for(
unsigned int i = 0; i < inputs.size() - 3; i++)
898 test_eq += inputs[i];
902 std::vector<unsigned int> index_reac(_reactants.size(),0);
903 for(
unsigned int ir = 0; ir < _reactants.size(); ir++)
905 if(input_line.find(_reactants[ir].first) == std::string::npos)
910 index_reac.push_back(input_line.find(_reactants[ir].first));
915 for(
unsigned int ip = 0; ip < _products.size(); ip++)
917 if(input_line.find(_products[ip].first) == std::string::npos)
922 for(
unsigned int i = 0; i < index_reac.size(); i++)
925 if(input_line.find(_products[ip].first) < index_reac[i])
929 for(
unsigned int jr = 0; jr < _reactants.size(); jr++)
932 if(_reactants[jr].first.find(_products[ip].first) != std::string::npos)out =
false;
945 template <
typename NumericType>
948 if(_next_is_reverse)
return false;
952 while(line.empty() || _spec.is_comment(line[0]))
955 line.find(_spec.end_tag()) != std::string::npos || _doc.eof()
966 template <
typename NumericType>
967 template <
typename CurveType>
982 std::cerr <<
"Thermodynamics description not found" << std::endl;
989 std::vector<NumericType> coeffs;
990 std::vector<NumericType> temps(3,0.);
992 this->skip_comments(_doc);
1000 std::stringstream tmp;
1001 this->skip_comments(_doc);
1005 if(line.find(_spec.end_tag()) != std::string::npos)
break;
1009 if(line.size() != 80)
1011 std::vector<std::string> temp_tmp;
1013 if(temp_tmp.size() == 0)
1015 std::cerr <<
"This line is not understandable by the chemkin parser:\n" << line << std::endl;
1018 temps.resize(temp_tmp.size(),0.);
1019 for(
unsigned int t = 0; t < temp_tmp.size(); t++)
1021 temps[t] = std::atof(temp_tmp[t].c_str());
1026 tmp << line.substr(0,18);
1029 tmp << line.substr(45,10);
1030 tmp <<
" " << line.substr(55,10);
1031 tmp <<
" " << line.substr(65,10);
1034 for(
unsigned int n = 0; n < 3; n++)
1038 std::cerr <<
"NASA input file error" << std::endl;
1042 tmp << line.substr(0,15) <<
" "
1043 << line.substr(15,15) <<
" "
1044 << line.substr(30,15) <<
" "
1045 << line.substr(45,15) <<
" "
1046 << line.substr(60,15) <<
" ";
1054 coeffs.resize(14,0);
1055 for(
unsigned int i = 7; i < 21; i++)
bool rate_constant_preexponential_parameter(NumericType &A, std::string &A_unit, std::string &def_unit) const
return true if pre exponentiel coefficient
bool after_coma_digits(NumericType number) const
check if the stoichiometric coef is an integer
void parse_orders(const std::string &line, std::vector< std::pair< std::string, NumericType > > &reaction_orders)
Convenient method.
bool rate_constant_Tref_parameter(NumericType &Tref, std::string &Tref_unit, std::string &def_unit) const
return true if Tref
const std::string get_symbol() const
String symbol getter.
void rescale_stoichiometry()
if stoichiometry is real, make them integer
unsigned int factor_to_int(NumericType number) const
look for q when given r = p / q
void parse_equation_coef(const std::string &line)
Convenient method.
std::map< ParsingKey, std::string > _map
bool rate_constant_power_parameter(NumericType &b, std::string &b_unit, std::string &def_unit) const
return true if beta coefficient
void read_thermodynamic_data_root(NASAThermoMixture< NumericType, CurveType > &thermo)
reads the thermo, NASA generalist
bool Troe_alpha_parameter(NumericType &alpha, std::string &alpha_unit, std::string &def_unit) const
return true is alpha
bool rate_constant_activation_energy_parameter(NumericType &Ea, std::string &Ea_unit, std::string &def_unit) const
return true if activation energie
bool products_pairs(std::vector< std::pair< std::string, int > > &products_pair) const
return pairs of products and stoichiometric coefficients
void parse_forward_orders(const std::string &line)
Convenient method.
bool next_reaction(const std::string &line)
verify if line is a new reaction
bool initialize()
Read header of file, go to interesting part.
const std::map< std::string, NumericType > reactants_orders() const
return a map between reactants' name and found partial orders
bool Troe_T3_parameter(NumericType &T3, std::string &T3_unit, std::string &def_unit) const
return true is alpha
ANTIOCH_NUMERIC_TYPE_CLASS_INSTANTIATE(Antioch::ChemKinParser)
void add_curve_fit(const std::string &species_name, const std::vector< CoeffType > &coeffs)
int ascii_getline(std::istream &buf, std::string &line)
adapted getline, never believe ascii file for the formatting of end-of-line.
bool reaction()
go to next reaction
bool reactants_pairs(std::vector< std::pair< std::string, int > > &reactants_pair) const
return pairs of reactants and stoichiometric coefficients
const std::map< std::string, Species > & species_name_map() const
bool Troe_T2_parameter(NumericType &T2, std::string &T2_unit, std::string &def_unit) const
return true is alpha
void parse_equation(std::string &equation)
Convenient method.
std::map< ParsingKey, std::string > _default_unit
const ChemicalMixture< CoeffType > & chemical_mixture() const
ChemKinParser()
Never use default constructor.
bool next_meaningful_line(std::string &line)
finding next line that might be a reaction
std::map< std::string, std::string > _unit_custom_ea
void parse_reversible_parameters(const std::string &line)
Convenient method.
const std::vector< std::string > species_list()
read SPECIES block
int SplitString(const std::string &input, const std::string &delimiter, std::vector< std::string > &results, bool includeEmpties=true)
Taken from FIN-S for XML parsing.
void clear()
Clear the unit.
#define antioch_parsing_error(description)
bool Troe_T1_parameter(NumericType &T1, std::string &T1_unit, std::string &def_unit) const
return true is alpha
void parse_coefficients_line(const std::string &line)
Convenient method.
const std::map< std::string, NumericType > products_orders() const
return a map between products' name and found partial orders
void change_file(const std::string &filename)
#define antioch_assert_greater_equal(expr1, expr2)
Class storing chemical mixture properties.
The parameters are reduced parameters.
bool efficiencies(std::vector< std::pair< std::string, NumericType > > &par_values) const
return true if efficiencies are found
std::map< std::string, std::string > _unit_custom_A
std::pair< std::string, NumericType > parse_molecule(const std::string &molecule)
Convenient method.
A parser is an instance related to a file.
void parse_backward_orders(const std::string &line)
Convenient method.
bool is_real_number(const char &c) const
Convenient method.
void substract(const Units< T > &rhs)
Alternative call to Units& operator-=(const Units &)
void parse_a_line(const std::string &line)
Convenient method.
ChemKin format file reader.
bool rate_constant(const std::string &)
go to next rate constant