equilibriumFlameT.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 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Application
27  equilibriumFlameT
28 
29 Group
30  grpThermophysicalUtilities
31 
32 Description
33  Calculate the equilibrium flame temperature for a given fuel and
34  pressure for a range of unburnt gas temperatures and equivalence
35  ratios. Includes the effects of dissociation on O2, H2O and CO2.
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #include "argList.H"
40 #include "Time.H"
41 #include "dictionary.H"
42 #include "IFstream.H"
43 #include "OSspecific.H"
44 #include "etcFiles.H"
45 #include "IOmanip.H"
46 
47 #include "specie.H"
48 #include "perfectGas.H"
49 #include "thermo.H"
50 #include "janafThermo.H"
51 #include "absoluteEnthalpy.H"
52 
53 using namespace Foam;
54 
56  thermo;
57 
58 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
59 
60 int main(int argc, char *argv[])
61 {
63  (
64  "Calculate the equilibrium flame temperature for a given fuel and"
65  " pressure for a range of unburnt gas temperatures and equivalence"
66  " ratios.\n"
67  "Includes the effects of dissociation on O2, H2O and CO2."
68  );
69 
71  argList::noFunctionObjects(); // Never use function objects
72  argList::addArgument("controlFile");
73 
74  argList args(argc, argv);
75 
76  const fileName controlFileName = args[1];
77 
78  // Construct control dictionary
79  IFstream controlFile(controlFileName);
80 
81  // Check controlFile stream is OK
82  if (!controlFile.good())
83  {
85  << "Cannot read file " << controlFileName
86  << abort(FatalError);
87  }
88 
89  dictionary control(controlFile);
90 
91 
92  const scalar P(control.get<scalar>("P"));
93  const word fuelName(control.get<word>("fuel"));
94  const scalar n(control.get<scalar>("n"));
95  const scalar m(control.get<scalar>("m"));
96 
97 
98  Info<< nl << "Reading thermodynamic data dictionary" << endl;
99 
100  fileName thermoDataFileName(findEtcFile("thermoData/thermoData"));
101 
102  // Construct control dictionary
103  IFstream thermoDataFile(thermoDataFileName);
104 
105  // Check thermoData stream is OK
106  if (!thermoDataFile.good())
107  {
109  << "Cannot read file " << thermoDataFileName
110  << abort(FatalError);
111  }
112 
113  dictionary thermoData(thermoDataFile);
114 
115 
116  Info<< nl << "Reading thermodynamic data for relevant species"
117  << nl << endl;
118 
119  // Reactants (mole-based)
120  thermo FUEL(thermoData.subDict(fuelName)); FUEL *= FUEL.W();
121 
122  // Oxidant (mole-based)
123  thermo O2(thermoData.subDict("O2")); O2 *= O2.W();
124  thermo N2(thermoData.subDict("N2")); N2 *= N2.W();
125 
126  // Intermediates (mole-based)
127  thermo H2(thermoData.subDict("H2")); H2 *= H2.W();
128 
129  // Products (mole-based)
130  thermo CO2(thermoData.subDict("CO2")); CO2 *= CO2.W();
131  thermo H2O(thermoData.subDict("H2O")); H2O *= H2O.W();
132  thermo CO(thermoData.subDict("CO")); CO *= CO.W();
133 
134 
135  // Product dissociation reactions
136 
137  thermo CO2BreakUp
138  (
139  CO2 == CO + 0.5*O2
140  );
141 
142  thermo H2OBreakUp
143  (
144  H2O == H2 + 0.5*O2
145  );
146 
147 
148  // Stoiciometric number of moles of species for one mole of fuel
149  scalar stoicO2 = n + m/4.0;
150  scalar stoicN2 = (0.79/0.21)*(n + m/4.0);
151  scalar stoicCO2 = n;
152  scalar stoicH2O = m/2.0;
153 
154  // Oxidant
155  thermo oxidant
156  (
157  "oxidant",
158  stoicO2*O2
159  + stoicN2*N2
160  );
161 
162  dimensionedScalar stoichiometricAirFuelMassRatio
163  (
164  "stoichiometricAirFuelMassRatio",
165  dimless,
166  oxidant.Y()/FUEL.W()
167  );
168 
169  Info<< "stoichiometricAirFuelMassRatio "
170  << stoichiometricAirFuelMassRatio << ';' << endl;
171 
172  Info<< "Equilibrium flame temperature data ("
173  << P/1e5 << " bar)" << nl << nl
174  << setw(3) << "Phi"
175  << setw(12) << "ft"
176  << setw(7) << "T0"
177  << setw(12) << "Tad"
178  << setw(12) << "Teq"
179  << setw(12) << "Terror"
180  << setw(20) << "O2res (mole frac)" << nl
181  << endl;
182 
183 
184  // Loop over equivalence ratios
185  for (int i=0; i<16; i++)
186  {
187  scalar equiv = 0.6 + i*0.05;
188  scalar ft = 1/(1 + stoichiometricAirFuelMassRatio.value()/equiv);
189 
190  // Loop over initial temperatures
191  for (int j=0; j<28; j++)
192  {
193  scalar T0 = 300.0 + j*100.0;
194 
195  // Number of moles of species for one mole of fuel
196  scalar o2 = (1.0/equiv)*stoicO2;
197  scalar n2 = (0.79/0.21)*o2;
198  scalar fres = max(1.0 - 1.0/equiv, 0.0);
199  scalar fburnt = 1.0 - fres;
200 
201  // Initial guess for number of moles of product species
202  // ignoring product dissociation
203  scalar oresInit = max(1.0/equiv - 1.0, 0.0)*stoicO2;
204  scalar co2Init = fburnt*stoicCO2;
205  scalar h2oInit = fburnt*stoicH2O;
206 
207  scalar ores = oresInit;
208  scalar co2 = co2Init;
209  scalar h2o = h2oInit;
210 
211  scalar co = 0.0;
212  scalar h2 = 0.0;
213 
214  // Total number of moles in system
215  scalar N = fres + n2 + co2 + h2o + ores;
216 
217 
218  // Initial guess for adiabatic flame temperature
219  scalar adiabaticFlameTemperature =
220  T0
221  + (fburnt/(1.0 + o2 + n2))/(1.0/(1.0 + (1.0 + 0.79/0.21)*stoicO2))
222  *2000.0;
223 
224  scalar equilibriumFlameTemperature = adiabaticFlameTemperature;
225 
226 
227  // Iteration loop for adiabatic flame temperature
228  for (int j=0; j<20; j++)
229  {
230  if (j > 0)
231  {
232  co = co2*
233  min
234  (
235  CO2BreakUp.Kn(P, equilibriumFlameTemperature, N)
236  /::sqrt(max(ores, 0.001)),
237  1.0
238  );
239 
240  h2 = h2o*
241  min
242  (
243  H2OBreakUp.Kn(P, equilibriumFlameTemperature, N)
244  /::sqrt(max(ores, 0.001)),
245  1.0
246  );
247 
248  co2 = co2Init - co;
249  h2o = h2oInit - h2;
250  ores = oresInit + 0.5*co + 0.5*h2;
251  }
252 
253  thermo reactants
254  (
255  FUEL + o2*O2 + n2*N2
256  );
257 
258  thermo products
259  (
260  fres*FUEL + ores*O2 + n2*N2
261  + co2*CO2 + h2o*H2O + co*CO + h2*H2
262  );
263 
264 
265  scalar equilibriumFlameTemperatureNew =
266  products.THa(reactants.Ha(P, T0), P, adiabaticFlameTemperature);
267 
268  if (j==0)
269  {
270  adiabaticFlameTemperature = equilibriumFlameTemperatureNew;
271  }
272  else
273  {
274  equilibriumFlameTemperature = 0.5*
275  (
276  equilibriumFlameTemperature
277  + equilibriumFlameTemperatureNew
278  );
279  }
280  }
281 
282  Info<< setw(3) << equiv
283  << setw(12) << ft
284  << setw(7) << T0
285  << setw(12) << adiabaticFlameTemperature
286  << setw(12) << equilibriumFlameTemperature
287  << setw(12)
288  << adiabaticFlameTemperature - equilibriumFlameTemperature
289  << setw(12) << ores/N
290  << endl;
291  }
292  }
293 
294  Info<< nl << "End" << nl << endl;
295 
296  return 0;
297 }
298 
299 
300 // ************************************************************************* //
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:85
Foam::N2
Liquid N2.
Definition: N2.H:60
thermo
psiReactionThermo & thermo
Definition: createFields.H:28
Foam::absoluteEnthalpy
Thermodynamics mapping class to expose the absolute enthalpy functions.
Definition: absoluteEnthalpy.H:49
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
thermo
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:123
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
specie.H
Foam::thermophysicalProperties::W
scalar W() const
Molecular weight [kg/kmol].
Definition: thermophysicalPropertiesI.H:36
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:302
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:454
Foam::findEtcFile
fileName findEtcFile(const fileName &name, const bool mandatory=false, unsigned short location=0777)
Search for a single FILE within the etc directories.
Definition: etcFiles.C:446
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
janafThermo.H
Foam::H2O
water
Definition: H2O.H:59
argList.H
IOmanip.H
Istream and Ostream manipulators taking arguments.
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
IFstream.H
perfectGas.H
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::dimensioned< scalar >
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::species::thermo
Definition: thermo.H:54
etcFiles.H
Functions to search 'etc' directories for configuration files etc.
Time.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::sqrt
dimensionedScalar sqrt(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:144
dictionary.H
N
const Vector< label > N(dict.get< Vector< label >>("N"))
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:491
args
Foam::argList args(argc, argv)
T0
scalar T0
Definition: createFields.H:22
absoluteEnthalpy.H