FreeFOAM The Cross-Platform CFD Toolkit
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 | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
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
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  Simple extension of ReactionThermo to handle Reaction kinetics in addition
26  to the equilibrium thermodynamics already handled.
27 
28 \*---------------------------------------------------------------------------*/
29 
30 #include "Reaction.H"
31 #include <OpenFOAM/DynamicList.H>
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
39 
40 template<class ReactionThermo>
41 void Reaction<ReactionThermo>::setThermo
42 (
43  const HashPtrTable<ReactionThermo>& thermoDatabase
44 )
45 {
46  ReactionThermo::operator=
47  (
48  rhs_[0].stoichCoeff*(*thermoDatabase[species_[rhs_[0].index]])
49  );
50 
51  for (label i=1; i<rhs_.size(); i++)
52  {
53  operator+=
54  (
55  rhs_[i].stoichCoeff*(*thermoDatabase[species_[rhs_[i].index]])
56  );
57  }
58 
59  for (label i=0; i<lhs_.size(); i++)
60  {
61  operator-=
62  (
63  lhs_[i].stoichCoeff*(*thermoDatabase[species_[lhs_[i].index]])
64  );
65  }
66 }
67 
68 
69 // Construct from components
70 template<class ReactionThermo>
72 (
73  const speciesTable& species,
74  const List<specieCoeffs>& lhs,
75  const List<specieCoeffs>& rhs,
76  const HashPtrTable<ReactionThermo>& thermoDatabase
77 )
78 :
79  ReactionThermo(*thermoDatabase[species[0]]),
80  species_(species),
81  lhs_(lhs),
82  rhs_(rhs)
83 {
84  setThermo(thermoDatabase);
85 }
86 
87 
88 // Construct as copy given new speciesTable
89 template<class ReactionThermo>
91 (
92  const Reaction<ReactionThermo>& r,
93  const speciesTable& species
94 )
95 :
96  ReactionThermo(r),
97  species_(species),
98  lhs_(r.lhs_),
99  rhs_(r.rhs_)
100 {}
101 
102 
103 template<class ReactionThermo>
105 (
106  const speciesTable& species,
107  Istream& is
108 )
109 {
110  token t(is);
111 
112  if (t.isNumber())
113  {
114  stoichCoeff = t.number();
115  is >> t;
116  }
117  else
118  {
119  stoichCoeff = 1.0;
120  }
121 
122  exponent = stoichCoeff;
123 
124  if (t.isWord())
125  {
126  word specieName = t.wordToken();
127 
128  size_t i = specieName.find('^');
129 
130  if (i != word::npos)
131  {
132  string exponentStr = specieName
133  (
134  i + 1,
135  specieName.size() - i - 1
136  );
137  exponent = atof(exponentStr.c_str());
138  specieName = specieName(0, i);
139  }
140 
141  index = species[specieName];
142  }
143  else
144  {
145  FatalIOErrorIn("Reaction<ReactionThermo>::lrhs(Istream& is)", is)
146  << "Expected a word but found " << t.info()
147  << exit(FatalIOError);
148  }
149 }
150 
151 
152 template<class ReactionThermo>
154 {
156 
157  while (is)
158  {
159  dlrhs.append(specieCoeffs(species_, is));
160 
161  token t(is);
162 
163  if (t.isPunctuation())
164  {
165  if (t == token::ADD)
166  {
167  }
168  else if (t == token::ASSIGN)
169  {
170  lhs_ = dlrhs.shrink();
171  dlrhs.clear();
172  }
173  else
174  {
175  rhs_ = dlrhs.shrink();
176  is.putBack(t);
177  return;
178  }
179  }
180  else
181  {
182  rhs_ = dlrhs.shrink();
183  is.putBack(t);
184  return;
185  }
186  }
187 
188  FatalIOErrorIn("Reaction<ReactionThermo>::lrhs(Istream& is)", is)
189  << "Cannot continue reading reaction data from stream"
190  << exit(FatalIOError);
191 }
192 
193 
194 //- Construct from Istream
195 template<class ReactionThermo>
197 (
198  const speciesTable& species,
199  const HashPtrTable<ReactionThermo>& thermoDatabase,
200  Istream& is
201 )
202 :
203  ReactionThermo(*thermoDatabase[species[0]]),
204  species_(species)
205 {
206  setLRhs(is);
207  setThermo(thermoDatabase);
208 }
209 
210 
211 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
212 
213 template<class ReactionThermo>
215 (
216  const speciesTable& species,
217  const HashPtrTable<ReactionThermo>& thermoDatabase,
218  Istream& is
219 )
220 {
221  if (is.eof())
222  {
224  (
225  "Reaction<ReactionThermo>::New(const speciesTable& species,"
226  " const HashPtrTable<ReactionThermo>& thermoDatabase, Istream&)",
227  is
228  ) << "Reaction type not specified" << endl << endl
229  << "Valid Reaction types are :" << endl
230  << IstreamConstructorTablePtr_->sortedToc()
231  << exit(FatalIOError);
232  }
233 
234  word reactionTypeName(is);
235 
236  typename IstreamConstructorTable::iterator cstrIter
237  = IstreamConstructorTablePtr_->find(reactionTypeName);
238 
239  if (cstrIter == IstreamConstructorTablePtr_->end())
240  {
242  (
243  "Reaction<ReactionThermo>::New(const speciesTable& species,"
244  " const HashPtrTable<ReactionThermo>& thermoDatabase, Istream&)",
245  is
246  ) << "Unknown reaction type " << reactionTypeName << endl << endl
247  << "Valid reaction types are :" << endl
248  << IstreamConstructorTablePtr_->sortedToc()
249  << exit(FatalIOError);
250  }
251 
253  (
254  cstrIter()(species, thermoDatabase, is)
255  );
256 }
257 
258 
259 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
260 
261 template<class ReactionThermo>
263 {
264  os << type() << nl << " ";
265 
266  forAll(lhs_, i)
267  {
268  const typename Reaction<ReactionThermo>::specieCoeffs& sc = lhs_[i];
269 
270  if (sc.stoichCoeff != 1)
271  {
272  os << sc.stoichCoeff;
273  }
274 
275  os << species_[sc.index];
276 
277  if (sc.exponent != sc.stoichCoeff)
278  {
279  os << '^' << sc.exponent;
280  }
281 
282  if (i < lhs_.size() - 1)
283  {
284  os << " + ";
285  }
286  }
287 
288  os << " = ";
289 
290  forAll(rhs_, i)
291  {
292  const typename Reaction<ReactionThermo>::specieCoeffs& sc = rhs_[i];
293 
294  if (sc.stoichCoeff != 1)
295  {
296  os << sc.stoichCoeff;
297  }
298 
299  os << species_[sc.index];
300 
301  if (sc.exponent != sc.stoichCoeff)
302  {
303  os << '^' << sc.exponent;
304  }
305 
306  if (i < rhs_.size() - 1)
307  {
308  os << " + ";
309  }
310  }
311 
312  os << endl << " ";
313 }
314 
315 
316 template<class ReactionThermo>
318 (
319  const scalar T,
320  const scalar p,
321  const scalarField& c
322 ) const
323 {
324  return 0.0;
325 }
326 
327 
328 template<class ReactionThermo>
330 (
331  const scalar kfwd,
332  const scalar T,
333  const scalar p,
334  const scalarField& c
335 ) const
336 {
337  return 0.0;
338 }
339 
340 template<class ReactionThermo>
342 (
343  const scalar T,
344  const scalar p,
345  const scalarField& c
346 ) const
347 {
348  return 0.0;
349 }
350 
351 
352 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
353 
354 } // End namespace Foam
355 
356 // ************************ vim: set sw=4 sts=4 et: ************************ //