SpalartAllmaras.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2022 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 "SpalartAllmaras.H"
27 #include "fvModels.H"
28 #include "fvConstraints.H"
29 #include "bound.H"
30 #include "wallDist.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 namespace RASModels
37 {
38 
39 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
40 
41 template<class BasicMomentumTransportModel>
43 {
44  return volScalarField::New(typedName("chi"), nuTilda_/this->nu());
45 }
46 
47 
48 template<class BasicMomentumTransportModel>
50 (
51  const volScalarField& chi
52 ) const
53 {
54  const volScalarField chi3(typedName("chi3"), pow3(chi));
55  return volScalarField::New(typedName("fv1"), chi3/(chi3 + pow3(Cv1_)));
56 }
57 
58 
59 template<class BasicMomentumTransportModel>
61 (
62  const volScalarField::Internal& chi,
63  const volScalarField::Internal& fv1
64 ) const
65 {
67  (
68  typedName("fv2"),
69  1.0 - chi/(1.0 + chi*fv1)
70  );
71 }
72 
73 
74 template<class BasicMomentumTransportModel>
77 (
78  const volScalarField::Internal& chi,
79  const volScalarField::Internal& fv1
80 ) const
81 {
82  const volScalarField::Internal Omega
83  (
84  typedName("Omega"),
85  ::sqrt(2.0)*mag(skew(fvc::grad(this->U_)().v()))
86  );
87 
89  (
90  typedName("Stilda"),
91  (
92  max
93  (
94  Omega
95  + fv2(chi, fv1)*nuTilda_/sqr(kappa_*y_),
96  Cs_*Omega
97  )
98  )
99  );
100 }
101 
102 
103 template<class BasicMomentumTransportModel>
105 (
106  const volScalarField::Internal& Stilda
107 ) const
108 {
110  (
111  typedName("r"),
112  min
113  (
114  nuTilda_()
115  /(
116  max
117  (
118  Stilda,
119  dimensionedScalar(Stilda.dimensions(), small)
120  )
121  *sqr(kappa_*y_)
122  ),
123  scalar(10.0)
124  )
125  );
126 
127  const volScalarField::Internal g(typedName("g"), r + Cw2_*(pow6(r) - r));
128 
130  (
131  typedName("fw"),
132  g*pow((1.0 + pow6(Cw3_))/(pow6(g) + pow6(Cw3_)), 1.0/6.0)
133  );
134 }
135 
136 
137 template<class BasicMomentumTransportModel>
139 (
140  const volScalarField& fv1
141 )
142 {
143  this->nut_ = nuTilda_*fv1;
144  this->nut_.correctBoundaryConditions();
145  fvConstraints::New(this->mesh_).constrain(this->nut_);
146 }
147 
148 
149 template<class BasicMomentumTransportModel>
151 {
152  correctNut(fv1(this->chi()));
153 }
154 
155 
156 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
157 
158 template<class BasicMomentumTransportModel>
160 (
161  const alphaField& alpha,
162  const rhoField& rho,
163  const volVectorField& U,
164  const surfaceScalarField& alphaRhoPhi,
165  const surfaceScalarField& phi,
166  const viscosity& viscosity,
167  const word& type
168 )
169 :
170  eddyViscosity<RASModel<BasicMomentumTransportModel>>
171  (
172  type,
173  alpha,
174  rho,
175  U,
176  alphaRhoPhi,
177  phi,
178  viscosity
179  ),
180 
181  sigmaNut_
182  (
183  dimensioned<scalar>::lookupOrAddToDict
184  (
185  "sigmaNut",
186  this->coeffDict_,
187  0.66666
188  )
189  ),
190  kappa_
191  (
192  dimensioned<scalar>::lookupOrAddToDict
193  (
194  "kappa",
195  this->coeffDict_,
196  0.41
197  )
198  ),
199 
200  Cb1_
201  (
202  dimensioned<scalar>::lookupOrAddToDict
203  (
204  "Cb1",
205  this->coeffDict_,
206  0.1355
207  )
208  ),
209  Cb2_
210  (
211  dimensioned<scalar>::lookupOrAddToDict
212  (
213  "Cb2",
214  this->coeffDict_,
215  0.622
216  )
217  ),
218  Cw1_(Cb1_/sqr(kappa_) + (1.0 + Cb2_)/sigmaNut_),
219  Cw2_
220  (
221  dimensioned<scalar>::lookupOrAddToDict
222  (
223  "Cw2",
224  this->coeffDict_,
225  0.3
226  )
227  ),
228  Cw3_
229  (
230  dimensioned<scalar>::lookupOrAddToDict
231  (
232  "Cw3",
233  this->coeffDict_,
234  2.0
235  )
236  ),
237  Cv1_
238  (
239  dimensioned<scalar>::lookupOrAddToDict
240  (
241  "Cv1",
242  this->coeffDict_,
243  7.1
244  )
245  ),
246  Cs_
247  (
248  dimensioned<scalar>::lookupOrAddToDict
249  (
250  "Cs",
251  this->coeffDict_,
252  0.3
253  )
254  ),
255 
256  nuTilda_
257  (
258  IOobject
259  (
260  "nuTilda",
261  this->runTime_.name(),
262  this->mesh_,
263  IOobject::MUST_READ,
264  IOobject::AUTO_WRITE
265  ),
266  this->mesh_
267  ),
268 
269  y_(wallDist::New(this->mesh_).y())
270 {
271  if (type == typeName)
272  {
273  this->printCoeffs(type);
274  }
275 }
276 
277 
278 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
279 
280 template<class BasicMomentumTransportModel>
282 {
284  {
285  sigmaNut_.readIfPresent(this->coeffDict());
286  kappa_.readIfPresent(this->coeffDict());
287 
288  Cb1_.readIfPresent(this->coeffDict());
289  Cb2_.readIfPresent(this->coeffDict());
290  Cw1_ = Cb1_/sqr(kappa_) + (1.0 + Cb2_)/sigmaNut_;
291  Cw2_.readIfPresent(this->coeffDict());
292  Cw3_.readIfPresent(this->coeffDict());
293  Cv1_.readIfPresent(this->coeffDict());
294  Cs_.readIfPresent(this->coeffDict());
295 
296  return true;
297  }
298  else
299  {
300  return false;
301  }
302 }
303 
304 
305 template<class BasicMomentumTransportModel>
308 {
309  return volScalarField::New
310  (
311  "DnuTildaEff",
312  (nuTilda_ + this->nu())/sigmaNut_
313  );
314 }
315 
316 
317 template<class BasicMomentumTransportModel>
319 {
320  return volScalarField::New
321  (
322  "k",
323  this->mesh_,
324  dimensionedScalar(dimensionSet(0, 2, -2, 0, 0), 0)
325  );
326 }
327 
328 
329 template<class BasicMomentumTransportModel>
332 {
334  << "Turbulence kinetic energy dissipation rate not defined for "
335  << "Spalart-Allmaras model. Returning zero field"
336  << endl;
337 
338  return volScalarField::New
339  (
340  "epsilon",
341  this->mesh_,
342  dimensionedScalar(dimensionSet(0, 2, -3, 0, 0), 0)
343  );
344 }
345 
346 
347 template<class BasicMomentumTransportModel>
350 {
352  << "Turbulence specific dissipation rate not defined for "
353  << "Spalart-Allmaras model. Returning zero field"
354  << endl;
355 
356  return volScalarField::New
357  (
358  "omega",
359  this->mesh_,
361  );
362 }
363 
364 
365 template<class BasicMomentumTransportModel>
367 {
368  if (!this->turbulence_)
369  {
370  return;
371  }
372 
373  // Local references
374  const alphaField& alpha = this->alpha_;
375  const rhoField& rho = this->rho_;
376  const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_;
377  const Foam::fvModels& fvModels(Foam::fvModels::New(this->mesh_));
379  (
380  Foam::fvConstraints::New(this->mesh_)
381  );
382 
384 
385  const volScalarField chi(this->chi());
386  const volScalarField fv1(this->fv1(chi));
387 
388  const volScalarField::Internal Stilda(this->Stilda(chi, fv1));
389 
390  tmp<fvScalarMatrix> nuTildaEqn
391  (
392  fvm::ddt(alpha, rho, nuTilda_)
393  + fvm::div(alphaRhoPhi, nuTilda_)
394  - fvm::laplacian(alpha*rho*DnuTildaEff(), nuTilda_)
395  - Cb2_/sigmaNut_*alpha*rho*magSqr(fvc::grad(nuTilda_))
396  ==
397  Cb1_*alpha()*rho()*Stilda*nuTilda_()
398  - fvm::Sp(Cw1_*alpha()*rho()*fw(Stilda)*nuTilda_()/sqr(y_), nuTilda_)
399  + fvModels.source(alpha, rho, nuTilda_)
400  );
401 
402  nuTildaEqn.ref().relax();
403  fvConstraints.constrain(nuTildaEqn.ref());
404  solve(nuTildaEqn);
405  fvConstraints.constrain(nuTilda_);
406  bound(nuTilda_, dimensionedScalar(nuTilda_.dimensions(), 0));
407  nuTilda_.correctBoundaryConditions();
408 
409  correctNut(fv1);
410 }
411 
412 
413 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
414 
415 } // End namespace RASModels
416 } // End namespace Foam
417 
418 // ************************************************************************* //
scalar y
Bound the given scalar field where it is below the specified minimum.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const dimensionSet & dimensions() const
Return dimensions.
static tmp< DimensionedField< Type, GeoMesh > > New(const word &name, const Mesh &mesh, const dimensionSet &, const Field< Type > &)
Return a temporary field constructed from name, mesh,.
Generic GeometricField class.
static tmp< GeometricField< Type, PatchField, GeoMesh > > New(const word &name, const Internal &, const PtrList< PatchField< Type >> &)
Return a temporary field constructed from name,.
void correctBoundaryConditions()
Correct boundary field.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
Templated abstract base class for RAS turbulence models.
Definition: RASModel.H:56
tmp< volScalarField > chi() const
virtual tmp< volScalarField > k() const
Return the turbulence kinetic energy.
virtual void correct()
Solve the turbulence equations and correct the turbulence viscosity.
tmp< volScalarField > DnuTildaEff() const
Return the effective diffusivity for nuTilda.
tmp< volScalarField > fv1(const volScalarField &chi) const
tmp< volScalarField::Internal > fv2(const volScalarField::Internal &chi, const volScalarField::Internal &fv1) const
virtual tmp< volScalarField > epsilon() const
Return the turbulence kinetic energy dissipation rate.
tmp< volScalarField::Internal > fw(const volScalarField::Internal &Stilda) const
SpalartAllmaras(const alphaField &alpha, const rhoField &rho, const volVectorField &U, const surfaceScalarField &alphaRhoPhi, const surfaceScalarField &phi, const viscosity &viscosity, const word &type=typeName)
Construct from components.
tmp< volScalarField::Internal > Stilda(const volScalarField::Internal &chi, const volScalarField::Internal &fv1) const
virtual tmp< volScalarField > omega() const
Return the turbulence specific dissipation rate.
virtual bool read()
Read RASProperties dictionary.
static autoPtr< dictionary > New(Istream &)
Construct top-level dictionary on freestore from Istream.
Definition: dictionaryIO.C:100
Dimension set for the base types.
Definition: dimensionSet.H:122
Generic dimensioned Type class.
bool readIfPresent(const dictionary &)
Update the value of dimensioned<Type> if found in the dictionary.
Eddy viscosity turbulence model base class.
Definition: eddyViscosity.H:52
Finite volume constraints.
Definition: fvConstraints.H:62
bool constrain(fvMatrix< Type > &eqn) const
Apply constraints to an equation.
Finite volume models.
Definition: fvModels.H:65
BasicMomentumTransportModel::alphaField alphaField
BasicMomentumTransportModel::rhoField rhoField
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
Abstract base class for all fluid physical properties.
Definition: viscosity.H:50
Interface to run-time selectable methods to calculate the distance-to-wall and normal-to-wall fields.
Definition: wallDist.H:71
A class for handling words, derived from string.
Definition: word.H:62
Foam::fvConstraints & fvConstraints(Foam::fvConstraints::New(mesh))
Foam::fvModels & fvModels(Foam::fvModels::New(mesh))
U
Definition: pEqn.H:72
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
#define WarningInFunction
Report a warning using Foam::Warning.
void correct(const RdeltaTType &rDeltaT, const RhoType &rho, volScalarField &psi, const surfaceScalarField &phiCorr, const SpType &Sp, const SuType &Su)
tmp< VolField< typename outerProduct< vector, Type >::type > > grad(const SurfaceField< Type > &ssf)
Definition: fvcGrad.C:46
tmp< fvMatrix< Type > > laplacian(const VolField< Type > &vf, const word &name)
Definition: fvmLaplacian.C:47
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const VolField< Type > &)
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const VolField< Type > &vf, const word &name)
Definition: fvmDiv.C:48
tmp< fvMatrix< Type > > ddt(const VolField< Type > &vf)
Definition: fvmDdt.C:46
Namespace for OpenFOAM.
dimensionedScalar pow6(const dimensionedScalar &ds)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
bool read(const char *, int32_t &)
Definition: int32IO.C:85
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
dimensionedScalar pow3(const dimensionedScalar &ds)
const dimensionSet dimless
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
const dimensionSet dimTime
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< scalar > mag(const dimensioned< Type > &)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
word typedName(Name name)
Return the name of the object within the given type.
Definition: typeInfo.H:149
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
bool bound(volScalarField &, const dimensionedScalar &min)
Bound the given scalar field where it is below the specified min value.
Definition: bound.C:31
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
dimensioned< scalar > magSqr(const dimensioned< Type > &)
dimensionedTensor skew(const dimensionedTensor &dt)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
SolverPerformance< Type > solve(fvMatrix< Type > &, const word &)
Solve returning the solution statistics given convergence tolerance.