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 | 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 \*---------------------------------------------------------------------------*/
25 
26 #include "FSD.H"
28 #include "LESModel.H"
29 #include "fvcGrad.H"
30 #include "fvcDiv.H"
31 
32 namespace Foam
33 {
34 namespace combustionModels
35 {
36 
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
39 template<class CombThermoType, class ThermoType>
40 FSD<CombThermoType, ThermoType>::FSD
41 (
42  const word& modelType,
43  const fvMesh& mesh,
44  const word& phaseName
45 )
46 :
48  (
49  modelType,
50  mesh,
51  phaseName
52  ),
53  reactionRateFlameArea_
54  (
56  (
57  this->coeffs(),
58  this->mesh(),
59  *this
60  )
61  ),
62  ft_
63  (
64  IOobject
65  (
66  IOobject::groupName("ft", phaseName),
67  this->mesh().time().timeName(),
68  this->mesh(),
71  ),
72  this->mesh(),
73  dimensionedScalar("zero", dimless, 0.0)
74  ),
75  YFuelFuelStream_(dimensionedScalar("YFuelStream", dimless, 1.0)),
76  YO2OxiStream_(dimensionedScalar("YOxiStream", dimless, 0.23)),
77  Cv_(readScalar(this->coeffs().lookup("Cv"))),
78  C_(5.0),
79  ftMin_(0.0),
80  ftMax_(1.0),
81  ftDim_(300),
82  ftVarMin_(readScalar(this->coeffs().lookup("ftVarMin")))
83 {}
84 
85 
86 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
87 
88 template<class CombThermoType, class ThermoType>
90 {}
91 
92 
93 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
94 
95 template<class CombThermoType, class ThermoType>
97 {
98  this->singleMixturePtr_->fresCorrect();
99 
100  const label fuelI = this->singleMixturePtr_->fuelIndex();
101 
102  const volScalarField& YFuel = this->thermoPtr_->composition().Y()[fuelI];
103 
104  const volScalarField& YO2 = this->thermoPtr_->composition().Y("O2");
105 
106  const dimensionedScalar s = this->singleMixturePtr_->s();
107 
108  ft_ =
109  (s*YFuel - (YO2 - YO2OxiStream_))/(s*YFuelFuelStream_ + YO2OxiStream_);
110 
111 
112  volVectorField nft(fvc::grad(ft_));
113 
114  volScalarField mgft(mag(nft));
115 
116  surfaceVectorField SfHat(this->mesh().Sf()/this->mesh().magSf());
117 
118  volScalarField cAux(scalar(1) - ft_);
119 
120  dimensionedScalar dMgft = 1.0e-3*
121  (ft_*cAux*mgft)().weightedAverage(this->mesh().V())
122  /((ft_*cAux)().weightedAverage(this->mesh().V()) + SMALL)
123  + dimensionedScalar("ddMgft", mgft.dimensions(), SMALL);
124 
125  mgft += dMgft;
126 
127  nft /= mgft;
128 
129  const volVectorField& U = YO2.db().lookupObject<volVectorField>("U");
130 
131  const volScalarField sigma
132  (
133  (nft & nft)*fvc::div(U) - (nft & fvc::grad(U) & nft)
134  );
135 
136  reactionRateFlameArea_->correct(sigma);
137 
138  const volScalarField& omegaFuel = reactionRateFlameArea_->omega();
139 
140 
141  const scalar ftStoich =
142  YO2OxiStream_.value()
143  /(
144  s.value()*YFuelFuelStream_.value() + YO2OxiStream_.value()
145  );
146 
148  (
149  new volScalarField
150  (
151  IOobject
152  (
153  IOobject::groupName("Pc", this->phaseName_),
154  U.time().timeName(),
155  U.db(),
158  ),
159  U.mesh(),
160  dimensionedScalar("Pc", dimless, 0)
161  )
162  );
163 
164  volScalarField& pc = tPc.ref();
165 
166  tmp<volScalarField> tomegaFuel
167  (
168  new volScalarField
169  (
170  IOobject
171  (
172  IOobject::groupName("omegaFuelBar", this->phaseName_),
173  U.time().timeName(),
174  U.db(),
177  ),
178  U.mesh(),
180  (
181  "omegaFuelBar",
182  omegaFuel.dimensions(),
183  0
184  )
185  )
186  );
187 
188  volScalarField& omegaFuelBar = tomegaFuel.ref();
189 
190  // Calculation of the mixture fraction variance (ftVar)
191  const compressible::LESModel& lesModel =
193  (
195  );
196 
197  const volScalarField& delta = lesModel.delta();
198  const volScalarField ftVar(Cv_*sqr(delta)*sqr(mgft));
199 
200  // Thickened flame (average flame thickness for counterflow configuration
201  // is 1.5 mm)
202 
203  volScalarField deltaF
204  (
205  lesModel.delta()/dimensionedScalar("flame", dimLength, 1.5e-3)
206  );
207 
208  // Linear correlation between delta and flame thickness
209  volScalarField omegaF(max(deltaF*(4.0/3.0) + (2.0/3.0), scalar(1)));
210 
211  scalar deltaFt = 1.0/ftDim_;
212 
213  forAll(ft_, celli)
214  {
215  if (ft_[celli] > ftMin_ && ft_[celli] < ftMax_)
216  {
217  scalar ftCell = ft_[celli];
218 
219  if (ftVar[celli] > ftVarMin_) //sub-grid beta pdf of ft_
220  {
221  scalar ftVarc = ftVar[celli];
222  scalar a =
223  max(ftCell*(ftCell*(1.0 - ftCell)/ftVarc - 1.0), 0.0);
224  scalar b = max(a/ftCell - a, 0.0);
225 
226  for (int i=1; i<ftDim_; i++)
227  {
228  scalar ft = i*deltaFt;
229  pc[celli] += pow(ft, a-1.0)*pow(1.0 - ft, b - 1.0)*deltaFt;
230  }
231 
232  for (int i=1; i<ftDim_; i++)
233  {
234  scalar ft = i*deltaFt;
235  omegaFuelBar[celli] +=
236  omegaFuel[celli]/omegaF[celli]
237  *exp
238  (
239  -sqr(ft - ftStoich)
240  /(2.0*sqr(0.01*omegaF[celli]))
241  )
242  *pow(ft, a - 1.0)
243  *pow(1.0 - ft, b - 1.0)
244  *deltaFt;
245  }
246  omegaFuelBar[celli] /= max(pc[celli], 1e-4);
247  }
248  else
249  {
250  omegaFuelBar[celli] =
251  omegaFuel[celli]/omegaF[celli]
252  *exp(-sqr(ftCell - ftStoich)/(2.0*sqr(0.01*omegaF[celli])));
253  }
254  }
255  else
256  {
257  omegaFuelBar[celli] = 0.0;
258  }
259  }
260 
261 
262  // Combustion progress variable, c
263 
264  List<label> productsIndex(2, label(-1));
265  {
266  label i = 0;
267  forAll(this->singleMixturePtr_->specieProd(), specieI)
268  {
269  if (this->singleMixturePtr_->specieProd()[specieI] < 0)
270  {
271  productsIndex[i] = specieI;
272  i++;
273  }
274  }
275  }
276 
277 
278  // Flamelet probability of the progress c based on IFC (reuse pc)
279  scalar YprodTotal = 0;
280  forAll(productsIndex, j)
281  {
282  YprodTotal += this->singleMixturePtr_->Yprod0()[productsIndex[j]];
283  }
284 
285  forAll(ft_, celli)
286  {
287  if (ft_[celli] < ftStoich)
288  {
289  pc[celli] = ft_[celli]*(YprodTotal/ftStoich);
290  }
291  else
292  {
293  pc[celli] = (1.0 - ft_[celli])*(YprodTotal/(1.0 - ftStoich));
294  }
295  }
296 
297  tmp<volScalarField> tproducts
298  (
299  new volScalarField
300  (
301  IOobject
302  (
303  IOobject::groupName("products", this->phaseName_),
304  U.time().timeName(),
305  U.db(),
308  ),
309  U.mesh(),
310  dimensionedScalar("products", dimless, 0)
311  )
312  );
313 
314  volScalarField& products = tproducts.ref();
315 
316  forAll(productsIndex, j)
317  {
318  label specieI = productsIndex[j];
319  const volScalarField& Yp = this->thermoPtr_->composition().Y()[specieI];
320  products += Yp;
321  }
322 
324  (
325  max(scalar(1) - products/max(pc, scalar(1e-5)), scalar(0))
326  );
327 
328  pc = min(C_*c, scalar(1));
329 
330  const volScalarField fres(this->singleMixturePtr_->fres(fuelI));
331 
332  this->wFuel_ == mgft*pc*omegaFuelBar;
333 }
334 
335 
336 template<class CombThermoType, class ThermoType>
338 {
339  this->wFuel_ ==
341 
342  if (this->active())
343  {
344  calculateSourceNorm();
345  }
346 }
347 
348 
349 template<class CombThermoType, class ThermoType>
351 {
353  {
354  this->coeffs().lookup("Cv") >> Cv_ ;
355  this->coeffs().lookup("ftVarMin") >> ftVarMin_;
356  reactionRateFlameArea_->read(this->coeffs());
357  return true;
358  }
359  else
360  {
361  return false;
362  }
363 }
364 
365 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
366 
367 } // End namespace combustionModels
368 } // End namespace Foam
369 
370 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scalar delta
Flame Surface Dennsity (FDS) combustion model.
Definition: FSD.H:80
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:52
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
U
Definition: pEqn.H:83
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
virtual bool read()
Update properties.
Definition: FSD.C:350
const objectRegistry & db() const
Return the local objectRegistry.
Definition: IOobject.C:221
const double e
Elementary charge.
Definition: doubleFloat.H:78
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:47
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m2/K4].
const Type & value() const
Return const reference to value.
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
Definition: Time.C:715
Macros for easy insertion into run-time selection tables.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().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))
stressControl lookup("compactNormalStress") >> compactNormalStress
dynamicFvMesh & mesh
dimensionedScalar exp(const dimensionedScalar &ds)
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Calculate the gradient of the given field.
static const word propertiesName
Default name of the turbulence properties dictionary.
A class for handling words, derived from string.
Definition: word.H:59
const Time & time() const
Return time.
Definition: IOobject.C:227
static word groupName(Name name, const word &group)
LESModel< EddyDiffusivity< turbulenceModel > > LESModel
Typedefs for turbulence, RAS and LES models for compressible flow based on the standard laminar trans...
word timeName
Definition: getTimeIndex.H:3
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
Definition: doubleScalar.H:63
const dimensionSet & dimensions() const
Return dimensions.
Calculate the divergence of the given field.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Internal & ref()
Return a reference to the dimensioned internal field.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
dimensionedScalar pow3(const dimensionedScalar &ds)
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:47
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:50
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
const Mesh & mesh() const
Return mesh.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
const dimensionedScalar c
Speed of light in a vacuum.
virtual void correct()
Correct combustion rate.
Definition: FSD.C:337
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
dimensioned< scalar > mag(const dimensioned< Type > &)
Base class for combustion models using singleStepReactingMixture.
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:49
A class for managing temporary objects.
Definition: PtrList.H:54
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:174
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
static autoPtr< reactionRateFlameArea > New(const dictionary &dict, const fvMesh &mesh, const combustionModel &combModel)
Namespace for OpenFOAM.