1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 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"
38 // flex input buffer size
39 int Foam::chemkinReader::yyBufSize = YY_BUF_SIZE;
41 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
43 int yyFlexLexer::yylex()
45 Foam::FatalErrorIn("yyFlexLexer::yylex()")
46 << "should not have called this function"
47 << abort(Foam::FatalError);
54 // Dummy yywrap to keep yylex happy at compile time.
55 // It is called by yylex but is not used as the mechanism to change file.
58 #if YY_FLEX_SUBMINOR_VERSION < 34
59 extern "C" int yywrap()
61 int yyFlexLexer::yywrap()
69 Foam::string foamSpecieString(const char* YYText)
71 Foam::string specieString(YYText);
72 // Transforming parentheses is no longer necessary
73 //specieString.replaceAll('(', '<');
74 //specieString.replaceAll(')', '>');
79 Foam::word foamName(const char* YYText)
81 Foam::string fn(YYText);
82 Foam::string::stripInvalid<Foam::word>(fn);
87 Foam::word foamName(const Foam::string& s)
90 Foam::string::stripInvalid<Foam::word>(fn);
95 /* ------------------------------------------------------------------------- *\
96 ------ cppLexer::yylex()
97 \* ------------------------------------------------------------------------- */
99 #define YY_DECL int Foam::chemkinReader::lex()
105 some_space {one_space}+
112 hex_digit [0-9a-fA-F]
114 identifier {alpha}({alpha}|{digit})*
116 label [1-9]{dec_digit}*
119 word ([[:alnum:]]|[[:punct:]])+
120 string {word}({some_space}{word})*
122 exponent_part [eEdD][-+]?{digit}+
123 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
125 double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
128 elements {space}("ELEMENTS"|"ELEM"){space}
129 species {space}("SPECIES"|"SPECIE"|"SPEC"){space}
130 thermoAll {space}"THERMO"{some_space}"ALL"{space}
131 thermo {space}"THERMO"{space}
132 reactions {space}("REACTIONS"|"REAC"){space}
133 end {space}"END"{space}
135 elementName {space}([A-Z]|([A-Z][A-Z])){space}
136 startIsotopeMolW {space}"/"{space}
137 isotopeMolW {space}{double}{space}"/"{space}
139 specieName {space}[A-Za-z](([A-Za-z0-9)*+-])|("("[^+]))*{space}
140 nMoles {space}{double}{space}
144 thermoSpecieName .{18}
150 thermoCommonTemp .{8}
153 thermoLineLabel1 " "1{space}
154 thermoLineLabel2 " "{4}2{space}
155 thermoLineLabel3 " "{4}3{space}
156 thermoLineLabel4 " "{4}4{space}
158 specieDelimiter {space}"+"{space}
159 reversibleReactionDelimiter {space}("="|"<=>"){space}
160 irreversibleReactionDelimiter {space}"=>"{space}
161 startPDependentSpecie {space}"("{space}"+"{space}
162 pDependentSpecie {specieName}")"{space}
163 reactionCoeffs {space}{double}{some_space}{double}{some_space}{double}{space}
164 reactionKeyword {space}[A-Za-z](([A-Za-z0-9)*-])|("("[^+]))*{space}
165 reactionKeywordSlash {reactionKeyword}"/"{space}
166 thirdBodyEfficiency {space}{double}{space}"/"{space}
167 startReactionCoeffs {space}"/"{space}
168 endReactionCoeffs {space}"/"{space}
169 reactionCoeff {space}{double}{space}
171 calPerMol {space}"CAL/MOLE"{space}
172 kcalPerMol {space}"KCAL/MOLE"{space}
173 joulePerMol {space}"JOULES/MOLE"{space}
174 otherReactionsUnit {space}("KELVINS"|"EVOLTS"|"MOLES"|"MOLECULES"){space}
176 cal {space}"CAL"{space}
177 kcal {space}"KCAL"{space}
178 joule {space}"JOUL"{space}
179 kjoule {space}"KJOU"{space}
180 otherReactionUnit {space}("MOLE"|"MOLECULE"|"KELV"|"KELVIN"|"EVOL"|"EVOLTS"){space}
183 /* ------------------------------------------------------------------------- *\
184 ----- Exclusive start states -----
185 \* ------------------------------------------------------------------------- */
193 %x readThermoSpecieName
198 %x readThermoFormula2
199 %x readThermoLineLabel1
201 %x readThermoLineLabel2
203 %x readThermoLineLabel3
205 %x readThermoLineLabel4
206 %x readReactionsUnits
207 %x readReactionKeyword
208 %x readSpecieNamePlus
209 %x readReactionDelimiter
210 %x readPDependentSpecie
211 %x readThirdBodyEfficiency
212 %x readReactionCoeffs
214 %x readReactionOrderSpecie
223 static const char* stateNames[30] =
225 "reading CHEMKIN III file",
227 "reading isotope molecular weight",
229 "reading all thermodynamic data temperatures",
230 "reading thermodynamic specie name",
231 "reading thermodynamic data date",
232 "reading thermodynamic data specie formula",
233 "reading thermodynamic data specie phase",
234 "reading thermodynamic data temperatures",
235 "reading thermodynamic data specie formula (supplement)",
236 "reading thermodynamic data line label 1",
237 "reading thermodynamic data coefficient set 1",
238 "reading thermodynamic data line label 2",
239 "reading thermodynamic data coefficient set 2",
240 "reading thermodynamic data line label 3",
241 "reading thermodynamic data coefficient set 3",
242 "reading thermodynamic data line label 4",
243 "reading reaction units",
244 "reading reaction specie/keyword",
245 "reading reaction specie",
246 "reading reaction delimiter",
247 "reading reaction pressure dependent specie",
248 "reading third-body efficiency",
249 "reading reaction coeff",
250 "reading temperature dependent specie name",
251 "reading reaction order specie name",
252 "reading reaction order",
253 "reading reaction unit",
257 static const char* stateExpects[30] =
259 "'ELEMENTS' or 'ELEM', 'SPECIES' or 'SPEC', 'THERMO' or 'THERMO ALL', 'REACTIONS'",
260 "<elementName>, <isotopeName> / or 'END'",
262 "<specieName> or 'END'",
263 "<scalar><scalar><scalar> (3F10.0)",
266 "<word><label><word><label><word><label><word><label> (4(2A1,I3))",
268 "<scalar><scalar><scalar> (E10.0E10.0E8.0)",
269 "<word><label> (2A1,I3)",
271 "<scalar><scalar><scalar><scalar><scalar> (5(E15.0))",
273 "<scalar><scalar><scalar><scalar><scalar> (5(E15.0))",
275 "<scalar><scalar><scalar><scalar> (4(E15.0))",
277 "'CAL/MOLE', 'KCAL/MOLE', 'JOULES/MOLE', 'KELVINS', 'EVOLTS', 'MOLES' or 'MOLECULES'",
280 "'+', '=', '<=>', '=>', '(+<word>', '<scalar> <scalar> <scalar>'",
287 "'MOLE', 'MOLECULE', 'CAL', 'KCAL', 'JOUL', 'KJOU', 'KELV', 'KELVIN', 'EVOL' or 'EVOLTS'",
293 static const scalar RRjoule = 8.31451; // J/kg-mol-K
294 static const scalar RRcal = 1.987316; // cal/g-mol-K
296 scalar RRreactions = RRcal;
297 scalar RRreaction = RRcal;
299 scalar allCommonT = 1000.0;
301 word currentElementName;
302 label currentElementIndex = 0;
304 word currentSpecieName;
305 label currentSpecieIndex = 0;
306 label nSpecieElements = 0;
307 List<specieElement> currentSpecieComposition(5);
309 scalar currentLowT = 0;
310 scalar currentHighT = 0;
311 scalar currentCommonT = 0;
312 gasThermoPhysics::coeffArray highCpCoeffs;
313 gasThermoPhysics::coeffArray lowCpCoeffs;
315 gasReaction::specieCoeffs currentSpecieCoeff;
317 DynamicList<gasReaction::specieCoeffs> lhs;
318 DynamicList<gasReaction::specieCoeffs> rhs;
320 scalarList ArrheniusCoeffs(3);
321 DynamicList<scalar> reactionCoeffs;
322 scalarList thirdBodyEfficiencies;
323 label currentThirdBodyIndex = -1;
325 word reactionCoeffsName = word::null;
326 HashTable<scalarList> reactionCoeffsTable;
328 DynamicList<gasReaction::specieCoeffs> *lrhsPtr = &lhs;
330 reactionType rType = unknownReactionType;
331 reactionRateType rrType = Arrhenius;
332 fallOffFunctionType fofType = unknownFallOffFunctionType;
333 word pDependentSpecieName = word::null;
334 label lhsThirdBodyCounter = 0;
335 label rhsThirdBodyCounter = 0;
337 bool finishReaction = false;
341 /* ------------------------------------------------------------------------- *\
342 ------ Start Lexing ------
343 \* ------------------------------------------------------------------------- */
345 /* ------------------------------------------------------------------------- *\
346 ------ Discard comments being careful to count comments
347 \* ------------------------------------------------------------------------- */
349 <*>{space}"!".* { // Remove one line comments
352 /* ------------------------------------------------------------------------- *\
354 \* ------------------------------------------------------------------------- */
360 <readElements>{elementName} {
361 currentElementName = foamName(YYText());
362 correctElementName(currentElementName);
364 if (!elementIndices_.found(currentElementName))
366 elementIndices_.insert(currentElementName, currentElementIndex++);
367 elementNames_.append(currentElementName);
371 WarningIn("chemkinReader::lex()")
372 << "element " << currentElementName
373 << " already in table." << endl;
377 <readElements>{startIsotopeMolW} {
378 BEGIN(readIsotopeMolW);
381 <readIsotopeMolW>{isotopeMolW} {
382 isotopeAtomicWts_.insert(currentElementName, stringToScalar(YYText()));
386 <readElements>{end} {
390 /* ------------------------------------------------------------------------- *\
392 \* ------------------------------------------------------------------------- */
394 <INITIAL,readElements>{species} {
398 <readSpecies>{specieName} {
399 word specieName(foamName(foamSpecieString(YYText())));
401 if (specieName == "THERMO")
403 specieNames_.shrink();
404 speciesTable_ = specieNames_;
405 thirdBodyEfficiencies.setSize(specieNames_.size());
406 thirdBodyEfficiencies = 1.0;
407 BEGIN(readThermoSpecieName);
409 else if (specieName == "END")
411 specieNames_.shrink();
412 speciesTable_ = specieNames_;
413 thirdBodyEfficiencies.setSize(specieNames_.size());
414 thirdBodyEfficiencies = 1.0;
419 if (!specieIndices_.found(specieName))
421 specieNames_.append(specieName);
422 specieIndices_.insert(specieName, currentSpecieIndex++);
426 WarningIn("chemkinReader::lex()")
427 << "specie " << specieName
428 << " already in table." << endl;
433 /* ------------------------------------------------------------------------- *\
435 \* ------------------------------------------------------------------------- */
437 <INITIAL,readSpecies>{thermo} {
438 BEGIN(readThermoSpecieName);
441 <INITIAL,readSpecies>{thermoAll} {
442 BEGIN(readThermoAll);
445 <readThermoAll>{thermoTemp}{thermoTemp}{thermoTemp} {
446 string temperaturesString(YYText());
447 //scalar lowestT(stringToScalar(temperaturesString(0, 10)));
448 allCommonT = stringToScalar(temperaturesString(10, 10));
449 //scalar highestT(stringToScalar(temperaturesString(20, 10)));
450 BEGIN(readThermoSpecieName);
453 <readThermoSpecieName>{thermoSpecieName} {
454 string specieString(foamSpecieString(YYText()));
455 size_t spacePos = specieString.find(' ');
456 if (spacePos != string::npos)
458 currentSpecieName = specieString(0, spacePos);
462 currentSpecieName = specieString;
464 BEGIN(readThermoDate);
467 <readThermoDate>{thermoDate} {
468 // string thermoDate(YYText());
469 // Date is not currently used
470 BEGIN(readThermoFormula);
473 <readThermoFormula>{thermoFormula} {
474 string thermoFormula(YYText());
477 currentSpecieComposition.setSize(5);
479 for (int i=0; i<4; i++)
481 word elementName(foamName(thermoFormula(5*i, 2)));
482 label nAtoms = atoi(thermoFormula(5*i + 2, 3).c_str());
484 if (elementName.size() && nAtoms)
486 correctElementName(elementName);
487 currentSpecieComposition[nSpecieElements].elementName =
489 currentSpecieComposition[nSpecieElements++].nAtoms = nAtoms;
493 BEGIN(readThermoPhase);
496 <readThermoPhase>{thermoPhase} {
497 char phaseChar = YYText()[0];
502 speciePhase_.insert(currentSpecieName, solid);
506 speciePhase_.insert(currentSpecieName, liquid);
510 speciePhase_.insert(currentSpecieName, gas);
514 BEGIN(readThermoTemps);
517 <readThermoTemps>{thermoLowTemp}{thermoHighTemp}{thermoCommonTemp} {
518 string temperaturesString(YYText());
519 currentLowT = stringToScalar(temperaturesString(0, 10));
520 currentHighT = stringToScalar(temperaturesString(10, 10));
521 currentCommonT = stringToScalar(temperaturesString(20, 8));
523 if (currentCommonT < SMALL)
525 currentCommonT = allCommonT;
528 BEGIN(readThermoFormula2);
531 <readThermoFormula2>{thermoFormula2} {
532 string thermoFormula(YYText());
533 word elementName(foamName(thermoFormula(0, 2)));
534 label nAtoms = atoi(thermoFormula(2, 3).c_str());
539 && elementName.find('0') == string::npos
543 correctElementName(elementName);
544 currentSpecieComposition[nSpecieElements].elementName =
546 currentSpecieComposition[nSpecieElements++].nAtoms = nAtoms;
549 currentSpecieComposition.setSize(nSpecieElements);
551 HashTable<List<specieElement> >::iterator specieCompositionIter
553 specieComposition_.find(currentSpecieName)
556 if (specieCompositionIter != specieComposition_.end())
558 specieComposition_.erase(specieCompositionIter);
561 specieComposition_.insert
564 currentSpecieComposition
567 BEGIN(readThermoLineLabel1);
570 <readThermoLineLabel1>{thermoLineLabel1} {
571 BEGIN(readThermoCoeff1);
574 <readThermoCoeff1>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
575 string thermoCoeffString(YYText());
577 highCpCoeffs[0] = stringToScalar(thermoCoeffString(0, 15));
578 highCpCoeffs[1] = stringToScalar(thermoCoeffString(15, 15));
579 highCpCoeffs[2] = stringToScalar(thermoCoeffString(30, 15));
580 highCpCoeffs[3] = stringToScalar(thermoCoeffString(45, 15));
581 highCpCoeffs[4] = stringToScalar(thermoCoeffString(60, 15));
583 BEGIN(readThermoLineLabel2);
586 <readThermoLineLabel2>{thermoLineLabel2} {
587 BEGIN(readThermoCoeff2);
590 <readThermoCoeff2>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
591 string thermoCoeffString(YYText());
593 highCpCoeffs[5] = stringToScalar(thermoCoeffString(0, 15));
594 highCpCoeffs[6] = stringToScalar(thermoCoeffString(15, 15));
596 lowCpCoeffs[0] = stringToScalar(thermoCoeffString(30, 15));
597 lowCpCoeffs[1] = stringToScalar(thermoCoeffString(45, 15));
598 lowCpCoeffs[2] = stringToScalar(thermoCoeffString(60, 15));
600 BEGIN(readThermoLineLabel3);
603 <readThermoLineLabel3>{thermoLineLabel3} {
604 BEGIN(readThermoCoeff3);
607 <readThermoCoeff3>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
608 string thermoCoeffString(YYText());
610 lowCpCoeffs[3] = stringToScalar(thermoCoeffString(0, 15));
611 lowCpCoeffs[4] = stringToScalar(thermoCoeffString(15, 15));
612 lowCpCoeffs[5] = stringToScalar(thermoCoeffString(30, 15));
613 lowCpCoeffs[6] = stringToScalar(thermoCoeffString(45, 15));
615 BEGIN(readThermoLineLabel4);
618 <readThermoLineLabel4>{thermoLineLabel4} {
620 HashPtrTable<gasThermoPhysics>::iterator specieThermoIter
622 speciesThermo_.find(currentSpecieName)
625 if (specieThermoIter != speciesThermo_.end())
627 speciesThermo_.erase(specieThermoIter);
630 speciesThermo_.insert
635 janafThermo<perfectGas>
641 molecularWeight(currentSpecieComposition)
654 BEGIN(readThermoSpecieName);
657 <readThermoSpecieName>{end} {
661 /* ------------------------------------------------------------------------- *\
662 ------ Read reactions
663 \* ------------------------------------------------------------------------- */
665 <INITIAL,readThermoSpecieName>{reactions} {
666 currentSpecieCoeff.stoichCoeff = 1.0;
667 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
668 BEGIN(readReactionsUnits);
671 <readReactionsUnits>{calPerMol} {
675 <readReactionsUnits>{kcalPerMol} {
676 RRreactions = RRcal/1000.0;
679 <readReactionsUnits>{joulePerMol} {
680 RRreactions = RRjoule;
683 <readReactionsUnits>{otherReactionsUnit} {
686 <readReactionsUnits>\n {
688 BEGIN(readReactionKeyword);
691 <readReactionKeyword>{nMoles} {
692 currentSpecieCoeff.stoichCoeff = atof(YYText());
693 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
696 <readReactionKeyword>{reactionKeyword} {
698 word keyword(foamName(YYText()));
700 HashTable<int>::iterator reactionKeywordIter
702 reactionKeywordTable_.find(keyword)
705 if (reactionKeywordIter != reactionKeywordTable_.end())
707 switch(reactionKeywordIter())
709 case duplicateReactionType:
711 BEGIN(readReactionKeyword);
715 case thirdBodyReactionType:
717 if (rrType != Arrhenius && rrType != thirdBodyArrhenius)
719 FatalErrorIn("chemkinReader::lex()")
720 << "Attempt to set reaction rate type to"
721 " thirdBodyArrhenius when it is already set to "
722 << reactionRateTypeNames[rrType]
723 << " on line " << lineNo_
727 if (pDependentSpecieName.size())
729 FatalErrorIn("chemkinReader::lex()")
730 << "A non-pressure dependent third-body appears in"
731 " the pressure dependent reaction on line "
736 rrType = thirdBodyArrhenius;
740 lhsThirdBodyCounter++;
744 rhsThirdBodyCounter++;
747 BEGIN(readReactionDelimiter);
751 case plasmaMomentumTransfer:
753 FatalErrorIn("chemkinReader::lex()")
754 << "Plasma momentum-transfer in reaction on line "
755 << lineNo_ << "not yet supported"
758 BEGIN(readReactionKeyword);
762 case collisionCrossSection:
764 FatalErrorIn("chemkinReader::lex()")
765 << "Collision cross-section in reaction on line "
766 << lineNo_ << "not yet supported"
769 BEGIN(readReactionKeyword);
780 thirdBodyEfficiencies,
788 finishReaction = false;
789 rType = unknownReactionType;
791 fofType = unknownFallOffFunctionType;
792 thirdBodyEfficiencies = 1.0;
793 pDependentSpecieName = word::null;
800 FatalErrorIn("chemkinReader::lex()")
801 << "keyword " << keyword
802 << " should be followed by parameters"
803 << " on line " << lineNo_
810 currentSpecieName = foamName(foamSpecieString(YYText()));
812 HashTable<label>::iterator specieIndexIter
814 specieIndices_.find(currentSpecieName)
817 if (specieIndexIter != specieIndices_.end())
825 thirdBodyEfficiencies,
833 finishReaction = false;
834 rType = unknownReactionType;
836 fofType = unknownFallOffFunctionType;
837 thirdBodyEfficiencies = 1.0;
838 pDependentSpecieName = word::null;
842 currentSpecieCoeff.index = specieIndexIter();
843 lrhsPtr->append(currentSpecieCoeff);
845 BEGIN(readReactionDelimiter);
849 BEGIN(readSpecieNamePlus);
854 <readReactionKeyword>{reactionKeywordSlash} {
856 word keyword(foamName(YYText()));
858 HashTable<int>::iterator reactionKeywordIter
860 reactionKeywordTable_.find(keyword)
863 if (reactionKeywordIter != reactionKeywordTable_.end())
865 switch(reactionKeywordIter())
867 case unimolecularFallOffReactionType:
869 if (!pDependentSpecieName.size())
871 FatalErrorIn("chemkinReader::lex()")
872 << "LOW keyword given for a unimolecular fall-off"
873 " reaction which does not contain a pressure"
874 " dependent specie" << " on line " << lineNo_
878 if (rrType == Arrhenius)
880 rrType = unimolecularFallOff;
884 FatalErrorIn("chemkinReader::lex()")
885 << "Attempt to set reaction rate type to"
886 " unimolecularFallOff when it is already set to "
887 << reactionRateTypeNames[rrType]
888 << " on line " << lineNo_
892 if (fofType == unknownFallOffFunctionType)
897 reactionCoeffsName = reactionRateTypeNames[rrType];
898 BEGIN(readReactionCoeffs);
902 case chemicallyActivatedBimolecularReactionType:
904 if (!pDependentSpecieName.size())
906 FatalErrorIn("chemkinReader::lex()")
907 << "HIGH keyword given for a chemically"
908 " activated bimolecular reaction which does not"
909 " contain a pressure dependent specie"
910 << " on line " << lineNo_
914 if (rrType == Arrhenius)
916 rrType = chemicallyActivatedBimolecular;
920 FatalErrorIn("chemkinReader::lex()")
921 << "Attempt to set reaction rate type to"
922 " chemicallyActivatedBimolecular when it is"
924 << reactionRateTypeNames[rrType]
925 << " on line " << lineNo_
929 if (fofType == unknownFallOffFunctionType)
934 reactionCoeffsName = reactionRateTypeNames[rrType];
935 BEGIN(readReactionCoeffs);
939 case TroeReactionType:
941 if (!pDependentSpecieName.size())
943 FatalErrorIn("chemkinReader::lex()")
944 << "TROE keyword given for a"
945 " reaction which does not contain a pressure"
946 " dependent specie" << " on line " << lineNo_
952 fofType == unknownFallOffFunctionType
953 || fofType == Lindemann
960 FatalErrorIn("chemkinReader::lex()")
961 << "Attempt to set fall-off function type to Troe"
962 " when it is already set to "
963 << fallOffFunctionNames[fofType]
964 << " on line " << lineNo_
968 reactionCoeffsName = fallOffFunctionNames[fofType];
969 BEGIN(readReactionCoeffs);
973 case SRIReactionType:
975 if (!pDependentSpecieName.size())
977 FatalErrorIn("chemkinReader::lex()")
978 << "SRI keyword given for a"
979 " reaction which does not contain a pressure"
980 " dependent specie" << " on line " << lineNo_
986 fofType == unknownFallOffFunctionType
987 || fofType == Lindemann
994 FatalErrorIn("chemkinReader::lex()")
995 << "Attempt to set fall-off function type to SRI"
996 " when it is already set to "
997 << fallOffFunctionNames[fofType]
998 << " on line " << lineNo_
1002 reactionCoeffsName = fallOffFunctionNames[fofType];
1003 BEGIN(readReactionCoeffs);
1007 case LandauTellerReactionType:
1009 if (pDependentSpecieName.size())
1011 FatalErrorIn("chemkinReader::lex()")
1012 << "Landau-Teller reaction rate cannot be used"
1013 " for the pressure-dependent reaction on line "
1015 << exit(FatalError);
1018 if (rrType == Arrhenius)
1020 rrType = LandauTeller;
1024 FatalErrorIn("chemkinReader::lex()")
1025 << "Attempt to set reaction rate type to"
1026 " LandauTeller when it is already set to "
1027 << reactionRateTypeNames[rrType]
1028 << " on line " << lineNo_
1029 << exit(FatalError);
1032 rrType = LandauTeller;
1033 reactionCoeffsName = reactionRateTypeNames[rrType];
1034 BEGIN(readReactionCoeffs);
1038 case reverseLandauTellerReactionType:
1040 if (pDependentSpecieName.size())
1042 FatalErrorIn("chemkinReader::lex()")
1043 << "Non-equilibrium Landau-Teller reaction rate"
1045 " for the pressure-dependent reaction on line "
1047 << exit(FatalError);
1050 if (rType != nonEquilibriumReversible)
1052 FatalErrorIn("chemkinReader::lex()")
1053 << "Reverse reaction Arrhenius coefficients not"
1054 " given for reverse LandauTeller reaction."
1055 " Please reorder 'REV' keyword to preceed 'RLT'"
1056 << " on line " << lineNo_
1057 << exit(FatalError);
1060 rrType = LandauTeller;
1061 reactionCoeffsName =
1062 word(reactionTypeNames[rType])
1063 + reactionRateTypeNames[rrType];
1064 BEGIN(readReactionCoeffs);
1068 case JanevReactionType:
1070 if (rrType == Arrhenius)
1076 FatalErrorIn("chemkinReader::lex()")
1077 << "Attempt to set reaction rate type to"
1078 " Janev when it is already set to "
1079 << reactionRateTypeNames[rrType]
1080 << " on line " << lineNo_
1081 << exit(FatalError);
1084 reactionCoeffsName = reactionRateTypeNames[rrType];
1085 BEGIN(readReactionCoeffs);
1089 case powerSeriesReactionRateType:
1091 if (rrType == Arrhenius)
1093 rrType = powerSeries;
1097 FatalErrorIn("chemkinReader::lex()")
1098 << "Attempt to set reaction rate type to"
1099 " powerSeries when it is already set to "
1100 << reactionRateTypeNames[rrType]
1101 << " on line " << lineNo_
1102 << exit(FatalError);
1105 reactionCoeffsName = reactionRateTypeNames[rrType];
1106 BEGIN(readReactionCoeffs);
1110 case radiationActivatedReactionType:
1112 FatalErrorIn("chemkinReader::lex()")
1113 << "Radiation activated reaction on line "
1114 << lineNo_ << "not yet supported"
1115 << exit(FatalError);
1116 //reactionCoeffsName = reactionRateTypeNames[rrType];
1117 BEGIN(readReactionCoeffs);
1121 case energyLossReactionType:
1123 FatalErrorIn("chemkinReader::lex()")
1124 << "Energy loss in reaction on line "
1125 << lineNo_ << "not yet supported"
1126 << exit(FatalError);
1127 //reactionCoeffsName = reactionRateTypeNames[rrType];
1128 BEGIN(readReactionCoeffs);
1132 case nonEquilibriumReversibleReactionType:
1134 rType = nonEquilibriumReversible;
1135 reactionCoeffsName = reactionTypeNames[rType];
1136 BEGIN(readReactionCoeffs);
1140 case speciesOrderForward:
1143 BEGIN(readReactionOrderSpecie);
1147 case speciesOrderReverse:
1150 BEGIN(readReactionOrderSpecie);
1154 case UnitsOfReaction:
1156 BEGIN(readReactionUnit);
1162 FatalErrorIn("chemkinReader::lex()")
1163 << "unknown reaction keyword " << keyword
1164 << " on line " << lineNo_
1165 << exit(FatalError);
1171 HashTable<label>::iterator specieIndexIter
1173 specieIndices_.find(keyword)
1176 if (specieIndexIter != specieIndices_.end())
1178 currentThirdBodyIndex = specieIndexIter();
1182 FatalErrorIn("chemkinReader::lex()")
1183 << "unknown third-body specie " << keyword
1184 << " on line " << lineNo_ << nl
1185 << "Valid species are : " << nl
1186 << specieIndices_.toc() << endl
1187 << exit(FatalError);
1190 BEGIN(readThirdBodyEfficiency);
1194 <readSpecieNamePlus>"+" {
1195 currentSpecieName += "+";
1197 HashTable<label>::iterator specieIndexIter
1199 specieIndices_.find(currentSpecieName)
1202 if (specieIndexIter != specieIndices_.end())
1210 thirdBodyEfficiencies,
1215 reactionCoeffsTable,
1218 finishReaction = false;
1219 rType = unknownReactionType;
1221 fofType = unknownFallOffFunctionType;
1222 thirdBodyEfficiencies = 1.0;
1223 pDependentSpecieName = word::null;
1227 currentSpecieCoeff.index = specieIndexIter();
1228 lrhsPtr->append(currentSpecieCoeff);
1230 BEGIN(readReactionDelimiter);
1234 FatalErrorIn("chemkinReader::lex()")
1235 << "unknown specie " << currentSpecieName
1236 << " on line " << lineNo_ << nl
1237 << "Valid species are : " << nl
1238 << specieIndices_.toc() << endl
1239 << exit(FatalError);
1243 <readReactionDelimiter>{specieDelimiter} {
1244 currentSpecieCoeff.stoichCoeff = 1.0;
1245 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1246 BEGIN(readReactionKeyword);
1249 <readReactionDelimiter>{irreversibleReactionDelimiter} {
1250 currentSpecieCoeff.stoichCoeff = 1.0;
1251 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1252 rType = irreversible;
1254 BEGIN(readReactionKeyword);
1257 <readReactionDelimiter>{reversibleReactionDelimiter} {
1258 currentSpecieCoeff.stoichCoeff = 1.0;
1259 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1262 BEGIN(readReactionKeyword);
1265 <readReactionDelimiter>& {
1268 <readReactionDelimiter>{reactionCoeffs} {
1269 string reactionCoeffsString(YYText());
1270 reactionCoeffsString.replaceAll("d", "e");
1271 reactionCoeffsString.replaceAll("D", "e");
1272 IStringStream reactionCoeffsStream(reactionCoeffsString);
1273 reactionCoeffsStream.lineNumber() = lineNo_;
1275 reactionCoeffsStream
1276 >> ArrheniusCoeffs[0]
1277 >> ArrheniusCoeffs[1]
1278 >> ArrheniusCoeffs[2];
1280 finishReaction = true;
1281 currentSpecieCoeff.stoichCoeff = 1.0;
1282 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1283 RRreaction = RRreactions;
1285 if (lhsThirdBodyCounter || rhsThirdBodyCounter)
1287 if (!lhsThirdBodyCounter || !rhsThirdBodyCounter)
1289 FatalErrorIn("chemkinReader::lex()")
1290 << "Third body not present on both sides of reaction"
1291 " on line " << lineNo_
1292 << exit(FatalError);
1295 if (lhsThirdBodyCounter != 1)
1297 FatalErrorIn("chemkinReader::lex()")
1298 << "More than 1 third body present on l.h.s. side"
1299 " of reaction on line " << lineNo_
1300 << exit(FatalError);
1303 if (rhsThirdBodyCounter != 1)
1305 FatalErrorIn("chemkinReader::lex()")
1306 << "More than 1 third body present on r.h.s. side"
1307 " of reaction on line " << lineNo_
1308 << exit(FatalError);
1311 lhsThirdBodyCounter = 0;
1312 rhsThirdBodyCounter = 0;
1315 BEGIN(readReactionKeyword);
1319 <readThirdBodyEfficiency>{thirdBodyEfficiency} {
1320 thirdBodyEfficiencies[currentThirdBodyIndex] = stringToScalar(YYText());
1321 BEGIN(readReactionKeyword);
1324 <readReactionDelimiter>{startPDependentSpecie} {
1325 BEGIN(readPDependentSpecie);
1328 <readPDependentSpecie>{pDependentSpecie} {
1330 word rhsPDependentSpecieName = pDependentSpecieName;
1331 pDependentSpecieName =
1332 foamName(foamSpecieString(YYText()));
1333 pDependentSpecieName =
1334 pDependentSpecieName(0, pDependentSpecieName.size() - 1);
1336 if (rrType == thirdBodyArrhenius)
1338 FatalErrorIn("chemkinReader::lex()")
1339 << "The pressure-dependent third-body '"
1340 << pDependentSpecieName
1341 << "' is given in non-pressure-dependent third-body reaction"
1342 << " on line " << lineNo_
1343 << exit(FatalError);
1346 if (lrhsPtr == &lhs)
1348 lhsThirdBodyCounter++;
1352 if (pDependentSpecieName != rhsPDependentSpecieName)
1354 FatalErrorIn("chemkinReader::lex()")
1355 << "The third-body reactant '"
1356 << pDependentSpecieName
1357 << "' is not the same as the third-body product '"
1358 << rhsPDependentSpecieName
1359 << "' in pressure-dependent reaction on line " << lineNo_
1360 << exit(FatalError);
1363 rhsThirdBodyCounter++;
1366 if (pDependentSpecieName != "M")
1368 HashTable<label>::iterator specieIndexIter
1370 specieIndices_.find(pDependentSpecieName)
1373 if (specieIndexIter != specieIndices_.end())
1375 thirdBodyEfficiencies = 0.0;
1376 thirdBodyEfficiencies[specieIndexIter()] = 1.0;
1380 FatalErrorIn("chemkinReader::lex()")
1381 << "unknown third-body specie " << pDependentSpecieName
1382 << " on line " << lineNo_ << nl
1383 << "Valid species are : " << nl
1384 << specieIndices_.toc() << endl
1385 << exit(FatalError);
1389 BEGIN(readReactionDelimiter);
1392 <readReactionCoeffs>{reactionCoeff} {
1393 reactionCoeffs.append(stringToScalar(YYText()));
1396 <readReactionCoeffs>{endReactionCoeffs} {
1397 reactionCoeffsTable.insert(reactionCoeffsName, reactionCoeffs.shrink());
1398 reactionCoeffs.clear();
1399 BEGIN(readReactionKeyword);
1402 <readTdepSpecie>{specieName} {
1403 word specieName(foamName(foamSpecieString(YYText())));
1404 FatalErrorIn("chemkinReader::lex()")
1405 << "Temperature-dependent reaction on line "
1406 << lineNo_ << "not yet supported"
1407 << exit(FatalError);
1408 BEGIN(readReactionKeyword);
1411 <readReactionOrderSpecie>{specieName} {
1413 word(foamName(foamSpecieString(YYText())));
1415 HashTable<label>::iterator specieIndexIter
1417 specieIndices_.find(currentSpecieName)
1420 if (specieIndexIter != specieIndices_.end())
1422 currentSpecieIndex = specieIndexIter();
1426 FatalErrorIn("chemkinReader::lex()")
1427 << "unknown specie " << currentSpecieName
1428 << " given in reaction-order specification"
1429 << " on line " << lineNo_ << nl
1430 << "Valid species are : " << nl
1431 << specieIndices_.toc() << endl
1432 << exit(FatalError);
1435 BEGIN(readReactionOrder);
1438 <readReactionOrder>{reactionCoeff}{endReactionCoeffs} {
1440 DynamicList<gasReaction::specieCoeffs>& lrhs = *lrhsPtr;
1446 if (lrhs[i].index == currentSpecieIndex)
1448 lrhs[i].exponent = stringToScalar(YYText());
1456 word side("l.h.s.");
1458 if (lrhsPtr == &rhs)
1463 FatalErrorIn("chemkinReader::lex()")
1464 << "Specie " << currentSpecieName
1465 << " on line " << lineNo_
1466 << " not present in " << side << " of reaction " << nl << lrhs
1467 << exit(FatalError);
1470 BEGIN(readReactionKeyword);
1473 <readReactionUnit>{cal} {
1477 <readReactionUnit>{kcal} {
1478 RRreaction = RRcal/1000.0;
1481 <readReactionUnit>{joule} {
1482 RRreaction = RRjoule;
1485 <readReactionUnit>{kjoule} {
1486 RRreaction = RRjoule/1000.0;
1489 <readReactionUnit>{otherReactionsUnit} {
1492 <readReactionUnit>{endReactionCoeffs} {
1493 BEGIN(readReactionKeyword);
1497 /* ------------------ Ignore remaining space and \n s. --------------------- */
1499 <*>\n { lineNo_++; }
1501 /* ------ Ignore remaining space and \n s. Any other characters are errors. */
1504 startError = YYText();
1505 yy_push_state(CHEMKINError);
1510 FatalErrorIn("chemkinReader::lex()")
1511 << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
1512 << " expected " << stateExpects[YY_START]
1513 << " but found '" << startError << YYText() << "'"
1514 << exit(FatalError);
1518 /* ------------------------ On EOF terminate. ---------------------------- */
1527 thirdBodyEfficiencies,
1532 reactionCoeffsTable,
1540 /* ------------------------------------------------------------------------- *\
1541 ------ End of chemkinLexer.L
1542 \* ------------------------------------------------------------------------- */