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 | Copyright (C) 2011-2016 OpenFOAM Foundation
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 Application
25  equilibriumFlameT
26 
27 Description
28  Calculates the equilibrium flame temperature for a given fuel and
29  pressure for a range of unburnt gas temperatures and equivalence
30  ratios; the effects of dissociation on O2, H2O and CO2 are included.
31 
32 \*---------------------------------------------------------------------------*/
33 
34 #include "argList.H"
35 #include "Time.H"
36 #include "dictionary.H"
37 #include "IFstream.H"
38 #include "OSspecific.H"
39 #include "etcFiles.H"
40 #include "IOmanip.H"
41 
42 #include "specie.H"
43 #include "perfectGas.H"
44 #include "thermo.H"
45 #include "janafThermo.H"
46 #include "absoluteEnthalpy.H"
47 
48 using namespace Foam;
49 
51  thermo;
52 
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 
55 int main(int argc, char *argv[])
56 {
57  argList::validArgs.append("controlFile");
58  argList args(argc, argv);
59 
60  const fileName controlFileName = args[1];
61 
62  // Construct control dictionary
63  IFstream controlFile(controlFileName);
64 
65  // Check controlFile stream is OK
66  if (!controlFile.good())
67  {
69  << "Cannot read file " << controlFileName
70  << abort(FatalError);
71  }
72 
73  dictionary control(controlFile);
74 
75 
76  scalar P(readScalar(control.lookup("P")));
77  const word fuelName(control.lookup("fuel"));
78  scalar n(readScalar(control.lookup("n")));
79  scalar m(readScalar(control.lookup("m")));
80 
81 
82  Info<< nl << "Reading thermodynamic data dictionary" << endl;
83 
84  fileName thermoDataFileName(findEtcFile("thermoData/thermoData"));
85 
86  // Construct control dictionary
87  IFstream thermoDataFile(thermoDataFileName);
88 
89  // Check thermoData stream is OK
90  if (!thermoDataFile.good())
91  {
93  << "Cannot read file " << thermoDataFileName
94  << abort(FatalError);
95  }
96 
97  dictionary thermoData(thermoDataFile);
98 
99 
100  Info<< nl << "Reading thermodynamic data for relevant species"
101  << nl << endl;
102 
103  // Reactants
104  thermo FUEL(thermoData.subDict(fuelName));
105  thermo O2(thermoData.subDict("O2"));
106  thermo N2(thermoData.subDict("N2"));
107 
108  // Products
109  thermo CO2(thermoData.subDict("CO2"));
110  thermo H2O(thermoData.subDict("H2O"));
111 
112  // Product fragments
113  thermo CO(thermoData.subDict("CO"));
114  thermo H2(thermoData.subDict("H2"));
115 
116 
117  // Product dissociation reactions
118 
119  thermo CO2BreakUp
120  (
121  CO2 == CO + 0.5* O2
122  );
123 
124  thermo H2OBreakUp
125  (
126  H2O == H2 + 0.5*O2
127  );
128 
129 
130  // Stoiciometric number of moles of species for one mole of fuel
131  scalar stoicO2 = n + m/4.0;
132  scalar stoicN2 = (0.79/0.21)*(n + m/4.0);
133  scalar stoicCO2 = n;
134  scalar stoicH2O = m/2.0;
135 
136  // Oxidant
137  thermo oxidant
138  (
139  "oxidant",
140  stoicO2*O2
141  + stoicN2*N2
142  );
143 
144  dimensionedScalar stoichiometricAirFuelMassRatio
145  (
146  "stoichiometricAirFuelMassRatio",
147  dimless,
148  (oxidant.W()*oxidant.nMoles())/FUEL.W()
149  );
150 
151  Info<< "stoichiometricAirFuelMassRatio "
152  << stoichiometricAirFuelMassRatio << ';' << endl;
153 
154  Info<< "Equilibrium flame temperature data ("
155  << P/1e5 << " bar)" << nl << nl
156  << setw(3) << "Phi"
157  << setw(12) << "ft"
158  << setw(7) << "T0"
159  << setw(12) << "Tad"
160  << setw(12) << "Teq"
161  << setw(12) << "Terror"
162  << setw(20) << "O2res (mole frac)" << nl
163  << endl;
164 
165 
166  // Loop over equivalence ratios
167  for (int i=0; i<16; i++)
168  {
169  scalar equiv = 0.6 + i*0.05;
170  scalar ft = 1/(1 + stoichiometricAirFuelMassRatio.value()/equiv);
171 
172  // Loop over initial temperatures
173  for (int j=0; j<28; j++)
174  {
175  scalar T0 = 300.0 + j*100.0;
176 
177  // Number of moles of species for one mole of fuel
178  scalar o2 = (1.0/equiv)*stoicO2;
179  scalar n2 = (0.79/0.21)*o2;
180  scalar fres = max(1.0 - 1.0/equiv, 0.0);
181  scalar fburnt = 1.0 - fres;
182 
183  // Initial guess for number of moles of product species
184  // ignoring product dissociation
185  scalar oresInit = max(1.0/equiv - 1.0, 0.0)*stoicO2;
186  scalar co2Init = fburnt*stoicCO2;
187  scalar h2oInit = fburnt*stoicH2O;
188 
189  scalar ores = oresInit;
190  scalar co2 = co2Init;
191  scalar h2o = h2oInit;
192 
193  scalar co = 0.0;
194  scalar h2 = 0.0;
195 
196  // Total number of moles in system
197  scalar N = fres + n2 + co2 + h2o + ores;
198 
199 
200  // Initial guess for adiabatic flame temperature
201  scalar adiabaticFlameTemperature =
202  T0
203  + (fburnt/(1.0 + o2 + n2))/(1.0/(1.0 + (1.0 + 0.79/0.21)*stoicO2))
204  *2000.0;
205 
206  scalar equilibriumFlameTemperature = adiabaticFlameTemperature;
207 
208 
209  // Iteration loop for adiabatic flame temperature
210  for (int j=0; j<20; j++)
211  {
212 
213  if (j > 0)
214  {
215  co = co2*
216  min
217  (
218  CO2BreakUp.Kn(P, equilibriumFlameTemperature, N)
219  /::sqrt(max(ores, 0.001)),
220  1.0
221  );
222 
223  h2 = h2o*
224  min
225  (
226  H2OBreakUp.Kn(P, equilibriumFlameTemperature, N)
227  /::sqrt(max(ores, 0.001)),
228  1.0
229  );
230 
231  co2 = co2Init - co;
232  h2o = h2oInit - h2;
233  ores = oresInit + 0.5*co + 0.5*h2;
234  }
235 
236  thermo reactants
237  (
238  FUEL + o2*O2 + n2*N2
239  );
240 
241  thermo products
242  (
243  fres*FUEL + ores*O2 + n2*N2
244  + co2*CO2 + h2o*H2O + co*CO + h2*H2
245  );
246 
247 
248  scalar equilibriumFlameTemperatureNew =
249  products.THa(reactants.Ha(P, T0), P, adiabaticFlameTemperature);
250 
251  if (j==0)
252  {
253  adiabaticFlameTemperature = equilibriumFlameTemperatureNew;
254  }
255  else
256  {
257  equilibriumFlameTemperature = 0.5*
258  (
259  equilibriumFlameTemperature
260  + equilibriumFlameTemperatureNew
261  );
262  }
263  }
264 
265  Info<< setw(3) << equiv
266  << setw(12) << ft
267  << setw(7) << T0
268  << setw(12) << adiabaticFlameTemperature
269  << setw(12) << equilibriumFlameTemperature
270  << setw(12)
271  << adiabaticFlameTemperature - equilibriumFlameTemperature
272  << setw(12) << ores/N
273  << endl;
274  }
275  }
276 
277  Info<< nl << "end" << endl;
278 
279  return 0;
280 }
281 
282 
283 // ************************************************************************* //
A class for handling file names.
Definition: fileName.H:69
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
water
Definition: H2O.H:57
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:154
Thermodynamics mapping class to expose the absolute enthalpy function as the standard enthalpy functi...
psiReactionThermo & thermo
Definition: createFields.H:31
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
A class for handling words, derived from string.
Definition: word.H:59
Functions to search &#39;etc&#39; directories for configuration files etc.
Extract command arguments and options from the supplied argc and argv parameters. ...
Definition: argList.H:102
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
Definition: doubleScalar.H:63
errorManip< error > abort(error &err)
Definition: errorManip.H:131
fileName findEtcFile(const fileName &, bool mandatory=false)
Search for a file using findEtcFiles.
Definition: etcFiles.C:252
Liquid N2.
Definition: N2.H:58
Istream and Ostream manipulators taking arguments.
static const char nl
Definition: Ostream.H:262
Input from file stream.
Definition: IFstream.H:81
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:47
messageStream Info
label N
Definition: createFields.H:22
label n
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::argList args(argc, argv)
Namespace for OpenFOAM.