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-2015 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].elementName;
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  specieComposition_[speciesTable_[lhs[i].index]];
432 
433  forAll(specieComposition, j)
434  {
435  label elementi = elementIndices_[specieComposition[j].elementName];
436  nAtoms[elementi] += lhs[i].stoichCoeff*specieComposition[j].nAtoms;
437  }
438  }
439 
440  forAll(rhs, i)
441  {
442  const List<specieElement>& specieComposition =
443  specieComposition_[speciesTable_[rhs[i].index]];
444 
445  forAll(specieComposition, j)
446  {
447  label elementi = elementIndices_[specieComposition[j].elementName];
448  nAtoms[elementi] -= rhs[i].stoichCoeff*specieComposition[j].nAtoms;
449  }
450  }
451 
452 
453  // Calculate the unit conversion factor for the A coefficient
454  // for the change from mol/cm^3 to kmol/m^3 concentraction units
455  const scalar concFactor = 0.001;
456  scalar sumExp = 0.0;
457  forAll(lhs, i)
458  {
459  sumExp += lhs[i].exponent;
460  }
461  scalar Afactor = pow(concFactor, sumExp - 1.0);
462 
463  scalar AfactorRev = Afactor;
464 
465  if (rType == nonEquilibriumReversible)
466  {
467  sumExp = 0.0;
468  forAll(rhs, i)
469  {
470  sumExp += rhs[i].exponent;
471  }
472  AfactorRev = pow(concFactor, sumExp - 1.0);
473  }
474 
475  switch (rrType)
476  {
477  case Arrhenius:
478  {
479  if (rType == nonEquilibriumReversible)
480  {
481  const scalarList& reverseArrheniusCoeffs =
482  reactionCoeffsTable[reactionTypeNames[rType]];
483 
484  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
485 
486  reactions_.append
487  (
488  new NonEquilibriumReversibleReaction
489  <Reaction, gasHThermoPhysics, ArrheniusReactionRate>
490  (
491  Reaction<gasHThermoPhysics>
492  (
493  speciesTable_,
494  lhs.shrink(),
495  rhs.shrink(),
496  speciesThermo_
497  ),
498  ArrheniusReactionRate
499  (
500  Afactor*ArrheniusCoeffs[0],
501  ArrheniusCoeffs[1],
502  ArrheniusCoeffs[2]/RR
503  ),
504  ArrheniusReactionRate
505  (
506  AfactorRev*reverseArrheniusCoeffs[0],
507  reverseArrheniusCoeffs[1],
508  reverseArrheniusCoeffs[2]/RR
509  )
510  )
511  );
512  }
513  else
514  {
515  addReactionType
516  (
517  rType,
518  lhs, rhs,
519  ArrheniusReactionRate
520  (
521  Afactor*ArrheniusCoeffs[0],
522  ArrheniusCoeffs[1],
523  ArrheniusCoeffs[2]/RR
524  )
525  );
526  }
527  break;
528  }
529  case thirdBodyArrhenius:
530  {
531  if (rType == nonEquilibriumReversible)
532  {
533  const scalarList& reverseArrheniusCoeffs =
534  reactionCoeffsTable[reactionTypeNames[rType]];
535 
536  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
537 
538  reactions_.append
539  (
540  new NonEquilibriumReversibleReaction
541  <
542  Reaction,
544  thirdBodyArrheniusReactionRate
545  >
546  (
547  Reaction<gasHThermoPhysics>
548  (
549  speciesTable_,
550  lhs.shrink(),
551  rhs.shrink(),
552  speciesThermo_
553  ),
554  thirdBodyArrheniusReactionRate
555  (
556  Afactor*concFactor*ArrheniusCoeffs[0],
557  ArrheniusCoeffs[1],
558  ArrheniusCoeffs[2]/RR,
559  thirdBodyEfficiencies(speciesTable_, efficiencies)
560  ),
561  thirdBodyArrheniusReactionRate
562  (
563  AfactorRev*concFactor*reverseArrheniusCoeffs[0],
564  reverseArrheniusCoeffs[1],
565  reverseArrheniusCoeffs[2]/RR,
566  thirdBodyEfficiencies(speciesTable_, efficiencies)
567  )
568  )
569  );
570  }
571  else
572  {
573  addReactionType
574  (
575  rType,
576  lhs, rhs,
577  thirdBodyArrheniusReactionRate
578  (
579  Afactor*concFactor*ArrheniusCoeffs[0],
580  ArrheniusCoeffs[1],
581  ArrheniusCoeffs[2]/RR,
582  thirdBodyEfficiencies(speciesTable_, efficiencies)
583  )
584  );
585  }
586  break;
587  }
588  case unimolecularFallOff:
589  {
590  addPressureDependentReaction<FallOffReactionRate>
591  (
592  rType,
593  fofType,
594  lhs,
595  rhs,
596  efficiencies,
597  reactionCoeffsTable[reactionRateTypeNames[rrType]],
598  ArrheniusCoeffs,
599  reactionCoeffsTable,
600  concFactor*Afactor,
601  Afactor,
602  RR
603  );
604  break;
605  }
606  case chemicallyActivatedBimolecular:
607  {
608  addPressureDependentReaction<ChemicallyActivatedReactionRate>
609  (
610  rType,
611  fofType,
612  lhs,
613  rhs,
614  efficiencies,
615  ArrheniusCoeffs,
616  reactionCoeffsTable[reactionRateTypeNames[rrType]],
617  reactionCoeffsTable,
618  Afactor,
619  Afactor/concFactor,
620  RR
621  );
622  break;
623  }
624  case LandauTeller:
625  {
626  const scalarList& LandauTellerCoeffs =
627  reactionCoeffsTable[reactionRateTypeNames[rrType]];
628  checkCoeffs(LandauTellerCoeffs, "Landau-Teller", 2);
629 
630  if (rType == nonEquilibriumReversible)
631  {
632  const scalarList& reverseArrheniusCoeffs =
633  reactionCoeffsTable[reactionTypeNames[rType]];
634  checkCoeffs(reverseArrheniusCoeffs, "reverse Arrhenius", 3);
635 
636  const scalarList& reverseLandauTellerCoeffs =
637  reactionCoeffsTable
638  [
639  word(reactionTypeNames[rType])
640  + reactionRateTypeNames[rrType]
641  ];
642  checkCoeffs(LandauTellerCoeffs, "reverse Landau-Teller", 2);
643 
644  reactions_.append
645  (
646  new NonEquilibriumReversibleReaction
647  <Reaction, gasHThermoPhysics, LandauTellerReactionRate>
648  (
649  Reaction<gasHThermoPhysics>
650  (
651  speciesTable_,
652  lhs.shrink(),
653  rhs.shrink(),
654  speciesThermo_
655  ),
656  LandauTellerReactionRate
657  (
658  Afactor*ArrheniusCoeffs[0],
659  ArrheniusCoeffs[1],
660  ArrheniusCoeffs[2]/RR,
661  LandauTellerCoeffs[0],
662  LandauTellerCoeffs[1]
663  ),
664  LandauTellerReactionRate
665  (
666  AfactorRev*reverseArrheniusCoeffs[0],
667  reverseArrheniusCoeffs[1],
668  reverseArrheniusCoeffs[2]/RR,
669  reverseLandauTellerCoeffs[0],
670  reverseLandauTellerCoeffs[1]
671  )
672  )
673  );
674  }
675  else
676  {
677  addReactionType
678  (
679  rType,
680  lhs, rhs,
681  LandauTellerReactionRate
682  (
683  Afactor*ArrheniusCoeffs[0],
684  ArrheniusCoeffs[1],
685  ArrheniusCoeffs[2]/RR,
686  LandauTellerCoeffs[0],
687  LandauTellerCoeffs[1]
688  )
689  );
690  }
691  break;
692  }
693  case Janev:
694  {
695  const scalarList& JanevCoeffs =
696  reactionCoeffsTable[reactionRateTypeNames[rrType]];
697 
698  checkCoeffs(JanevCoeffs, "Janev", 9);
699 
700  addReactionType
701  (
702  rType,
703  lhs, rhs,
704  JanevReactionRate
705  (
706  Afactor*ArrheniusCoeffs[0],
707  ArrheniusCoeffs[1],
708  ArrheniusCoeffs[2]/RR,
709  FixedList<scalar, 9>(JanevCoeffs)
710  )
711  );
712  break;
713  }
714  case powerSeries:
715  {
716  const scalarList& powerSeriesCoeffs =
717  reactionCoeffsTable[reactionRateTypeNames[rrType]];
718 
719  checkCoeffs(powerSeriesCoeffs, "power-series", 4);
720 
721  addReactionType
722  (
723  rType,
724  lhs, rhs,
725  powerSeriesReactionRate
726  (
727  Afactor*ArrheniusCoeffs[0],
728  ArrheniusCoeffs[1],
729  ArrheniusCoeffs[2]/RR,
730  FixedList<scalar, 4>(powerSeriesCoeffs)
731  )
732  );
733  break;
734  }
735  case unknownReactionRateType:
736  {
738  << "Internal error on line " << lineNo_-1
739  << ": reaction rate type has not been set"
740  << exit(FatalError);
741  break;
742  }
743  default:
744  {
746  << "Reaction rate type " << reactionRateTypeNames[rrType]
747  << " on line " << lineNo_-1
748  << " not implemented"
749  << exit(FatalError);
750  }
751  }
752 
753 
754  forAll(nAtoms, i)
755  {
756  if (mag(nAtoms[i]) > imbalanceTol_)
757  {
759  << "Elemental imbalance of " << mag(nAtoms[i])
760  << " in " << elementNames_[i]
761  << " in reaction" << nl
762  << reactions_.last() << nl
763  << " on line " << lineNo_-1
764  << exit(FatalError);
765  }
766  }
767 
768  lhs.clear();
769  rhs.clear();
770  reactionCoeffsTable.clear();
771 }
772 
773 
774 void Foam::chemkinReader::read
775 (
776  const fileName& CHEMKINFileName,
777  const fileName& thermoFileName,
778  const fileName& transportFileName
779 )
780 {
781  transportDict_.read(IFstream(transportFileName)());
782 
783  if (thermoFileName != fileName::null)
784  {
785  std::ifstream thermoStream(thermoFileName.c_str());
786 
787  if (!thermoStream)
788  {
790  << "file " << thermoFileName << " not found"
791  << exit(FatalError);
792  }
793 
794  yy_buffer_state* bufferPtr(yy_create_buffer(&thermoStream, yyBufSize));
795  yy_switch_to_buffer(bufferPtr);
796 
797  while (lex() != 0)
798  {}
799 
800  yy_delete_buffer(bufferPtr);
801 
802  lineNo_ = 1;
803  }
804 
805  std::ifstream CHEMKINStream(CHEMKINFileName.c_str());
806 
807  if (!CHEMKINStream)
808  {
810  << "file " << CHEMKINFileName << " not found"
811  << exit(FatalError);
812  }
813 
814  yy_buffer_state* bufferPtr(yy_create_buffer(&CHEMKINStream, yyBufSize));
815  yy_switch_to_buffer(bufferPtr);
816 
817  initReactionKeywordTable();
818 
819  while (lex() != 0)
820  {}
821 
822  yy_delete_buffer(bufferPtr);
823 }
824 
825 
826 // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
827 
828 Foam::chemkinReader::chemkinReader
829 (
830  speciesTable& species,
831  const fileName& CHEMKINFileName,
832  const fileName& transportFileName,
833  const fileName& thermoFileName,
834  const bool newFormat
835 )
836 :
837  lineNo_(1),
838  specieNames_(10),
839  speciesTable_(species),
840  reactions_(speciesTable_, speciesThermo_),
841  newFormat_(newFormat),
842  imbalanceTol_(ROOTSMALL)
843 {
844  read(CHEMKINFileName, thermoFileName, transportFileName);
845 }
846 
847 
848 Foam::chemkinReader::chemkinReader
849 (
850  const dictionary& thermoDict,
851  speciesTable& species
852 )
853 :
854  lineNo_(1),
855  specieNames_(10),
856  speciesTable_(species),
857  reactions_(speciesTable_, speciesThermo_),
858  newFormat_(thermoDict.lookupOrDefault("newFormat", false)),
859  imbalanceTol_(thermoDict.lookupOrDefault("imbalanceTolerance", ROOTSMALL))
860 {
861  if (newFormat_)
862  {
863  Info<< "Reading CHEMKIN thermo data in new file format" << endl;
864  }
865 
866  fileName chemkinFile(fileName(thermoDict.lookup("CHEMKINFile")).expand());
867 
868  fileName thermoFile = fileName::null;
869 
870  if (thermoDict.found("CHEMKINThermoFile"))
871  {
872  thermoFile = fileName(thermoDict.lookup("CHEMKINThermoFile")).expand();
873  }
874 
875  fileName transportFile
876  (
877  fileName(thermoDict.lookup("CHEMKINTransportFile")).expand()
878  );
879 
880  // allow relative file names
881  fileName relPath = thermoDict.name().path();
882  if (relPath.size())
883  {
884  if (!chemkinFile.isAbsolute())
885  {
886  chemkinFile = relPath/chemkinFile;
887  }
888 
889  if (thermoFile != fileName::null && !thermoFile.isAbsolute())
890  {
891  thermoFile = relPath/thermoFile;
892  }
893 
894  if (!transportFile.isAbsolute())
895  {
896  transportFile = relPath/transportFile;
897  }
898  }
899 
900  read(chemkinFile, thermoFile, transportFile);
901 }
902 
903 
904 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:103
Macros for easy insertion into run-time selection tables.
bool read(const char *, int32_t &)
Definition: int32IO.C:85
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
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
addChemistryReaderType(chemkinReader, gasHThermoPhysics)
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:306
atomicWeightTable atomicWeights
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:57
static const char nl
Definition: Ostream.H:262
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
A wordList with hashed indices for faster lookup by name.
messageStream Info
dimensioned< scalar > mag(const dimensioned< Type > &)
const scalar RR
Universal gas constant (default in [J/(kmol K)])
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:249
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
Namespace for OpenFOAM.
sutherlandTransport< species::thermo< janafThermo< perfectGas< specie > >, sensibleEnthalpy > > gasHThermoPhysics
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:451