chemkinReader.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "chemkinReader.H"
30 #include "IFstream.H"
31 #include "atomicWeights.H"
32 #include "IrreversibleReaction.H"
33 #include "ReversibleReaction.H"
35 #include "ArrheniusReactionRate.H"
37 #include "FallOffReactionRate.H"
40 #include "TroeFallOffFunction.H"
41 #include "SRIFallOffFunction.H"
43 #include "JanevReactionRate.H"
46 
47 
48 /* * * * * * * * * * * * * * * * * Static data * * * * * * * * * * * * * * * */
49 
50 namespace Foam
51 {
53 }
54 
55 
56 /* * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * */
57 
58 const char* Foam::chemkinReader::reactionTypeNames[4] =
59 {
60  "irreversible",
61  "reversible",
62  "nonEquilibriumReversible",
63  "unknownReactionType"
64 };
65 
66 const char* Foam::chemkinReader::reactionRateTypeNames[8] =
67 {
68  "Arrhenius",
69  "thirdBodyArrhenius",
70  "unimolecularFallOff",
71  "chemicallyActivatedBimolecular",
72  "LandauTeller",
73  "Janev",
74  "powerSeries",
75  "unknownReactionRateType"
76 };
77 
78 const char* Foam::chemkinReader::fallOffFunctionNames[4] =
79 {
80  "Lindemann",
81  "Troe",
82  "SRI",
83  "unknownFallOffFunctionType"
84 };
85 
86 void Foam::chemkinReader::initReactionKeywordTable()
87 {
88  reactionKeywordTable_.insert("M", thirdBodyReactionType);
89  reactionKeywordTable_.insert("LOW", unimolecularFallOffReactionType);
90  reactionKeywordTable_.insert
91  (
92  "HIGH",
93  chemicallyActivatedBimolecularReactionType
94  );
95  reactionKeywordTable_.insert("TROE", TroeReactionType);
96  reactionKeywordTable_.insert("SRI", SRIReactionType);
97  reactionKeywordTable_.insert("LT", LandauTellerReactionType);
98  reactionKeywordTable_.insert("RLT", reverseLandauTellerReactionType);
99  reactionKeywordTable_.insert("JAN", JanevReactionType);
100  reactionKeywordTable_.insert("FIT1", powerSeriesReactionRateType);
101  reactionKeywordTable_.insert("HV", radiationActivatedReactionType);
102  reactionKeywordTable_.insert("TDEP", speciesTempReactionType);
103  reactionKeywordTable_.insert("EXCI", energyLossReactionType);
104  reactionKeywordTable_.insert("MOME", plasmaMomentumTransfer);
105  reactionKeywordTable_.insert("XSMI", collisionCrossSection);
106  reactionKeywordTable_.insert("REV", nonEquilibriumReversibleReactionType);
107  reactionKeywordTable_.insert("DUPLICATE", duplicateReactionType);
108  reactionKeywordTable_.insert("DUP", duplicateReactionType);
109  reactionKeywordTable_.insert("FORD", speciesOrderForward);
110  reactionKeywordTable_.insert("RORD", speciesOrderReverse);
111  reactionKeywordTable_.insert("UNITS", UnitsOfReaction);
112  reactionKeywordTable_.insert("END", end);
113 }
114 
115 
116 Foam::scalar Foam::chemkinReader::molecularWeight
117 (
118  const List<specieElement>& specieComposition
119 ) const
120 {
121  scalar molWt = 0.0;
122 
123  forAll(specieComposition, i)
124  {
125  label nAtoms = specieComposition[i].nAtoms();
126  const word& elementName = specieComposition[i].name();
127 
128  if (isotopeAtomicWts_.found(elementName))
129  {
130  molWt += nAtoms*isotopeAtomicWts_[elementName];
131  }
132  else if (atomicWeights.found(elementName))
133  {
134  molWt += nAtoms*atomicWeights[elementName];
135  }
136  else
137  {
139  << "Unknown element " << elementName
140  << " on line " << lineNo_-1 << nl
141  << " specieComposition: " << specieComposition
142  << exit(FatalError);
143  }
144  }
145 
146  return molWt;
147 }
148 
149 
150 void Foam::chemkinReader::checkCoeffs
151 (
152  const scalarList& reactionCoeffs,
153  const char* reactionRateName,
154  const label nCoeffs
155 ) const
156 {
157  if (reactionCoeffs.size() != nCoeffs)
158  {
160  << "Wrong number of coefficients for the " << reactionRateName
161  << " rate expression on line "
162  << lineNo_-1 << ", should be "
163  << nCoeffs << " but " << reactionCoeffs.size() << " supplied." << nl
164  << "Coefficients are "
165  << reactionCoeffs << nl
166  << exit(FatalError);
167  }
168 }
169 
170 template<class ReactionRateType>
171 void Foam::chemkinReader::addReactionType
172 (
173  const reactionType rType,
174  DynamicList<gasHReaction::specieCoeffs>& lhs,
175  DynamicList<gasHReaction::specieCoeffs>& rhs,
176  const ReactionRateType& rr
177 )
178 {
179  switch (rType)
180  {
181  case irreversible:
182  {
183  reactions_.append
184  (
185  new IrreversibleReaction
186  <Reaction, gasHThermoPhysics, ReactionRateType>
187  (
188  Reaction<gasHThermoPhysics>
189  (
190  speciesTable_,
191  lhs.shrink(),
192  rhs.shrink(),
193  speciesThermo_
194  ),
195  rr
196  )
197  );
198  }
199  break;
200 
201  case reversible:
202  {
203  reactions_.append
204  (
205  new ReversibleReaction
206  <Reaction, gasHThermoPhysics, ReactionRateType>
207  (
208  Reaction<gasHThermoPhysics>
209  (
210  speciesTable_,
211  lhs.shrink(),
212  rhs.shrink(),
213  speciesThermo_
214  ),
215  rr
216  )
217  );
218  }
219  break;
220 
221  default:
222  {
223  if (rType < 3)
224  {
226  << "Unhandled reaction type " << reactionTypeNames[rType]
227  << " on line " << lineNo_-1 << nl
228  << exit(FatalError);
229  }
230  else
231  {
233  << "Unknown reaction type (" << int(rType)
234  << "), on line " << lineNo_-1 << nl
235  << exit(FatalError);
236  }
237  }
238  }
239 }
240 
241 template<template<class, class> class PressureDependencyType>
242 void Foam::chemkinReader::addPressureDependentReaction
243 (
244  const reactionType rType,
245  const fallOffFunctionType fofType,
246  DynamicList<gasHReaction::specieCoeffs>& lhs,
247  DynamicList<gasHReaction::specieCoeffs>& rhs,
248  const scalarList& efficiencies,
249  const scalarList& k0Coeffs,
250  const scalarList& kInfCoeffs,
251  const HashTable<scalarList>& reactionCoeffsTable,
252  const scalar Afactor0,
253  const scalar AfactorInf,
254  const scalar RR
255 )
256 {
257  checkCoeffs(k0Coeffs, "k0", 3);
258  checkCoeffs(kInfCoeffs, "kInf", 3);
259 
260  switch (fofType)
261  {
262  case Lindemann:
263  {
264  addReactionType
265  (
266  rType,
267  lhs, rhs,
268  PressureDependencyType
269  <ArrheniusReactionRate, LindemannFallOffFunction>
270  (
271  ArrheniusReactionRate
272  (
273  Afactor0*k0Coeffs[0],
274  k0Coeffs[1],
275  k0Coeffs[2]/RR
276  ),
277  ArrheniusReactionRate
278  (
279  AfactorInf*kInfCoeffs[0],
280  kInfCoeffs[1],
281  kInfCoeffs[2]/RR
282  ),
283  LindemannFallOffFunction(),
284  thirdBodyEfficiencies(speciesTable_, efficiencies)
285  )
286  );
287  break;
288  }
289  case Troe:
290  {
291  scalarList TroeCoeffs
292  (
293  reactionCoeffsTable[fallOffFunctionNames[fofType]]
294  );
295 
296  if (TroeCoeffs.size() != 4 && TroeCoeffs.size() != 3)
297  {
299  << "Wrong number of coefficients for Troe rate expression"
300  " on line " << lineNo_-1 << ", should be 3 or 4 but "
301  << TroeCoeffs.size() << " supplied." << nl
302  << "Coefficients are "
303  << TroeCoeffs << nl
304  << exit(FatalError);
305  }
306 
307  if (TroeCoeffs.size() == 3)
308  {
309  TroeCoeffs.setSize(4);
310  TroeCoeffs[3] = GREAT;
311  }
312 
313  addReactionType
314  (
315  rType,
316  lhs, rhs,
317  PressureDependencyType
318  <ArrheniusReactionRate, TroeFallOffFunction>
319  (
320  ArrheniusReactionRate
321  (
322  Afactor0*k0Coeffs[0],
323  k0Coeffs[1],
324  k0Coeffs[2]/RR
325  ),
326  ArrheniusReactionRate
327  (
328  AfactorInf*kInfCoeffs[0],
329  kInfCoeffs[1],
330  kInfCoeffs[2]/RR
331  ),
332  TroeFallOffFunction
333  (
334  TroeCoeffs[0],
335  TroeCoeffs[1],
336  TroeCoeffs[2],
337  TroeCoeffs[3]
338  ),
339  thirdBodyEfficiencies(speciesTable_, efficiencies)
340  )
341  );
342  break;
343  }
344  case SRI:
345  {
346  scalarList SRICoeffs
347  (
348  reactionCoeffsTable[fallOffFunctionNames[fofType]]
349  );
350 
351  if (SRICoeffs.size() != 5 && SRICoeffs.size() != 3)
352  {
354  << "Wrong number of coefficients for SRI rate expression"
355  " on line " << lineNo_-1 << ", should be 3 or 5 but "
356  << SRICoeffs.size() << " supplied." << nl
357  << "Coefficients are "
358  << SRICoeffs << nl
359  << exit(FatalError);
360  }
361 
362  if (SRICoeffs.size() == 3)
363  {
364  SRICoeffs.setSize(5);
365  SRICoeffs[3] = 1.0;
366  SRICoeffs[4] = 0.0;
367  }
368 
369  addReactionType
370  (
371  rType,
372  lhs, rhs,
373  PressureDependencyType
374  <ArrheniusReactionRate, SRIFallOffFunction>
375  (
376  ArrheniusReactionRate
377  (
378  Afactor0*k0Coeffs[0],
379  k0Coeffs[1],
380  k0Coeffs[2]/RR
381  ),
382  ArrheniusReactionRate
383  (
384  AfactorInf*kInfCoeffs[0],
385  kInfCoeffs[1],
386  kInfCoeffs[2]/RR
387  ),
388  SRIFallOffFunction
389  (
390  SRICoeffs[0],
391  SRICoeffs[1],
392  SRICoeffs[2],
393  SRICoeffs[3],
394  SRICoeffs[4]
395  ),
396  thirdBodyEfficiencies(speciesTable_, efficiencies)
397  )
398  );
399  break;
400  }
401  default:
402  {
404  << "Fall-off function type (" << int(fofType)
405  << ") not implemented, line " << lineNo_-1
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(), Zero);
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 concentration 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  Reaction<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  Reaction<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  <Reaction, gasHThermoPhysics, LandauTellerReactionRate>
651  (
652  Reaction<gasHThermoPhysics>
653  (
654  speciesTable_,
655  lhs.shrink(),
656  rhs.shrink(),
657  speciesThermo_
658  ),
659  LandauTellerReactionRate
660  (
661  Afactor*ArrheniusCoeffs[0],
662  ArrheniusCoeffs[1],
663  ArrheniusCoeffs[2]/RR,
664  LandauTellerCoeffs[0],
665  LandauTellerCoeffs[1]
666  ),
667  LandauTellerReactionRate
668  (
669  AfactorRev*reverseArrheniusCoeffs[0],
670  reverseArrheniusCoeffs[1],
671  reverseArrheniusCoeffs[2]/RR,
672  reverseLandauTellerCoeffs[0],
673  reverseLandauTellerCoeffs[1]
674  )
675  )
676  );
677  }
678  else
679  {
680  addReactionType
681  (
682  rType,
683  lhs, rhs,
684  LandauTellerReactionRate
685  (
686  Afactor*ArrheniusCoeffs[0],
687  ArrheniusCoeffs[1],
688  ArrheniusCoeffs[2]/RR,
689  LandauTellerCoeffs[0],
690  LandauTellerCoeffs[1]
691  )
692  );
693  }
694  break;
695  }
696  case Janev:
697  {
698  const scalarList& JanevCoeffs =
699  reactionCoeffsTable[reactionRateTypeNames[rrType]];
700 
701  checkCoeffs(JanevCoeffs, "Janev", 9);
702 
703  addReactionType
704  (
705  rType,
706  lhs, rhs,
707  JanevReactionRate
708  (
709  Afactor*ArrheniusCoeffs[0],
710  ArrheniusCoeffs[1],
711  ArrheniusCoeffs[2]/RR,
712  FixedList<scalar, 9>(JanevCoeffs)
713  )
714  );
715  break;
716  }
717  case powerSeries:
718  {
719  const scalarList& powerSeriesCoeffs =
720  reactionCoeffsTable[reactionRateTypeNames[rrType]];
721 
722  checkCoeffs(powerSeriesCoeffs, "power-series", 4);
723 
724  addReactionType
725  (
726  rType,
727  lhs, rhs,
728  powerSeriesReactionRate
729  (
730  Afactor*ArrheniusCoeffs[0],
731  ArrheniusCoeffs[1],
732  ArrheniusCoeffs[2]/RR,
733  FixedList<scalar, 4>(powerSeriesCoeffs)
734  )
735  );
736  break;
737  }
738  case unknownReactionRateType:
739  {
741  << "Internal error on line " << lineNo_-1
742  << ": reaction rate type has not been set"
743  << exit(FatalError);
744  break;
745  }
746  default:
747  {
749  << "Reaction rate type (" << int(rrType)
750  << ") not implemented, on line " << lineNo_-1
751  << exit(FatalError);
752  }
753  }
754 
755 
756  forAll(nAtoms, i)
757  {
758  if (mag(nAtoms[i]) > imbalanceTol_)
759  {
761  << "Elemental imbalance of " << mag(nAtoms[i])
762  << " in " << elementNames_[i]
763  << " in reaction" << nl
764  << reactions_.last() << nl
765  << " on line " << lineNo_-1
766  << exit(FatalError);
767  }
768  }
769 
770  lhs.clear();
771  rhs.clear();
772  reactionCoeffsTable.clear();
773 }
774 
775 
776 void Foam::chemkinReader::read
777 (
778  const fileName& CHEMKINFileName,
779  const fileName& thermoFileName,
780  const fileName& transportFileName
781 )
782 {
783  transportDict_.read(IFstream(transportFileName)());
784 
785  if (!thermoFileName.empty())
786  {
787  std::ifstream thermoStream(thermoFileName);
788 
789  if (!thermoStream)
790  {
792  << "file " << thermoFileName << " not found"
793  << exit(FatalError);
794  }
795 
796  yy_buffer_state* bufferPtr(yy_create_buffer(&thermoStream, yyBufSize));
797  yy_switch_to_buffer(bufferPtr);
798 
799  while (lex() != 0)
800  {}
801 
802  yy_delete_buffer(bufferPtr);
803 
804  lineNo_ = 1;
805  }
806 
807  std::ifstream CHEMKINStream(CHEMKINFileName);
808 
809  if (!CHEMKINStream)
810  {
812  << "file " << CHEMKINFileName << " not found"
813  << exit(FatalError);
814  }
815 
816  yy_buffer_state* bufferPtr(yy_create_buffer(&CHEMKINStream, yyBufSize));
817  yy_switch_to_buffer(bufferPtr);
818 
819  initReactionKeywordTable();
820 
821  while (lex() != 0)
822  {}
823 
824  yy_delete_buffer(bufferPtr);
825 }
826 
827 
828 // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
829 
830 Foam::chemkinReader::chemkinReader
831 (
832  speciesTable& species,
833  const fileName& CHEMKINFileName,
834  const fileName& transportFileName,
835  const fileName& thermoFileName,
836  const bool newFormat
837 )
838 :
839  lineNo_(1),
840  specieNames_(10),
841  speciesTable_(species),
842  reactions_(speciesTable_, speciesThermo_),
843  newFormat_(newFormat),
844  imbalanceTol_(ROOTSMALL)
845 {
846  read(CHEMKINFileName, thermoFileName, transportFileName);
847 }
848 
849 
850 Foam::chemkinReader::chemkinReader
851 (
852  const dictionary& thermoDict,
853  speciesTable& species
854 )
855 :
856  lineNo_(1),
857  specieNames_(10),
858  speciesTable_(species),
859  reactions_(speciesTable_, speciesThermo_),
860  newFormat_(thermoDict.getOrDefault("newFormat", false)),
861  imbalanceTol_(thermoDict.getOrDefault("imbalanceTolerance", ROOTSMALL))
862 {
863  if (newFormat_)
864  {
865  Info<< "Reading CHEMKIN thermo data in new file format" << endl;
866  }
867 
868  fileName chemkinFile(thermoDict.get<fileName>("CHEMKINFile"));
869  chemkinFile.expand();
870 
871  fileName thermoFile;
872  thermoDict.readIfPresent("CHEMKINThermoFile", thermoFile);
873  thermoFile.expand();
874 
875  fileName transportFile(thermoDict.get<fileName>("CHEMKINTransportFile"));
876  transportFile.expand();
877 
878  // allow relative file names
879  fileName relPath = thermoDict.name().path();
880  if (relPath.size())
881  {
882  if (!chemkinFile.isAbsolute())
883  {
884  chemkinFile = relPath/chemkinFile;
885  }
886 
887  if (!thermoFile.empty() && !thermoFile.isAbsolute())
888  {
889  thermoFile = relPath/thermoFile;
890  }
891 
892  if (!transportFile.isAbsolute())
893  {
894  transportFile = relPath/transportFile;
895  }
896  }
897 
898  read(chemkinFile, thermoFile, transportFile);
899 }
900 
901 
902 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
List< scalar > scalarList
List of scalar.
Definition: scalarList.H:32
A class for handling file names.
Definition: fileName.H:72
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
bool found(const Key &key) const
Same as contains()
Definition: HashTable.H:1370
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Macros for easy insertion into run-time selection tables.
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:127
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
addChemistryReaderType(chemkinReader, gasHThermoPhysics)
const dictionary & thermoDict
Definition: EEqn.H:16
atomicWeightTable atomicWeights
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
A wordList with hashed named lookup, which can be faster in some situations than using the normal lis...
messageStream Info
Information stream (stdout output on master, null elsewhere)
const scalar RR
Universal gas constant: default in [J/(kmol K)].
Namespace for OpenFOAM.
sutherlandTransport< species::thermo< janafThermo< perfectGas< specie > >, sensibleEnthalpy > > gasHThermoPhysics
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127