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  ICharStream reactionIs(dict.getString("reaction"));
336 
337  setLRhs
338  (
339  reactionIs,
340  species_,
341  lhs_,
342  rhs_,
343  failUnknownSpecie
344  );
345 
346  if (initReactionThermo)
347  {
348  setThermo(thermoDatabase);
349  }
350 }
352 
353 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
354 
355 template<class ReactionThermo>
358 (
359  const speciesTable& species,
360  const ReactionTable<ReactionThermo>& thermoDatabase,
361  const dictionary& dict
362 )
363 {
364  const word reactionTypeName(dict.get<word>("type"));
365 
366  auto* ctorPtr = dictionaryConstructorTable(reactionTypeName);
367 
368  if (!ctorPtr)
369  {
371  (
372  dict,
373  "reaction",
374  reactionTypeName,
375  *dictionaryConstructorTablePtr_
376  ) << exit(FatalIOError);
377  }
378 
380  (
381  ctorPtr(species, thermoDatabase, dict)
382  );
383 }
384 
385 
386 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
387 
388 template<class ReactionThermo>
390 {
392  os.writeEntry("reaction", reactionStr(reaction));
393 }
394 
395 
396 template<class ReactionThermo>
398 (
399  const scalar p,
400  const scalar T,
401  const scalarField& c
402 ) const
403 {
404  return 0.0;
405 }
406 
407 
408 template<class ReactionThermo>
410 (
411  const scalar kfwd,
412  const scalar p,
413  const scalar T,
414  const scalarField& c
415 ) const
416 {
417  return 0.0;
418 }
419 
420 
421 template<class ReactionThermo>
423 (
424  const scalar p,
425  const scalar T,
426  const scalarField& c
427 ) const
428 {
429  return 0.0;
430 }
431 
432 
433 template<class ReactionThermo>
435 {
437  return NullObjectRef<speciesTable>();
438 }
439 
440 
441 template<class ReactionThermo>
444 {
446  return List<specieCoeffs>::null();
447 }
448 
449 
450 template<class ReactionThermo>
453 {
455  return List<specieCoeffs>::null();
456 }
457 
458 
459 // ************************************************************************* //
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:403
virtual scalar kf(const scalar p, const scalar T, const scalarField &c) const
Forward rate constant.
Definition: Reaction.C:391
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:445
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:608
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:382
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:351
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:436
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:427
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:637
A wordList with hashed named lookup, which can be faster in some situations than using the normal lis...
const dimensionedScalar c
Speed of light in a vacuum.
An ISstream with internal List storage. Always UNCOMPRESSED.
Definition: ICharStream.H:241
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:696
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:645
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:208
static const List< T > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
Definition: List.H:153
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 ...