1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "SpalartAllmaras.H"
28 #include "addToRunTimeSelectionTable.H"
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 namespace incompressible
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 defineTypeNameAndDebug(SpalartAllmaras, 0);
42 addToRunTimeSelectionTable(LESModel, SpalartAllmaras, dictionary);
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46 void SpalartAllmaras::updateSubGridScaleFields()
48 nuSgs_.internalField() = fv1()*nuTilda_.internalField();
49 nuSgs_.correctBoundaryConditions();
53 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
55 tmp<volScalarField> SpalartAllmaras::fv1() const
57 volScalarField chi3 = pow3(nuTilda_/nu());
58 return chi3/(chi3 + pow3(Cv1_));
62 tmp<volScalarField> SpalartAllmaras::fv2() const
64 return 1/pow3(scalar(1) + nuTilda_/(Cv2_*nu()));
68 tmp<volScalarField> SpalartAllmaras::fv3() const
70 volScalarField chi = nuTilda_/nu();
71 volScalarField chiByCv2 = (1/Cv2_)*chi;
74 (scalar(1) + chi*fv1())
76 *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2))
77 /pow3(scalar(1) + chiByCv2);
81 tmp<volScalarField> SpalartAllmaras::S(const volTensorField& gradU) const
83 return sqrt(2.0)*mag(skew(gradU));
87 tmp<volScalarField> SpalartAllmaras::STilda
89 const volScalarField& S,
90 const volScalarField& dTilda
93 return fv3()*S + fv2()*nuTilda_/sqr(kappa_*dTilda);
97 tmp<volScalarField> SpalartAllmaras::r
99 const volScalarField& visc,
100 const volScalarField& S,
101 const volScalarField& dTilda
111 dimensionedScalar("SMALL", S.dimensions(), SMALL)
117 dimensionSet(0, 2 , -1, 0, 0),
126 tmp<volScalarField> SpalartAllmaras::fw
128 const volScalarField& S,
129 const volScalarField& dTilda
132 volScalarField r = this->r(nuTilda_, S, dTilda);
134 volScalarField g = r + Cw2_*(pow6(r) - r);
136 return g*pow((1 + pow6(Cw3_))/(pow6(g) + pow6(Cw3_)), 1.0/6.0);
140 tmp<volScalarField> SpalartAllmaras::dTilda(const volScalarField&) const
142 return min(CDES_*delta(), y_);
146 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
148 SpalartAllmaras::SpalartAllmaras
150 const volVectorField& U,
151 const surfaceScalarField& phi,
152 transportModel& transport,
153 const word& modelName
156 LESModel(modelName, U, phi, transport),
160 dimensioned<scalar>::lookupOrAddToDict
169 dimensioned<scalar>::lookupOrAddToDict
178 dimensioned<scalar>::lookupOrAddToDict
187 dimensioned<scalar>::lookupOrAddToDict
196 dimensioned<scalar>::lookupOrAddToDict
205 dimensioned<scalar>::lookupOrAddToDict
214 dimensioned<scalar>::lookupOrAddToDict
223 dimensioned<scalar>::lookupOrAddToDict
230 Cw1_(Cb1_/sqr(kappa_) + (1.0 + Cb2_)/sigmaNut_),
233 dimensioned<scalar>::lookupOrAddToDict
242 dimensioned<scalar>::lookupOrAddToDict
278 updateSubGridScaleFields();
282 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
284 void SpalartAllmaras::correct(const tmp<volTensorField>& gradU)
286 LESModel::correct(gradU);
288 if (mesh_.changing())
291 y_.boundaryField() = max(y_.boundaryField(), VSMALL);
294 const volScalarField S = this->S(gradU);
295 const volScalarField dTilda = this->dTilda(S);
296 const volScalarField STilda = this->STilda(S, dTilda);
298 fvScalarMatrix nuTildaEqn
301 + fvm::div(phi(), nuTilda_)
304 (nuTilda_ + nu())/sigmaNut_,
306 "laplacian(DnuTildaEff,nuTilda)"
308 - Cb2_/sigmaNut_*magSqr(fvc::grad(nuTilda_))
311 - fvm::Sp(Cw1_*fw(STilda, dTilda)*nuTilda_/sqr(dTilda), nuTilda_)
317 bound(nuTilda_, dimensionedScalar("zero", nuTilda_.dimensions(), 0.0));
318 nuTilda_.correctBoundaryConditions();
320 updateSubGridScaleFields();
324 tmp<volScalarField> SpalartAllmaras::k() const
326 return sqr(nuSgs()/ck_/dTilda(S(fvc::grad(U()))));
330 tmp<volScalarField> SpalartAllmaras::epsilon() const
332 return 2*nuEff()*magSqr(symm(fvc::grad(U())));
336 tmp<volSymmTensorField> SpalartAllmaras::B() const
338 return ((2.0/3.0)*I)*k() - nuSgs()*twoSymm(fvc::grad(U()));
342 tmp<volSymmTensorField> SpalartAllmaras::devBeff() const
344 return -nuEff()*dev(twoSymm(fvc::grad(U())));
348 tmp<fvVectorMatrix> SpalartAllmaras::divDevBeff(volVectorField& U) const
352 - fvm::laplacian(nuEff(), U) - fvc::div(nuEff()*dev(fvc::grad(U)().T()))
357 bool SpalartAllmaras::read()
359 if (LESModel::read())
361 sigmaNut_.readIfPresent(coeffDict());
362 kappa_.readIfPresent(*this);
363 Cb1_.readIfPresent(coeffDict());
364 Cb2_.readIfPresent(coeffDict());
365 Cv1_.readIfPresent(coeffDict());
366 Cv2_.readIfPresent(coeffDict());
367 CDES_.readIfPresent(coeffDict());
368 ck_.readIfPresent(coeffDict());
369 Cw1_ = Cb1_/sqr(kappa_) + (1.0 + Cb2_)/sigmaNut_;
370 Cw2_.readIfPresent(coeffDict());
371 Cw3_.readIfPresent(coeffDict());
382 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
384 } // End namespace LESModels
385 } // End namespace incompressible
386 } // End namespace Foam
388 // ************************************************************************* //