Reaction.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2017-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "Reaction.H"
30 #include "DynamicList.H"
31 
32 // * * * * * * * * * * * * * * * * Static Data * * * * * * * * * * * * * * * //
33 
34 template<class ReactionThermo>
36 
37 
38 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
39 
40 template<class ReactionThermo>
42 (
44  const speciesTable& species,
45  const List<specieCoeffs>& reactCoeffs
46 )
47 {
48  for (label i = 0; i < reactCoeffs.size(); ++i)
49  {
50  const specieCoeffs& coeff = reactCoeffs[i];
51 
52  if (i)
53  {
54  reaction << " + ";
55  }
56  if (mag(coeff.stoichCoeff - 1) > SMALL)
57  {
58  reaction << coeff.stoichCoeff;
59  }
60  reaction << species[coeff.index];
61  if (mag(coeff.exponent - coeff.stoichCoeff) > SMALL)
62  {
63  reaction << "^" << coeff.exponent;
64  }
65  }
66 }
67 
68 
69 template<class ReactionThermo>
71 (
72  OStringStream& reaction
73 ) const
74 {
75  reactionStr(reaction, species_, lhs_);
76 }
77 
78 
79 template<class ReactionThermo>
81 (
83 ) const
84 {
85  reactionStr(reaction, species_, rhs_);
86 }
87 
88 
89 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
90 
91 template<class ReactionThermo>
93 {
94  return nUnNamedReactions++;
95 }
96 
97 
98 template<class ReactionThermo>
100 (
101  OStringStream& reaction
102 ) const
103 {
104  reactionStrLeft(reaction);
105  reaction << " = ";
106  reactionStrRight(reaction);
107  return reaction.str();
108 }
109 
110 
111 template<class ReactionThermo>
113 (
114  const ReactionTable<ReactionThermo>& thermoDatabase
115 )
116 {
117 
118  typename ReactionThermo::thermoType rhsThermo
119  (
120  rhs_[0].stoichCoeff
121  *(*thermoDatabase[species_[rhs_[0].index]]).W()
122  *(*thermoDatabase[species_[rhs_[0].index]])
123  );
124 
125  for (label i=1; i<rhs_.size(); ++i)
126  {
127  rhsThermo +=
128  rhs_[i].stoichCoeff
129  *(*thermoDatabase[species_[rhs_[i].index]]).W()
130  *(*thermoDatabase[species_[rhs_[i].index]]);
131  }
132 
133  typename ReactionThermo::thermoType lhsThermo
134  (
135  lhs_[0].stoichCoeff
136  *(*thermoDatabase[species_[lhs_[0].index]]).W()
137  *(*thermoDatabase[species_[lhs_[0].index]])
138  );
139 
140  for (label i=1; i<lhs_.size(); ++i)
141  {
142  lhsThermo +=
143  lhs_[i].stoichCoeff
144  *(*thermoDatabase[species_[lhs_[i].index]]).W()
145  *(*thermoDatabase[species_[lhs_[i].index]]);
146  }
147 
148  ReactionThermo::thermoType::operator=(lhsThermo == rhsThermo);
149 }
151 
152 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
153 
154 
155 template<class ReactionThermo>
157 (
158  const speciesTable& species,
159  const List<specieCoeffs>& lhs,
160  const List<specieCoeffs>& rhs,
161  const ReactionTable<ReactionThermo>& thermoDatabase,
162  bool initReactionThermo
163 )
164 :
165  ReactionThermo::thermoType(*thermoDatabase[species[0]]),
166  name_("un-named-reaction-" + Foam::name(getNewReactionID())),
167  species_(species),
168  lhs_(lhs),
169  rhs_(rhs)
170 {
171  if (initReactionThermo)
172  {
173  setThermo(thermoDatabase);
174  }
175 }
176 
177 
178 template<class ReactionThermo>
180 (
181  const Reaction<ReactionThermo>& r,
182  const speciesTable& species
183 )
184 :
185  ReactionThermo::thermoType(r),
186  name_(r.name() + "Copy"),
187  species_(species),
188  lhs_(r.lhs_),
189  rhs_(r.rhs_)
190 {}
191 
192 
193 template<class ReactionThermo>
195 (
196  const speciesTable& species,
197  Istream& is,
198  bool failUnknownSpecie
199 )
200 {
201  token t(is);
202  if (t.isNumber())
203  {
204  stoichCoeff = t.number();
205  is >> t;
206  }
207  else
208  {
209  stoichCoeff = 1.0;
210  }
211 
212  exponent = stoichCoeff;
213 
214  if (t.isWord())
215  {
216  word specieName = t.wordToken();
217 
218  const size_t i = specieName.find('^');
219 
220  if (i != word::npos)
221  {
222  exponent = atof(specieName.substr(i + 1).c_str());
223  specieName.resize(i);
224  }
225 
226  // Lookup specie name: -1 if not found
227  index = species.find(specieName);
228 
229  if (failUnknownSpecie && index < 0)
230  {
232  << "Unknown specie " << specieName << nl
233  << "Not in " << flatOutput(species) << endl
234  << exit(FatalError);
235  }
236  }
237  else
238  {
240  << "Expected a word but found " << t.info()
242  }
243 }
244 
245 
246 template<class ReactionThermo>
248 (
249  Istream& is,
250  const speciesTable& species,
251  List<specieCoeffs>& lhs,
252  List<specieCoeffs>& rhs,
253  bool failUnknownSpecie
254 )
255 {
256  DynamicList<specieCoeffs> dlrhs;
257 
258  bool parsingRight = false;
259 
260  while (is.good())
261  {
262  dlrhs.push_back(specieCoeffs(species, is, failUnknownSpecie));
263 
264  if (dlrhs.back().index < 0)
265  {
266  dlrhs.pop_back();
267  }
268 
269  if (is.good())
270  {
271  token t(is);
272  if (t.isPunctuation())
273  {
274  if (t == token::ADD)
275  {
276  }
277  else if (t == token::ASSIGN)
278  {
279  if (parsingRight)
280  {
282  << "Multiple '=' in reaction equation" << endl
283  << exit(FatalError);
284  }
285 
286  lhs = dlrhs;
287  dlrhs.clear();
288  parsingRight = true;
289  }
290  else
291  {
293  << "Unknown punctuation token '" << t
294  << "' in reaction equation" << endl
295  << exit(FatalError);
296  }
297  }
298  else
299  {
300  rhs = dlrhs;
301  is.putBack(t);
302  return;
303  }
304  }
305  else if (parsingRight)
306  {
307  if (!dlrhs.empty())
308  {
309  rhs = dlrhs;
310  }
311  return;
312  }
313  }
314 
316  << "Cannot continue reading reaction data from stream"
317  << exit(FatalIOError);
318 }
319 
320 
321 template<class ReactionThermo>
323 (
324  const speciesTable& species,
325  const ReactionTable<ReactionThermo>& thermoDatabase,
326  const dictionary& dict,
327  bool initReactionThermo,
328  bool failUnknownSpecie
329 )
330 :
331  ReactionThermo::thermoType(*thermoDatabase[species[0]]),
332  name_(dict.dictName()),
333  species_(species)
334 {
335  setLRhs
336  (
337  IStringStream(dict.getString("reaction"))(),
338  species_,
339  lhs_,
340  rhs_,
341  failUnknownSpecie
342  );
343 
344  if (initReactionThermo)
345  {
346  setThermo(thermoDatabase);
347  }
348 }
350 
351 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
352 
353 template<class ReactionThermo>
356 (
357  const speciesTable& species,
358  const ReactionTable<ReactionThermo>& thermoDatabase,
359  const dictionary& dict
360 )
361 {
362  const word reactionTypeName(dict.get<word>("type"));
363 
364  auto* ctorPtr = dictionaryConstructorTable(reactionTypeName);
365 
366  if (!ctorPtr)
367  {
369  (
370  dict,
371  "reaction",
372  reactionTypeName,
373  *dictionaryConstructorTablePtr_
374  ) << exit(FatalIOError);
375  }
376 
378  (
379  ctorPtr(species, thermoDatabase, dict)
380  );
381 }
382 
383 
384 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
385 
386 template<class ReactionThermo>
388 {
390  os.writeEntry("reaction", reactionStr(reaction));
391 }
392 
393 
394 template<class ReactionThermo>
396 (
397  const scalar p,
398  const scalar T,
399  const scalarField& c
400 ) const
401 {
402  return 0.0;
403 }
404 
405 
406 template<class ReactionThermo>
408 (
409  const scalar kfwd,
410  const scalar p,
411  const scalar T,
412  const scalarField& c
413 ) const
414 {
415  return 0.0;
416 }
417 
418 
419 template<class ReactionThermo>
421 (
422  const scalar p,
423  const scalar T,
424  const scalarField& c
425 ) const
426 {
427  return 0.0;
428 }
429 
430 
431 template<class ReactionThermo>
433 {
435  return NullObjectRef<speciesTable>();
436 }
437 
438 
439 template<class ReactionThermo>
442 {
444  return NullObjectRef<List<specieCoeffs>>();
445 }
446 
447 
448 template<class ReactionThermo>
451 {
453  return NullObjectRef<List<specieCoeffs>>();
454 }
455 
456 
457 // ************************************************************************* //
virtual scalar kr(const scalar kfwd, const scalar p, const scalar T, const scalarField &c) const
Reverse rate constant from the given forward rate constant.
Definition: Reaction.C:401
virtual scalar kf(const scalar p, const scalar T, const scalarField &c) const
Forward rate constant.
Definition: Reaction.C:389
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
virtual const List< specieCoeffs > & grhs() const
Access to gas components of the reaction.
Definition: Reaction.C:443
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
A token holds an item read from Istream.
Definition: token.H:65
const word dictName("faMeshDefinition")
virtual void write(Ostream &os) const
Write.
Definition: Reaction.C:380
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static autoPtr< Reaction< ReactionThermo > > New(const speciesTable &species, const ReactionTable< ReactionThermo > &thermoDatabase, const dictionary &dict)
Return a pointer to new patchField created on freestore from dict.
Definition: Reaction.C:349
Addition [isseparator].
Definition: token.H:158
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:321
Assignment/equals [isseparator].
Definition: token.H:143
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
hashedWordList speciesTable
A table of species as a hashedWordList.
Definition: speciesTable.H:38
Hold specie index and its coefficients in the reaction rate expression.
Definition: Reaction.H:86
Simple extension of ReactionThermo to handle reaction kinetics in addition to the equilibrium thermod...
Definition: Reaction.H:55
void reactionStrLeft(OStringStream &reaction) const
Add string representation of the left of the reaction.
Definition: Reaction.C:64
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
Reaction(const speciesTable &species, const List< specieCoeffs > &lhs, const List< specieCoeffs > &rhs, const ReactionTable< ReactionThermo > &thermoDatabase, bool initReactionThermo=true)
Construct from components.
Definition: Reaction.C:150
virtual const List< specieCoeffs > & glhs() const
Definition: Reaction.C:434
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
virtual const speciesTable & gasSpecies() const
Access to gas specie list.
Definition: Reaction.C:425
void reactionStrRight(OStringStream &reaction) const
Add string representation of the right of the reaction.
Definition: Reaction.C:74
void setLRhs(Istream &, const speciesTable &, List< specieCoeffs > &lhs, List< specieCoeffs > &rhs, bool failUnknownSpecie=true)
Construct the left- and right-hand-side reaction coefficients.
Definition: Reaction.C:241
CombustionModel< rhoReactionThermo > & reaction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
A wordList with hashed named lookup, which can be faster in some situations than using the normal lis...
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
Definition: StringStream.H:120
const dimensionedScalar c
Speed of light in a vacuum.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
volScalarField & p
label find(const word &val) const
Find index of the value (searches the hash).
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:686
A class for handling character strings derived from std::string.
Definition: string.H:72
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:635
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:256
Namespace for OpenFOAM.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...