Loading...
Searching...
No Matches
FSD.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 Copyright (C) 2019 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "FSD.H"
31#include "LESModel.H"
32#include "fvcGrad.H"
33#include "fvcDiv.H"
34
35namespace Foam
37namespace combustionModels
38{
39
40// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
41
42template<class ReactionThermo, class ThermoType>
43FSD<ReactionThermo, ThermoType>::FSD
44(
45 const word& modelType,
46 ReactionThermo& thermo,
48 const word& combustionProperties
49)
50:
51 singleStepCombustion<ReactionThermo, ThermoType>
52 (
53 modelType,
54 thermo,
55 turb,
56 combustionProperties
57 ),
58 reactionRateFlameArea_
59 (
61 (
62 this->coeffs(),
63 this->mesh(),
64 *this
65 )
66 ),
67 ft_
68 (
70 (
71 this->thermo().phasePropertyName("ft"),
72 this->mesh().time().timeName(),
73 this->mesh(),
77 ),
78 this->mesh(),
80 ),
81 YFuelFuelStream_(dimensionedScalar("YFuelStream", dimless, 1.0)),
82 YO2OxiStream_(dimensionedScalar("YOxiStream", dimless, 0.23)),
83 Cv_(this->coeffs().getScalar("Cv")),
84 C_(5.0),
85 ftMin_(0.0),
86 ftMax_(1.0),
87 ftDim_(300),
88 ftVarMin_(this->coeffs().getScalar("ftVarMin"))
89{}
90
91
92// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
93
94template<class ReactionThermo, class ThermoType>
96{}
97
98
99// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
100
101template<class ReactionThermo, class ThermoType>
102void FSD<ReactionThermo, ThermoType>::calculateSourceNorm()
103{
104 this->singleMixturePtr_->fresCorrect();
105
106 const label fuelI = this->singleMixturePtr_->fuelIndex();
107
108 const volScalarField& YFuel = this->thermo().composition().Y()[fuelI];
109
110 const volScalarField& YO2 = this->thermo().composition().Y("O2");
111
112 const dimensionedScalar s = this->singleMixturePtr_->s();
113
114 ft_ =
115 (s*YFuel - (YO2 - YO2OxiStream_))/(s*YFuelFuelStream_ + YO2OxiStream_);
116
117
118 volVectorField nft(fvc::grad(ft_));
119
120 volScalarField mgft(mag(nft));
121
122 surfaceVectorField SfHat(this->mesh().Sf()/this->mesh().magSf());
123
124 volScalarField cAux(scalar(1) - ft_);
125
126 dimensionedScalar dMgft = 1.0e-3*
127 (ft_*cAux*mgft)().weightedAverage(this->mesh().V())
128 /((ft_*cAux)().weightedAverage(this->mesh().V()) + SMALL)
129 + dimensionedScalar("ddMgft", mgft.dimensions(), SMALL);
130
131 mgft += dMgft;
132
133 nft /= mgft;
134
135 const volVectorField& U = YO2.db().lookupObject<volVectorField>("U");
136
138 (
139 (nft & nft)*fvc::div(U) - (nft & fvc::grad(U) & nft)
140 );
141
142 reactionRateFlameArea_->correct(sigma);
143
144 const volScalarField& omegaFuel = reactionRateFlameArea_->omega();
145
146
147 const scalar ftStoich =
148 YO2OxiStream_.value()
149 /(
150 s.value()*YFuelFuelStream_.value() + YO2OxiStream_.value()
151 );
152
153 auto tPc = volScalarField::New
154 (
155 this->thermo().phasePropertyName("Pc"),
157 U.mesh(),
159 );
160 auto& pc = tPc.ref();
161
162 auto tomegaFuel = volScalarField::New
163 (
164 this->thermo().phasePropertyName("omegaFuelBar"),
166 U.mesh(),
167 dimensionedScalar(omegaFuel.dimensions(), Zero)
168 );
169 auto& omegaFuelBar = tomegaFuel.ref();
170
171 // Calculation of the mixture fraction variance (ftVar)
172 const compressible::LESModel& lesModel =
174 (
176 );
177
178 const volScalarField& delta = lesModel.delta();
179 const volScalarField ftVar(Cv_*sqr(delta)*sqr(mgft));
180
181 // Thickened flame (average flame thickness for counterflow configuration
182 // is 1.5 mm)
183
184 volScalarField deltaF
185 (
186 delta/dimensionedScalar("flame", dimLength, 1.5e-3)
187 );
188
189 // Linear correlation between delta and flame thickness
190 volScalarField omegaF(max(deltaF*(4.0/3.0) + (2.0/3.0), scalar(1)));
191
192 scalar deltaFt = 1.0/ftDim_;
193
194 forAll(ft_, celli)
195 {
196 if (ft_[celli] > ftMin_ && ft_[celli] < ftMax_)
197 {
198 scalar ftCell = ft_[celli];
199
200 if (ftVar[celli] > ftVarMin_) //sub-grid beta pdf of ft_
201 {
202 scalar ftVarc = ftVar[celli];
203 scalar a =
204 max(ftCell*(ftCell*(1.0 - ftCell)/ftVarc - 1.0), 0.0);
205 scalar b = max(a/ftCell - a, 0.0);
206
207 for (int i=1; i<ftDim_; i++)
208 {
209 scalar ft = i*deltaFt;
210 pc[celli] += pow(ft, a-1.0)*pow(1.0 - ft, b - 1.0)*deltaFt;
211 }
212
213 for (int i=1; i<ftDim_; i++)
214 {
215 scalar ft = i*deltaFt;
216 omegaFuelBar[celli] +=
217 omegaFuel[celli]/omegaF[celli]
218 *exp
219 (
220 -sqr(ft - ftStoich)
221 /(2.0*sqr(0.01*omegaF[celli]))
222 )
223 *pow(ft, a - 1.0)
224 *pow(1.0 - ft, b - 1.0)
225 *deltaFt;
226 }
227 omegaFuelBar[celli] /= max(pc[celli], 1e-4);
228 }
229 else
230 {
231 omegaFuelBar[celli] =
232 omegaFuel[celli]/omegaF[celli]
233 *exp(-sqr(ftCell - ftStoich)/(2.0*sqr(0.01*omegaF[celli])));
234 }
235 }
236 else
237 {
238 omegaFuelBar[celli] = 0.0;
239 }
240 }
241
242
243 // Combustion progress variable, c
244
245 List<label> productsIndex(2, label(-1));
246 {
247 label i = 0;
248 forAll(this->singleMixturePtr_->specieProd(), specieI)
249 {
250 if (this->singleMixturePtr_->specieProd()[specieI] < 0)
251 {
252 productsIndex[i] = specieI;
253 i++;
254 }
255 }
256 }
257
258
259 // Flamelet probability of the progress c based on IFC (reuse pc)
260 scalar YprodTotal = 0;
261 forAll(productsIndex, j)
262 {
263 YprodTotal += this->singleMixturePtr_->Yprod0()[productsIndex[j]];
264 }
265
266 forAll(ft_, celli)
267 {
268 if (ft_[celli] < ftStoich)
269 {
270 pc[celli] = ft_[celli]*(YprodTotal/ftStoich);
271 }
272 else
273 {
274 pc[celli] = (1.0 - ft_[celli])*(YprodTotal/(1.0 - ftStoich));
275 }
276 }
277
278 auto tproducts = volScalarField::New
279 (
280 this->thermo().phasePropertyName("products"),
282 U.mesh(),
284 );
285 auto& products = tproducts.ref();
286
287 forAll(productsIndex, j)
288 {
289 label specieI = productsIndex[j];
290 const volScalarField& Yp = this->thermo().composition().Y()[specieI];
291 products += Yp;
292 }
293
295 (
296 max(scalar(1) - products/max(pc, scalar(1e-5)), scalar(0))
297 );
298
299 pc = min(C_*c, scalar(1));
300
301 const volScalarField fres(this->singleMixturePtr_->fres(fuelI));
302
303 this->wFuel_ == mgft*pc*omegaFuelBar;
304}
305
306
307template<class ReactionThermo, class ThermoType>
309{
310 this->wFuel_ == Zero;
311
312 if (this->active())
314 calculateSourceNorm();
315 }
316}
317
318
319template<class ReactionThermo, class ThermoType>
321{
323 {
324 this->coeffs().readEntry("Cv", Cv_);
325 this->coeffs().readEntry("ftVarMin", ftVarMin_);
326 reactionRateFlameArea_->read(this->coeffs());
327 return true;
328 }
329
330 return false;
331}
332
333// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
334
335} // End namespace combustionModels
336} // End namespace Foam
337
338// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scalar delta
Macros for easy insertion into run-time selection tables.
compressible::turbulenceModel & turb
static autoPtr< CombustionModel > New(ReactionThermo &thermo, const compressibleTurbulenceModel &turb, const word &combustionProperties=combustionPropertiesName)
Selector.
const dimensionSet & dimensions() const noexcept
Return dimensions.
static tmp< GeometricField< scalar, fvPatchField, volMesh > > New(const word &name, IOobjectOption::registerOption regOpt, const Mesh &mesh, const dimensionSet &dims, const word &patchFieldType=fvPatchField< scalar >::calculatedType())
@ NO_REGISTER
Do not request registration (bool: false).
@ REGISTER
Request registration (bool: true).
@ NO_READ
Nothing to be read.
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
const Time & time() const noexcept
Return Time associated with the objectRegistry.
Definition IOobject.C:456
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition IOobject.C:450
virtual ReactionThermo & thermo()
Return access to the thermo package.
const dictionary & coeffs() const
Return const dictionary of the model.
Switch active() const noexcept
Is combustion active?
const fvMesh & mesh() const
Return const access to the mesh database.
virtual void correct()
Correct combustion rate.
Definition FSD.C:301
virtual ~FSD()
Destructor.
Definition FSD.C:88
virtual bool read()
Update properties.
Definition FSD.C:313
singleStepReactingMixture< ThermoType > * singleMixturePtr_
Pointer to singleStepReactingMixture mixture.
volScalarField wFuel_
Fuel consumption rate.
virtual bool read()
Update properties from given dictionary.
Abstract base class for turbulence models (RAS, LES and laminar).
scalar getScalar(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Same as get<scalar>(const word&, keyType::option).
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
Abstract class for reaction rate per flame area unit.
static autoPtr< reactionRateFlameArea > New(const dictionary &dict, const fvMesh &mesh, const combustionModel &combModel)
static const word propertiesName
Default name of the turbulence properties dictionary.
A class for handling words, derived from Foam::string.
Definition word.H:66
U
Definition pEqn.H:72
dynamicFvMesh & mesh
Calculate the divergence of the given field.
Calculate the gradient of the given field.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
word timeName
Definition getTimeIndex.H:3
LESModel< EddyDiffusivity< turbulenceModel > > LESModel
Typedefs for turbulence, RAS and LES models for compressible flow based on the standard laminar trans...
const dimensionedScalar c
Speed of light in a vacuum.
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh > > grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition fvcGrad.C:47
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition fvcDiv.C:42
Namespace for OpenFOAM.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
dimensionedScalar exp(const dimensionedScalar &ds)
GeometricField< vector, fvPatchField, volMesh > volVectorField
const dimensionSet dimless
Dimensionless.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
GeometricField< scalar, fvPatchField, volMesh > volScalarField
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
volScalarField & b
psiReactionThermo & thermo
volScalarField & e
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299