DATurbulenceModel.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v3
5 
6 \*---------------------------------------------------------------------------*/
7 
8 #include "DATurbulenceModel.H"
9 
10 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
11 
12 namespace Foam
13 {
14 
15 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
16 
17 defineTypeNameAndDebug(DATurbulenceModel, 0);
18 defineRunTimeSelectionTable(DATurbulenceModel, dictionary);
19 
20 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
21 
22 DATurbulenceModel::DATurbulenceModel(
23  const word modelType,
24  const fvMesh& mesh,
25  const DAOption& daOption)
26  : regIOobject(
27  IOobject(
28  "DATurbulenceModel",
29  mesh.time().timeName(),
30  mesh, // register to mesh
31  IOobject::NO_READ,
32  IOobject::NO_WRITE,
33  true // always register object
34  )),
35  mesh_(mesh),
36  daOption_(daOption),
37  allOptions_(daOption.getAllOptions()),
38  nut_(const_cast<volScalarField&>(
39  mesh.thisDb().lookupObject<volScalarField>("nut"))),
40  U_(const_cast<volVectorField&>(
41  mesh.thisDb().lookupObject<volVectorField>("U"))),
42  phi_(const_cast<surfaceScalarField&>(
43  mesh.thisDb().lookupObject<surfaceScalarField>("phi"))),
44  phase_(
45  IOobject(
46  "phase",
47  mesh.time().timeName(),
48  mesh,
49  IOobject::NO_READ,
50  IOobject::NO_WRITE,
51  false),
52  mesh,
53  dimensionedScalar("phase", dimensionSet(0, 0, 0, 0, 0, 0, 0), 1.0),
54  zeroGradientFvPatchField<scalar>::typeName),
55  phaseRhoPhi_(const_cast<surfaceScalarField&>(
56  mesh.thisDb().lookupObject<surfaceScalarField>("phi"))),
57 #ifdef IncompressibleFlow
58  daRegDbTransport_(mesh.thisDb().lookupObject<DARegDbSinglePhaseTransportModel>(
59  "DARegDbSinglePhaseTransportModel")),
60  laminarTransport_(daRegDbTransport_.getObject()),
61  daRegDbTurbIncomp_(mesh.thisDb().lookupObject<DARegDbTurbulenceModelIncompressible>(
62  "DARegDbTurbulenceModelIncompressible")),
63  turbulence_(daRegDbTurbIncomp_.getObject()),
64  // for incompressible, we use uniform one field for rho
65  rho_(
66  IOobject(
67  "rho",
68  mesh.time().timeName(),
69  mesh,
70  IOobject::NO_READ,
71  IOobject::NO_WRITE,
72  false),
73  mesh,
74  dimensionedScalar("rho", dimensionSet(0, 0, 0, 0, 0, 0, 0), 1.0),
75  zeroGradientFvPatchField<scalar>::typeName),
76 #endif
77 #ifdef CompressibleFlow
78  daRegDbThermo_(mesh.thisDb().lookupObject<DARegDbFluidThermo>("DARegDbFluidThermo")),
79  thermo_(daRegDbThermo_.getObject()),
80  daRegDbTurbComp_(mesh.thisDb().lookupObject<DARegDbTurbulenceModelCompressible>(
81  "DARegDbTurbulenceModelCompressible")),
82  turbulence_(daRegDbTurbComp_.getObject()),
83  // for compressible flow, we lookup rho in fvMesh
84  rho_(const_cast<volScalarField&>(mesh.thisDb().lookupObject<volScalarField>("rho"))),
85 #endif
86  turbDict_(
87  IOobject(
88  "turbulenceProperties",
89  mesh.time().constant(),
90  mesh,
91  IOobject::MUST_READ,
92  IOobject::NO_WRITE,
93  false)),
94  coeffDict_(turbDict_.subDict("RAS")),
95  kMin_(dimensioned<scalar>::lookupOrAddToDict(
96  "kMin",
97  coeffDict_,
98  sqr(dimVelocity),
99  SMALL)),
100  epsilonMin_(dimensioned<scalar>::lookupOrAddToDict(
101  "epsilonMin",
102  coeffDict_,
103  kMin_.dimensions() / dimTime,
104  SMALL)),
105  omegaMin_(dimensioned<scalar>::lookupOrAddToDict(
106  "omegaMin",
107  coeffDict_,
108  dimless / dimTime,
109  SMALL)),
110  nuTildaMin_(dimensioned<scalar>::lookupOrAddToDict(
111  "nuTildaMin",
112  coeffDict_,
113  nut_.dimensions(),
114  SMALL))
115 {
116 
117  // Now we need to initialize other variables
118 #ifdef IncompressibleFlow
119 
120  // initialize the Prandtl number from transportProperties
121  IOdictionary transportProperties(
122  IOobject(
123  "transportProperties",
124  mesh.time().constant(),
125  mesh,
126  IOobject::MUST_READ,
127  IOobject::NO_WRITE,
128  false));
129  Pr_ = readScalar(transportProperties.lookup("Pr"));
130 
131  if (mesh_.thisDb().foundObject<volScalarField>("alphat"))
132  {
133  Prt_ = readScalar(transportProperties.lookup("Prt"));
134  }
135 
136 #endif
137 
138 #ifdef CompressibleFlow
139 
140  // initialize the Prandtl number from thermophysicalProperties
141  IOdictionary thermophysicalProperties(
142  IOobject(
143  "thermophysicalProperties",
144  mesh.time().constant(),
145  mesh,
146  IOobject::MUST_READ,
147  IOobject::NO_WRITE,
148  false));
149  Pr_ = readScalar(
150  thermophysicalProperties.subDict("mixture").subDict("transport").lookup("Pr"));
151 
152  if (mesh_.thisDb().foundObject<volScalarField>("alphat"))
153  {
154  const IOdictionary& turbDict = mesh_.thisDb().lookupObject<IOdictionary>("turbulenceProperties");
155  dictionary rasSubDict = turbDict.subDict("RAS");
156  Prt_ = rasSubDict.getScalar("Prt");
157  }
158 
159 #endif
160 }
161 
162 // * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
163 
164 autoPtr<DATurbulenceModel> DATurbulenceModel::New(
165  const word modelType,
166  const fvMesh& mesh,
167  const DAOption& daOption)
168 {
169  if (daOption.getAllOptions().lookupOrDefault<label>("debug", 0))
170  {
171  Info << "Selecting " << modelType << " for DATurbulenceModel" << endl;
172  }
173 
174  dictionaryConstructorTable::iterator cstrIter =
175  dictionaryConstructorTablePtr_->find(modelType);
176 
177  if (cstrIter == dictionaryConstructorTablePtr_->end())
178  {
179  FatalErrorIn(
180  "DATurbulenceModel::New"
181  "("
182  " const word,"
183  " const fvMesh&,"
184  " const DAOption&"
185  ")")
186  << "Unknown DATurbulenceModel type "
187  << modelType << nl << nl
188  << "Valid DATurbulenceModel types:" << endl
189  << dictionaryConstructorTablePtr_->sortedToc()
190  << exit(FatalError);
191  }
192 
193  return autoPtr<DATurbulenceModel>(
194  cstrIter()(modelType, mesh, daOption));
195 }
196 
197 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
198 
199 // this is a virtual function for regIOobject
200 bool DATurbulenceModel::writeData(Ostream& os) const
201 {
202  // do nothing
203  return true;
204 }
205 
207 {
208  // see src/TurbulenceModels/compressible/EddyDiffusivity/EddyDiffusivity.C
209  if (mesh_.thisDb().foundObject<volScalarField>("alphat"))
210  {
211  dimensionedScalar Prt(
212  "Prt1",
213  dimless,
214  Prt_);
215 
216  volScalarField& alphat = const_cast<volScalarField&>(
217  mesh_.thisDb().lookupObject<volScalarField>("alphat"));
218  alphat = rho_ * nut_ / Prt;
219  alphat.correctBoundaryConditions();
220  }
221 }
222 
223 tmp<volScalarField> DATurbulenceModel::nuEff() const
224 {
225  /*
226  Description:
227  Return nut+nu
228  */
229 
230  return tmp<volScalarField>(
231  new volScalarField(
232  "nuEff",
233  this->nu() + nut_));
234 }
235 
236 tmp<volScalarField> DATurbulenceModel::alphaEff()
237 {
238  /*
239  Description:
240  Return alphat+alpha
241  For compressible flow, we get it from thermo object
242  For incompressible flow we use alpha+alphat
243  */
244 
245 #ifdef IncompressibleFlow
246  const volScalarField& alphat = mesh_.thisDb().lookupObject<volScalarField>("alphat");
247  return tmp<volScalarField>(
248  new volScalarField(
249  "alphaEff",
250  this->getAlpha() + alphat));
251 #endif
252 
253 #ifdef CompressibleFlow
254  const volScalarField& alphat = mesh_.thisDb().lookupObject<volScalarField>("alphat");
255  return tmp<volScalarField>(
256  new volScalarField(
257  "alphaEff",
258  thermo_.alphaEff(alphat)));
259 #endif
260 }
261 
262 tmp<volScalarField> DATurbulenceModel::nu() const
263 {
264  /*
265  Description:
266  Return nu
267  For compressible flow, we get it from mu/rho
268  For incompressible flow we get it from ther laminarTransport object
269  */
270 
271 #ifdef IncompressibleFlow
272  return laminarTransport_.nu();
273 #endif
274 
275 #ifdef CompressibleFlow
276  return thermo_.mu() / rho_;
277 #endif
278 }
279 
280 tmp<volScalarField> DATurbulenceModel::getAlpha() const
281 {
282  /*
283  Description:
284  Return alpha = nu/Pr
285  */
286  return this->nu() / Pr_;
287 }
288 
289 tmp<Foam::volScalarField> DATurbulenceModel::getMu() const
290 {
291  /*
292  Description:
293  Return mu
294  For compressible flow, we get it from thermo
295  Not appliable for other flow conditions
296  */
297 
298 #ifdef CompressibleFlow
299  return thermo_.mu();
300 #else
301  FatalErrorIn("flowCondition not valid!") << abort(FatalError);
302  return nut_;
303 #endif
304 }
305 
306 tmp<volSymmTensorField> DATurbulenceModel::devRhoReff() const
307 {
308  /*
309  Description:
310  Return devRhoReff for computing viscous force
311  */
312 
313  return tmp<volSymmTensorField>(
314  new volSymmTensorField(
315  IOobject(
316  IOobject::groupName("devRhoReff", U_.group()),
317  mesh_.time().timeName(),
318  mesh_,
319  IOobject::NO_READ,
320  IOobject::NO_WRITE),
321  (-phase_ * rho_ * nuEff()) * dev(twoSymm(fvc::grad(U_)))));
322 }
323 
325  volVectorField& U)
326 {
327  /*
328  Description:
329  Return divDevRhoReff for the laplacian terms
330  */
331 
332 #ifdef IncompressibleFlow
333  word divScheme = "div((nuEff*dev2(T(grad(U)))))";
334 #endif
335 #ifdef CompressibleFlow
336  word divScheme = "div(((rho*nuEff)*dev2(T(grad(U)))))";
337 #endif
338 
339  volScalarField& phase = phase_;
340  volScalarField& rho = rho_;
341 
342  return (
343  -fvm::laplacian(phase * rho * nuEff(), U)
344  - fvc::div((phase * rho * nuEff()) * dev2(T(fvc::grad(U))), divScheme));
345 }
346 
347 tmp<fvVectorMatrix> DATurbulenceModel::divDevReff(
348  volVectorField& U)
349 {
350  /*
351  Description:
352  Call divDevRhoReff
353  */
354 
355  return divDevRhoReff(U);
356 }
357 
359 {
360  /*
361  Description:
362  Update the near wall distance
363  */
364 
365  // ********* TODO ********
366  // ********* this is not implemented yet ********
367  //d_.correct();
368  // need to correct turbulence boundary conditions
369  // this is because when the near wall distance changes, the nut, omega, epsilon at wall
370  // may change if you use wall functions
372 }
373 
374 #ifdef CompressibleFlow
375 const fluidThermo& DATurbulenceModel::getThermo() const
376 {
377  /*
378  Description:
379  Return the thermo object, only for compressible flow
380  */
381  return thermo_;
382 }
383 #endif
384 
386 {
387  /*
388  Description:
389  Calculate the min, max, and mean yPlus for all walls and print the
390  values to screen
391  Modified from src/functionObjects/field/yPlus/yPlus.C
392  */
393 
394  volScalarField yPlus(
395  IOobject(
396  typeName,
397  mesh_.time().timeName(),
398  mesh_,
399  IOobject::NO_READ,
400  IOobject::AUTO_WRITE),
401  mesh_,
402  dimensionedScalar(dimless, Zero));
403  volScalarField::Boundary& yPlusBf = yPlus.boundaryFieldRef();
404 
405  const nearWallDist nwd(mesh_);
406  const volScalarField::Boundary& d = nwd.y();
407 
408  const fvPatchList& patches = mesh_.boundary();
409 
410  const volScalarField::Boundary& nutBf = nut_.boundaryField();
411  const volVectorField::Boundary& UBf = U_.boundaryField();
412 
413  volScalarField nuEff = this->nuEff();
414  volScalarField nu = this->nu();
415 
416  const volScalarField::Boundary& nuEffBf = nuEff.boundaryField();
417  const volScalarField::Boundary& nuBf = nu.boundaryField();
418 
419  forAll(patches, patchI)
420  {
421  const fvPatch& patch = patches[patchI];
422 
423  if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchI]))
424  {
425  const nutWallFunctionFvPatchScalarField& nutPf =
426  dynamic_cast<const nutWallFunctionFvPatchScalarField&>(
427  nutBf[patchI]);
428 
429  yPlusBf[patchI] = nutPf.yPlus();
430  }
431  else if (isA<wallFvPatch>(patch))
432  {
433  yPlusBf[patchI] =
434  d[patchI]
435  * sqrt(
436  nuEffBf[patchI]
437  * mag(UBf[patchI].snGrad()))
438  / nuBf[patchI];
439  }
440  }
441 
442  // now compute the global min, max, and mean
443  scalarList yPlusAll;
444  forAll(patches, patchI)
445  {
446  const fvPatch& patch = patches[patchI];
447  if (isA<wallFvPatch>(patch))
448  {
449  forAll(yPlusBf[patchI], faceI)
450  {
451  yPlusAll.append(yPlusBf[patchI][faceI]);
452  }
453  }
454  }
455  scalar minYplus = gMin(yPlusAll);
456  scalar maxYplus = gMax(yPlusAll);
457  scalar avgYplus = gAverage(yPlusAll);
458 
459  Info << "yPlus min: " << minYplus
460  << " max: " << maxYplus
461  << " mean: " << avgYplus << endl;
462 }
463 
465  const Time& runTime,
466  const label printInterval) const
467 {
468  /*
469  Description:
470  Check if it is print time
471  */
472 
473  if (runTime.timeIndex() % printInterval == 0 || runTime.timeIndex() == 1)
474  {
475  return 1;
476  }
477  else
478  {
479  return 0;
480  }
481 }
482 
483 void DATurbulenceModel::getTurbProdTerm(scalarList& prodTerm) const
484 {
485  /*
486  Description:
487  Return the value of the production term from the turbulence model
488  */
489 
490  FatalErrorIn("DATurbulenceModel::getSAProdTerm")
491  << "Child class not implemented!"
492  << abort(FatalError);
493 }
494 
496  const volScalarField& mySource,
497  volScalarField& pseudoNuTilda)
498 {
499  /*
500  Description:
501  Inverse transpose product, M_nuTilda^(-T)
502  */
503 
504  FatalErrorIn("DATurbulenceModel::invTranProdNuTildaEqn")
505  << "Child class not implemented!"
506  << abort(FatalError);
507 }
508 
509 void DATurbulenceModel::calcLduResidualTurb(volScalarField& nuTildaRes)
510 {
511  /*
512  Description:
513  calculate the turbulence residual using LDU matrix
514  */
515 
516  FatalErrorIn("DATurbulenceModel::calcLduResidualTurb")
517  << "Child class not implemented!"
518  << abort(FatalError);
519 }
520 
522 {
523  /*
524  Description:
525  construct the pseudo nuTildaEqn
526  */
527 
528  FatalErrorIn("DATurbulenceModel::constructPseudoNuTildaEqn")
529  << "Child class not implemented!"
530  << abort(FatalError);
531 }
532 
533 void DATurbulenceModel::rhsSolvePseudoNuTildaEqn(const volScalarField& nuTildaSource)
534 {
535  /*
536  Description:
537  solve the pseudo nuTildaEqn with overwritten rhs
538  */
539 
540  FatalErrorIn("DATurbulenceModel::rhsSolvePseudoNuTildaEqn")
541  << "Child class not implemented!"
542  << abort(FatalError);
543 }
544 
545 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
546 
547 } // End namespace Foam
548 
549 // ************************************************************************* //
Foam::DARegDbTurbulenceModelCompressible
Definition: DARegDbTurbulenceModelCompressible.H:43
Foam::DATurbulenceModel::nuEff
tmp< volScalarField > nuEff() const
return effective viscosity
Definition: DATurbulenceModel.C:223
U
U
Definition: pEqnPimpleDyM.H:60
Foam::DATurbulenceModel::constructPseudoNuTildaEqn
virtual void constructPseudoNuTildaEqn()
Definition: DATurbulenceModel.C:521
forAll
forAll(pseudoP.boundaryField(), patchI)
Definition: solvePseudoPEqn.H:10
Foam::DATurbulenceModel::divDevRhoReff
tmp< fvVectorMatrix > divDevRhoReff(volVectorField &U)
divDev terms
Definition: DATurbulenceModel.C:324
Foam::DATurbulenceModel::divDevReff
tmp< fvVectorMatrix > divDevReff(volVectorField &U)
divDev terms
Definition: DATurbulenceModel.C:347
Foam::DAOption
Definition: DAOption.H:29
daOption
DAOption daOption(mesh, pyOptions_)
pseudoNuTilda
volScalarField & pseudoNuTilda
Definition: pseudoEqns.H:34
Foam::DATurbulenceModel::New
static autoPtr< DATurbulenceModel > New(const word modelType, const fvMesh &mesh, const DAOption &daOption)
Definition: DATurbulenceModel.C:164
Foam::DATurbulenceModel::Prt_
scalar Prt_
turbulent Prandtl number
Definition: DATurbulenceModel.H:145
Foam::DATurbulenceModel::correctBoundaryConditions
virtual void correctBoundaryConditions()=0
update turbulence variable boundary values
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(DAFvSource, dictionary)
Foam::DATurbulenceModel::calcLduResidualTurb
virtual void calcLduResidualTurb(volScalarField &nuTildaRes)
calculate the turbulence residual using LDU matrix
Definition: DATurbulenceModel.C:509
Foam::DATurbulenceModel::getMu
tmp< Foam::volScalarField > getMu() const
get mu
Definition: DATurbulenceModel.C:289
Foam::DATurbulenceModel::getAlpha
tmp< volScalarField > getAlpha() const
get alpha field
Definition: DATurbulenceModel.C:280
Foam::DATurbulenceModel::correctWallDist
void correctWallDist()
update wall distance for d_. Note: y_ will be automatically updated in mesh_ object
Definition: DATurbulenceModel.C:358
Foam::DATurbulenceModel::U_
volVectorField & U_
velocity
Definition: DATurbulenceModel.H:86
Foam::DATurbulenceModel::nut_
volScalarField & nut_
turbulence viscosity
Definition: DATurbulenceModel.H:83
Foam
Definition: multiFreqScalarFvPatchField.C:144
divScheme
word divScheme
Definition: pseudoEqns.H:1
T
volScalarField & T
Definition: createRefsHeatTransfer.H:5
Foam::DATurbulenceModel::invTranProdNuTildaEqn
virtual void invTranProdNuTildaEqn(const volScalarField &mySource, volScalarField &pseudoNuTilda)
Inverse transpose product, M_nuTilda^(-T)
Definition: DATurbulenceModel.C:495
Foam::DATurbulenceModel::devRhoReff
tmp< volSymmTensorField > devRhoReff() const
dev terms
Definition: DATurbulenceModel.C:306
Foam::DARegDbTurbulenceModelIncompressible
Definition: DARegDbTurbulenceModelIncompressible.H:43
Foam::DATurbulenceModel::rhsSolvePseudoNuTildaEqn
virtual void rhsSolvePseudoNuTildaEqn(const volScalarField &nuTildaSource)
Definition: DATurbulenceModel.C:533
Foam::DATurbulenceModel::nu
tmp< volScalarField > nu() const
get the nu field
Definition: DATurbulenceModel.C:262
Foam::DARegDbFluidThermo
Definition: DARegDbFluidThermo.H:40
Foam::DATurbulenceModel::correctAlphat
void correctAlphat()
update alphat
Definition: DATurbulenceModel.C:206
Prt
dimensionedScalar Prt
Definition: createRefsSimpleT.H:18
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFvSource, 0)
Foam::DATurbulenceModel::getTurbProdTerm
virtual void getTurbProdTerm(scalarList &prodTerm) const
return the value of the production term from the Spalart Allmaras model
Definition: DATurbulenceModel.C:483
Foam::DATurbulenceModel::mesh_
const fvMesh & mesh_
fvMesh
Definition: DATurbulenceModel.H:74
alphat
volScalarField & alphat
Definition: createRefsSimpleT.H:19
Foam::DATurbulenceModel::isPrintTime
label isPrintTime(const Time &runTime, const label printInterval) const
Definition: DATurbulenceModel.C:464
Foam::DATurbulenceModel::alphaEff
tmp< volScalarField > alphaEff()
return effective thermal diffusivity
Definition: DATurbulenceModel.C:236
Foam::DATurbulenceModel::printYPlus
void printYPlus() const
print the min max and mean yPlus to screen
Definition: DATurbulenceModel.C:385
runTime
Time & runTime
Definition: createRefsHeatTransfer.H:1
Foam::DATurbulenceModel::Pr_
scalar Pr_
Prandtl number.
Definition: DATurbulenceModel.H:142
Foam::DARegDbSinglePhaseTransportModel
Definition: DARegDbSinglePhaseTransportModel.H:40
DATurbulenceModel.H
Foam::DATurbulenceModel::phase_
volScalarField phase_
phase field
Definition: DATurbulenceModel.H:92
Foam::DATurbulenceModel::writeData
bool writeData(Ostream &os) const
this is a virtual function for regIOobject
Definition: DATurbulenceModel.C:200
rho
volScalarField & rho
Definition: createRefsRhoSimpleC.H:8