1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
30 #include "chemkinReader.H"
33 #include "IStringStream.H"
37 // flex input buffer size
38 int Foam::chemkinReader::yyBufSize = YY_BUF_SIZE;
40 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
42 int yyFlexLexer::yylex()
44 Foam::FatalErrorIn("yyFlexLexer::yylex()")
45 << "should not have called this function"
46 << abort(Foam::FatalError);
53 // Dummy yywrap to keep yylex happy at compile time.
54 // It is called by yylex but is not used as the mechanism to change file.
57 #if YY_FLEX_MINOR_VERSION < 6 && YY_FLEX_SUBMINOR_VERSION < 34
58 extern "C" int yywrap()
60 int yyFlexLexer::yywrap()
68 Foam::string foamSpecieString(const char* YYText)
70 Foam::string specieString(YYText);
71 // Transforming parentheses is no longer necessary
72 //specieString.replaceAll('(', '<');
73 //specieString.replaceAll(')', '>');
78 Foam::word foamName(const char* YYText)
80 Foam::string fn(YYText);
81 Foam::string::stripInvalid<Foam::word>(fn);
86 Foam::word foamName(const Foam::string& s)
89 Foam::string::stripInvalid<Foam::word>(fn);
94 /* ------------------------------------------------------------------------- *\
95 ------ cppLexer::yylex()
96 \* ------------------------------------------------------------------------- */
98 #define YY_DECL int Foam::chemkinReader::lex()
104 some_space {one_space}+
111 hex_digit [0-9a-fA-F]
113 identifier {alpha}({alpha}|{digit})*
115 label [1-9]{dec_digit}*
118 word ([[:alnum:]]|[[:punct:]])+
119 string {word}({some_space}{word})*
121 exponent_part [eEdD][-+]?{digit}+
122 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
124 double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
127 elements {space}("ELEMENTS"|"ELEM"){space}
128 species {space}("SPECIES"|"SPECIE"|"SPEC"){space}
129 thermoAll {space}"THERMO"{some_space}"ALL"{space}
130 thermo {space}"THERMO"{space}
131 reactions {space}("REACTIONS"|"REAC"){space}
132 end {space}"END"{space}
134 elementName {space}([A-Z]|([A-Z][A-Z])){space}
135 startIsotopeMolW {space}"/"{space}
136 isotopeMolW {space}{double}{space}"/"{space}
138 specieName {space}[A-Za-z](([A-Za-z0-9)*+-])|("("[^+]))*{space}
139 nMoles {space}{double}{space}
143 thermoSpecieName .{18}
149 thermoCommonTemp .{8}
152 thermoLineLabel1 " "1{space}
153 thermoLineLabel2 " "{4}2{space}
154 thermoLineLabel3 " "{4}3{space}
155 thermoLineLabel4 " "{4}4{space}
157 specieDelimiter {space}"+"{space}
158 reversibleReactionDelimiter {space}("="|"<=>"){space}
159 irreversibleReactionDelimiter {space}"=>"{space}
160 startPDependentSpecie {space}"("{space}"+"{space}
161 pDependentSpecie {specieName}")"{space}
162 reactionCoeffs {space}{double}{some_space}{double}{some_space}{double}{space}
163 reactionKeyword {space}[A-Za-z](([A-Za-z0-9)*-])|("("[^+]))*{space}
164 reactionKeywordSlash {reactionKeyword}"/"{space}
165 thirdBodyEfficiency {space}{double}{space}"/"{space}
166 startReactionCoeffs {space}"/"{space}
167 endReactionCoeffs {space}"/"{space}
168 reactionCoeff {space}{double}{space}
170 calPerMol {space}"CAL/MOLE"{space}
171 kcalPerMol {space}"KCAL/MOLE"{space}
172 joulePerMol {space}"JOULES/MOLE"{space}
173 otherReactionsUnit {space}("KELVINS"|"EVOLTS"|"MOLES"|"MOLECULES"){space}
175 cal {space}"CAL"{space}
176 kcal {space}"KCAL"{space}
177 joule {space}"JOUL"{space}
178 kjoule {space}"KJOU"{space}
179 otherReactionUnit {space}("MOLE"|"MOLECULE"|"KELV"|"KELVIN"|"EVOL"|"EVOLTS"){space}
182 /* ------------------------------------------------------------------------- *\
183 ----- Exclusive start states -----
184 \* ------------------------------------------------------------------------- */
192 %x readThermoSpecieName
197 %x readThermoFormula2
198 %x readThermoLineLabel1
200 %x readThermoLineLabel2
202 %x readThermoLineLabel3
204 %x readThermoLineLabel4
205 %x readReactionsUnits
206 %x readReactionKeyword
207 %x readSpecieNamePlus
208 %x readReactionDelimiter
209 %x readPDependentSpecie
210 %x readThirdBodyEfficiency
211 %x readReactionCoeffs
213 %x readReactionOrderSpecie
222 static const char* stateNames[30] =
224 "reading CHEMKIN III file",
226 "reading isotope molecular weight",
228 "reading all thermodynamic data temperatures",
229 "reading thermodynamic specie name",
230 "reading thermodynamic data date",
231 "reading thermodynamic data specie formula",
232 "reading thermodynamic data specie phase",
233 "reading thermodynamic data temperatures",
234 "reading thermodynamic data specie formula (supplement)",
235 "reading thermodynamic data line label 1",
236 "reading thermodynamic data coefficient set 1",
237 "reading thermodynamic data line label 2",
238 "reading thermodynamic data coefficient set 2",
239 "reading thermodynamic data line label 3",
240 "reading thermodynamic data coefficient set 3",
241 "reading thermodynamic data line label 4",
242 "reading reaction units",
243 "reading reaction specie/keyword",
244 "reading reaction specie",
245 "reading reaction delimiter",
246 "reading reaction pressure dependent specie",
247 "reading third-body efficiency",
248 "reading reaction coeff",
249 "reading temperature dependent specie name",
250 "reading reaction order specie name",
251 "reading reaction order",
252 "reading reaction unit",
256 static const char* stateExpects[30] =
258 "'ELEMENTS' or 'ELEM', 'SPECIES' or 'SPEC', 'THERMO' or 'THERMO ALL', 'REACTIONS'",
259 "<elementName>, <isotopeName> / or 'END'",
261 "<specieName> or 'END'",
262 "<scalar><scalar><scalar> (3F10.0)",
265 "<word><label><word><label><word><label><word><label> (4(2A1,I3))",
267 "<scalar><scalar><scalar> (E10.0E10.0E8.0)",
268 "<word><label> (2A1,I3)",
270 "<scalar><scalar><scalar><scalar><scalar> (5(E15.0))",
272 "<scalar><scalar><scalar><scalar><scalar> (5(E15.0))",
274 "<scalar><scalar><scalar><scalar> (4(E15.0))",
276 "'CAL/MOLE', 'KCAL/MOLE', 'JOULES/MOLE', 'KELVINS', 'EVOLTS', 'MOLES' or 'MOLECULES'",
279 "'+', '=', '<=>', '=>', '(+<word>', '<scalar> <scalar> <scalar>'",
286 "'MOLE', 'MOLECULE', 'CAL', 'KCAL', 'JOUL', 'KJOU', 'KELV', 'KELVIN', 'EVOL' or 'EVOLTS'",
292 static const scalar RRjoule = 8.31451; // J/kg-mol-K
293 static const scalar RRcal = 1.987316; // cal/g-mol-K
295 scalar RRreactions = RRcal;
296 scalar RRreaction = RRcal;
298 scalar allCommonT = 1000.0;
300 word currentElementName;
301 label currentElementIndex = 0;
303 word currentSpecieName;
304 label currentSpecieIndex = 0;
305 label nSpecieElements = 0;
306 List<specieElement> currentSpecieComposition(5);
308 scalar currentLowT = 0;
309 scalar currentHighT = 0;
310 scalar currentCommonT = 0;
311 gasThermoPhysics::coeffArray highCpCoeffs(scalarList(7));
312 gasThermoPhysics::coeffArray lowCpCoeffs(scalarList(7));
314 gasReaction::specieCoeffs currentSpecieCoeff;
316 DynamicList<gasReaction::specieCoeffs> lhs;
317 DynamicList<gasReaction::specieCoeffs> rhs;
319 scalarList ArrheniusCoeffs(3);
320 DynamicList<scalar> reactionCoeffs;
321 scalarList thirdBodyEfficiencies;
322 label currentThirdBodyIndex = -1;
324 word reactionCoeffsName = word::null;
325 HashTable<scalarList> reactionCoeffsTable;
327 DynamicList<gasReaction::specieCoeffs> *lrhsPtr = &lhs;
329 reactionType rType = unknownReactionType;
330 reactionRateType rrType = Arrhenius;
331 fallOffFunctionType fofType = unknownFallOffFunctionType;
332 word pDependentSpecieName = word::null;
333 label lhsThirdBodyCounter = 0;
334 label rhsThirdBodyCounter = 0;
336 bool finishReaction = false;
340 /* ------------------------------------------------------------------------- *\
341 ------ Start Lexing ------
342 \* ------------------------------------------------------------------------- */
344 /* ------------------------------------------------------------------------- *\
345 ------ Discard comments being careful to count comments
346 \* ------------------------------------------------------------------------- */
348 <*>{space}"!".* { // Remove one line comments
351 /* ------------------------------------------------------------------------- *\
353 \* ------------------------------------------------------------------------- */
359 <readElements>{elementName} {
360 currentElementName = foamName(YYText());
361 correctElementName(currentElementName);
363 if (!elementIndices_.found(currentElementName))
365 elementIndices_.insert(currentElementName, currentElementIndex++);
366 elementNames_.append(currentElementName);
370 WarningIn("chemkinReader::lex()")
371 << "element " << currentElementName
372 << " already in table." << endl;
376 <readElements>{startIsotopeMolW} {
377 BEGIN(readIsotopeMolW);
380 <readIsotopeMolW>{isotopeMolW} {
381 isotopeAtomicWts_.insert(currentElementName, stringToScalar(YYText()));
385 <readElements>{end} {
389 /* ------------------------------------------------------------------------- *\
391 \* ------------------------------------------------------------------------- */
393 <INITIAL,readElements>{species} {
397 <readSpecies>{specieName} {
398 word specieName(foamName(foamSpecieString(YYText())));
400 if (specieName == "THERMO")
402 specieNames_.shrink();
403 speciesTable_ = specieNames_;
404 thirdBodyEfficiencies.setSize(specieNames_.size());
405 thirdBodyEfficiencies = 1.0;
406 BEGIN(readThermoSpecieName);
408 else if (specieName == "END")
410 specieNames_.shrink();
411 speciesTable_ = specieNames_;
412 thirdBodyEfficiencies.setSize(specieNames_.size());
413 thirdBodyEfficiencies = 1.0;
418 if (!specieIndices_.found(specieName))
420 specieNames_.append(specieName);
421 specieIndices_.insert(specieName, currentSpecieIndex++);
425 WarningIn("chemkinReader::lex()")
426 << "specie " << specieName
427 << " already in table." << endl;
432 /* ------------------------------------------------------------------------- *\
434 \* ------------------------------------------------------------------------- */
436 <INITIAL,readSpecies>{thermo} {
437 BEGIN(readThermoSpecieName);
440 <INITIAL,readSpecies>{thermoAll} {
441 BEGIN(readThermoAll);
444 <readThermoAll>{thermoTemp}{thermoTemp}{thermoTemp} {
445 string temperaturesString(YYText());
446 //scalar lowestT(stringToScalar(temperaturesString(0, 10)));
447 allCommonT = stringToScalar(temperaturesString(10, 10));
448 //scalar highestT(stringToScalar(temperaturesString(20, 10)));
449 BEGIN(readThermoSpecieName);
452 <readThermoSpecieName>{thermoSpecieName} {
453 string specieString(foamSpecieString(YYText()));
454 size_t spacePos = specieString.find(' ');
455 if (spacePos != string::npos)
457 currentSpecieName = specieString(0, spacePos);
461 currentSpecieName = specieString;
463 BEGIN(readThermoDate);
466 <readThermoDate>{thermoDate} {
467 // string thermoDate(YYText());
468 // Date is not currently used
469 BEGIN(readThermoFormula);
472 <readThermoFormula>{thermoFormula} {
473 string thermoFormula(YYText());
476 currentSpecieComposition.setSize(5);
478 for (int i=0; i<4; i++)
480 word elementName(foamName(thermoFormula(5*i, 2)));
481 label nAtoms = atoi(thermoFormula(5*i + 2, 3).c_str());
483 if (elementName.size() && nAtoms)
485 correctElementName(elementName);
486 currentSpecieComposition[nSpecieElements].elementName =
488 currentSpecieComposition[nSpecieElements++].nAtoms = nAtoms;
492 BEGIN(readThermoPhase);
495 <readThermoPhase>{thermoPhase} {
496 char phaseChar = YYText()[0];
501 speciePhase_.insert(currentSpecieName, solid);
505 speciePhase_.insert(currentSpecieName, liquid);
509 speciePhase_.insert(currentSpecieName, gas);
513 BEGIN(readThermoTemps);
516 <readThermoTemps>{thermoLowTemp}{thermoHighTemp}{thermoCommonTemp} {
517 string temperaturesString(YYText());
518 currentLowT = stringToScalar(temperaturesString(0, 10));
519 currentHighT = stringToScalar(temperaturesString(10, 10));
520 currentCommonT = stringToScalar(temperaturesString(20, 8));
522 if (currentCommonT < SMALL)
524 currentCommonT = allCommonT;
527 BEGIN(readThermoFormula2);
530 <readThermoFormula2>{thermoFormula2} {
531 string thermoFormula(YYText());
532 word elementName(foamName(thermoFormula(0, 2)));
533 label nAtoms = atoi(thermoFormula(2, 3).c_str());
538 && elementName.find('0') == string::npos
542 correctElementName(elementName);
543 currentSpecieComposition[nSpecieElements].elementName =
545 currentSpecieComposition[nSpecieElements++].nAtoms = nAtoms;
548 currentSpecieComposition.setSize(nSpecieElements);
550 HashTable<List<specieElement> >::iterator specieCompositionIter
552 specieComposition_.find(currentSpecieName)
555 if (specieCompositionIter != specieComposition_.end())
557 specieComposition_.erase(specieCompositionIter);
560 specieComposition_.insert
563 currentSpecieComposition
566 BEGIN(readThermoLineLabel1);
569 <readThermoLineLabel1>{thermoLineLabel1} {
570 BEGIN(readThermoCoeff1);
573 <readThermoCoeff1>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
574 string thermoCoeffString(YYText());
576 highCpCoeffs[0] = stringToScalar(thermoCoeffString(0, 15));
577 highCpCoeffs[1] = stringToScalar(thermoCoeffString(15, 15));
578 highCpCoeffs[2] = stringToScalar(thermoCoeffString(30, 15));
579 highCpCoeffs[3] = stringToScalar(thermoCoeffString(45, 15));
580 highCpCoeffs[4] = stringToScalar(thermoCoeffString(60, 15));
582 BEGIN(readThermoLineLabel2);
585 <readThermoLineLabel2>{thermoLineLabel2} {
586 BEGIN(readThermoCoeff2);
589 <readThermoCoeff2>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
590 string thermoCoeffString(YYText());
592 highCpCoeffs[5] = stringToScalar(thermoCoeffString(0, 15));
593 highCpCoeffs[6] = stringToScalar(thermoCoeffString(15, 15));
595 lowCpCoeffs[0] = stringToScalar(thermoCoeffString(30, 15));
596 lowCpCoeffs[1] = stringToScalar(thermoCoeffString(45, 15));
597 lowCpCoeffs[2] = stringToScalar(thermoCoeffString(60, 15));
599 BEGIN(readThermoLineLabel3);
602 <readThermoLineLabel3>{thermoLineLabel3} {
603 BEGIN(readThermoCoeff3);
606 <readThermoCoeff3>{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff}{thermoCoeff} {
607 string thermoCoeffString(YYText());
609 lowCpCoeffs[3] = stringToScalar(thermoCoeffString(0, 15));
610 lowCpCoeffs[4] = stringToScalar(thermoCoeffString(15, 15));
611 lowCpCoeffs[5] = stringToScalar(thermoCoeffString(30, 15));
612 lowCpCoeffs[6] = stringToScalar(thermoCoeffString(45, 15));
614 BEGIN(readThermoLineLabel4);
617 <readThermoLineLabel4>{thermoLineLabel4} {
619 HashPtrTable<gasThermoPhysics>::iterator specieThermoIter
621 speciesThermo_.find(currentSpecieName)
624 if (specieThermoIter != speciesThermo_.end())
626 speciesThermo_.erase(specieThermoIter);
629 speciesThermo_.insert
634 janafThermo<perfectGas>
640 molecularWeight(currentSpecieComposition)
653 BEGIN(readThermoSpecieName);
656 <readThermoSpecieName>{end} {
660 /* ------------------------------------------------------------------------- *\
661 ------ Read reactions
662 \* ------------------------------------------------------------------------- */
664 <INITIAL,readThermoSpecieName>{reactions} {
665 currentSpecieCoeff.stoichCoeff = 1.0;
666 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
667 BEGIN(readReactionsUnits);
670 <readReactionsUnits>{calPerMol} {
674 <readReactionsUnits>{kcalPerMol} {
675 RRreactions = RRcal/1000.0;
678 <readReactionsUnits>{joulePerMol} {
679 RRreactions = RRjoule;
682 <readReactionsUnits>{otherReactionsUnit} {
685 <readReactionsUnits>\n {
687 BEGIN(readReactionKeyword);
690 <readReactionKeyword>{nMoles} {
691 currentSpecieCoeff.stoichCoeff = atof(YYText());
692 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
695 <readReactionKeyword>{reactionKeyword} {
697 word keyword(foamName(YYText()));
699 HashTable<int>::iterator reactionKeywordIter
701 reactionKeywordTable_.find(keyword)
704 if (reactionKeywordIter != reactionKeywordTable_.end())
706 switch(reactionKeywordIter())
708 case duplicateReactionType:
710 BEGIN(readReactionKeyword);
714 case thirdBodyReactionType:
716 if (rrType != Arrhenius && rrType != thirdBodyArrhenius)
718 FatalErrorIn("chemkinReader::lex()")
719 << "Attempt to set reaction rate type to"
720 " thirdBodyArrhenius when it is already set to "
721 << reactionRateTypeNames[rrType]
722 << " on line " << lineNo_
726 if (pDependentSpecieName.size())
728 FatalErrorIn("chemkinReader::lex()")
729 << "A non-pressure dependent third-body appears in"
730 " the pressure dependent reaction on line "
735 rrType = thirdBodyArrhenius;
739 lhsThirdBodyCounter++;
743 rhsThirdBodyCounter++;
746 BEGIN(readReactionDelimiter);
750 case plasmaMomentumTransfer:
752 FatalErrorIn("chemkinReader::lex()")
753 << "Plasma momentum-transfer in reaction on line "
754 << lineNo_ << "not yet supported"
757 BEGIN(readReactionKeyword);
761 case collisionCrossSection:
763 FatalErrorIn("chemkinReader::lex()")
764 << "Collision cross-section in reaction on line "
765 << lineNo_ << "not yet supported"
768 BEGIN(readReactionKeyword);
779 thirdBodyEfficiencies,
787 finishReaction = false;
788 rType = unknownReactionType;
790 fofType = unknownFallOffFunctionType;
791 thirdBodyEfficiencies = 1.0;
792 pDependentSpecieName = word::null;
799 FatalErrorIn("chemkinReader::lex()")
800 << "keyword " << keyword
801 << " should be followed by parameters"
802 << " on line " << lineNo_
809 currentSpecieName = foamName(foamSpecieString(YYText()));
811 HashTable<label>::iterator specieIndexIter
813 specieIndices_.find(currentSpecieName)
816 if (specieIndexIter != specieIndices_.end())
824 thirdBodyEfficiencies,
832 finishReaction = false;
833 rType = unknownReactionType;
835 fofType = unknownFallOffFunctionType;
836 thirdBodyEfficiencies = 1.0;
837 pDependentSpecieName = word::null;
841 currentSpecieCoeff.index = specieIndexIter();
842 lrhsPtr->append(currentSpecieCoeff);
844 BEGIN(readReactionDelimiter);
848 BEGIN(readSpecieNamePlus);
853 <readReactionKeyword>{reactionKeywordSlash} {
855 word keyword(foamName(YYText()));
857 HashTable<int>::iterator reactionKeywordIter
859 reactionKeywordTable_.find(keyword)
862 if (reactionKeywordIter != reactionKeywordTable_.end())
864 switch(reactionKeywordIter())
866 case unimolecularFallOffReactionType:
868 if (!pDependentSpecieName.size())
870 FatalErrorIn("chemkinReader::lex()")
871 << "LOW keyword given for a unimolecular fall-off"
872 " reaction which does not contain a pressure"
873 " dependent specie" << " on line " << lineNo_
877 if (rrType == Arrhenius)
879 rrType = unimolecularFallOff;
883 FatalErrorIn("chemkinReader::lex()")
884 << "Attempt to set reaction rate type to"
885 " unimolecularFallOff when it is already set to "
886 << reactionRateTypeNames[rrType]
887 << " on line " << lineNo_
891 if (fofType == unknownFallOffFunctionType)
896 reactionCoeffsName = reactionRateTypeNames[rrType];
897 BEGIN(readReactionCoeffs);
901 case chemicallyActivatedBimolecularReactionType:
903 if (!pDependentSpecieName.size())
905 FatalErrorIn("chemkinReader::lex()")
906 << "HIGH keyword given for a chemically"
907 " activated bimolecular reaction which does not"
908 " contain a pressure dependent specie"
909 << " on line " << lineNo_
913 if (rrType == Arrhenius)
915 rrType = chemicallyActivatedBimolecular;
919 FatalErrorIn("chemkinReader::lex()")
920 << "Attempt to set reaction rate type to"
921 " chemicallyActivatedBimolecular when it is"
923 << reactionRateTypeNames[rrType]
924 << " on line " << lineNo_
928 if (fofType == unknownFallOffFunctionType)
933 reactionCoeffsName = reactionRateTypeNames[rrType];
934 BEGIN(readReactionCoeffs);
938 case TroeReactionType:
940 if (!pDependentSpecieName.size())
942 FatalErrorIn("chemkinReader::lex()")
943 << "TROE keyword given for a"
944 " reaction which does not contain a pressure"
945 " dependent specie" << " on line " << lineNo_
951 fofType == unknownFallOffFunctionType
952 || fofType == Lindemann
959 FatalErrorIn("chemkinReader::lex()")
960 << "Attempt to set fall-off function type to Troe"
961 " when it is already set to "
962 << fallOffFunctionNames[fofType]
963 << " on line " << lineNo_
967 reactionCoeffsName = fallOffFunctionNames[fofType];
968 BEGIN(readReactionCoeffs);
972 case SRIReactionType:
974 if (!pDependentSpecieName.size())
976 FatalErrorIn("chemkinReader::lex()")
977 << "SRI keyword given for a"
978 " reaction which does not contain a pressure"
979 " dependent specie" << " on line " << lineNo_
985 fofType == unknownFallOffFunctionType
986 || fofType == Lindemann
993 FatalErrorIn("chemkinReader::lex()")
994 << "Attempt to set fall-off function type to SRI"
995 " when it is already set to "
996 << fallOffFunctionNames[fofType]
997 << " on line " << lineNo_
1001 reactionCoeffsName = fallOffFunctionNames[fofType];
1002 BEGIN(readReactionCoeffs);
1006 case LandauTellerReactionType:
1008 if (pDependentSpecieName.size())
1010 FatalErrorIn("chemkinReader::lex()")
1011 << "Landau-Teller reaction rate cannot be used"
1012 " for the pressure-dependent reaction on line "
1014 << exit(FatalError);
1017 if (rrType == Arrhenius)
1019 rrType = LandauTeller;
1023 FatalErrorIn("chemkinReader::lex()")
1024 << "Attempt to set reaction rate type to"
1025 " LandauTeller when it is already set to "
1026 << reactionRateTypeNames[rrType]
1027 << " on line " << lineNo_
1028 << exit(FatalError);
1031 rrType = LandauTeller;
1032 reactionCoeffsName = reactionRateTypeNames[rrType];
1033 BEGIN(readReactionCoeffs);
1037 case reverseLandauTellerReactionType:
1039 if (pDependentSpecieName.size())
1041 FatalErrorIn("chemkinReader::lex()")
1042 << "Non-equilibrium Landau-Teller reaction rate"
1044 " for the pressure-dependent reaction on line "
1046 << exit(FatalError);
1049 if (rType != nonEquilibriumReversible)
1051 FatalErrorIn("chemkinReader::lex()")
1052 << "Reverse reaction Arrhenius coefficients not"
1053 " given for reverse LandauTeller reaction."
1054 " Please reorder 'REV' keyword to preceed 'RLT'"
1055 << " on line " << lineNo_
1056 << exit(FatalError);
1059 rrType = LandauTeller;
1060 reactionCoeffsName =
1061 word(reactionTypeNames[rType])
1062 + reactionRateTypeNames[rrType];
1063 BEGIN(readReactionCoeffs);
1067 case JanevReactionType:
1069 if (rrType == Arrhenius)
1075 FatalErrorIn("chemkinReader::lex()")
1076 << "Attempt to set reaction rate type to"
1077 " Janev when it is already set to "
1078 << reactionRateTypeNames[rrType]
1079 << " on line " << lineNo_
1080 << exit(FatalError);
1083 reactionCoeffsName = reactionRateTypeNames[rrType];
1084 BEGIN(readReactionCoeffs);
1088 case powerSeriesReactionRateType:
1090 if (rrType == Arrhenius)
1092 rrType = powerSeries;
1096 FatalErrorIn("chemkinReader::lex()")
1097 << "Attempt to set reaction rate type to"
1098 " powerSeries when it is already set to "
1099 << reactionRateTypeNames[rrType]
1100 << " on line " << lineNo_
1101 << exit(FatalError);
1104 reactionCoeffsName = reactionRateTypeNames[rrType];
1105 BEGIN(readReactionCoeffs);
1109 case radiationActivatedReactionType:
1111 FatalErrorIn("chemkinReader::lex()")
1112 << "Radiation activated reaction on line "
1113 << lineNo_ << "not yet supported"
1114 << exit(FatalError);
1115 //reactionCoeffsName = reactionRateTypeNames[rrType];
1116 BEGIN(readReactionCoeffs);
1120 case energyLossReactionType:
1122 FatalErrorIn("chemkinReader::lex()")
1123 << "Energy loss in reaction on line "
1124 << lineNo_ << "not yet supported"
1125 << exit(FatalError);
1126 //reactionCoeffsName = reactionRateTypeNames[rrType];
1127 BEGIN(readReactionCoeffs);
1131 case nonEquilibriumReversibleReactionType:
1133 rType = nonEquilibriumReversible;
1134 reactionCoeffsName = reactionTypeNames[rType];
1135 BEGIN(readReactionCoeffs);
1139 case speciesOrderForward:
1142 BEGIN(readReactionOrderSpecie);
1146 case speciesOrderReverse:
1149 BEGIN(readReactionOrderSpecie);
1153 case UnitsOfReaction:
1155 BEGIN(readReactionUnit);
1161 FatalErrorIn("chemkinReader::lex()")
1162 << "unknown reaction keyword " << keyword
1163 << " on line " << lineNo_
1164 << exit(FatalError);
1170 HashTable<label>::iterator specieIndexIter
1172 specieIndices_.find(keyword)
1175 if (specieIndexIter != specieIndices_.end())
1177 currentThirdBodyIndex = specieIndexIter();
1181 FatalErrorIn("chemkinReader::lex()")
1182 << "unknown third-body specie " << keyword
1183 << " on line " << lineNo_ << nl
1184 << "Valid species are : " << nl
1185 << specieIndices_.toc() << endl
1186 << exit(FatalError);
1189 BEGIN(readThirdBodyEfficiency);
1193 <readSpecieNamePlus>"+" {
1194 currentSpecieName += "+";
1196 HashTable<label>::iterator specieIndexIter
1198 specieIndices_.find(currentSpecieName)
1201 if (specieIndexIter != specieIndices_.end())
1209 thirdBodyEfficiencies,
1214 reactionCoeffsTable,
1217 finishReaction = false;
1218 rType = unknownReactionType;
1220 fofType = unknownFallOffFunctionType;
1221 thirdBodyEfficiencies = 1.0;
1222 pDependentSpecieName = word::null;
1226 currentSpecieCoeff.index = specieIndexIter();
1227 lrhsPtr->append(currentSpecieCoeff);
1229 BEGIN(readReactionDelimiter);
1233 FatalErrorIn("chemkinReader::lex()")
1234 << "unknown specie " << currentSpecieName
1235 << " on line " << lineNo_ << nl
1236 << "Valid species are : " << nl
1237 << specieIndices_.toc() << endl
1238 << exit(FatalError);
1242 <readReactionDelimiter>{specieDelimiter} {
1243 currentSpecieCoeff.stoichCoeff = 1.0;
1244 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1245 BEGIN(readReactionKeyword);
1248 <readReactionDelimiter>{irreversibleReactionDelimiter} {
1249 currentSpecieCoeff.stoichCoeff = 1.0;
1250 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1251 rType = irreversible;
1253 BEGIN(readReactionKeyword);
1256 <readReactionDelimiter>{reversibleReactionDelimiter} {
1257 currentSpecieCoeff.stoichCoeff = 1.0;
1258 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1261 BEGIN(readReactionKeyword);
1264 <readReactionDelimiter>& {
1267 <readReactionDelimiter>{reactionCoeffs} {
1268 string reactionCoeffsString(YYText());
1269 reactionCoeffsString.replaceAll("d", "e");
1270 reactionCoeffsString.replaceAll("D", "e");
1271 IStringStream reactionCoeffsStream(reactionCoeffsString);
1272 reactionCoeffsStream.lineNumber() = lineNo_;
1274 reactionCoeffsStream
1275 >> ArrheniusCoeffs[0]
1276 >> ArrheniusCoeffs[1]
1277 >> ArrheniusCoeffs[2];
1279 finishReaction = true;
1280 currentSpecieCoeff.stoichCoeff = 1.0;
1281 currentSpecieCoeff.exponent = currentSpecieCoeff.stoichCoeff;
1282 RRreaction = RRreactions;
1284 if (lhsThirdBodyCounter || rhsThirdBodyCounter)
1286 if (!lhsThirdBodyCounter || !rhsThirdBodyCounter)
1288 FatalErrorIn("chemkinReader::lex()")
1289 << "Third body not present on both sides of reaction"
1290 " on line " << lineNo_
1291 << exit(FatalError);
1294 if (lhsThirdBodyCounter != 1)
1296 FatalErrorIn("chemkinReader::lex()")
1297 << "More than 1 third body present on l.h.s. side"
1298 " of reaction on line " << lineNo_
1299 << exit(FatalError);
1302 if (rhsThirdBodyCounter != 1)
1304 FatalErrorIn("chemkinReader::lex()")
1305 << "More than 1 third body present on r.h.s. side"
1306 " of reaction on line " << lineNo_
1307 << exit(FatalError);
1310 lhsThirdBodyCounter = 0;
1311 rhsThirdBodyCounter = 0;
1314 BEGIN(readReactionKeyword);
1318 <readThirdBodyEfficiency>{thirdBodyEfficiency} {
1319 thirdBodyEfficiencies[currentThirdBodyIndex] = stringToScalar(YYText());
1320 BEGIN(readReactionKeyword);
1323 <readReactionDelimiter>{startPDependentSpecie} {
1324 BEGIN(readPDependentSpecie);
1327 <readPDependentSpecie>{pDependentSpecie} {
1329 word rhsPDependentSpecieName = pDependentSpecieName;
1330 pDependentSpecieName =
1331 foamName(foamSpecieString(YYText()));
1332 pDependentSpecieName =
1333 pDependentSpecieName(0, pDependentSpecieName.size() - 1);
1335 if (rrType == thirdBodyArrhenius)
1337 FatalErrorIn("chemkinReader::lex()")
1338 << "The pressure-dependent third-body '"
1339 << pDependentSpecieName
1340 << "' is given in non-pressure-dependent third-body reaction"
1341 << " on line " << lineNo_
1342 << exit(FatalError);
1345 if (lrhsPtr == &lhs)
1347 lhsThirdBodyCounter++;
1351 if (pDependentSpecieName != rhsPDependentSpecieName)
1353 FatalErrorIn("chemkinReader::lex()")
1354 << "The third-body reactant '"
1355 << pDependentSpecieName
1356 << "' is not the same as the third-body product '"
1357 << rhsPDependentSpecieName
1358 << "' in pressure-dependent reaction on line " << lineNo_
1359 << exit(FatalError);
1362 rhsThirdBodyCounter++;
1365 if (pDependentSpecieName != "M")
1367 HashTable<label>::iterator specieIndexIter
1369 specieIndices_.find(pDependentSpecieName)
1372 if (specieIndexIter != specieIndices_.end())
1374 thirdBodyEfficiencies = 0.0;
1375 thirdBodyEfficiencies[specieIndexIter()] = 1.0;
1379 FatalErrorIn("chemkinReader::lex()")
1380 << "unknown third-body specie " << pDependentSpecieName
1381 << " on line " << lineNo_ << nl
1382 << "Valid species are : " << nl
1383 << specieIndices_.toc() << endl
1384 << exit(FatalError);
1388 BEGIN(readReactionDelimiter);
1391 <readReactionCoeffs>{reactionCoeff} {
1392 reactionCoeffs.append(stringToScalar(YYText()));
1395 <readReactionCoeffs>{endReactionCoeffs} {
1396 reactionCoeffsTable.insert(reactionCoeffsName, reactionCoeffs.shrink());
1397 reactionCoeffs.clear();
1398 BEGIN(readReactionKeyword);
1401 <readTdepSpecie>{specieName} {
1402 word specieName(foamName(foamSpecieString(YYText())));
1403 FatalErrorIn("chemkinReader::lex()")
1404 << "Temperature-dependent reaction on line "
1405 << lineNo_ << "not yet supported"
1406 << exit(FatalError);
1407 BEGIN(readReactionKeyword);
1410 <readReactionOrderSpecie>{specieName} {
1412 word(foamName(foamSpecieString(YYText())));
1414 HashTable<label>::iterator specieIndexIter
1416 specieIndices_.find(currentSpecieName)
1419 if (specieIndexIter != specieIndices_.end())
1421 currentSpecieIndex = specieIndexIter();
1425 FatalErrorIn("chemkinReader::lex()")
1426 << "unknown specie " << currentSpecieName
1427 << " given in reaction-order specification"
1428 << " on line " << lineNo_ << nl
1429 << "Valid species are : " << nl
1430 << specieIndices_.toc() << endl
1431 << exit(FatalError);
1434 BEGIN(readReactionOrder);
1437 <readReactionOrder>{reactionCoeff}{endReactionCoeffs} {
1439 DynamicList<gasReaction::specieCoeffs>& lrhs = *lrhsPtr;
1445 if (lrhs[i].index == currentSpecieIndex)
1447 lrhs[i].exponent = stringToScalar(YYText());
1455 word side("l.h.s.");
1457 if (lrhsPtr == &rhs)
1462 FatalErrorIn("chemkinReader::lex()")
1463 << "Specie " << currentSpecieName
1464 << " on line " << lineNo_
1465 << " not present in " << side << " of reaction " << nl << lrhs
1466 << exit(FatalError);
1469 BEGIN(readReactionKeyword);
1472 <readReactionUnit>{cal} {
1476 <readReactionUnit>{kcal} {
1477 RRreaction = RRcal/1000.0;
1480 <readReactionUnit>{joule} {
1481 RRreaction = RRjoule;
1484 <readReactionUnit>{kjoule} {
1485 RRreaction = RRjoule/1000.0;
1488 <readReactionUnit>{otherReactionsUnit} {
1491 <readReactionUnit>{endReactionCoeffs} {
1492 BEGIN(readReactionKeyword);
1496 /* ------------------ Ignore remaining space and \n s. --------------------- */
1498 <*>\n { lineNo_++; }
1500 /* ------ Ignore remaining space and \n s. Any other characters are errors. */
1503 startError = YYText();
1504 yy_push_state(CHEMKINError);
1509 FatalErrorIn("chemkinReader::lex()")
1510 << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
1511 << " expected " << stateExpects[YY_START]
1512 << " but found '" << startError << YYText() << "'"
1513 << exit(FatalError);
1517 /* ------------------------ On EOF terminate. ---------------------------- */
1526 thirdBodyEfficiencies,
1531 reactionCoeffsTable,
1539 /* ------------------------------------------------------------------------- *\
1540 ------ End of chemkinLexer.L
1541 \* ------------------------------------------------------------------------- */