chemkinReader.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "chemkinReader.H"
27 #include <fstream>
28 #include "atomicWeights.H"
29 #include "ReactionProxy.H"
30 #include "IrreversibleReaction.H"
31 #include "ReversibleReaction.H"
33 #include "ArrheniusReactionRate.H"
35 #include "FallOffReactionRate.H"
38 #include "TroeFallOffFunction.H"
39 #include "SRIFallOffFunction.H"
41 #include "JanevReactionRate.H"
44 
45 
46 /* * * * * * * * * * * * * * * * * Static data * * * * * * * * * * * * * * * */
47 
48 namespace Foam
49 {
51 }
52 
53 
54 /* * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * */
55 
56 const char* Foam::chemkinReader::reactionTypeNames[4] =
57 {
58  "irreversible",
59  "reversible",
60  "nonEquilibriumReversible",
61  "unknownReactionType"
62 };
63 
64 const char* Foam::chemkinReader::reactionRateTypeNames[8] =
65 {
66  "Arrhenius",
67  "thirdBodyArrhenius",
68  "unimolecularFallOff",
69  "chemicallyActivatedBimolecular",
70  "LandauTeller",
71  "Janev",
72  "powerSeries",
73  "unknownReactionRateType"
74 };
75 
76 const char* Foam::chemkinReader::fallOffFunctionNames[4] =
77 {
78  "Lindemann",
79  "Troe",
80  "SRI",
81  "unknownFallOffFunctionType"
82 };
83 
84 void Foam::chemkinReader::initReactionKeywordTable()
85 {
86  reactionKeywordTable_.insert("M", thirdBodyReactionType);
87  reactionKeywordTable_.insert("LOW", unimolecularFallOffReactionType);
88  reactionKeywordTable_.insert
89  (
90  "HIGH",
91  chemicallyActivatedBimolecularReactionType
92  );
93  reactionKeywordTable_.insert("TROE", TroeReactionType);
94  reactionKeywordTable_.insert("SRI", SRIReactionType);
95  reactionKeywordTable_.insert("LT", LandauTellerReactionType);
96  reactionKeywordTable_.insert("RLT", reverseLandauTellerReactionType);
97  reactionKeywordTable_.insert("JAN", JanevReactionType);
98  reactionKeywordTable_.insert("FIT1", powerSeriesReactionRateType);
99  reactionKeywordTable_.insert("HV", radiationActivatedReactionType);
100  reactionKeywordTable_.insert("TDEP", speciesTempReactionType);
101  reactionKeywordTable_.insert("EXCI", energyLossReactionType);
102  reactionKeywordTable_.insert("MOME", plasmaMomentumTransfer);
103  reactionKeywordTable_.insert("XSMI", collisionCrossSection);
104  reactionKeywordTable_.insert("REV", nonEquilibriumReversibleReactionType);
105  reactionKeywordTable_.insert("DUPLICATE", duplicateReactionType);
106  reactionKeywordTable_.insert("DUP", duplicateReactionType);
107  reactionKeywordTable_.insert("FORD", speciesOrderForward);
108  reactionKeywordTable_.insert("RORD", speciesOrderReverse);
109  reactionKeywordTable_.insert("UNITS", UnitsOfReaction);
110  reactionKeywordTable_.insert("END", end);
111 }
112 
113 
114 Foam::scalar Foam::chemkinReader::molecularWeight
115 (
116  const List<specieElement>& specieComposition
117 ) const
118 {
119  scalar molWt = 0.0;
120 
121  forAll(specieComposition, i)
122  {
123  label nAtoms = specieComposition[i].nAtoms();
124  const word& elementName = specieComposition[i].name();
125 
126  if (isotopeAtomicWts_.found(elementName))
127  {
128  molWt += nAtoms*isotopeAtomicWts_[elementName];
129  }
130  else if (atomicWeights.found(elementName))
131  {
132  molWt += nAtoms*atomicWeights[elementName];
133  }
134  else
135  {
137  << "Unknown element " << elementName
138  << " on line " << lineNo_-1 << nl
139  << " specieComposition: " << specieComposition
140  << exit(FatalError);
141  }
142  }
143 
144  return molWt;
145 }
146 
147 
148 void Foam::chemkinReader::checkCoeffs
149 (
150  const scalarList& reactionCoeffs,
151  const char* reactionRateName,
152  const label nCoeffs
153 ) const
154 {
155  if (reactionCoeffs.size() != nCoeffs)
156  {
158  << "Wrong number of coefficients for the " << reactionRateName
159  << " rate expression on line "
160  << lineNo_-1 << ", should be "
161  << nCoeffs << " but " << reactionCoeffs.size() << " supplied." << nl
162  << "Coefficients are "
163  << reactionCoeffs << nl
164  << exit(FatalError);
165  }
166 }
167 
168 template<class ReactionRateType>
169 void Foam::chemkinReader::addReactionType
170 (
171  const reactionType rType,
172  DynamicList<gasHReaction::specieCoeffs>& lhs,
173  DynamicList<gasHReaction::specieCoeffs>& rhs,
174  const ReactionRateType& rr
175 )
176 {
177  switch (rType)
178  {
179  case irreversible:
180  {
181  reactions_.append
182  (
183  new IrreversibleReaction
184  <Reaction, gasHThermoPhysics, ReactionRateType>
185  (
186  ReactionProxy<gasHThermoPhysics>
187  (
188  speciesTable_,
189  lhs.shrink(),
190  rhs.shrink(),
191  speciesThermo_
192  ),
193  rr
194  )
195  );
196  }
197  break;
198 
199  case reversible:
200  {
201  reactions_.append
202  (
203  new ReversibleReaction
204  <Reaction, gasHThermoPhysics, ReactionRateType>
205  (
206  ReactionProxy<gasHThermoPhysics>
207  (
208  speciesTable_,
209  lhs.shrink(),
210  rhs.shrink(),
211  speciesThermo_
212  ),
213  rr
214  )
215  );
216  }
217  break;
218 
219  default:
220 
221  if (rType < 3)
222  {
224  << "Reaction type " << reactionTypeNames[rType]
225  << " on line " << lineNo_-1
226  << " not handled by this function"
227  << exit(FatalError);
228  }
229  else
230  {
232  << "Unknown reaction type " << rType
233  << " on line " << lineNo_-1
234  << exit(FatalError);
235  }
236  }
237 }
238 
239 template<template<class, class> class PressureDependencyType>
240 void Foam::chemkinReader::addPressureDependentReaction
241 (
242  const reactionType rType,
243  const fallOffFunctionType fofType,
244  DynamicList<gasHReaction::specieCoeffs>& lhs,
245  DynamicList<gasHReaction::specieCoeffs>& rhs,
246  const scalarList& efficiencies,
247  const scalarList& k0Coeffs,
248  const scalarList& kInfCoeffs,
249  const HashTable<scalarList>& reactionCoeffsTable,
250  const scalar Afactor0,
251  const scalar AfactorInf,
252  const scalar RR
253 )
254 {
255  checkCoeffs(k0Coeffs, "k0", 3);
256  checkCoeffs(kInfCoeffs, "kInf", 3);
257 
258  switch (fofType)
259  {
260  case Lindemann:
261  {
262  addReactionType
263  (
264  rType,
265  lhs, rhs,
266  PressureDependencyType
267  <ArrheniusReactionRate, LindemannFallOffFunction>
268  (
269  ArrheniusReactionRate
270  (
271  Afactor0*k0Coeffs[0],
272  k0Coeffs[1],
273  k0Coeffs[2]/RR
274  ),
275  ArrheniusReactionRate
276  (
277  AfactorInf*kInfCoeffs[0],
278  kInfCoeffs[1],
279  kInfCoeffs[2]/RR
280  ),
281  LindemannFallOffFunction(),
282  thirdBodyEfficiencies(speciesTable_, efficiencies)
283  )
284  );
285  break;
286  }
287  case Troe:
288  {
289  scalarList TroeCoeffs
290  (
291  reactionCoeffsTable[fallOffFunctionNames[fofType]]
292  );
293 
294  if (TroeCoeffs.size() != 4 && TroeCoeffs.size() != 3)
295  {
297  << "Wrong number of coefficients for Troe rate expression"
298  " on line " << lineNo_-1 << ", should be 3 or 4 but "
299  << TroeCoeffs.size() << " supplied." << nl
300  << "Coefficients are "
301  << TroeCoeffs << nl
302  << exit(FatalError);
303  }
304 
305  if (TroeCoeffs.size() == 3)
306  {
307  TroeCoeffs.setSize(4);
308  TroeCoeffs[3] = great;
309  }
310 
311  addReactionType
312  (
313  rType,
314  lhs, rhs,
315  PressureDependencyType
316  <ArrheniusReactionRate, TroeFallOffFunction>
317  (
318  ArrheniusReactionRate
319  (
320  Afactor0*k0Coeffs[0],
321  k0Coeffs[1],
322  k0Coeffs[2]/RR
323  ),
324  ArrheniusReactionRate
325  (
326  AfactorInf*kInfCoeffs[0],
327  kInfCoeffs[1],
328  kInfCoeffs[2]/RR
329  ),
330  TroeFallOffFunction
331  (
332  TroeCoeffs[0],
333  TroeCoeffs[1],
334  TroeCoeffs[2],
335  TroeCoeffs[3]
336  ),
337  thirdBodyEfficiencies(speciesTable_, efficiencies)
338  )
339  );
340  break;
341  }
342  case SRI:
343  {
344  scalarList SRICoeffs
345  (
346  reactionCoeffsTable[fallOffFunctionNames[fofType]]
347  );
348 
349  if (SRICoeffs.size() != 5 && SRICoeffs.size() != 3)
350  {
352  << "Wrong number of coefficients for SRI rate expression"
353  " on line " << lineNo_-1 << ", should be 3 or 5 but "
354  << SRICoeffs.size() << " supplied." << nl
355  << "Coefficients are "
356  << SRICoeffs << nl
357  << exit(FatalError);
358  }
359 
360  if (SRICoeffs.size() == 3)
361  {
362  SRICoeffs.setSize(5);
363  SRICoeffs[3] = 1.0;
364  SRICoeffs[4] = 0.0;
365  }
366 
367  addReactionType
368  (
369  rType,
370  lhs, rhs,
371  PressureDependencyType
372  <ArrheniusReactionRate, SRIFallOffFunction>
373  (
374  ArrheniusReactionRate
375  (
376  Afactor0*k0Coeffs[0],
377  k0Coeffs[1],
378  k0Coeffs[2]/RR
379  ),
380  ArrheniusReactionRate
381  (
382  AfactorInf*kInfCoeffs[0],
383  kInfCoeffs[1],
384  kInfCoeffs[2]/RR
385  ),
386  SRIFallOffFunction
387  (
388  SRICoeffs[0],
389  SRICoeffs[1],
390  SRICoeffs[2],
391  SRICoeffs[3],
392  SRICoeffs[4]
393  ),
394  thirdBodyEfficiencies(speciesTable_, efficiencies)
395  )
396  );
397  break;
398  }
399  default:
400  {
402  << "Fall-off function type "
403  << fallOffFunctionNames[fofType]
404  << " on line " << lineNo_-1
405  << " not implemented"
406  << exit(FatalError);
407  }
408  }
409 }
410 
411 
412 void Foam::chemkinReader::addReaction
413 (
414  DynamicList<gasHReaction::specieCoeffs>& lhs,
415  DynamicList<gasHReaction::specieCoeffs>& rhs,
416  const scalarList& efficiencies,
417  const reactionType rType,
418  const reactionRateType rrType,
419  const fallOffFunctionType fofType,
420  const scalarList& ArrheniusCoeffs,
421  HashTable<scalarList>& reactionCoeffsTable,
422  const scalar RR
423 )
424 {
425  checkCoeffs(ArrheniusCoeffs, "Arrhenius", 3);
426 
427  scalarList nAtoms(elementNames_.size(), 0.0);
428 
429  forAll(lhs, i)
430  {
431  const List<specieElement>& specieComposition =
432  speciesComposition_[speciesTable_[lhs[i].index]];
433 
434  forAll(specieComposition, j)
435  {
436  label elementi = elementIndices_[specieComposition[j].name()];
437  nAtoms[elementi] +=
438  lhs[i].stoichCoeff*specieComposition[j].nAtoms();
439  }
440  }
441 
442  forAll(rhs, i)
443  {
444  const List<specieElement>& specieComposition =
445  speciesComposition_[speciesTable_[rhs[i].index]];
446 
447  forAll(specieComposition, j)
448  {
449  label elementi = elementIndices_[specieComposition[j].name()];
450  nAtoms[elementi] -=
451  rhs[i].stoichCoeff*specieComposition[j].nAtoms();
452  }
453  }
454 
455 
456  // Calculate the unit conversion factor for the A coefficient
457  // for the change from mol/cm^3 to kmol/m^3 concentraction units
458  const scalar concFactor = 0.001;
459  scalar sumExp = 0.0;
460  forAll(lhs, i)
461  {
462  sumExp += lhs[i].exponent;
463  }
464  scalar Afactor = pow(concFactor, sumExp - 1.0);
465 
466  scalar AfactorRev = Afactor;
467 
468  if (rType == nonEquilibriumReversible)
469  {
470  sumExp = 0.0;
471  forAll(rhs, i)
472  {
473  sumExp += rhs[i].exponent;
474  }
475  AfactorRev = pow(concFactor, sumExp - 1.0);
476  }
477 
478  switch (rrType)
479  {
480  case Arrhenius:
481  {
482  if (rType == nonEquilibriumReversible)
483  {
484  const scalarList& reverseArrheniusCoeffs =
485  reactionCoeffsTable[reactionTypeNames[rType]];
486 
487  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
488 
489  reactions_.append
490  (
491  new NonEquilibriumReversibleReaction
492  <Reaction, gasHThermoPhysics, ArrheniusReactionRate>
493  (
494  ReactionProxy<gasHThermoPhysics>
495  (
496  speciesTable_,
497  lhs.shrink(),
498  rhs.shrink(),
499  speciesThermo_
500  ),
501  ArrheniusReactionRate
502  (
503  Afactor*ArrheniusCoeffs[0],
504  ArrheniusCoeffs[1],
505  ArrheniusCoeffs[2]/RR
506  ),
507  ArrheniusReactionRate
508  (
509  AfactorRev*reverseArrheniusCoeffs[0],
510  reverseArrheniusCoeffs[1],
511  reverseArrheniusCoeffs[2]/RR
512  )
513  )
514  );
515  }
516  else
517  {
518  addReactionType
519  (
520  rType,
521  lhs, rhs,
522  ArrheniusReactionRate
523  (
524  Afactor*ArrheniusCoeffs[0],
525  ArrheniusCoeffs[1],
526  ArrheniusCoeffs[2]/RR
527  )
528  );
529  }
530  break;
531  }
532  case thirdBodyArrhenius:
533  {
534  if (rType == nonEquilibriumReversible)
535  {
536  const scalarList& reverseArrheniusCoeffs =
537  reactionCoeffsTable[reactionTypeNames[rType]];
538 
539  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
540 
541  reactions_.append
542  (
543  new NonEquilibriumReversibleReaction
544  <
545  Reaction,
547  thirdBodyArrheniusReactionRate
548  >
549  (
550  ReactionProxy<gasHThermoPhysics>
551  (
552  speciesTable_,
553  lhs.shrink(),
554  rhs.shrink(),
555  speciesThermo_
556  ),
557  thirdBodyArrheniusReactionRate
558  (
559  Afactor*concFactor*ArrheniusCoeffs[0],
560  ArrheniusCoeffs[1],
561  ArrheniusCoeffs[2]/RR,
562  thirdBodyEfficiencies(speciesTable_, efficiencies)
563  ),
564  thirdBodyArrheniusReactionRate
565  (
566  AfactorRev*concFactor*reverseArrheniusCoeffs[0],
567  reverseArrheniusCoeffs[1],
568  reverseArrheniusCoeffs[2]/RR,
569  thirdBodyEfficiencies(speciesTable_, efficiencies)
570  )
571  )
572  );
573  }
574  else
575  {
576  addReactionType
577  (
578  rType,
579  lhs, rhs,
580  thirdBodyArrheniusReactionRate
581  (
582  Afactor*concFactor*ArrheniusCoeffs[0],
583  ArrheniusCoeffs[1],
584  ArrheniusCoeffs[2]/RR,
585  thirdBodyEfficiencies(speciesTable_, efficiencies)
586  )
587  );
588  }
589  break;
590  }
591  case unimolecularFallOff:
592  {
593  addPressureDependentReaction<FallOffReactionRate>
594  (
595  rType,
596  fofType,
597  lhs,
598  rhs,
599  efficiencies,
600  reactionCoeffsTable[reactionRateTypeNames[rrType]],
601  ArrheniusCoeffs,
602  reactionCoeffsTable,
603  concFactor*Afactor,
604  Afactor,
605  RR
606  );
607  break;
608  }
609  case chemicallyActivatedBimolecular:
610  {
611  addPressureDependentReaction<ChemicallyActivatedReactionRate>
612  (
613  rType,
614  fofType,
615  lhs,
616  rhs,
617  efficiencies,
618  ArrheniusCoeffs,
619  reactionCoeffsTable[reactionRateTypeNames[rrType]],
620  reactionCoeffsTable,
621  Afactor,
622  Afactor/concFactor,
623  RR
624  );
625  break;
626  }
627  case LandauTeller:
628  {
629  const scalarList& LandauTellerCoeffs =
630  reactionCoeffsTable[reactionRateTypeNames[rrType]];
631  checkCoeffs(LandauTellerCoeffs, "Landau-Teller", 2);
632 
633  if (rType == nonEquilibriumReversible)
634  {
635  const scalarList& reverseArrheniusCoeffs =
636  reactionCoeffsTable[reactionTypeNames[rType]];
637  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
638 
639  const scalarList& reverseLandauTellerCoeffs =
640  reactionCoeffsTable
641  [
642  word(reactionTypeNames[rType])
643  + reactionRateTypeNames[rrType]
644  ];
645  checkCoeffs(LandauTellerCoeffs, "reverse Landau-Teller", 2);
646 
647  reactions_.append
648  (
649  new NonEquilibriumReversibleReaction
650  <
651  Reaction,
653  LandauTellerReactionRate
654  >
655  (
656  ReactionProxy<gasHThermoPhysics>
657  (
658  speciesTable_,
659  lhs.shrink(),
660  rhs.shrink(),
661  speciesThermo_
662  ),
663  LandauTellerReactionRate
664  (
665  Afactor*ArrheniusCoeffs[0],
666  ArrheniusCoeffs[1],
667  ArrheniusCoeffs[2]/RR,
668  LandauTellerCoeffs[0],
669  LandauTellerCoeffs[1]
670  ),
671  LandauTellerReactionRate
672  (
673  AfactorRev*reverseArrheniusCoeffs[0],
674  reverseArrheniusCoeffs[1],
675  reverseArrheniusCoeffs[2]/RR,
676  reverseLandauTellerCoeffs[0],
677  reverseLandauTellerCoeffs[1]
678  )
679  )
680  );
681  }
682  else
683  {
684  addReactionType
685  (
686  rType,
687  lhs, rhs,
688  LandauTellerReactionRate
689  (
690  Afactor*ArrheniusCoeffs[0],
691  ArrheniusCoeffs[1],
692  ArrheniusCoeffs[2]/RR,
693  LandauTellerCoeffs[0],
694  LandauTellerCoeffs[1]
695  )
696  );
697  }
698  break;
699  }
700  case Janev:
701  {
702  const scalarList& JanevCoeffs =
703  reactionCoeffsTable[reactionRateTypeNames[rrType]];
704 
705  checkCoeffs(JanevCoeffs, "Janev", 9);
706 
707  addReactionType
708  (
709  rType,
710  lhs, rhs,
711  JanevReactionRate
712  (
713  Afactor*ArrheniusCoeffs[0],
714  ArrheniusCoeffs[1],
715  ArrheniusCoeffs[2]/RR,
716  FixedList<scalar, 9>(JanevCoeffs)
717  )
718  );
719  break;
720  }
721  case powerSeries:
722  {
723  const scalarList& powerSeriesCoeffs =
724  reactionCoeffsTable[reactionRateTypeNames[rrType]];
725 
726  checkCoeffs(powerSeriesCoeffs, "power-series", 4);
727 
728  addReactionType
729  (
730  rType,
731  lhs, rhs,
732  powerSeriesReactionRate
733  (
734  Afactor*ArrheniusCoeffs[0],
735  ArrheniusCoeffs[1],
736  ArrheniusCoeffs[2]/RR,
737  FixedList<scalar, 4>(powerSeriesCoeffs)
738  )
739  );
740  break;
741  }
742  case unknownReactionRateType:
743  {
745  << "Internal error on line " << lineNo_-1
746  << ": reaction rate type has not been set"
747  << exit(FatalError);
748  break;
749  }
750  default:
751  {
753  << "Reaction rate type " << reactionRateTypeNames[rrType]
754  << " on line " << lineNo_-1
755  << " not implemented"
756  << exit(FatalError);
757  }
758  }
759 
760 
761  forAll(nAtoms, i)
762  {
763  if (mag(nAtoms[i]) > imbalanceTol_)
764  {
766  << "Elemental imbalance of " << mag(nAtoms[i])
767  << " in " << elementNames_[i]
768  << " in reaction" << nl
769  << reactions_.last() << nl
770  << " on line " << lineNo_-1
771  << exit(FatalError);
772  }
773  }
774 
775  lhs.clear();
776  rhs.clear();
777  reactionCoeffsTable.clear();
778 }
779 
780 
781 void Foam::chemkinReader::read
782 (
783  const fileName& CHEMKINFileName,
784  const fileName& thermoFileName,
785  const fileName& transportFileName
786 )
787 {
790 
791  transportDict_.read(IFstream(transportFileName)());
792 
793  if (thermoFileName != fileName::null)
794  {
795  std::ifstream thermoStream(thermoFileName.c_str());
796 
797  if (!thermoStream)
798  {
800  << "file " << thermoFileName << " not found"
801  << exit(FatalError);
802  }
803 
804  yy_buffer_state* bufferPtr(yy_create_buffer(&thermoStream, yyBufSize));
805  yy_switch_to_buffer(bufferPtr);
806 
807  while (lex() != 0)
808  {}
809 
810  yy_delete_buffer(bufferPtr);
811 
812  lineNo_ = 1;
813  }
814 
815  std::ifstream CHEMKINStream(CHEMKINFileName.c_str());
816 
817  if (!CHEMKINStream)
818  {
820  << "file " << CHEMKINFileName << " not found"
821  << exit(FatalError);
822  }
823 
824  yy_buffer_state* bufferPtr(yy_create_buffer(&CHEMKINStream, yyBufSize));
825  yy_switch_to_buffer(bufferPtr);
826 
827  initReactionKeywordTable();
828 
829  while (lex() != 0)
830  {}
831 
832  yy_delete_buffer(bufferPtr);
833 }
834 
835 
836 // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
837 
838 Foam::chemkinReader::chemkinReader
839 (
840  speciesTable& species,
841  const fileName& CHEMKINFileName,
842  const fileName& transportFileName,
843  const fileName& thermoFileName,
844  const bool newFormat
845 )
846 :
847  lineNo_(1),
848  specieNames_(10),
849  speciesTable_(species),
850  reactions_(speciesTable_, speciesThermo_),
851  newFormat_(newFormat),
852  imbalanceTol_(rootSmall)
853 {
854  read(CHEMKINFileName, thermoFileName, transportFileName);
855 }
856 
857 
858 Foam::chemkinReader::chemkinReader
859 (
860  const dictionary& thermoDict,
861  speciesTable& species
862 )
863 :
864  lineNo_(1),
865  specieNames_(10),
866  speciesTable_(species),
867  reactions_(speciesTable_, speciesThermo_),
868  newFormat_(thermoDict.lookupOrDefault("newFormat", false)),
869  imbalanceTol_(thermoDict.lookupOrDefault("imbalanceTolerance", rootSmall))
870 {
871  if (newFormat_)
872  {
873  Info<< "Reading CHEMKIN thermo data in new file format" << endl;
874  }
875 
876  fileName chemkinFile(fileName(thermoDict.lookup("CHEMKINFile")).expand());
877 
878  fileName thermoFile = fileName::null;
879 
880  if (thermoDict.found("CHEMKINThermoFile"))
881  {
882  thermoFile = fileName(thermoDict.lookup("CHEMKINThermoFile")).expand();
883  }
884 
885  fileName transportFile
886  (
887  fileName(thermoDict.lookup("CHEMKINTransportFile")).expand()
888  );
889 
890  // allow relative file names
891  fileName relPath = thermoDict.name().path();
892  if (relPath.size())
893  {
894  if (!chemkinFile.isAbsolute())
895  {
896  chemkinFile = relPath/chemkinFile;
897  }
898 
899  if (thermoFile != fileName::null && !thermoFile.isAbsolute())
900  {
901  thermoFile = relPath/thermoFile;
902  }
903 
904  if (!transportFile.isAbsolute())
905  {
906  transportFile = relPath/transportFile;
907  }
908  }
909 
910  read(chemkinFile, thermoFile, transportFile);
911 }
912 
913 
914 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:431
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
string expand(const string &, const HashTable< string, word, string::hash > &mapping, const char sigil='$')
Expand occurrences of variables according to the mapping.
Definition: stringOps.C:75
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
A class for handling file names.
Definition: fileName.H:69
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
static const fileName null
An empty fileName.
Definition: fileName.H:97
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
Macros for easy insertion into run-time selection tables.
static scalar TlowDefault
Default temperature limits of applicability of reaction rates.
Definition: Reaction.H:89
bool read(const char *, int32_t &)
Definition: int32IO.C:85
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:103
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:113
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:57
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
addChemistryReaderType(chemkinReader, gasHThermoPhysics)
static scalar ThighDefault
Definition: Reaction.H:89
atomicWeightTable atomicWeights
static const char nl
Definition: Ostream.H:265
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
A wordList with hashed indices for faster lookup by name.
messageStream Info
dimensioned< scalar > mag(const dimensioned< Type > &)
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:249
const scalar RR
Universal gas constant (default in [J/(kmol K)])
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:576
sutherlandTransport< species::thermo< janafThermo< perfectGas< specie > >, sensibleEnthalpy > > gasHThermoPhysics