1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
31 #include "chemkinReader.H"
34 #include "IStringStream.H"
36 // flex input buffer size
37 int Foam::chemkinReader::yyBufSize = YY_BUF_SIZE;
39 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
41 int yyFlexLexer::yylex()
43 Foam::FatalErrorIn("yyFlexLexer::yylex()")
44 << "should not have called this function"
45 << abort(Foam::FatalError);
52 // Dummy yywrap to keep yylex happy at compile time.
53 // It is called by yylex but is not used as the mechanism to change file.
56 #if YY_FLEX_SUBMINOR_VERSION < 34
57 extern "C" int yywrap()
59 int yyFlexLexer::yywrap()
67 Foam::string foamSpecieString(const char* YYText)
69 Foam::string specieString(YYText);
70 specieString.replaceAll('(', '<');
71 specieString.replaceAll(')', '>');
76 Foam::word foamName(const char* YYText)
78 Foam::string fn(YYText);
79 Foam::string::stripInvalid<Foam::word>(fn);
84 Foam::word foamName(const Foam::string& s)
87 Foam::string::stripInvalid<Foam::word>(fn);
92 /* ------------------------------------------------------------------------- *\
93 ------ cppLexer::yylex()
94 \* ------------------------------------------------------------------------- */
96 #define YY_DECL int Foam::chemkinReader::lex()
102 some_space {one_space}+
109 hex_digit [0-9a-fA-F]
111 identifier {alpha}({alpha}|{digit})*
113 label [1-9]{dec_digit}*
116 word ([[:alnum:]]|[[:punct:]])+
117 string {word}({some_space}{word})*
119 exponent_part [eEdD][-+]?{digit}+
120 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
122 double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
125 elements {space}("ELEMENTS"|"ELEM"){space}
126 species {space}("SPECIES"|"SPECIE"|"SPEC"){space}
127 thermoAll {space}"THERMO"{some_space}"ALL"{space}
128 thermo {space}"THERMO"{space}
129 reactions {space}("REACTIONS"|"REAC"){space}
130 end {space}"END"{space}
132 elementName {space}([A-Z]|([A-Z][A-Z])){space}
133 startIsotopeMolW {space}"/"{space}
134 isotopeMolW {space}{double}{space}"/"{space}
136 specieName {space}[A-Za-z](([A-Za-z0-9)*+-])|("("[^+]))*{space}
137 nMoles {space}{double}{space}
141 thermoSpecieName .{18}
147 thermoCommonTemp .{8}
150 thermoLineLabel1 " "1{space}
151 thermoLineLabel2 " "{4}2{space}
152 thermoLineLabel3 " "{4}3{space}
153 thermoLineLabel4 " "{4}4{space}
155 specieDelimiter {space}"+"{space}
156 reversibleReactionDelimiter {space}("="|"<=>"){space}
157 irreversibleReactionDelimiter {space}"=>"{space}
158 startPDependentSpecie {space}"("{space}"+"{space}
159 pDependentSpecie {specieName}")"{space}
160 reactionCoeffs {space}{double}{some_space}{double}{some_space}{double}{space}
161 reactionKeyword {space}[A-Za-z](([A-Za-z0-9)*-])|("("[^+]))*{space}
162 reactionKeywordSlash {reactionKeyword}"/"{space}
163 thirdBodyEfficiency {space}{double}{space}"/"{space}
164 startReactionCoeffs {space}"/"{space}
165 endReactionCoeffs {space}"/"{space}
166 reactionCoeff {space}{double}{space}
168 calPerMol {space}"CAL/MOLE"{space}
169 kcalPerMol {space}"KCAL/MOLE"{space}
170 joulePerMol {space}"JOULES/MOLE"{space}
171 otherReactionsUnit {space}("KELVINS"|"EVOLTS"|"MOLES"|"MOLECULES"){space}
173 cal {space}"CAL"{space}
174 kcal {space}"KCAL"{space}
175 joule {space}"JOUL"{space}
176 kjoule {space}"KJOU"{space}
177 otherReactionUnit {space}("MOLE"|"MOLECULE"|"KELV"|"KELVIN"|"EVOL"|"EVOLTS"){space}
180 /* ------------------------------------------------------------------------- *\
181 ----- Exclusive start states -----
182 \* ------------------------------------------------------------------------- */
190 %x readThermoSpecieName
195 %x readThermoFormula2
196 %x readThermoLineLabel1
198 %x readThermoLineLabel2
200 %x readThermoLineLabel3
202 %x readThermoLineLabel4
203 %x readReactionsUnits
204 %x readReactionKeyword
205 %x readSpecieNamePlus
206 %x readReactionDelimiter
207 %x readPDependentSpecie
208 %x readThirdBodyEfficiency
209 %x readReactionCoeffs
211 %x readReactionOrderSpecie
220 static const char* stateNames[30] =
222 "reading CHEMKIN III file",
224 "reading isotope molecular weight",
226 "reading all thermodynamic data temperatures",
227 "reading thermodynamic specie name",
228 "reading thermodynamic data date",
229 "reading thermodynamic data specie formula",
230 "reading thermodynamic data specie phase",
231 "reading thermodynamic data temperatures",
232 "reading thermodynamic data specie formula (supplement)",
233 "reading thermodynamic data line label 1",
234 "reading thermodynamic data coefficient set 1",
235 "reading thermodynamic data line label 2",
236 "reading thermodynamic data coefficient set 2",
237 "reading thermodynamic data line label 3",
238 "reading thermodynamic data coefficient set 3",
239 "reading thermodynamic data line label 4",
240 "reading reaction units",
241 "reading reaction specie/keyword",
242 "reading reaction specie",
243 "reading reaction delimiter",
244 "reading reaction pressure dependent specie",
245 "reading third-body efficiency",
246 "reading reaction coeff",
247 "reading temperature dependent specie name",
248 "reading reaction order specie name",
249 "reading reaction order",
250 "reading reaction unit",
254 static const char* stateExpects[30] =
256 "'ELEMENTS' or 'ELEM', 'SPECIES' or 'SPEC', 'THERMO' or 'THERMO ALL', 'REACTIONS'",
257 "<elementName>, <isotopeName> / or 'END'",
259 "<specieName> or 'END'",
260 "<scalar><scalar><scalar> (3F10.0)",
263 "<word><label><word><label><word><label><word><label> (4(2A1,I3))",
265 "<scalar><scalar><scalar> (E10.0E10.0E8.0)",
266 "<word><label> (2A1,I3)",
268 "<scalar><scalar><scalar><scalar><scalar> (5(E15.0))",
270 "<scalar><scalar><scalar><scalar><scalar> (5(E15.0))",
272 "<scalar><scalar><scalar><scalar> (4(E15.0))",
274 "'CAL/MOLE', 'KCAL/MOLE', 'JOULES/MOLE', 'KELVINS', 'EVOLTS', 'MOLES' or 'MOLECULES'",
277 "'+', '=', '<=>', '=>', '(+<word>', '<scalar> <scalar> <scalar>'",
284 "'MOLE', 'MOLECULE', 'CAL', 'KCAL', 'JOUL', 'KJOU', 'KELV', 'KELVIN', 'EVOL' or 'EVOLTS'",
290 static const scalar RRjoule = 8.31451; // J/kg-mol-K
291 static const scalar RRcal = 1.987316; // cal/g-mol-K
293 scalar RRreactions = RRcal;
294 scalar RRreaction = RRcal;
296 scalar allCommonT = 1000.0;
298 word currentElementName;
299 label currentElementIndex = 0;
301 word currentSpecieName;
302 label currentSpecieIndex = 0;
303 label nSpecieElements = 0;
304 List<specieElement> currentSpecieComposition(5);
306 scalar currentLowT = 0;
307 scalar currentHighT = 0;
308 scalar currentCommonT = 0;
309 reactionThermo::coeffArray highCpCoeffs;
310 reactionThermo::coeffArray lowCpCoeffs;
312 reaction::specieCoeffs currentSpecieCoeff;
314 DynamicList<reaction::specieCoeffs> lhs;
315 DynamicList<reaction::specieCoeffs> rhs;
317 scalarList ArrheniusCoeffs(3);
318 DynamicList<scalar> reactionCoeffs;
319 scalarList thirdBodyEfficiencies;
320 label currentThirdBodyIndex = -1;
322 word reactionCoeffsName = word::null;
323 HashTable<scalarList> reactionCoeffsTable;
325 DynamicList<reaction::specieCoeffs> *lrhsPtr = &lhs;
327 reactionType rType = unknownReactionType;
328 reactionRateType rrType = Arrhenius;
329 fallOffFunctionType fofType = unknownFallOffFunctionType;
330 word pDependentSpecieName = word::null;
331 label lhsThirdBodyCounter = 0;
332 label rhsThirdBodyCounter = 0;
334 bool finishReaction = false;
338 /* ------------------------------------------------------------------------- *\
339 ------ Start Lexing ------
340 \* ------------------------------------------------------------------------- */
342 /* ------------------------------------------------------------------------- *\
343 ------ Discard comments being careful to count comments
344 \* ------------------------------------------------------------------------- */
346 <*>{space}"!".* { // Remove one line comments
349 /* ------------------------------------------------------------------------- *\
351 \* ------------------------------------------------------------------------- */
357 <readElements>{elementName} {
358 currentElementName = foamName(YYText());
359 correctElementName(currentElementName);
361 if (!elementIndices_.found(currentElementName))
363 elementIndices_.insert(currentElementName, currentElementIndex++);
364 elementNames_.append(currentElementName);
368 WarningIn("chemkinReader::lex()")
369 << "element " << currentElementName
370 << " already in table." << endl;
374 <readElements>{startIsotopeMolW} {
375 BEGIN(readIsotopeMolW);
378 <readIsotopeMolW>{isotopeMolW} {
379 isotopeAtomicWts_.insert(currentElementName, stringToScalar(YYText()));
383 <readElements>{end} {
387 /* ------------------------------------------------------------------------- *\
389 \* ------------------------------------------------------------------------- */
391 <INITIAL,readElements>{species} {
395 <readSpecies>{specieName} {
396 word specieName(foamName(foamSpecieString(YYText())));
398 if (specieName == "THERMO")
400 specieNames_.shrink();
401 speciesTable_ = specieNames_;
402 thirdBodyEfficiencies.setSize(specieNames_.size());
403 thirdBodyEfficiencies = 1.0;
404 BEGIN(readThermoSpecieName);
406 else if (specieName == "END")
408 specieNames_.shrink();
409 speciesTable_ = specieNames_;
410 thirdBodyEfficiencies.setSize(specieNames_.size());
411 thirdBodyEfficiencies = 1.0;
416 if (!specieIndices_.found(specieName))
418 specieNames_.append(specieName);
419 specieIndices_.insert(specieName, currentSpecieIndex++);
423 WarningIn("chemkinReader::lex()")
424 << "specie " << specieName
425 << " already in table." << endl;
430 /* ------------------------------------------------------------------------- *\
432 \* ------------------------------------------------------------------------- */
434 <INITIAL,readSpecies>{thermo} {
435 BEGIN(readThermoSpecieName);
438 <INITIAL,readSpecies>{thermoAll} {
439 BEGIN(readThermoAll);
442 <readThermoAll>{thermoTemp}{thermoTemp}{thermoTemp} {
443 string temperaturesString(YYText());
444 //scalar lowestT(stringToScalar(temperaturesString(0, 10)));
445 allCommonT = stringToScalar(temperaturesString(10, 10));
446 //scalar highestT(stringToScalar(temperaturesString(20, 10)));
447 BEGIN(readThermoSpecieName);
450 <readThermoSpecieName>{thermoSpecieName} {
451 string specieString(foamSpecieString(YYText()));
452 size_t spacePos = specieString.find(' ');
453 if (spacePos != string::npos)
455 currentSpecieName = specieString(0, spacePos);
459 currentSpecieName = specieString;
461 BEGIN(readThermoDate);
464 <readThermoDate>{thermoDate} {
465 // string thermoDate(YYText());
466 // Date is not currently used
467 BEGIN(readThermoFormula);
470 <readThermoFormula>{thermoFormula} {
471 string thermoFormula(YYText());
474 currentSpecieComposition.setSize(5);
476 for (int i=0; i<4; i++)
478 word elementName(foamName(thermoFormula(5*i, 2)));
479 label nAtoms = atoi(thermoFormula(5*i + 2, 3).c_str());
481 if (elementName.size() && nAtoms)
483 correctElementName(elementName);
484 currentSpecieComposition[nSpecieElements].elementName =
486 currentSpecieComposition[nSpecieElements++].nAtoms = nAtoms;
490 BEGIN(readThermoPhase);
493 <readThermoPhase>{thermoPhase} {
494 char phaseChar = YYText()[0];
499 speciePhase_.insert(currentSpecieName, solid);
503 speciePhase_.insert(currentSpecieName, liquid);
507 speciePhase_.insert(currentSpecieName, gas);
511 BEGIN(readThermoTemps);
514 <readThermoTemps>{thermoLowTemp}{thermoHighTemp}{thermoCommonTemp} {
515 string temperaturesString(YYText());
516 currentLowT = stringToScalar(temperaturesString(0, 10));
517 currentHighT = stringToScalar(temperaturesString(10, 10));
518 currentCommonT = stringToScalar(temperaturesString(20, 8));
520 if (currentCommonT < SMALL)
522 currentCommonT = allCommonT;
525 BEGIN(readThermoFormula2);
528 <readThermoFormula2>{thermoFormula2} {
529 string thermoFormula(YYText());
530 word elementName(foamName(thermoFormula(0, 2)));
531 label nAtoms = atoi(thermoFormula(2, 3).c_str());
536 && elementName.find('0') == string::npos
540 correctElementName(elementName);
541 currentSpecieComposition[nSpecieElements].elementName =
543 currentSpecieComposition[nSpecieElements++].nAtoms = nAtoms;
546 currentSpecieComposition.setSize(nSpecieElements);
548 HashTable<List<specieElement> >::iterator specieCompositionIter
550 specieComposition_.find(currentSpecieName)
553 if (specieCompositionIter != specieComposition_.end())
555 specieComposition_.erase(specieCompositionIter);
558 specieComposition_.insert
561 currentSpecieComposition
564 BEGIN(readThermoLineLabel1);
567 <readThermoLineLabel1>{thermoLineLabel1} {
568 BEGIN(readThermoCoeff1);
571 <readThermoCoeff1>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
572 string thermoCoeffString(YYText());
574 highCpCoeffs[0] = stringToScalar(thermoCoeffString(0, 15));
575 highCpCoeffs[1] = stringToScalar(thermoCoeffString(15, 15));
576 highCpCoeffs[2] = stringToScalar(thermoCoeffString(30, 15));
577 highCpCoeffs[3] = stringToScalar(thermoCoeffString(45, 15));
578 highCpCoeffs[4] = stringToScalar(thermoCoeffString(60, 15));
580 BEGIN(readThermoLineLabel2);
583 <readThermoLineLabel2>{thermoLineLabel2} {
584 BEGIN(readThermoCoeff2);
587 <readThermoCoeff2>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
588 string thermoCoeffString(YYText());
590 highCpCoeffs[5] = stringToScalar(thermoCoeffString(0, 15));
591 highCpCoeffs[6] = stringToScalar(thermoCoeffString(15, 15));
593 lowCpCoeffs[0] = stringToScalar(thermoCoeffString(30, 15));
594 lowCpCoeffs[1] = stringToScalar(thermoCoeffString(45, 15));
595 lowCpCoeffs[2] = stringToScalar(thermoCoeffString(60, 15));
597 BEGIN(readThermoLineLabel3);
600 <readThermoLineLabel3>{thermoLineLabel3} {
601 BEGIN(readThermoCoeff3);
604 <readThermoCoeff3>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
605 string thermoCoeffString(YYText());
607 lowCpCoeffs[3] = stringToScalar(thermoCoeffString(0, 15));
608 lowCpCoeffs[4] = stringToScalar(thermoCoeffString(15, 15));
609 lowCpCoeffs[5] = stringToScalar(thermoCoeffString(30, 15));
610 lowCpCoeffs[6] = stringToScalar(thermoCoeffString(45, 15));
612 BEGIN(readThermoLineLabel4);
615 <readThermoLineLabel4>{thermoLineLabel4} {
617 HashPtrTable<reactionThermo>::iterator specieThermoIter
619 speciesThermo_.find(currentSpecieName)
622 if (specieThermoIter != speciesThermo_.end())
624 speciesThermo_.erase(specieThermoIter);
627 speciesThermo_.insert
632 janafThermo<perfectGas>
638 molecularWeight(currentSpecieComposition)
651 BEGIN(readThermoSpecieName);
654 <readThermoSpecieName>{end} {
658 /* ------------------------------------------------------------------------- *\
659 ------ Read reactions
660 \* ------------------------------------------------------------------------- */
662 <INITIAL,readThermoSpecieName>{reactions} {
663 currentSpecieCoeff.stoichCoeff = 1.0;
664 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
665 BEGIN(readReactionsUnits);
668 <readReactionsUnits>{calPerMol} {
672 <readReactionsUnits>{kcalPerMol} {
673 RRreactions = RRcal/1000.0;
676 <readReactionsUnits>{joulePerMol} {
677 RRreactions = RRjoule;
680 <readReactionsUnits>{otherReactionsUnit} {
683 <readReactionsUnits>\n {
685 BEGIN(readReactionKeyword);
688 <readReactionKeyword>{nMoles} {
689 currentSpecieCoeff.stoichCoeff = atof(YYText());
690 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
693 <readReactionKeyword>{reactionKeyword} {
695 word keyword(foamName(YYText()));
697 HashTable<int>::iterator reactionKeywordIter
699 reactionKeywordTable_.find(keyword)
702 if (reactionKeywordIter != reactionKeywordTable_.end())
704 switch(reactionKeywordIter())
706 case duplicateReactionType:
708 BEGIN(readReactionKeyword);
712 case thirdBodyReactionType:
714 if (rrType != Arrhenius && rrType != thirdBodyArrhenius)
716 FatalErrorIn("chemkinReader::lex()")
717 << "Attempt to set reaction rate type to"
718 " thirdBodyArrhenius when it is already set to "
719 << reactionRateTypeNames[rrType]
720 << " on line " << lineNo_
724 if (pDependentSpecieName.size())
726 FatalErrorIn("chemkinReader::lex()")
727 << "A non-pressure dependent third-body appears in"
728 " the pressure dependent reaction on line "
733 rrType = thirdBodyArrhenius;
737 lhsThirdBodyCounter++;
741 rhsThirdBodyCounter++;
744 BEGIN(readReactionDelimiter);
748 case plasmaMomentumTransfer:
750 FatalErrorIn("chemkinReader::lex()")
751 << "Plasma momentum-transfer in reaction on line "
752 << lineNo_ << "not yet supported"
755 BEGIN(readReactionKeyword);
759 case collisionCrossSection:
761 FatalErrorIn("chemkinReader::lex()")
762 << "Collision cross-section in reaction on line "
763 << lineNo_ << "not yet supported"
766 BEGIN(readReactionKeyword);
777 thirdBodyEfficiencies,
785 finishReaction = false;
786 rType = unknownReactionType;
788 fofType = unknownFallOffFunctionType;
789 thirdBodyEfficiencies = 1.0;
790 pDependentSpecieName = word::null;
797 FatalErrorIn("chemkinReader::lex()")
798 << "keyword " << keyword
799 << " should be followed by parameters"
800 << " on line " << lineNo_
807 currentSpecieName = keyword;
809 HashTable<label>::iterator specieIndexIter
811 specieIndices_.find(currentSpecieName)
814 if (specieIndexIter != specieIndices_.end())
822 thirdBodyEfficiencies,
830 finishReaction = false;
831 rType = unknownReactionType;
833 fofType = unknownFallOffFunctionType;
834 thirdBodyEfficiencies = 1.0;
835 pDependentSpecieName = word::null;
839 currentSpecieCoeff.index = specieIndexIter();
840 lrhsPtr->append(currentSpecieCoeff);
842 BEGIN(readReactionDelimiter);
846 BEGIN(readSpecieNamePlus);
851 <readReactionKeyword>{reactionKeywordSlash} {
853 word keyword(foamName(YYText()));
855 HashTable<int>::iterator reactionKeywordIter
857 reactionKeywordTable_.find(keyword)
860 if (reactionKeywordIter != reactionKeywordTable_.end())
862 switch(reactionKeywordIter())
864 case unimolecularFallOffReactionType:
866 if (!pDependentSpecieName.size())
868 FatalErrorIn("chemkinReader::lex()")
869 << "LOW keyword given for a unimolecular fall-off"
870 " reaction which does not contain a pressure"
871 " dependent specie" << " on line " << lineNo_
875 if (rrType == Arrhenius)
877 rrType = unimolecularFallOff;
881 FatalErrorIn("chemkinReader::lex()")
882 << "Attempt to set reaction rate type to"
883 " unimolecularFallOff when it is already set to "
884 << reactionRateTypeNames[rrType]
885 << " on line " << lineNo_
889 if (fofType == unknownFallOffFunctionType)
894 reactionCoeffsName = reactionRateTypeNames[rrType];
895 BEGIN(readReactionCoeffs);
899 case chemicallyActivatedBimolecularReactionType:
901 if (!pDependentSpecieName.size())
903 FatalErrorIn("chemkinReader::lex()")
904 << "HIGH keyword given for a chemically"
905 " activated bimolecular reaction which does not"
906 " contain a pressure dependent specie"
907 << " on line " << lineNo_
911 if (rrType == Arrhenius)
913 rrType = chemicallyActivatedBimolecular;
917 FatalErrorIn("chemkinReader::lex()")
918 << "Attempt to set reaction rate type to"
919 " chemicallyActivatedBimolecular when it is"
921 << reactionRateTypeNames[rrType]
922 << " on line " << lineNo_
926 if (fofType == unknownFallOffFunctionType)
931 reactionCoeffsName = reactionRateTypeNames[rrType];
932 BEGIN(readReactionCoeffs);
936 case TroeReactionType:
938 if (!pDependentSpecieName.size())
940 FatalErrorIn("chemkinReader::lex()")
941 << "TROE keyword given for a"
942 " reaction which does not contain a pressure"
943 " dependent specie" << " on line " << lineNo_
949 fofType == unknownFallOffFunctionType
950 || fofType == Lindemann
957 FatalErrorIn("chemkinReader::lex()")
958 << "Attempt to set fall-off function type to Troe"
959 " when it is already set to "
960 << fallOffFunctionNames[fofType]
961 << " on line " << lineNo_
965 reactionCoeffsName = fallOffFunctionNames[fofType];
966 BEGIN(readReactionCoeffs);
970 case SRIReactionType:
972 if (!pDependentSpecieName.size())
974 FatalErrorIn("chemkinReader::lex()")
975 << "SRI keyword given for a"
976 " reaction which does not contain a pressure"
977 " dependent specie" << " on line " << lineNo_
983 fofType == unknownFallOffFunctionType
984 || fofType == Lindemann
991 FatalErrorIn("chemkinReader::lex()")
992 << "Attempt to set fall-off function type to SRI"
993 " when it is already set to "
994 << fallOffFunctionNames[fofType]
995 << " on line " << lineNo_
999 reactionCoeffsName = fallOffFunctionNames[fofType];
1000 BEGIN(readReactionCoeffs);
1004 case LandauTellerReactionType:
1006 if (pDependentSpecieName.size())
1008 FatalErrorIn("chemkinReader::lex()")
1009 << "Landau-Teller reaction rate cannot be used"
1010 " for the pressure-dependent reaction on line "
1012 << exit(FatalError);
1015 if (rrType == Arrhenius)
1017 rrType = LandauTeller;
1021 FatalErrorIn("chemkinReader::lex()")
1022 << "Attempt to set reaction rate type to"
1023 " LandauTeller when it is already set to "
1024 << reactionRateTypeNames[rrType]
1025 << " on line " << lineNo_
1026 << exit(FatalError);
1029 rrType = LandauTeller;
1030 reactionCoeffsName = reactionRateTypeNames[rrType];
1031 BEGIN(readReactionCoeffs);
1035 case reverseLandauTellerReactionType:
1037 if (pDependentSpecieName.size())
1039 FatalErrorIn("chemkinReader::lex()")
1040 << "Non-equilibrium Landau-Teller reaction rate"
1042 " for the pressure-dependent reaction on line "
1044 << exit(FatalError);
1047 if (rType != nonEquilibriumReversible)
1049 FatalErrorIn("chemkinReader::lex()")
1050 << "Reverse reaction Arrhenius coefficients not"
1051 " given for reverse LandauTeller reaction."
1052 " Please reorder 'REV' keyword to preceed 'RLT'"
1053 << " on line " << lineNo_
1054 << exit(FatalError);
1057 rrType = LandauTeller;
1058 reactionCoeffsName =
1059 word(reactionTypeNames[rType])
1060 + reactionRateTypeNames[rrType];
1061 BEGIN(readReactionCoeffs);
1065 case JanevReactionType:
1067 if (rrType == Arrhenius)
1073 FatalErrorIn("chemkinReader::lex()")
1074 << "Attempt to set reaction rate type to"
1075 " Janev when it is already set to "
1076 << reactionRateTypeNames[rrType]
1077 << " on line " << lineNo_
1078 << exit(FatalError);
1081 reactionCoeffsName = reactionRateTypeNames[rrType];
1082 BEGIN(readReactionCoeffs);
1086 case powerSeriesReactionRateType:
1088 if (rrType == Arrhenius)
1090 rrType = powerSeries;
1094 FatalErrorIn("chemkinReader::lex()")
1095 << "Attempt to set reaction rate type to"
1096 " powerSeries when it is already set to "
1097 << reactionRateTypeNames[rrType]
1098 << " on line " << lineNo_
1099 << exit(FatalError);
1102 reactionCoeffsName = reactionRateTypeNames[rrType];
1103 BEGIN(readReactionCoeffs);
1107 case radiationActivatedReactionType:
1109 FatalErrorIn("chemkinReader::lex()")
1110 << "Radiation activated reaction on line "
1111 << lineNo_ << "not yet supported"
1112 << exit(FatalError);
1113 //reactionCoeffsName = reactionRateTypeNames[rrType];
1114 BEGIN(readReactionCoeffs);
1118 case energyLossReactionType:
1120 FatalErrorIn("chemkinReader::lex()")
1121 << "Energy loss in reaction on line "
1122 << lineNo_ << "not yet supported"
1123 << exit(FatalError);
1124 //reactionCoeffsName = reactionRateTypeNames[rrType];
1125 BEGIN(readReactionCoeffs);
1129 case nonEquilibriumReversibleReactionType:
1131 rType = nonEquilibriumReversible;
1132 reactionCoeffsName = reactionTypeNames[rType];
1133 BEGIN(readReactionCoeffs);
1137 case speciesOrderForward:
1140 BEGIN(readReactionOrderSpecie);
1144 case speciesOrderReverse:
1147 BEGIN(readReactionOrderSpecie);
1151 case UnitsOfReaction:
1153 BEGIN(readReactionUnit);
1159 FatalErrorIn("chemkinReader::lex()")
1160 << "unknown reaction keyword " << keyword
1161 << " on line " << lineNo_
1162 << exit(FatalError);
1168 HashTable<label>::iterator specieIndexIter
1170 specieIndices_.find(keyword)
1173 if (specieIndexIter != specieIndices_.end())
1175 currentThirdBodyIndex = specieIndexIter();
1179 FatalErrorIn("chemkinReader::lex()")
1180 << "unknown third-body specie " << keyword
1181 << " on line " << lineNo_ << nl
1182 << "Valid species are : " << nl
1183 << specieIndices_.toc() << endl
1184 << exit(FatalError);
1187 BEGIN(readThirdBodyEfficiency);
1191 <readSpecieNamePlus>"+" {
1192 currentSpecieName += "+";
1194 HashTable<label>::iterator specieIndexIter
1196 specieIndices_.find(currentSpecieName)
1199 if (specieIndexIter != specieIndices_.end())
1207 thirdBodyEfficiencies,
1212 reactionCoeffsTable,
1215 finishReaction = false;
1216 rType = unknownReactionType;
1218 fofType = unknownFallOffFunctionType;
1219 thirdBodyEfficiencies = 1.0;
1220 pDependentSpecieName = word::null;
1224 currentSpecieCoeff.index = specieIndexIter();
1225 lrhsPtr->append(currentSpecieCoeff);
1227 BEGIN(readReactionDelimiter);
1231 FatalErrorIn("chemkinReader::lex()")
1232 << "unknown specie " << currentSpecieName
1233 << " on line " << lineNo_ << nl
1234 << "Valid species are : " << nl
1235 << specieIndices_.toc() << endl
1236 << exit(FatalError);
1240 <readReactionDelimiter>{specieDelimiter} {
1241 currentSpecieCoeff.stoichCoeff = 1.0;
1242 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1243 BEGIN(readReactionKeyword);
1246 <readReactionDelimiter>{irreversibleReactionDelimiter} {
1247 currentSpecieCoeff.stoichCoeff = 1.0;
1248 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1249 rType = irreversible;
1251 BEGIN(readReactionKeyword);
1254 <readReactionDelimiter>{reversibleReactionDelimiter} {
1255 currentSpecieCoeff.stoichCoeff = 1.0;
1256 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1259 BEGIN(readReactionKeyword);
1262 <readReactionDelimiter>& {
1265 <readReactionDelimiter>{reactionCoeffs} {
1266 string reactionCoeffsString(YYText());
1267 reactionCoeffsString.replaceAll("d", "e");
1268 reactionCoeffsString.replaceAll("D", "e");
1269 IStringStream reactionCoeffsStream(reactionCoeffsString);
1270 reactionCoeffsStream.lineNumber() = lineNo_;
1272 reactionCoeffsStream
1273 >> ArrheniusCoeffs[0]
1274 >> ArrheniusCoeffs[1]
1275 >> ArrheniusCoeffs[2];
1277 finishReaction = true;
1278 currentSpecieCoeff.stoichCoeff = 1.0;
1279 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1280 RRreaction = RRreactions;
1282 if (lhsThirdBodyCounter || rhsThirdBodyCounter)
1284 if (!lhsThirdBodyCounter || !rhsThirdBodyCounter)
1286 FatalErrorIn("chemkinReader::lex()")
1287 << "Third body not present on both sides of reaction"
1288 " on line " << lineNo_
1289 << exit(FatalError);
1292 if (lhsThirdBodyCounter != 1)
1294 FatalErrorIn("chemkinReader::lex()")
1295 << "More than 1 third body present on l.h.s. side"
1296 " of reaction on line " << lineNo_
1297 << exit(FatalError);
1300 if (rhsThirdBodyCounter != 1)
1302 FatalErrorIn("chemkinReader::lex()")
1303 << "More than 1 third body present on r.h.s. side"
1304 " of reaction on line " << lineNo_
1305 << exit(FatalError);
1308 lhsThirdBodyCounter = 0;
1309 rhsThirdBodyCounter = 0;
1312 BEGIN(readReactionKeyword);
1316 <readThirdBodyEfficiency>{thirdBodyEfficiency} {
1317 thirdBodyEfficiencies[currentThirdBodyIndex] = stringToScalar(YYText());
1318 BEGIN(readReactionKeyword);
1321 <readReactionDelimiter>{startPDependentSpecie} {
1322 BEGIN(readPDependentSpecie);
1325 <readPDependentSpecie>{pDependentSpecie} {
1327 word rhsPDependentSpecieName = pDependentSpecieName;
1328 pDependentSpecieName =
1329 foamName(foamSpecieString(YYText()));
1330 pDependentSpecieName =
1331 pDependentSpecieName(0, pDependentSpecieName.size() - 1);
1333 if (rrType == thirdBodyArrhenius)
1335 FatalErrorIn("chemkinReader::lex()")
1336 << "The pressure-dependent third-body '"
1337 << pDependentSpecieName
1338 << "' is given in non-pressure-dependent third-body reaction"
1339 << " on line " << lineNo_
1340 << exit(FatalError);
1343 if (lrhsPtr == &lhs)
1345 lhsThirdBodyCounter++;
1349 if (pDependentSpecieName != rhsPDependentSpecieName)
1351 FatalErrorIn("chemkinReader::lex()")
1352 << "The third-body reactant '"
1353 << pDependentSpecieName
1354 << "' is not the same as the third-body product '"
1355 << rhsPDependentSpecieName
1356 << "' in pressure-dependent reaction on line " << lineNo_
1357 << exit(FatalError);
1360 rhsThirdBodyCounter++;
1363 if (pDependentSpecieName != "M")
1365 HashTable<label>::iterator specieIndexIter
1367 specieIndices_.find(pDependentSpecieName)
1370 if (specieIndexIter != specieIndices_.end())
1372 thirdBodyEfficiencies = 0.0;
1373 thirdBodyEfficiencies[specieIndexIter()] = 1.0;
1377 FatalErrorIn("chemkinReader::lex()")
1378 << "unknown third-body specie " << pDependentSpecieName
1379 << " on line " << lineNo_ << nl
1380 << "Valid species are : " << nl
1381 << specieIndices_.toc() << endl
1382 << exit(FatalError);
1386 BEGIN(readReactionDelimiter);
1389 <readReactionCoeffs>{reactionCoeff} {
1390 reactionCoeffs.append(stringToScalar(YYText()));
1393 <readReactionCoeffs>{endReactionCoeffs} {
1394 reactionCoeffsTable.insert(reactionCoeffsName, reactionCoeffs.shrink());
1395 reactionCoeffs.clear();
1396 BEGIN(readReactionKeyword);
1399 <readTdepSpecie>{specieName} {
1400 word specieName(foamName(foamSpecieString(YYText())));
1401 FatalErrorIn("chemkinReader::lex()")
1402 << "Temperature-dependent reaction on line "
1403 << lineNo_ << "not yet supported"
1404 << exit(FatalError);
1405 BEGIN(readReactionKeyword);
1408 <readReactionOrderSpecie>{specieName} {
1410 word(foamName(foamSpecieString(YYText())));
1412 HashTable<label>::iterator specieIndexIter
1414 specieIndices_.find(currentSpecieName)
1417 if (specieIndexIter != specieIndices_.end())
1419 currentSpecieIndex = specieIndexIter();
1423 FatalErrorIn("chemkinReader::lex()")
1424 << "unknown specie " << currentSpecieName
1425 << " given in reaction-order specification"
1426 << " on line " << lineNo_ << nl
1427 << "Valid species are : " << nl
1428 << specieIndices_.toc() << endl
1429 << exit(FatalError);
1432 BEGIN(readReactionOrder);
1435 <readReactionOrder>{reactionCoeff}{endReactionCoeffs} {
1437 DynamicList<reaction::specieCoeffs>& lrhs = *lrhsPtr;
1443 if (lrhs[i].index == currentSpecieIndex)
1445 lrhs[i].exponent = stringToScalar(YYText());
1453 word side("l.h.s.");
1455 if (lrhsPtr == &rhs)
1460 FatalErrorIn("chemkinReader::lex()")
1461 << "Specie " << currentSpecieName
1462 << " on line " << lineNo_
1463 << " not present in " << side << " of reaction " << nl << lrhs
1464 << exit(FatalError);
1467 BEGIN(readReactionKeyword);
1470 <readReactionUnit>{cal} {
1474 <readReactionUnit>{kcal} {
1475 RRreaction = RRcal/1000.0;
1478 <readReactionUnit>{joule} {
1479 RRreaction = RRjoule;
1482 <readReactionUnit>{kjoule} {
1483 RRreaction = RRjoule/1000.0;
1486 <readReactionUnit>{otherReactionsUnit} {
1489 <readReactionUnit>{endReactionCoeffs} {
1490 BEGIN(readReactionKeyword);
1494 /* ------------------ Ignore remaining space and \n s. --------------------- */
1496 <*>\n { lineNo_++; }
1498 /* ------ Ignore remaining space and \n s. Any other characters are errors. */
1501 startError = YYText();
1502 yy_push_state(CHEMKINError);
1507 FatalErrorIn("chemkinReader::lex()")
1508 << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
1509 << " expected " << stateExpects[YY_START]
1510 << " but found '" << startError << YYText() << "'"
1511 << exit(FatalError);
1515 /* ------------------------ On EOF terminate. ---------------------------- */
1524 thirdBodyEfficiencies,
1529 reactionCoeffsTable,
1537 /* ------------------------------------------------------------------------- *\
1538 ------ End of STLToFoam.L
1539 \* ------------------------------------------------------------------------- */