antioch-0.4.0
ascii_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/ascii_parser.h"
29 
30 // Antioch
34 #include "antioch/cea_thermo.h"
35 #include "antioch/nasa_mixture.h"
37 
38 // C++
39 #include <algorithm> // std::search_n
40 
41 namespace Antioch
42 {
43  template <typename NumericType>
44  ASCIIParser<NumericType>::ASCIIParser(const std::string & file, bool verbose)
45  : ParserBase<NumericType>("ascii",file,verbose,"#!"),
46  _doc(file.c_str()),
47  _n_columns_chemical_species(4), // Spec. Mol. Wt., Hform (0K), cfs, zns
48  _n_columns_vib_data(2), // Species Theta_v degeneracy
49  _n_columns_el_data(2), // Species ThetaE edg #elevels
50  _n_columns_transport_species(5), // Species, eps/kB (K), sigma (ang), alpha (D), alpha (ang^3), Zrot@298 K
51  _is_antioch_default_mixture_file(false)
52  {
53  if(!_doc.is_open())
54  {
55  std::cerr << "ERROR: unable to load file " << file << std::endl;
56  antioch_error();
57  }
58 
62 
63  if(this->verbose())std::cout << "Having opened file " << file << std::endl;
64 
65  this->skip_comments(_doc);
66 
67  _unit_map[MOL_WEIGHT] = "g/mol";
68  _unit_map[MASS_ENTHALPY] = "J/kg";
69  }
70 
71  template <typename NumericType>
73  {
74  _doc.close();
75  }
76 
77  template <typename NumericType>
78  void ASCIIParser<NumericType>::change_file(const std::string & filename)
79  {
80  _doc.close();
81  _doc.open(filename.c_str());
83  if(!_doc.is_open())
84  {
85  std::cerr << "ERROR: unable to load file " << filename << std::endl;
86  antioch_error();
87  }
88 
89  if( filename == DefaultSourceFilename::chemical_mixture() ||
91  _is_antioch_default_mixture_file = true;
92 
93  if(this->verbose())std::cout << "Having opened file " << filename << std::endl;
94 
95  this->skip_comments(_doc);
96  }
97 
98  template <typename NumericType>
99  void ASCIIParser<NumericType>::find_first(unsigned int & index,unsigned int n_data) const
100  {
101  // slow algorithm so whatever order of ignored column is fine
102  bool find(true);
103  while(find)
104  {
105  find = false;
106  for(unsigned int ii = 0; ii < _ignored.size(); ii++)
107  {
108  if(index == _ignored[ii])
109  {
110  find = true;
111  index++;
112  break;
113  }
114  }
115  }
116 
117  if(index > n_data)
118  {
119  std::cerr << "Error while reading " << this->file() << std::endl
120  << "Total number of columns provided is " << n_data
121  << " with " << _ignored.size() << " ignored column." << std::endl
122  << "The provided ignored index are:\n";
123  for(unsigned int i = 0; i < _ignored.size(); i++)
124  {
125  std::cerr << _ignored[i] << std::endl;
126  }
127  std::cerr << "Indexes start at zero, maybe try decreasing them?" << std::endl;
128  antioch_parsing_error("Error in ASCII parser");
129  }
130  }
131 
132  template <typename NumericType>
133  void ASCIIParser<NumericType>::set_ignored_columns(const std::vector<unsigned int> & ignored)
134  {
135  _ignored = ignored;
136  }
137 
138  template <typename NumericType>
139  const std::vector<std::string> ASCIIParser<NumericType>::species_list()
140  {
141  std::vector<std::string> species_list;
142  std::string spec;
143 
144  while(_doc.good())
145  {
146  this->skip_comments(_doc); // if comments in the middle
147 
148  _doc >> spec;
149 
150  if(!_doc.good())break; // read successful?
151 
152  // checking doublon
153  bool doublon(false);
154  for(unsigned int s = 0; s < species_list.size(); s++)
155  {
156  if(spec == species_list[s])
157  {
158  doublon = true;
159  break;
160  }
161  if(doublon)
162  {
163  std::cerr << "Multiple declaration of " << spec
164  << ", skipping doublon" << std::endl;
165  continue;
166  }
167  // adding
168  }
169  if(this->verbose())std::cout << spec << std::endl;
170  species_list.push_back(spec);
171  }
172 
173  if(this->verbose())std::cout << "Found " << species_list.size() << " species\n\n" << std::endl;
174  return species_list;
175  }
176 
177  template <typename NumericType>
179  {
180  std::string name;
181  NumericType mol_wght, h_form, n_tr_dofs;
182  int charge;
183  NumericType mw_unit = Units<NumericType>(_unit_map.at(MOL_WEIGHT)).get_SI_factor();
184  NumericType ef_unit = Units<NumericType>(_unit_map.at(MASS_ENTHALPY)).get_SI_factor();
185 
186  const unsigned int n_data = _n_columns_chemical_species + _ignored.size(); // we read all those columns
187  unsigned int imw(0);
188  this->find_first(imw,n_data);
189  unsigned int ihf(imw+1);
190  this->find_first(ihf,n_data);
191  unsigned int itrdofs(ihf+1);
192  this->find_first(itrdofs,n_data);
193  unsigned int ic(itrdofs+1);
194  this->find_first(ic,n_data);
195 
196  std::vector<NumericType> read(n_data,0.);
197 
198  if(this->verbose())std::cout << "Reading species characteristics in file " << this->file() << std::endl;
199  while (_doc.good())
200  {
201 
202  this->skip_comments(_doc); // if comment in the middle
203 
204  _doc >> name; // Species Name
205  for(unsigned int i = 0; i < n_data; i++)_doc >> read[i];
206  mol_wght = read[imw]; // molecular weight (kg/kmol)
207  h_form = read[ihf]; // heat of formation at Ok (J/kg)
208  n_tr_dofs = read[itrdofs]; // number of translational/rotational DOFs
209  charge = int(read[ic]); // charge number
210 
211  mol_wght *= mw_unit; // to SI (kg/mol)
212  h_form *= ef_unit; // to SI (J/kg)
213 
214  // If we are still good, we have a valid set of thermodynamic
215  // data for this species. Otherwise, we read past end-of-file
216  // in the section above
217  if (_doc.good())
218  {
219  // If we do not have this species, just go on
220  if (!chem_mixture.species_name_map().count(name))continue;
221 
222  Species species = chem_mixture.species_name_map().at(name);
223 
224  // using default comparison:
225  std::vector<Species>::const_iterator it = std::search_n( chem_mixture.species_list().begin(),
226  chem_mixture.species_list().end(),
227  1, species);
228  if( it != chem_mixture.species_list().end() )
229  {
230  unsigned int index = static_cast<unsigned int>(it - chem_mixture.species_list().begin());
231  chem_mixture.add_species( index, name, mol_wght, h_form, n_tr_dofs, charge );
232  if(this->verbose())
233  {
234  std::cout << "Adding " << name << " informations:\n\t"
235  << "molecular weight: " << mol_wght << " kg/mol\n\t"
236  << "formation enthalpy @0 K: " << h_form << " J/mol\n\t"
237  << "trans-rot degrees of freedom: " << n_tr_dofs << "\n\t"
238  << "charge: " << charge << std::endl;
239  }
240  if(_is_antioch_default_mixture_file)
241  this->check_warn_for_species_with_untrusted_hf(name);
242  }
243 
244  }
245  }
246  }
247 
248  template <typename NumericType>
250  {
251  std::string name;
252  NumericType theta_v;
253  unsigned int n_degeneracies;
254 
255  const unsigned int n_data = _n_columns_vib_data + _ignored.size(); // we read all those columns
256  unsigned int itv(0);
257  this->find_first(itv,n_data);
258  unsigned int ide(itv+1);
259  this->find_first(ide,n_data);
260 
261  std::vector<NumericType> read(n_data,0);
262 
263  if(this->verbose())std::cout << "Reading vibrational data in file " << this->file() << std::endl;
264  while (_doc.good())
265  {
266 
267  this->skip_comments(_doc); // if comment in the middle
268 
269  _doc >> name; // Species Name
270  for(unsigned int i = 0; i < n_data; i++)_doc >> read[i];
271  theta_v = read[itv]; // characteristic vibrational temperature (K)
272  n_degeneracies = (unsigned int)(read[ide]); // degeneracy of the mode
273 
274  // If we are still good, we have a valid set of thermodynamic
275  // data for this species. Otherwise, we read past end-of-file
276  // in the section above
277  if (_doc.good())
278  {
279  // If we do not have this species, just keep going
280  if (!chem_mixture.species_name_map().count(name))continue;
281 
282  // ... otherwise we add the data
283  const unsigned int s =
284  chem_mixture.species_name_map().find(name)->second;
285 
286  antioch_assert_equal_to((chem_mixture.chemical_species()[s])->species(), name);
287 
288  chem_mixture.add_species_vibrational_data(s, theta_v, n_degeneracies);
289  if(this->verbose())
290  {
291  std::cout << "Adding vibrational data of species " << name << "\n\t"
292  << "vibrational temperature: " << theta_v << " K\n\t"
293  << "degeneracy: " << n_degeneracies << std::endl;
294  }
295  }
296  }
297  }
298 
299  template <typename NumericType>
301  {
302  std::string name;
303  NumericType theta_e;
304  unsigned int n_degeneracies;
305 
306  const unsigned int n_data = _n_columns_el_data + _ignored.size(); // we read all those columns
307  unsigned int ite(0);
308  this->find_first(ite,n_data);
309  unsigned int ide(ite+1);
310  this->find_first(ide,n_data);
311 
312  std::vector<NumericType> read(n_data,0);
313 
314  if(this->verbose())std::cout << "Reading electronic data in file " << this->file() << std::endl;
315  while (_doc.good())
316  {
317  _doc >> name; // Species Name
318  for(unsigned int i = 0; i < n_data; i++)_doc >> read[i];
319  theta_e = read[ite]; // characteristic electronic temperature (K)
320  n_degeneracies = (unsigned int)(read[ide]); // number of degeneracies for this level
321 
322  // If we are still good, we have a valid set of thermodynamic
323  // data for this species. Otherwise, we read past end-of-file
324  // in the section above
325  if (_doc.good())
326  {
327  // If we do not have this species, just go on
328  if (!chem_mixture.species_name_map().count(name))continue;
329 
330  // ... otherwise we add the data
331  const unsigned int s =
332  chem_mixture.species_name_map().find(name)->second;
333 
334  antioch_assert_equal_to((chem_mixture.chemical_species()[s])->species(), name);
335 
336  chem_mixture.add_species_electronic_data(s, theta_e, n_degeneracies);
337  if(this->verbose())
338  {
339  std::cout << "Adding electronic data of species " << name << "\n\t"
340  << "electronic temperature: " << theta_e << " K\n\t"
341  << "degeneracy: " << n_degeneracies << std::endl;
342  }
343  }
344  }
345  }
346 
347  template <typename NumericType>
348  template <typename CurveType>
350  {
351  std::string name;
352  unsigned int n_int;
353  std::vector<NumericType> coeffs;
354  NumericType h_form, val;
355 
356  const ChemicalMixture<NumericType>& chem_mixture = thermo.chemical_mixture();
357 
358 // \todo: only cea, should do NASA
359  while (_doc.good())
360  {
361  this->skip_comments(_doc);
362 
363  _doc >> name; // Species Name
364  _doc >> n_int; // Number of T intervals: [200-1000], [1000-6000], ([6000-20000])
365  _doc >> h_form; // Formation Enthalpy @ 298.15 K
366 
367  coeffs.clear();
368  for (unsigned int interval=0; interval<n_int; interval++)
369  {
370  for (unsigned int n=0; n<10; n++)
371  {
372  _doc >> val, coeffs.push_back(val);
373  }
374  }
375 
376  // If we are still good, we have a valid set of thermodynamic
377  // data for this species. Otherwise, we read past end-of-file
378  // in the section above
379  if (_doc.good())
380  {
381  // Check if this is a species we want.
382  if( chem_mixture.species_name_map().find(name) !=
383  chem_mixture.species_name_map().end() )
384  {
385  if(this->verbose())std::cout << "Adding curve fit " << name << std::endl;
386  thermo.add_curve_fit(name, coeffs);
387  }
388  }
389  } // end while
390  }
391 
392 
393  template <typename NumericType>
395  {
396  std::string name;
397  unsigned int n_int;
398  std::vector<NumericType> coeffs;
399  NumericType h_form, val;
400 
401  const ChemicalMixture<NumericType>& chem_mixture = thermo.chemical_mixture();
402 
403 // \todo: only cea, should do NASA
404  while (_doc.good())
405  {
406  this->skip_comments(_doc);
407 
408  _doc >> name; // Species Name
409  _doc >> n_int; // Number of T intervals: [200-1000], [1000-6000], ([6000-20000])
410  _doc >> h_form; // Formation Enthalpy @ 298.15 K
411 
412  coeffs.clear();
413  for (unsigned int interval=0; interval<n_int; interval++)
414  {
415  for (unsigned int n=0; n<10; n++)
416  {
417  _doc >> val, coeffs.push_back(val);
418  }
419  }
420 
421  // If we are still good, we have a valid set of thermodynamic
422  // data for this species. Otherwise, we read past end-of-file
423  // in the section above
424  if (_doc.good())
425  {
426  // Check if this is a species we want.
427  if( chem_mixture.species_name_map().find(name) !=
428  chem_mixture.species_name_map().end() )
429  {
430  thermo.add_curve_fit(name, coeffs);
431  }
432  }
433  } // end while
434  }
435 
436  template <typename NumericType>
437  template <typename Mixture>
439  {
440  std::string name;
441  NumericType LJ_eps_kB;
442  NumericType LJ_sigma;
443  NumericType dipole_moment;
444  NumericType pol;
445  NumericType Zrot;
446 
447  const unsigned int n_data = _n_columns_transport_species + _ignored.size(); // we read all those columns
448  unsigned int iLJeps(0);
449  this->find_first(iLJeps,n_data);
450  unsigned int iLJsig(iLJeps+1);
451  this->find_first(iLJsig,n_data);
452  unsigned int idip(iLJsig+1);
453  this->find_first(idip,n_data);
454  unsigned int ipol(idip+1);
455  this->find_first(ipol,n_data);
456  unsigned int irot(ipol+1);
457  this->find_first(irot,n_data);
458 
459  std::vector<NumericType> read(n_data,0.);
460 
461  while (_doc.good())
462  {
463  this->skip_comments(_doc);
464 
465  _doc >> name;
466  for(unsigned int i = 0; i < n_data; i++)_doc >> read[i];
467  LJ_eps_kB = read[iLJeps];
468  LJ_sigma = read[iLJsig];
469  dipole_moment = read[idip];
470  pol = read[ipol];
471  Zrot = read[irot];
472  if(transport.chemical_mixture().species_name_map().count(name))
473  {
474  unsigned int place = transport.chemical_mixture().species_name_map().at(name);
475  NumericType mass = transport.chemical_mixture().M(place);
476  // adding species in mixture
477  transport.add_species(place,LJ_eps_kB,LJ_sigma,dipole_moment,pol,Zrot,mass);
478  }
479  }
480  }
481 
482  template <typename NumericType>
484  {
485  std::vector<std::string> species_with_unknown_Hf(9);
486  species_with_unknown_Hf[0] = "CH2O";
487  species_with_unknown_Hf[1] = "HCCO";
488  species_with_unknown_Hf[2] = "HCCOH";
489  species_with_unknown_Hf[3] = "H2CN";
490  species_with_unknown_Hf[4] = "HCNN";
491  species_with_unknown_Hf[5] = "HCNO";
492  species_with_unknown_Hf[6] = "HOCN";
493  species_with_unknown_Hf[7] = "C3H7";
494  species_with_unknown_Hf[8] = "CH2CHO";
495 
496  std::vector<std::string>::const_iterator it = std::search_n( species_with_unknown_Hf.begin(),
497  species_with_unknown_Hf.end(),
498  1, name );
499  if( it != species_with_unknown_Hf.end() )
500  {
501  std::cout << "WARNING: Detected that you're using Antioch's default chemical mixture file" << std::endl
502  << " and using species " << name <<". The Enthaply of formation of this" << std::endl
503  << " species is currently NOT TRUSTED. BE AWARE THAT USING StatMechThermodynamics"
504  << std::endl
505  << " WILL LIKELY GIVE INACCURATE RESULTS! All other calculations are unaffected."
506  << std::endl;
507  }
508 
509  }
510 
511  // Instantiate
514 
515 } // end namespace Antioch
void read_thermodynamic_data_root(NASAThermoMixture< NumericType, CurveType > &thermo)
read the thermodynamic data
Definition: ascii_parser.C:349
unsigned int Species
bool _is_antioch_default_mixture_file
Needed to be able to warn about using not-trusted enthalpies of formation.
Definition: ascii_parser.h:171
ANTIOCH_NUMERIC_TYPE_CLASS_INSTANTIATE(ASCIIParser)
#define antioch_assert_equal_to(expr1, expr2)
const std::vector< Species > & species_list() const
void skip_comments(std::istream &doc)
Definition: parser_base.C:54
ANTIOCH_ASCII_PARSER_INSTANTIATE()
void read_electronic_data(ChemicalMixture< NumericType > &chem_mixture)
read the electronic data
Definition: ascii_parser.C:300
std::map< ParsingUnit, std::string > _unit_map
Definition: ascii_parser.h:162
void find_first(unsigned int &index, unsigned int n_data) const
find the index of the wanted data
Definition: ascii_parser.C:99
#define antioch_error()
static const std::string & chemical_mixture()
std::ifstream _doc
Definition: ascii_parser.h:161
void read_transport_data_root(Mixture &transport)
read the thermodynamic data
Definition: ascii_parser.C:438
void add_curve_fit(const std::string &species_name, const std::vector< CoeffType > &coeffs)
Definition: nasa_mixture.h:120
const std::map< std::string, Species > & species_name_map() const
void change_file(const std::string &filename)
Definition: ascii_parser.C:78
static const std::string & chemical_mixture()
void set_ignored_columns(const std::vector< unsigned int > &ignored)
set the indexes of to-be-ignored columns
Definition: ascii_parser.C:133
a int
Definition: eigen_utils.h:67
void check_warn_for_species_with_untrusted_hf(const std::string &name) const
Warn about species for which Antioch default mixture file has untrusted H_f values.
Definition: ascii_parser.C:483
bool verbose() const
Definition: parser_base.h:248
const ChemicalMixture< CoeffType > & chemical_mixture() const
Definition: nasa_mixture.h:200
const ChemicalMixture< CoeffType > & chemical_mixture() const
Definition: cea_thermo.h:572
#define antioch_parsing_error(description)
void add_species(const unsigned int index, const std::string &name, CoeffType mol_wght, CoeffType h_form, CoeffType n_tr_dofs, int charge)
void read_vibrational_data(ChemicalMixture< NumericType > &chem_mixture)
read the vibrational data
Definition: ascii_parser.C:249
void add_species_vibrational_data(const unsigned int index, const CoeffType theta_v, const unsigned int ndg_v)
void add_curve_fit(const std::string &species_name, const std::vector< CoeffType > &coeffs)
Definition: cea_thermo.h:227
Class storing chemical mixture properties.
void add_species_electronic_data(const unsigned int index, const CoeffType theta_e, const unsigned int ndg_e)
The parameters are reduced parameters.
An advanced unit class.
Definition: units.h:111
const std::vector< std::string > species_list()
read species list
Definition: ascii_parser.C:139
A parser is an instance related to a file.
void read_thermodynamic_data(NASAThermoMixture< NumericType, NASA7CurveFit< NumericType > > &)
reads the thermo, NASA generalist, no templates for virtual
Definition: ascii_parser.h:126
const std::vector< ChemicalSpecies< CoeffType > * > & chemical_species() const
ASCIIParser()
not allowed
void read_chemical_species(ChemicalMixture< NumericType > &chem_mixture)
read the mandatory data
Definition: ascii_parser.C:178

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