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