antioch-0.4.0
xml_parser.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 // This class
28 #include "antioch/xml_parser.h"
29 
30 // Antioch
34 #include "antioch/nasa_mixture.h"
35 #include "antioch/cea_thermo.h"
36 #include "antioch/cea_curve_fit.h"
38 
39 //XML
40 #include "antioch/tinyxml2_imp.h"
41 
42 // C++
43 #include <sstream>
44 #include <limits>
45 
46 namespace Antioch
47 {
48  template <typename NumericType>
49  XMLParser<NumericType>::XMLParser(const std::string &filename, bool verbose):
50  ParserBase<NumericType>("XML",filename,verbose),
51  _species_block(NULL),
52  _reaction_block(NULL),
53  _reaction(NULL),
54  _rate_constant(NULL),
55  _Troe(NULL)
56  {
58  if(_doc->LoadFile(filename.c_str()))
59  {
60  std::cerr << "ERROR: unable to load xml file " << filename << std::endl;
61  std::cerr << "Error of tinyxml2 library:\n"
62  << "\tID = " << _doc->ErrorID() << "\n"
63  << "\tError String1 = " << _doc->GetErrorStr1() << "\n"
64  << "\tError String2 = " << _doc->GetErrorStr2() << std::endl;
65  antioch_error();
66  }
67 
68  if(this->verbose())std::cout << "Having opened file " << filename << std::endl;
69 
70 
71  // XML block/section names
72  _map[ParsingKey::PHASE_BLOCK] = "phase";
73  _map[ParsingKey::SPECIES_SET] = "speciesArray";
74  _map[ParsingKey::SPECIES_DATA] = "speciesData";
75  _map[ParsingKey::SPECIES] = "species";
76  _map[ParsingKey::THERMO] = "thermo"; // thermo in ,<speciesData> <species> <thermo> <NASA> <floatArray> </floatArray></NASA> </thermo> </species> </speciesData>
77 
78  // Thermo parameters
79  _map[ParsingKey::TMIN] = "Tmin";
80  _map[ParsingKey::TMAX] = "Tmax";
81  _map[ParsingKey::NASADATA] = "floatArray";
82  _map[ParsingKey::NASA7] = "NASA";
83  _map[ParsingKey::NASA9] = "NASA9";
84 
85  // Kinetics parameters
86  _map[ParsingKey::REACTION_DATA] = "reactionData";
87  _map[ParsingKey::REACTION] = "reaction";
88  _map[ParsingKey::REVERSIBLE] = "reversible";
89  _map[ParsingKey::ID] = "id";
90  _map[ParsingKey::EQUATION] = "equation";
92  _map[ParsingKey::KINETICS_MODEL] = "rateCoeff";
93  _map[ParsingKey::REACTANTS] = "reactants";
94  _map[ParsingKey::PRODUCTS] = "products";
97  _map[ParsingKey::PREEXP] = "A";
98  _map[ParsingKey::POWER] = "b";
101  _map[ParsingKey::TREF] = "Tref";
102  _map[ParsingKey::HV_LAMBDA] = "lambda";
103  _map[ParsingKey::HV_CROSS_SECTION] = "cross_section";
104  _map[ParsingKey::UNIT] = "units";
105  _map[ParsingKey::EFFICIENCY] = "efficiencies";
108  _map[ParsingKey::TROE_FALLOFF] = "Troe";
109  _map[ParsingKey::TROE_F_ALPHA] = "alpha";
110  _map[ParsingKey::TROE_F_TS] = "T1";
113 
114  // typically Cantera files list
115  // pre-exponential parameters in (m3/kmol)^(m-1)/s
116  // activation energy in cal/mol, but we want it in K.
117  // power parameter without unit
118  // if falloff, we need to know who's k0 and kinfty
119  // if photochemistry, we have a cross-section on a lambda grid
120  // cross-section typically in cm2/nm (cross-section on a resolution bin,
121  // if bin unit not given, it is lambda unit (supposed to anyway), and a warning message)
122  // lambda typically in nm, sometimes in ang, default considered here is nm
123  // you can also have cm-1, conversion is done with
124  // formulae nm = cm-1 * / * adapted factor
125  _default_unit[ParsingKey::PREEXP] = "m3/kmol";
137 
138  this->initialize();
139  }
140 
141  template <typename NumericType>
143  {
144  delete _doc;
145  }
146 
147  template <typename NumericType>
148  void XMLParser<NumericType>::change_file(const std::string & filename)
149  {
151  _species_block = NULL;
152  _reaction_block = NULL;
153  _reaction = NULL;
154  _rate_constant = NULL;
155  _Troe = NULL;
156 
157  delete _doc;
158  _doc = new tinyxml2::XMLDocument;
159  if(_doc->LoadFile(filename.c_str()))
160  {
161  std::cerr << "ERROR: unable to load xml file " << filename << std::endl;
162  std::cerr << "Error of tinyxml2 library:\n"
163  << "\tID = " << _doc->ErrorID() << "\n"
164  << "\tError String1 = " << _doc->GetErrorStr1() << "\n"
165  << "\tError String2 = " << _doc->GetErrorStr2() << std::endl;
166  antioch_error();
167  }
168 
169  if(this->verbose())std::cout << "Having opened file " << filename << std::endl;
170 
171  this->initialize();
172  }
173 
174  template <typename NumericType>
176  {
177  //we start here
178  _reaction_block = _doc->FirstChildElement("ctml");
179  if (!_reaction_block)
180  {
181  std::cerr << "ERROR: no <ctml> tag found in input file"
182  << std::endl;
183  antioch_error();
184  }
185 
186  _species_block = _reaction_block->FirstChildElement(_map.at(ParsingKey::PHASE_BLOCK).c_str());
187  if(_species_block)
188  _species_block = _species_block->FirstChildElement(_map.at(ParsingKey::SPECIES_SET).c_str());
189 
190  _thermo_block = _reaction_block->FirstChildElement(_map.at(ParsingKey::SPECIES_DATA).c_str());
191 
192  _reaction_block = _reaction_block->FirstChildElement(_map.at(ParsingKey::REACTION_DATA).c_str());
193 
194  _reaction = NULL;
195  _rate_constant = NULL;
196 
197  return _reaction_block;
198  }
199 
200 
201 
202  template <typename NumericType>
203  const std::vector<std::string> XMLParser<NumericType>::species_list()
204  {
205  if(!_species_block)
206  antioch_error_msg("ERROR: Could not find "+_map.at(ParsingKey::SPECIES_SET)+" section in input file!");
207 
208  std::vector<std::string> molecules;
209 
210  split_string(std::string(_species_block->GetText())," ",molecules);
211  remove_newline_from_strings(molecules);
212 
213  return molecules;
214  }
215 
216  template <typename NumericType>
218  {
219  antioch_assert(_reaction_block);
220  _reaction = (_reaction)?
221  _reaction->NextSiblingElement(_map.at(ParsingKey::REACTION).c_str()):
222  _reaction_block->FirstChildElement(_map.at(ParsingKey::REACTION).c_str());
223 
224  _rate_constant = NULL;
225  _Troe = NULL;
226 
227  return _reaction;
228  }
229 
230  template <typename NumericType>
231  bool XMLParser<NumericType>::rate_constant(const std::string & kinetics_model)
232  {
233  // if in a reaction
234  if(_reaction)
235  {
236  // not the first one
237  if(_rate_constant)
238  {
239  _rate_constant = _rate_constant->NextSiblingElement(kinetics_model.c_str());
240  }else
241  {
242  // first one, we need to set _rate_constant and _Troe, because they contain environments
243  // we suppose that there is a rateCoeff environement
244  // _rate_constant => <rateCoeff> <kin model> </kin model> </rateCoeff>
245  // _Troe => <rateCoeff> <Troe> </Troe> </rateCoeff>
246  antioch_assert(_reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str()));
247  _rate_constant = _reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str())->FirstChildElement(kinetics_model.c_str());
248  _Troe = _reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str())->FirstChildElement(_map[ParsingKey::TROE_FALLOFF].c_str());
249  }
250  }else
251  {
252  _rate_constant = NULL;
253  }
254 
255  return _rate_constant;
256  }
257 
258  template <typename NumericType>
260  {
261  return _Troe;
262  }
263 
264  template <typename NumericType>
265  const std::string XMLParser<NumericType>::reaction_id() const
266  {
267  std::stringstream id;
268  id << _reaction->Attribute(_map.at(ParsingKey::ID).c_str());
269  return id.str();
270  }
271 
272  template <typename NumericType>
274  {
275  return _reaction->FirstChildElement(_map.at(ParsingKey::EQUATION).c_str())->GetText();
276  }
277 
278  template <typename NumericType>
280  {
281  const char * chem_proc = _reaction->Attribute(_map.at(ParsingKey::CHEMICAL_PROCESS).c_str());
282 
283  return (chem_proc)?
284  std::string(chem_proc):
285  std::string();
286  }
287 
288  template <typename NumericType>
290  {
291  return (_reaction->Attribute(_map.at(ParsingKey::REVERSIBLE).c_str()))?
292  (std::string(_reaction->Attribute(_map.at(ParsingKey::REVERSIBLE).c_str())) == std::string("no"))?false:true //explicit
293  :
294  true; //default
295  }
296 
297  template <typename NumericType>
298  const std::string XMLParser<NumericType>::reaction_kinetics_model(const std::vector<std::string> &kinetics_models) const
299  {
300  unsigned int imod(0);
301  tinyxml2::XMLElement * rate_constant = _reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str())->FirstChildElement(kinetics_models[imod].c_str());
302  while(!rate_constant)
303  {
304  if(imod == kinetics_models.size() - 1)
305  {
306  std::cerr << "Could not find a suitable kinetics model.\n"
307  << "Implemented kinetics models are:\n";
308 
309  for(unsigned int m = 0; m < kinetics_models.size(); m++)
310  std::cerr << " " << kinetics_models[m] << "\n";
311 
312  std::cerr << "See Antioch documentation for more details."
313  << std::endl;
315  }
316  imod++;
317  rate_constant = _reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str())->FirstChildElement(kinetics_models[imod].c_str());
318  }
319 
320  return kinetics_models[imod];
321  }
322 
323  template <typename NumericType>
324  bool XMLParser<NumericType>::reactants_pairs(std::vector<std::pair<std::string,int> > & reactants_pair) const
325  {
326  tinyxml2::XMLElement* reactants = _reaction->FirstChildElement(_map.at(ParsingKey::REACTANTS).c_str());
327  return this->molecules_pairs(reactants, reactants_pair);
328  }
329 
330  template <typename NumericType>
331  bool XMLParser<NumericType>::products_pairs(std::vector<std::pair<std::string,int> > & products_pair) const
332  {
333  tinyxml2::XMLElement* products = _reaction->FirstChildElement(_map.at(ParsingKey::PRODUCTS).c_str());
334  return this->molecules_pairs(products, products_pair);
335  }
336 
337  template <typename NumericType>
338  const std::map<std::string,NumericType> XMLParser<NumericType>::reactants_orders() const
339  {
340  tinyxml2::XMLElement* orders = _reaction->FirstChildElement(_map.at(ParsingKey::FORWARD_ORDER).c_str());
341  std::map<std::string,NumericType> map;
342  if(orders){
343  std::vector<std::pair<std::string,NumericType> > pairs;
344  if(this->molecules_pairs(orders,pairs))
345  {
346  for(unsigned int s = 0; s < pairs.size(); s++)
347  {
348  map.insert(pairs[s]);
349  }
350  }
351  }
352 
353  return map;
354  }
355 
356  template <typename NumericType>
357  const std::map<std::string,NumericType> XMLParser<NumericType>::products_orders() const
358  {
359  tinyxml2::XMLElement* orders = _reaction->FirstChildElement(_map.at(ParsingKey::BACKWARD_ORDER).c_str());
360  std::map<std::string,NumericType> map;
361  if(orders){
362  std::vector<std::pair<std::string,NumericType> > pairs;
363  if(this->molecules_pairs(orders,pairs))
364  {
365  for(unsigned int s = 0; s < pairs.size(); s++)
366  {
367  map.insert(pairs[s]);
368  }
369  }
370  }
371  return map;
372  }
373 
374 
375  template <typename NumericType>
376  template <typename PairedType>
377  bool XMLParser<NumericType>::molecules_pairs(tinyxml2::XMLElement * molecules, std::vector<std::pair<std::string,PairedType> > & molecules_pairs) const
378  {
379  bool out(true);
380  if(molecules)
381  {
382 
383  std::vector<std::string> mol_pairs;
384 
385  // Split the reactant string on whitespace. If no entries were found,
386  // there is no whitespace - and assume then only one reactant is listed.
387  split_string(std::string(molecules->GetText()), " ", mol_pairs);
388 
389  for( unsigned int p=0; p < mol_pairs.size(); p++ )
390  {
391  std::pair<std::string,PairedType> pair( split_string_on_colon<PairedType>(mol_pairs[p]) );
392 
393  molecules_pairs.push_back(pair);
394  }
395  }else
396  {
397  out = false;
398  }
399 
400  return out;
401  }
402 
403  template <typename NumericType>
404  bool XMLParser<NumericType>::is_k0(unsigned int nrc, const std::string & kin_model) const
405  {
406  bool k0(false);
407  if(_rate_constant->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str()))
408  {
409  if(std::string(_rate_constant->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str())) == _map.at(ParsingKey::FALLOFF_LOW))
410  {
411  k0 = true;
412  // now verifying the second one
413  if(nrc == 0) // first reaction rate block
414  {
415  antioch_assert(_rate_constant->NextSiblingElement(kin_model.c_str()));
416  if(_rate_constant->NextSiblingElement(kin_model.c_str())->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str())) // HAHA
417  {
418  std::string error = "I can understand the need to put attributes everywhere, really, but in this case, I'm ";
419  error += "afraid that it's not a good idea to have two \'name\' attributes: only the low pressure limit should have it.";
420  antioch_parsing_error(error);
421  }
422  }
423  }else
424  {
425  std::string error = "The keyword associated with the \'name\' attribute within the description of a falloff should be, and only be, ";
426  error += "\'k0\' to specify the low pressure limit. It seems that the one you provided, \'";
427  error += std::string(_rate_constant->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str()));
428  error += "\' is not this one. Please correct it at reaction";
429  error += this->reaction_id();
430  error += ": ";
431  error += this->reaction_equation();
432  error += ".";
433  antioch_parsing_error(error);
434  }
435  }else if(nrc == 0) // if we're indeed at the first reading
436  {
437  antioch_assert(_rate_constant->NextSiblingElement(kin_model.c_str()));
438  if(!_rate_constant->NextSiblingElement(kin_model.c_str())->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str())) // and the next doesn't have a name
439  {
440  k0 = true;
441  }else
442  {
443  if(std::string(_rate_constant->NextSiblingElement(kin_model.c_str())->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str())) == _map.at(ParsingKey::FALLOFF_LOW))k0 = false;
444  }
445  }
446  return k0;
447  }
448 
449  template <typename NumericType>
450  unsigned int XMLParser<NumericType>::where_is_k0(const std::string & kin_model) const
451  {
452  antioch_assert(!_rate_constant); //should be done exterior to rate constant block
453  antioch_assert(_reaction); //should be done interior to reaction block
454 
455  tinyxml2::XMLElement * rate_constant = _reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str());
456  antioch_assert(rate_constant);
457  rate_constant = rate_constant->FirstChildElement(kin_model.c_str());
458  unsigned int k0(0);
459  if(rate_constant->NextSiblingElement()->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str()))
460  {
461  if(std::string(rate_constant->NextSiblingElement()->Attribute(_map.at(ParsingKey::FALLOFF_LOW_NAME).c_str())) == _map.at(ParsingKey::FALLOFF_LOW))k0=1;
462  }
463 
464  return k0;
465  }
466 
467  template <typename NumericType>
468  bool XMLParser<NumericType>::get_parameter(const tinyxml2::XMLElement * ptr, const std::string & par, NumericType & par_value, std::string & par_unit) const
469  {
470  antioch_assert(ptr);
471 
472  bool out(false);
473  par_unit.clear();
474  if(ptr->FirstChildElement(par.c_str()))
475  {
476  par_value = std::atof(ptr->FirstChildElement(par.c_str())->GetText());
477  if(ptr->FirstChildElement(par.c_str())->Attribute(_map.at(ParsingKey::UNIT).c_str()))
478  par_unit = ptr->FirstChildElement(par.c_str())->Attribute(_map.at(ParsingKey::UNIT).c_str());
479  out = true;
480  }
481 
482  return out;
483  }
484 
485  template <typename NumericType>
486  bool XMLParser<NumericType>::get_parameter(const tinyxml2::XMLElement * ptr, const std::string & par, std::vector<NumericType> & par_values, std::string & par_unit) const
487  {
488  antioch_assert(ptr);
489 
490  bool out(false);
491  par_unit.clear();
492  if(ptr->FirstChildElement(par.c_str()))
493  {
494  std::vector<std::string> values;
495  split_string(ptr->FirstChildElement(par.c_str())->GetText()," ",values);
496 
497  par_values.resize(values.size());
498  for(unsigned int i = 0; i < values.size(); i++)
499  par_values[i] = string_to_T<NumericType>(values[i].c_str());
500 
501  if(ptr->FirstChildElement(par.c_str())->Attribute(_map.at(ParsingKey::UNIT).c_str()))
502  par_unit = ptr->FirstChildElement(par.c_str())->Attribute(_map.at(ParsingKey::UNIT).c_str());
503 
504  out = true;
505  }
506 
507  return out;
508  }
509 
510  template <typename NumericType>
512  const std::string& elem_name,
513  const std::string& attribute,
514  const std::string& attr_value ) const
515  {
516  antioch_assert(element);
517 
518  const tinyxml2::XMLElement * elem_with_attr = NULL;
519 
520  if( !element->Attribute(attribute.c_str()) )
521  antioch_error_msg("ERROR: Could not find attribute "+attribute+" for current element!");
522 
523  // First check if the first element has the attribute we're looking for
524  if( std::string( element->Attribute(attribute.c_str()) ) == attr_value )
525  elem_with_attr = element;
526 
527  // Otherwise, look at all the siblings
528  else
529  {
530  elem_with_attr = element->NextSiblingElement(elem_name.c_str());
531 
532  while( elem_with_attr )
533  {
534  std::string curr_attr;
535  if( elem_with_attr->Attribute(attribute.c_str()) )
536  curr_attr = std::string(elem_with_attr->Attribute(attribute.c_str()));
537 
538  if( curr_attr == attr_value )
539  break;
540 
541  elem_with_attr = elem_with_attr->NextSiblingElement(elem_name.c_str());
542  }
543 
544  // Error out if we couldn't find the attribute with the correct value
545  if( !elem_with_attr )
546  antioch_error_msg("ERROR: Could not find XMLElement with attribute = "+attribute+" whose value is "+attr_value+"!");
547 
548  }
549 
550  return const_cast<tinyxml2::XMLElement*>(elem_with_attr);
551  }
552 
553  template <typename NumericType>
554  bool XMLParser<NumericType>::rate_constant_preexponential_parameter(NumericType & A, std::string & A_unit, std::string & def_unit) const
555  {
556  def_unit = _default_unit.at(ParsingKey::PREEXP);
557  return this->get_parameter(_rate_constant,_map.at(ParsingKey::PREEXP).c_str(),A,A_unit);
558  }
559 
560 
561  template <typename NumericType>
562  bool XMLParser<NumericType>::rate_constant_power_parameter(NumericType & b, std::string & b_unit, std::string & def_unit) const
563  {
564  def_unit = _default_unit.at(ParsingKey::POWER);
565  return this->get_parameter(_rate_constant,_map.at(ParsingKey::POWER).c_str(),b,b_unit);
566  }
567 
568  template <typename NumericType>
569  bool XMLParser<NumericType>::rate_constant_activation_energy_parameter(NumericType & Ea, std::string & Ea_unit, std::string & def_unit) const
570  {
571  def_unit = _default_unit.at(ParsingKey::ACTIVATION_ENERGY);
572  return this->get_parameter(_rate_constant,_map.at(ParsingKey::ACTIVATION_ENERGY).c_str(),Ea,Ea_unit);
573  }
574 
575  template <typename NumericType>
576  bool XMLParser<NumericType>::rate_constant_Berthelot_coefficient_parameter(NumericType & D, std::string & D_unit, std::string & def_unit) const
577  {
578  def_unit = _default_unit.at(ParsingKey::BERTHELOT_COEFFICIENT);
579  return this->get_parameter(_rate_constant,_map.at(ParsingKey::BERTHELOT_COEFFICIENT).c_str(),D,D_unit);
580  }
581 
582  template <typename NumericType>
583  bool XMLParser<NumericType>::rate_constant_lambda_parameter(std::vector<NumericType> & lambda, std::string & lambda_unit, std::string & def_unit) const
584  {
585  def_unit = _default_unit.at(ParsingKey::HV_LAMBDA);
586  return this->get_parameter(_rate_constant,_map.at(ParsingKey::HV_LAMBDA).c_str(),lambda,lambda_unit);
587  }
588 
589  template <typename NumericType>
590  bool XMLParser<NumericType>::rate_constant_cross_section_parameter(std::vector<NumericType> & sigma, std::string & sigma_unit, std::string & def_unit) const
591  {
592  def_unit = _default_unit.at(ParsingKey::HV_CROSS_SECTION);
593  return this->get_parameter(_rate_constant,_map.at(ParsingKey::HV_CROSS_SECTION).c_str(),sigma,sigma_unit);
594  }
595 
596  template <typename NumericType>
597  bool XMLParser<NumericType>::rate_constant_Tref_parameter(NumericType & Tref, std::string & Tref_unit, std::string & def_unit) const
598  {
599  def_unit = _default_unit.at(ParsingKey::TREF);
600  return this->get_parameter(_rate_constant,_map.at(ParsingKey::TREF).c_str(),Tref,Tref_unit);
601  }
602 
603  template <typename NumericType>
605  {
606  bool out(false);
607  tinyxml2::XMLElement * rate_constant = _reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str());
608  antioch_assert(rate_constant->FirstChildElement("Arrhenius"));
609  rate_constant = rate_constant->FirstChildElement("Arrhenius");
610  if(rate_constant->FirstChildElement(_map.at(ParsingKey::POWER).c_str()))
611  {
612  if(std::atof(rate_constant->FirstChildElement(_map.at(ParsingKey::POWER).c_str())->GetText()) != 0.) //not a very good test
613  out = true;
614  }
615 
616  return out;
617  }
618 
619  template <typename NumericType>
620  bool XMLParser<NumericType>::efficiencies(std::vector<std::pair<std::string,NumericType> > & par_values) const
621  {
622  bool out = false;
623  if(_reaction)
624  {
625  tinyxml2::XMLElement * rate_constant = _reaction->FirstChildElement(_map.at(ParsingKey::KINETICS_MODEL).c_str());
626  if(rate_constant)
627  {
628  if(rate_constant->FirstChildElement(_map.at(ParsingKey::EFFICIENCY).c_str()))
629  {
630  std::vector<std::string> values;
631  std::string value_string = std::string((rate_constant->FirstChildElement(_map.at(ParsingKey::EFFICIENCY).c_str())->GetText())?rate_constant->FirstChildElement(_map.at(ParsingKey::EFFICIENCY).c_str())->GetText():"");
632 
633  split_string(value_string, " ", values);
634 
635  for(unsigned int i = 0; i < values.size(); i++)
636  par_values.push_back(split_string_on_colon<NumericType>(values[i]));
637 
638  out = true;
639  }
640  }
641  }
642  return out;
643  }
644 
645  template <typename NumericType>
646  bool XMLParser<NumericType>::Troe_alpha_parameter(NumericType & alpha, std::string & alpha_unit, std::string & def_unit) const
647  {
648  def_unit = _default_unit.at(ParsingKey::TROE_F_ALPHA);
649  return this->get_parameter(_Troe,_map.at(ParsingKey::TROE_F_ALPHA),alpha,alpha_unit);
650  }
651 
652  template <typename NumericType>
653  bool XMLParser<NumericType>::Troe_T1_parameter(NumericType & T1, std::string & T1_unit, std::string & def_unit) const
654  {
655  def_unit = _default_unit.at(ParsingKey::TROE_F_TS);
656  return this->get_parameter(_Troe,_map.at(ParsingKey::TROE_F_TS),T1,T1_unit);
657  }
658 
659  template <typename NumericType>
660  bool XMLParser<NumericType>::Troe_T2_parameter(NumericType & T2, std::string & T2_unit, std::string & def_unit) const
661  {
662  def_unit = _default_unit.at(ParsingKey::TROE_F_TSS);
663  return this->get_parameter(_Troe,_map.at(ParsingKey::TROE_F_TSS),T2,T2_unit);
664  }
665 
666  template <typename NumericType>
667  bool XMLParser<NumericType>::Troe_T3_parameter(NumericType & T3, std::string & T3_unit, std::string & def_unit) const
668  {
669  def_unit = _default_unit.at(ParsingKey::TROE_F_TSSS);
670  return this->get_parameter(_Troe,_map.at(ParsingKey::TROE_F_TSSS),T3,T3_unit);
671  }
672 
673 
674  template <typename NumericType>
675  template <typename ThermoType>
677  {
678  if(!_thermo_block)
679  antioch_error_msg("ERROR: No "+_map.at(ParsingKey::SPECIES_DATA)+" section found! Cannot parse thermo!");
680 
681  const ChemicalMixture<NumericType> & chem_mixture = thermo.chemical_mixture();
682  const std::vector<ChemicalSpecies<NumericType>*>& chem_species = chem_mixture.chemical_species();
683 
684  // Based on the ThermoType, namely the CurveFit, we deduce what the section name is.
685  std::string nasa_xml_section = this->nasa_xml_section(thermo);
686 
687  for(unsigned int s = 0; s < chem_mixture.n_species(); s++)
688  {
689  // Step to first species block
690  tinyxml2::XMLElement * species_block = _thermo_block->FirstChildElement(_map.at(ParsingKey::SPECIES).c_str());
691 
692  if(!species_block)
693  antioch_error_msg("ERROR: No "+_map.at(ParsingKey::SPECIES)+" block found within "+_map.at(ParsingKey::SPECIES_DATA)+" section! Cannot parse thermo!");
694 
695 
696  const std::string& name = chem_species[s]->species();
697 
698  tinyxml2::XMLElement * spec = NULL;
699  spec = this->find_element_with_attribute( species_block,
700  _map.at(ParsingKey::SPECIES),
701  "name",
702  name );
703 
704  if(!spec)
705  antioch_error_msg("ERROR: Species "+name+" has not been found in the "+_map.at(ParsingKey::SPECIES_DATA)+" section! Cannot parse thermo!");
706 
707  else
708  {
709  spec = spec->FirstChildElement(_map.at(ParsingKey::THERMO).c_str());
710 
711  if(!spec)
712  antioch_error_msg("ERROR: No "+_map.at(ParsingKey::THERMO)+" block found for species "+name+"! Cannot parse thermo!");
713 
714  // containers for parsing thermo data
715  std::vector<NumericType> temps;
716  std::vector<NumericType> values;
717  tinyxml2::XMLElement * coeffs;
718  std::vector<std::string> coeffs_str;
719 
720  // looping for each of the temperature intervals for this species
721  tinyxml2::XMLElement * nasa = spec->FirstChildElement(nasa_xml_section.c_str());
722  if(!nasa)
723  antioch_error_msg("ERROR: Could not find "+nasa_xml_section+" thermo section!");
724 
725  while(nasa)
726  {
727  if( !(nasa->Attribute(_map.at(ParsingKey::TMIN).c_str())) )
728  antioch_error_msg("ERROR: Could not find "+_map.at(ParsingKey::TMIN)+" attribute for species "+name+"!");
729 
730  if( !(nasa->Attribute(_map.at(ParsingKey::TMAX).c_str())) )
731  antioch_error_msg("ERROR: Could not find "+_map.at(ParsingKey::TMAX)+" attribute for species "+name+"!");
732  // By convention, we put the first TMIN in, and then only the TMAX thereafter
733  // We have a consistency check below to make sure the TMIN's in the input are consistent
734  if( temps.empty() )
735  temps.push_back(string_to_T<NumericType>(nasa->Attribute(_map.at(ParsingKey::TMIN).c_str())));
736 
737  // temperatures, only Tmax as Tmin is suppose to be last Tmax
738  temps.push_back(string_to_T<NumericType>(nasa->Attribute(_map.at(ParsingKey::TMAX).c_str())));
739 
740  // now coeffs
741  if( !(nasa->FirstChildElement(_map.at(ParsingKey::NASADATA).c_str())) )
742  antioch_error_msg("ERROR: Could not find "+_map.at(ParsingKey::NASADATA)+" data for species "+name+"!");
743 
744  coeffs = nasa->FirstChildElement(_map.at(ParsingKey::NASADATA).c_str());
745  split_string(std::string(coeffs->GetText())," ",coeffs_str);
746  remove_newline_from_strings(coeffs_str);
747 
748  for(unsigned int d = 0; d < coeffs_str.size(); d++)
749  values.push_back(string_to_T<NumericType>(coeffs_str[d]));
750 
751  // If we have more than one interval, make sure the temperature intervals match up
752  if( temps.size() > 1 )
753  {
754  NumericType prev_Tmax = *(temps.end()-2);
755  NumericType Tmin = string_to_T<NumericType>(nasa->Attribute(_map.at(ParsingKey::TMIN).c_str()));
756  NumericType diff = (Tmin - prev_Tmax)/prev_Tmax;
757 
758  const NumericType tol = std::numeric_limits<NumericType>::epsilon() * 10.;
759 
760  if(std::abs(diff) > tol)
761  antioch_error_msg("ERROR: Tmax/Tmin mismatch for species "+name+"!");
762  }
763 
764  // This is meant to store only data one interval at a time, so we must clear at each iteration
765  coeffs_str.clear();
766 
767  // Move onto next interval of data
768  nasa = nasa->NextSiblingElement(nasa_xml_section.c_str());
769 
770  } // end while loop
771 
772  thermo.add_curve_fit(name, values, temps);
773  }
774 
775  } // end species loop
776  }
777 
778  // Instantiate
781 
782 } // end namespace Antioch
const char * Attribute(const char *name, const char *value=0) const
void remove_newline_from_strings(std::vector< std::string > &strings)
Strips newline characters from strings in the input vector, strings.
Definition: string_utils.C:56
#define antioch_assert(asserted)
bool rate_constant_power_parameter(NumericType &b, std::string &b_unit, std::string &def_unit) const
return true if beta coefficient
Definition: xml_parser.C:562
const std::string reaction_id() const
return reaction id, 0 if not provided
Definition: xml_parser.C:265
void split_string(const std::string &input, const std::string &delimiter, std::vector< std::string > &results)
All characters in delimiter will be treated as a delimiter.
Definition: string_utils.C:34
bool rate_constant_Tref_parameter(NumericType &Tref, std::string &Tref_unit, std::string &def_unit) const
return true if Tref
Definition: xml_parser.C:597
bool initialize()
Read header of file, go to interesting part.
Definition: xml_parser.C:175
bool verify_Kooij_in_place_of_Arrhenius() const
return true if a Kooij is called Arrhenuis
Definition: xml_parser.C:604
bool Troe_T2_parameter(NumericType &T2, std::string &T2_unit, std::string &def_unit) const
return true is alpha
Definition: xml_parser.C:660
const std::map< std::string, NumericType > reactants_orders() const
return a map between reactants' name and found partial orders
Definition: xml_parser.C:338
std::map< ParsingKey, std::string > _default_unit
Definition: xml_parser.h:261
#define antioch_not_implemented()
void change_file(const std::string &filename)
Definition: xml_parser.C:148
bool Troe_alpha_parameter(NumericType &alpha, std::string &alpha_unit, std::string &def_unit) const
return true is alpha
Definition: xml_parser.C:646
ANTIOCH_NUMERIC_TYPE_CLASS_INSTANTIATE(ASCIIParser)
const ChemicalMixture< CoeffType > & chemical_mixture() const
method to send this back
const char * GetErrorStr1() const
Return a possibly helpful diagnostic location or string.
Definition: tinyxml2.h:1199
ANTIOCH_XML_PARSER_INSTANTIATE()
const char * GetErrorStr2() const
Return a possibly helpful secondary diagnostic location or string.
Definition: tinyxml2.h:1201
bool rate_constant_Berthelot_coefficient_parameter(NumericType &D, std::string &D_unit, std::string &def_unit) const
return true if D coefficient
Definition: xml_parser.C:576
bool efficiencies(std::vector< std::pair< std::string, NumericType > > &par_values) const
return true if efficiencies are found
Definition: xml_parser.C:620
bool rate_constant(const std::string &kinetics_model)
go to next rate constant
Definition: xml_parser.C:231
void read_thermodynamic_data_root(ThermoType &thermo)
reads the thermo, NASA generalist
Definition: xml_parser.C:676
const std::string reaction_chemical_process() const
return reaction chemical process
Definition: xml_parser.C:279
bool Troe_T3_parameter(NumericType &T3, std::string &T3_unit, std::string &def_unit) const
return true is alpha
Definition: xml_parser.C:667
XMLParser()
Never use default constructor.
#define antioch_error()
int ErrorID() const
Return the errorID.
Definition: tinyxml2.h:1197
int LoadFile(const char *filename)
bool molecules_pairs(tinyxml2::XMLElement *molecules, std::vector< std::pair< std::string, PairedType > > &products_pair) const
return pairs of molecules and stoichiometric coefficients
Definition: xml_parser.C:377
bool Troe() const
return true if there's a Troe block
Definition: xml_parser.C:259
const XMLElement * NextSiblingElement(const char *value=0) const
Get the next (right) sibling element of this node, with an opitionally supplied name.
Definition: tinyxml2_imp.h:770
bool rate_constant_preexponential_parameter(NumericType &A, std::string &A_unit, std::string &def_unit) const
return true if pre exponentiel coefficient
Definition: xml_parser.C:554
#define antioch_error_msg(errmsg)
bool rate_constant_activation_energy_parameter(NumericType &Ea, std::string &Ea_unit, std::string &def_unit) const
return true if activation energie
Definition: xml_parser.C:569
const std::string reaction_equation() const
return reaction equation
Definition: xml_parser.C:273
std::map< ParsingKey, std::string > _map
Definition: xml_parser.h:260
bool verbose() const
Definition: parser_base.h:248
const XMLElement * FirstChildElement(const char *value=0) const
Definition: tinyxml2_imp.h:740
tinyxml2::XMLDocument * _doc
Definition: xml_parser.h:249
bool products_pairs(std::vector< std::pair< std::string, int > > &products_pair) const
return pairs of products and stoichiometric coefficients
Definition: xml_parser.C:331
bool rate_constant_lambda_parameter(std::vector< NumericType > &lambda, std::string &lambda_unit, std::string &def_unit) const
return true if lambda
Definition: xml_parser.C:583
Nothing is stored, this parser is based on the tinyxml2 implementation.
#define antioch_parsing_error(description)
bool get_parameter(const tinyxml2::XMLElement *ptr, const std::string &par, NumericType &par_value, std::string &par_unit) const
return a parameter's value
Definition: xml_parser.C:468
bool reaction()
reaction
Definition: xml_parser.C:217
Class storing chemical mixture properties.
The parameters are reduced parameters.
bool is_k0(unsigned int nrc, const std::string &kin_model) const
return true if the concerned reaction rate is the low pressure limit
Definition: xml_parser.C:404
const std::string reaction_kinetics_model(const std::vector< std::string > &kinetics_models) const
return reaction kinetics model
Definition: xml_parser.C:298
bool reactants_pairs(std::vector< std::pair< std::string, int > > &reactants_pair) const
return pairs of reactants and stoichiometric coefficients
Definition: xml_parser.C:324
const std::vector< std::string > species_list()
reads the species set
Definition: xml_parser.C:203
tinyxml2::XMLElement * find_element_with_attribute(const tinyxml2::XMLElement *element, const std::string &elem_name, const std::string &attribute, const std::string &attr_value) const
Search the siblings of the element to find the element with the given value for the given attribute...
Definition: xml_parser.C:511
const char * GetText() const
A parser is an instance related to a file.
unsigned int where_is_k0(const std::string &kin_model) const
return index of k0 (0 or 1)
Definition: xml_parser.C:450
bool reaction_reversible() const
return reversible state
Definition: xml_parser.C:289
const std::map< std::string, NumericType > products_orders() const
return a map between products' name and found partial orders
Definition: xml_parser.C:357
bool Troe_T1_parameter(NumericType &T1, std::string &T1_unit, std::string &def_unit) const
return true is alpha
Definition: xml_parser.C:653
bool rate_constant_cross_section_parameter(std::vector< NumericType > &sigma, std::string &sigma_unit, std::string &def_unit) const
return true if sigma
Definition: xml_parser.C:590

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