1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
24 \*---------------------------------------------------------------------------*/
27 #include "SCOPELaminarFlameSpeed.H"
28 #include "addToRunTimeSelectionTable.H"
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 namespace laminarFlameSpeedModels
36 defineTypeNameAndDebug(SCOPE, 0);
38 addToRunTimeSelectionTable
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
50 Foam::laminarFlameSpeedModels::SCOPE::polynomial::polynomial
52 const dictionary& polyDict
55 FixedList<scalar, 7>(polyDict.lookup("coefficients")),
56 ll(readScalar(polyDict.lookup("lowerLimit"))),
57 ul(readScalar(polyDict.lookup("upperLimit"))),
58 llv(polyPhi(ll, *this)),
59 ulv(polyPhi(ul, *this)),
64 Foam::laminarFlameSpeedModels::SCOPE::SCOPE
66 const dictionary& dict,
67 const hhuCombustionThermo& ct
70 laminarFlameSpeed(dict, ct),
80 dict.lookup("fuelFile")
83 ).subDict(typeName + "Coeffs")
85 LFL_(readScalar(coeffsDict_.lookup("lowerFlamabilityLimit"))),
86 UFL_(readScalar(coeffsDict_.lookup("upperFlamabilityLimit"))),
87 SuPolyL_(coeffsDict_.subDict("lowerSuPolynomial")),
88 SuPolyU_(coeffsDict_.subDict("upperSuPolynomial")),
89 Texp_(readScalar(coeffsDict_.lookup("Texp"))),
90 pexp_(readScalar(coeffsDict_.lookup("pexp"))),
91 MaPolyL_(coeffsDict_.subDict("lowerMaPolynomial")),
92 MaPolyU_(coeffsDict_.subDict("upperMaPolynomial"))
94 SuPolyL_.ll = max(SuPolyL_.ll, LFL_) + SMALL;
95 SuPolyU_.ul = min(SuPolyU_.ul, UFL_) - SMALL;
97 SuPolyL_.lu = 0.5*(SuPolyL_.ul + SuPolyU_.ll);
98 SuPolyU_.lu = SuPolyL_.lu - SMALL;
100 MaPolyL_.lu = 0.5*(MaPolyL_.ul + MaPolyU_.ll);
101 MaPolyU_.lu = MaPolyL_.lu - SMALL;
105 Info<< "phi Su (T = Tref, p = pref)" << endl;
107 for (int i=0; i<n; i++)
109 scalar phi = (2.0*i)/n;
110 Info<< phi << token::TAB << SuRef(phi) << endl;
116 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
118 Foam::laminarFlameSpeedModels::SCOPE::~SCOPE()
122 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
124 inline Foam::scalar Foam::laminarFlameSpeedModels::SCOPE::polyPhi
130 scalar x = phi - 1.0;
136 + x*(a[1] + x*(a[2] + x*(a[3] + x*(a[4] + x*(a[5] + x*a[6])))))
141 inline Foam::scalar Foam::laminarFlameSpeedModels::SCOPE::SuRef
146 if (phi < LFL_ || phi > UFL_)
148 // Return 0 beyond the flamibility limits
151 else if (phi < SuPolyL_.ll)
153 // Use linear interpolation between the low end of the
154 // lower polynomial and the lower flamibility limit
155 return SuPolyL_.llv*(phi - LFL_)/(SuPolyL_.ll - LFL_);
157 else if (phi > SuPolyU_.ul)
159 // Use linear interpolation between the upper end of the
160 // upper polynomial and the upper flamibility limit
161 return SuPolyU_.ulv*(UFL_ - phi)/(UFL_ - SuPolyU_.ul);
163 else if (phi < SuPolyL_.lu)
165 // Evaluate the lower polynomial
166 return polyPhi(phi, SuPolyL_);
168 else if (phi > SuPolyU_.lu)
170 // Evaluate the upper polynomial
171 return polyPhi(phi, SuPolyU_);
175 FatalErrorIn("laminarFlameSpeedModels::SCOPE::SuRef(scalar phi)")
177 << " cannot be handled by SCOPE function with the "
186 inline Foam::scalar Foam::laminarFlameSpeedModels::SCOPE::Ma
191 if (phi < MaPolyL_.ll)
193 // Beyond the lower limit assume Ma is constant
196 else if (phi > MaPolyU_.ul)
198 // Beyond the upper limit assume Ma is constant
201 else if (phi < SuPolyL_.lu)
203 // Evaluate the lower polynomial
204 return polyPhi(phi, MaPolyL_);
206 else if (phi > SuPolyU_.lu)
208 // Evaluate the upper polynomial
209 return polyPhi(phi, MaPolyU_);
213 FatalErrorIn("laminarFlameSpeedModels::SCOPE::Ma(scalar phi)")
215 << " cannot be handled by SCOPE function with the "
224 inline Foam::scalar Foam::laminarFlameSpeedModels::SCOPE::Su0pTphi
231 static const scalar Tref = 300.0;
232 static const scalar pRef = 1.013e5;
234 return SuRef(phi)*pow((Tu/Tref), Texp_)*pow((p/pRef), pexp_);
238 Foam::tmp<Foam::volScalarField> Foam::laminarFlameSpeedModels::SCOPE::Su0pTphi
240 const volScalarField& p,
241 const volScalarField& Tu,
245 tmp<volScalarField> tSu0
258 dimensionedScalar("Su0", dimVelocity, 0.0)
262 volScalarField& Su0 = tSu0();
266 Su0[celli] = Su0pTphi(p[celli], Tu[celli], phi);
269 forAll(Su0.boundaryField(), patchi)
271 scalarField& Su0p = Su0.boundaryField()[patchi];
272 const scalarField& pp = p.boundaryField()[patchi];
273 const scalarField& Tup = Tu.boundaryField()[patchi];
277 Su0p[facei] = Su0pTphi(pp[facei], Tup[facei], phi);
285 Foam::tmp<Foam::volScalarField> Foam::laminarFlameSpeedModels::SCOPE::Su0pTphi
287 const volScalarField& p,
288 const volScalarField& Tu,
289 const volScalarField& phi
292 tmp<volScalarField> tSu0
305 dimensionedScalar("Su0", dimVelocity, 0.0)
309 volScalarField& Su0 = tSu0();
313 Su0[celli] = Su0pTphi(p[celli], Tu[celli], phi[celli]);
316 forAll(Su0.boundaryField(), patchi)
318 scalarField& Su0p = Su0.boundaryField()[patchi];
319 const scalarField& pp = p.boundaryField()[patchi];
320 const scalarField& Tup = Tu.boundaryField()[patchi];
321 const scalarField& phip = phi.boundaryField()[patchi];
339 Foam::tmp<Foam::volScalarField> Foam::laminarFlameSpeedModels::SCOPE::Ma
341 const volScalarField& phi
344 tmp<volScalarField> tMa
351 phi.time().timeName(),
357 dimensionedScalar("Ma", dimless, 0.0)
361 volScalarField& ma = tMa();
365 ma[celli] = Ma(phi[celli]);
368 forAll(ma.boundaryField(), patchi)
370 scalarField& map = ma.boundaryField()[patchi];
371 const scalarField& phip = phi.boundaryField()[patchi];
375 map[facei] = Ma(phip[facei]);
383 Foam::tmp<Foam::volScalarField>
384 Foam::laminarFlameSpeedModels::SCOPE::Ma() const
386 if (hhuCombustionThermo_.composition().contains("ft"))
388 const volScalarField& ft = hhuCombustionThermo_.composition().Y("ft");
394 hhuCombustionThermo_.lookup("stoichiometricAirFuelMassRatio")
395 )*ft/(scalar(1) - ft)
400 const fvMesh& mesh = hhuCombustionThermo_.p().mesh();
402 return tmp<volScalarField>
409 mesh.time().timeName(),
415 dimensionedScalar("Ma", dimless, Ma(equivalenceRatio_))
422 Foam::tmp<Foam::volScalarField>
423 Foam::laminarFlameSpeedModels::SCOPE::operator()() const
425 if (hhuCombustionThermo_.composition().contains("ft"))
427 const volScalarField& ft = hhuCombustionThermo_.composition().Y("ft");
431 hhuCombustionThermo_.p(),
432 hhuCombustionThermo_.Tu(),
435 hhuCombustionThermo_.lookup("stoichiometricAirFuelMassRatio")
436 )*ft/(scalar(1) - ft)
443 hhuCombustionThermo_.p(),
444 hhuCombustionThermo_.Tu(),
451 // ************************************************************************* //