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 | Copyright (C) 2011-2016 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 "IrreversibleReaction.H"
30 #include "ReversibleReaction.H"
32 #include "ArrheniusReactionRate.H"
34 #include "FallOffReactionRate.H"
37 #include "TroeFallOffFunction.H"
38 #include "SRIFallOffFunction.H"
40 #include "JanevReactionRate.H"
43 
44 
45 /* * * * * * * * * * * * * * * * * Static data * * * * * * * * * * * * * * * */
46 
47 namespace Foam
48 {
50 }
51 
52 
53 /* * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * */
54 
55 const char* Foam::chemkinReader::reactionTypeNames[4] =
56 {
57  "irreversible",
58  "reversible",
59  "nonEquilibriumReversible",
60  "unknownReactionType"
61 };
62 
63 const char* Foam::chemkinReader::reactionRateTypeNames[8] =
64 {
65  "Arrhenius",
66  "thirdBodyArrhenius",
67  "unimolecularFallOff",
68  "chemicallyActivatedBimolecular",
69  "LandauTeller",
70  "Janev",
71  "powerSeries",
72  "unknownReactionRateType"
73 };
74 
75 const char* Foam::chemkinReader::fallOffFunctionNames[4] =
76 {
77  "Lindemann",
78  "Troe",
79  "SRI",
80  "unknownFallOffFunctionType"
81 };
82 
83 void Foam::chemkinReader::initReactionKeywordTable()
84 {
85  reactionKeywordTable_.insert("M", thirdBodyReactionType);
86  reactionKeywordTable_.insert("LOW", unimolecularFallOffReactionType);
87  reactionKeywordTable_.insert
88  (
89  "HIGH",
90  chemicallyActivatedBimolecularReactionType
91  );
92  reactionKeywordTable_.insert("TROE", TroeReactionType);
93  reactionKeywordTable_.insert("SRI", SRIReactionType);
94  reactionKeywordTable_.insert("LT", LandauTellerReactionType);
95  reactionKeywordTable_.insert("RLT", reverseLandauTellerReactionType);
96  reactionKeywordTable_.insert("JAN", JanevReactionType);
97  reactionKeywordTable_.insert("FIT1", powerSeriesReactionRateType);
98  reactionKeywordTable_.insert("HV", radiationActivatedReactionType);
99  reactionKeywordTable_.insert("TDEP", speciesTempReactionType);
100  reactionKeywordTable_.insert("EXCI", energyLossReactionType);
101  reactionKeywordTable_.insert("MOME", plasmaMomentumTransfer);
102  reactionKeywordTable_.insert("XSMI", collisionCrossSection);
103  reactionKeywordTable_.insert("REV", nonEquilibriumReversibleReactionType);
104  reactionKeywordTable_.insert("DUPLICATE", duplicateReactionType);
105  reactionKeywordTable_.insert("DUP", duplicateReactionType);
106  reactionKeywordTable_.insert("FORD", speciesOrderForward);
107  reactionKeywordTable_.insert("RORD", speciesOrderReverse);
108  reactionKeywordTable_.insert("UNITS", UnitsOfReaction);
109  reactionKeywordTable_.insert("END", end);
110 }
111 
112 
113 Foam::scalar Foam::chemkinReader::molecularWeight
114 (
115  const List<specieElement>& specieComposition
116 ) const
117 {
118  scalar molWt = 0.0;
119 
120  forAll(specieComposition, i)
121  {
122  label nAtoms = specieComposition[i].nAtoms();
123  const word& elementName = specieComposition[i].name();
124 
125  if (isotopeAtomicWts_.found(elementName))
126  {
127  molWt += nAtoms*isotopeAtomicWts_[elementName];
128  }
129  else if (atomicWeights.found(elementName))
130  {
131  molWt += nAtoms*atomicWeights[elementName];
132  }
133  else
134  {
136  << "Unknown element " << elementName
137  << " on line " << lineNo_-1 << nl
138  << " specieComposition: " << specieComposition
139  << exit(FatalError);
140  }
141  }
142 
143  return molWt;
144 }
145 
146 
147 void Foam::chemkinReader::checkCoeffs
148 (
149  const scalarList& reactionCoeffs,
150  const char* reactionRateName,
151  const label nCoeffs
152 ) const
153 {
154  if (reactionCoeffs.size() != nCoeffs)
155  {
157  << "Wrong number of coefficients for the " << reactionRateName
158  << " rate expression on line "
159  << lineNo_-1 << ", should be "
160  << nCoeffs << " but " << reactionCoeffs.size() << " supplied." << nl
161  << "Coefficients are "
162  << reactionCoeffs << nl
163  << exit(FatalError);
164  }
165 }
166 
167 template<class ReactionRateType>
168 void Foam::chemkinReader::addReactionType
169 (
170  const reactionType rType,
171  DynamicList<gasHReaction::specieCoeffs>& lhs,
172  DynamicList<gasHReaction::specieCoeffs>& rhs,
173  const ReactionRateType& rr
174 )
175 {
176  switch (rType)
177  {
178  case irreversible:
179  {
180  reactions_.append
181  (
182  new IrreversibleReaction
183  <Reaction, gasHThermoPhysics, ReactionRateType>
184  (
185  Reaction<gasHThermoPhysics>
186  (
187  speciesTable_,
188  lhs.shrink(),
189  rhs.shrink(),
190  speciesThermo_
191  ),
192  rr
193  )
194  );
195  }
196  break;
197 
198  case reversible:
199  {
200  reactions_.append
201  (
202  new ReversibleReaction
203  <Reaction, gasHThermoPhysics, ReactionRateType>
204  (
205  Reaction<gasHThermoPhysics>
206  (
207  speciesTable_,
208  lhs.shrink(),
209  rhs.shrink(),
210  speciesThermo_
211  ),
212  rr
213  )
214  );
215  }
216  break;
217 
218  default:
219 
220  if (rType < 3)
221  {
223  << "Reaction type " << reactionTypeNames[rType]
224  << " on line " << lineNo_-1
225  << " not handled by this function"
226  << exit(FatalError);
227  }
228  else
229  {
231  << "Unknown reaction type " << rType
232  << " on line " << lineNo_-1
233  << exit(FatalError);
234  }
235  }
236 }
237 
238 template<template<class, class> class PressureDependencyType>
239 void Foam::chemkinReader::addPressureDependentReaction
240 (
241  const reactionType rType,
242  const fallOffFunctionType fofType,
243  DynamicList<gasHReaction::specieCoeffs>& lhs,
244  DynamicList<gasHReaction::specieCoeffs>& rhs,
245  const scalarList& efficiencies,
246  const scalarList& k0Coeffs,
247  const scalarList& kInfCoeffs,
248  const HashTable<scalarList>& reactionCoeffsTable,
249  const scalar Afactor0,
250  const scalar AfactorInf,
251  const scalar RR
252 )
253 {
254  checkCoeffs(k0Coeffs, "k0", 3);
255  checkCoeffs(kInfCoeffs, "kInf", 3);
256 
257  switch (fofType)
258  {
259  case Lindemann:
260  {
261  addReactionType
262  (
263  rType,
264  lhs, rhs,
265  PressureDependencyType
266  <ArrheniusReactionRate, LindemannFallOffFunction>
267  (
268  ArrheniusReactionRate
269  (
270  Afactor0*k0Coeffs[0],
271  k0Coeffs[1],
272  k0Coeffs[2]/RR
273  ),
274  ArrheniusReactionRate
275  (
276  AfactorInf*kInfCoeffs[0],
277  kInfCoeffs[1],
278  kInfCoeffs[2]/RR
279  ),
280  LindemannFallOffFunction(),
281  thirdBodyEfficiencies(speciesTable_, efficiencies)
282  )
283  );
284  break;
285  }
286  case Troe:
287  {
288  scalarList TroeCoeffs
289  (
290  reactionCoeffsTable[fallOffFunctionNames[fofType]]
291  );
292 
293  if (TroeCoeffs.size() != 4 && TroeCoeffs.size() != 3)
294  {
296  << "Wrong number of coefficients for Troe rate expression"
297  " on line " << lineNo_-1 << ", should be 3 or 4 but "
298  << TroeCoeffs.size() << " supplied." << nl
299  << "Coefficients are "
300  << TroeCoeffs << nl
301  << exit(FatalError);
302  }
303 
304  if (TroeCoeffs.size() == 3)
305  {
306  TroeCoeffs.setSize(4);
307  TroeCoeffs[3] = GREAT;
308  }
309 
310  addReactionType
311  (
312  rType,
313  lhs, rhs,
314  PressureDependencyType
315  <ArrheniusReactionRate, TroeFallOffFunction>
316  (
317  ArrheniusReactionRate
318  (
319  Afactor0*k0Coeffs[0],
320  k0Coeffs[1],
321  k0Coeffs[2]/RR
322  ),
323  ArrheniusReactionRate
324  (
325  AfactorInf*kInfCoeffs[0],
326  kInfCoeffs[1],
327  kInfCoeffs[2]/RR
328  ),
329  TroeFallOffFunction
330  (
331  TroeCoeffs[0],
332  TroeCoeffs[1],
333  TroeCoeffs[2],
334  TroeCoeffs[3]
335  ),
336  thirdBodyEfficiencies(speciesTable_, efficiencies)
337  )
338  );
339  break;
340  }
341  case SRI:
342  {
343  scalarList SRICoeffs
344  (
345  reactionCoeffsTable[fallOffFunctionNames[fofType]]
346  );
347 
348  if (SRICoeffs.size() != 5 && SRICoeffs.size() != 3)
349  {
351  << "Wrong number of coefficients for SRI rate expression"
352  " on line " << lineNo_-1 << ", should be 3 or 5 but "
353  << SRICoeffs.size() << " supplied." << nl
354  << "Coefficients are "
355  << SRICoeffs << nl
356  << exit(FatalError);
357  }
358 
359  if (SRICoeffs.size() == 3)
360  {
361  SRICoeffs.setSize(5);
362  SRICoeffs[3] = 1.0;
363  SRICoeffs[4] = 0.0;
364  }
365 
366  addReactionType
367  (
368  rType,
369  lhs, rhs,
370  PressureDependencyType
371  <ArrheniusReactionRate, SRIFallOffFunction>
372  (
373  ArrheniusReactionRate
374  (
375  Afactor0*k0Coeffs[0],
376  k0Coeffs[1],
377  k0Coeffs[2]/RR
378  ),
379  ArrheniusReactionRate
380  (
381  AfactorInf*kInfCoeffs[0],
382  kInfCoeffs[1],
383  kInfCoeffs[2]/RR
384  ),
385  SRIFallOffFunction
386  (
387  SRICoeffs[0],
388  SRICoeffs[1],
389  SRICoeffs[2],
390  SRICoeffs[3],
391  SRICoeffs[4]
392  ),
393  thirdBodyEfficiencies(speciesTable_, efficiencies)
394  )
395  );
396  break;
397  }
398  default:
399  {
401  << "Fall-off function type "
402  << fallOffFunctionNames[fofType]
403  << " on line " << lineNo_-1
404  << " not implemented"
405  << exit(FatalError);
406  }
407  }
408 }
409 
410 
411 void Foam::chemkinReader::addReaction
412 (
413  DynamicList<gasHReaction::specieCoeffs>& lhs,
414  DynamicList<gasHReaction::specieCoeffs>& rhs,
415  const scalarList& efficiencies,
416  const reactionType rType,
417  const reactionRateType rrType,
418  const fallOffFunctionType fofType,
419  const scalarList& ArrheniusCoeffs,
420  HashTable<scalarList>& reactionCoeffsTable,
421  const scalar RR
422 )
423 {
424  checkCoeffs(ArrheniusCoeffs, "Arrhenius", 3);
425 
426  scalarList nAtoms(elementNames_.size(), 0.0);
427 
428  forAll(lhs, i)
429  {
430  const List<specieElement>& specieComposition =
431  speciesComposition_[speciesTable_[lhs[i].index]];
432 
433  forAll(specieComposition, j)
434  {
435  label elementi = elementIndices_[specieComposition[j].name()];
436  nAtoms[elementi] +=
437  lhs[i].stoichCoeff*specieComposition[j].nAtoms();
438  }
439  }
440 
441  forAll(rhs, i)
442  {
443  const List<specieElement>& specieComposition =
444  speciesComposition_[speciesTable_[rhs[i].index]];
445 
446  forAll(specieComposition, j)
447  {
448  label elementi = elementIndices_[specieComposition[j].name()];
449  nAtoms[elementi] -=
450  rhs[i].stoichCoeff*specieComposition[j].nAtoms();
451  }
452  }
453 
454 
455  // Calculate the unit conversion factor for the A coefficient
456  // for the change from mol/cm^3 to kmol/m^3 concentraction units
457  const scalar concFactor = 0.001;
458  scalar sumExp = 0.0;
459  forAll(lhs, i)
460  {
461  sumExp += lhs[i].exponent;
462  }
463  scalar Afactor = pow(concFactor, sumExp - 1.0);
464 
465  scalar AfactorRev = Afactor;
466 
467  if (rType == nonEquilibriumReversible)
468  {
469  sumExp = 0.0;
470  forAll(rhs, i)
471  {
472  sumExp += rhs[i].exponent;
473  }
474  AfactorRev = pow(concFactor, sumExp - 1.0);
475  }
476 
477  switch (rrType)
478  {
479  case Arrhenius:
480  {
481  if (rType == nonEquilibriumReversible)
482  {
483  const scalarList& reverseArrheniusCoeffs =
484  reactionCoeffsTable[reactionTypeNames[rType]];
485 
486  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
487 
488  reactions_.append
489  (
490  new NonEquilibriumReversibleReaction
491  <Reaction, gasHThermoPhysics, ArrheniusReactionRate>
492  (
493  Reaction<gasHThermoPhysics>
494  (
495  speciesTable_,
496  lhs.shrink(),
497  rhs.shrink(),
498  speciesThermo_
499  ),
500  ArrheniusReactionRate
501  (
502  Afactor*ArrheniusCoeffs[0],
503  ArrheniusCoeffs[1],
504  ArrheniusCoeffs[2]/RR
505  ),
506  ArrheniusReactionRate
507  (
508  AfactorRev*reverseArrheniusCoeffs[0],
509  reverseArrheniusCoeffs[1],
510  reverseArrheniusCoeffs[2]/RR
511  )
512  )
513  );
514  }
515  else
516  {
517  addReactionType
518  (
519  rType,
520  lhs, rhs,
521  ArrheniusReactionRate
522  (
523  Afactor*ArrheniusCoeffs[0],
524  ArrheniusCoeffs[1],
525  ArrheniusCoeffs[2]/RR
526  )
527  );
528  }
529  break;
530  }
531  case thirdBodyArrhenius:
532  {
533  if (rType == nonEquilibriumReversible)
534  {
535  const scalarList& reverseArrheniusCoeffs =
536  reactionCoeffsTable[reactionTypeNames[rType]];
537 
538  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
539 
540  reactions_.append
541  (
542  new NonEquilibriumReversibleReaction
543  <
544  Reaction,
546  thirdBodyArrheniusReactionRate
547  >
548  (
549  Reaction<gasHThermoPhysics>
550  (
551  speciesTable_,
552  lhs.shrink(),
553  rhs.shrink(),
554  speciesThermo_
555  ),
556  thirdBodyArrheniusReactionRate
557  (
558  Afactor*concFactor*ArrheniusCoeffs[0],
559  ArrheniusCoeffs[1],
560  ArrheniusCoeffs[2]/RR,
561  thirdBodyEfficiencies(speciesTable_, efficiencies)
562  ),
563  thirdBodyArrheniusReactionRate
564  (
565  AfactorRev*concFactor*reverseArrheniusCoeffs[0],
566  reverseArrheniusCoeffs[1],
567  reverseArrheniusCoeffs[2]/RR,
568  thirdBodyEfficiencies(speciesTable_, efficiencies)
569  )
570  )
571  );
572  }
573  else
574  {
575  addReactionType
576  (
577  rType,
578  lhs, rhs,
579  thirdBodyArrheniusReactionRate
580  (
581  Afactor*concFactor*ArrheniusCoeffs[0],
582  ArrheniusCoeffs[1],
583  ArrheniusCoeffs[2]/RR,
584  thirdBodyEfficiencies(speciesTable_, efficiencies)
585  )
586  );
587  }
588  break;
589  }
590  case unimolecularFallOff:
591  {
592  addPressureDependentReaction<FallOffReactionRate>
593  (
594  rType,
595  fofType,
596  lhs,
597  rhs,
598  efficiencies,
599  reactionCoeffsTable[reactionRateTypeNames[rrType]],
600  ArrheniusCoeffs,
601  reactionCoeffsTable,
602  concFactor*Afactor,
603  Afactor,
604  RR
605  );
606  break;
607  }
608  case chemicallyActivatedBimolecular:
609  {
610  addPressureDependentReaction<ChemicallyActivatedReactionRate>
611  (
612  rType,
613  fofType,
614  lhs,
615  rhs,
616  efficiencies,
617  ArrheniusCoeffs,
618  reactionCoeffsTable[reactionRateTypeNames[rrType]],
619  reactionCoeffsTable,
620  Afactor,
621  Afactor/concFactor,
622  RR
623  );
624  break;
625  }
626  case LandauTeller:
627  {
628  const scalarList& LandauTellerCoeffs =
629  reactionCoeffsTable[reactionRateTypeNames[rrType]];
630  checkCoeffs(LandauTellerCoeffs, "Landau-Teller", 2);
631 
632  if (rType == nonEquilibriumReversible)
633  {
634  const scalarList& reverseArrheniusCoeffs =
635  reactionCoeffsTable[reactionTypeNames[rType]];
636  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
637 
638  const scalarList& reverseLandauTellerCoeffs =
639  reactionCoeffsTable
640  [
641  word(reactionTypeNames[rType])
642  + reactionRateTypeNames[rrType]
643  ];
644  checkCoeffs(LandauTellerCoeffs, "reverse Landau-Teller", 2);
645 
646  reactions_.append
647  (
648  new NonEquilibriumReversibleReaction
649  <Reaction, gasHThermoPhysics, LandauTellerReactionRate>
650  (
651  Reaction<gasHThermoPhysics>
652  (
653  speciesTable_,
654  lhs.shrink(),
655  rhs.shrink(),
656  speciesThermo_
657  ),
658  LandauTellerReactionRate
659  (
660  Afactor*ArrheniusCoeffs[0],
661  ArrheniusCoeffs[1],
662  ArrheniusCoeffs[2]/RR,
663  LandauTellerCoeffs[0],
664  LandauTellerCoeffs[1]
665  ),
666  LandauTellerReactionRate
667  (
668  AfactorRev*reverseArrheniusCoeffs[0],
669  reverseArrheniusCoeffs[1],
670  reverseArrheniusCoeffs[2]/RR,
671  reverseLandauTellerCoeffs[0],
672  reverseLandauTellerCoeffs[1]
673  )
674  )
675  );
676  }
677  else
678  {
679  addReactionType
680  (
681  rType,
682  lhs, rhs,
683  LandauTellerReactionRate
684  (
685  Afactor*ArrheniusCoeffs[0],
686  ArrheniusCoeffs[1],
687  ArrheniusCoeffs[2]/RR,
688  LandauTellerCoeffs[0],
689  LandauTellerCoeffs[1]
690  )
691  );
692  }
693  break;
694  }
695  case Janev:
696  {
697  const scalarList& JanevCoeffs =
698  reactionCoeffsTable[reactionRateTypeNames[rrType]];
699 
700  checkCoeffs(JanevCoeffs, "Janev", 9);
701 
702  addReactionType
703  (
704  rType,
705  lhs, rhs,
706  JanevReactionRate
707  (
708  Afactor*ArrheniusCoeffs[0],
709  ArrheniusCoeffs[1],
710  ArrheniusCoeffs[2]/RR,
711  FixedList<scalar, 9>(JanevCoeffs)
712  )
713  );
714  break;
715  }
716  case powerSeries:
717  {
718  const scalarList& powerSeriesCoeffs =
719  reactionCoeffsTable[reactionRateTypeNames[rrType]];
720 
721  checkCoeffs(powerSeriesCoeffs, "power-series", 4);
722 
723  addReactionType
724  (
725  rType,
726  lhs, rhs,
727  powerSeriesReactionRate
728  (
729  Afactor*ArrheniusCoeffs[0],
730  ArrheniusCoeffs[1],
731  ArrheniusCoeffs[2]/RR,
732  FixedList<scalar, 4>(powerSeriesCoeffs)
733  )
734  );
735  break;
736  }
737  case unknownReactionRateType:
738  {
740  << "Internal error on line " << lineNo_-1
741  << ": reaction rate type has not been set"
742  << exit(FatalError);
743  break;
744  }
745  default:
746  {
748  << "Reaction rate type " << reactionRateTypeNames[rrType]
749  << " on line " << lineNo_-1
750  << " not implemented"
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 != fileName::null)
786  {
787  std::ifstream thermoStream(thermoFileName.c_str());
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.c_str());
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.lookupOrDefault("newFormat", false)),
861  imbalanceTol_(thermoDict.lookupOrDefault("imbalanceTolerance", ROOTSMALL))
862 {
863  if (newFormat_)
864  {
865  Info<< "Reading CHEMKIN thermo data in new file format" << endl;
866  }
867 
868  fileName chemkinFile(fileName(thermoDict.lookup("CHEMKINFile")).expand());
869 
870  fileName thermoFile = fileName::null;
871 
872  if (thermoDict.found("CHEMKINThermoFile"))
873  {
874  thermoFile = fileName(thermoDict.lookup("CHEMKINThermoFile")).expand();
875  }
876 
877  fileName transportFile
878  (
879  fileName(thermoDict.lookup("CHEMKINTransportFile")).expand()
880  );
881 
882  // allow relative file names
883  fileName relPath = thermoDict.name().path();
884  if (relPath.size())
885  {
886  if (!chemkinFile.isAbsolute())
887  {
888  chemkinFile = relPath/chemkinFile;
889  }
890 
891  if (thermoFile != fileName::null && !thermoFile.isAbsolute())
892  {
893  thermoFile = relPath/thermoFile;
894  }
895 
896  if (!transportFile.isAbsolute())
897  {
898  transportFile = relPath/transportFile;
899  }
900  }
901 
902  read(chemkinFile, thermoFile, transportFile);
903 }
904 
905 
906 // * * * * * * * * * * * * * * * 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 occurences 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:253
Macros for easy insertion into run-time selection tables.
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:58
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
addChemistryReaderType(chemkinReader, gasHThermoPhysics)
atomicWeightTable atomicWeights
static const char nl
Definition: Ostream.H:262
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:250
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