qZeta.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-2026 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 "qZeta.H"
27 #include "fvcMagSqrGradGrad.H"
28 #include "bound.H"
30 
32 (
33  geometricOneField,
34  geometricOneField,
35  incompressibleMomentumTransportModel
36 )
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42 namespace incompressible
43 {
44 namespace RASModels
45 {
46 
47 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
48 
49 defineTypeNameAndDebug(qZeta, 0);
51 (
52  RASincompressibleMomentumTransportModel,
53  qZeta,
54  dictionary
55 );
56 
57 // * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
58 
59 void qZeta::boundZeta()
60 {
61  tmp<volScalarField> tCmuk2(Cmu_*sqr(k_));
62  zeta_ = max(zeta_, Cmu_*pow3(q_)/((2*nutMaxCoeff_)*nu()));
63 }
64 
65 
66 tmp<volScalarField> qZeta::fMu() const
67 {
68  const volScalarField Rt(q_*k_/(2.0*nu()*zeta_));
69 
70  if (anisotropic_)
71  {
72  return exp((-scalar(2.5) + Rt/20.0)/pow3(scalar(1) + Rt/130.0));
73  }
74  else
75  {
76  return
77  exp(-6.0/sqr(scalar(1) + Rt/50.0))
78  *(scalar(1) + 3.0*exp(-Rt/10.0));
79  }
80 }
81 
82 
83 tmp<volScalarField> qZeta::f2() const
84 {
85  tmp<volScalarField> Rt = q_*k_/(2.0*nu()*zeta_);
86  return scalar(1) - 0.3*exp(-sqr(Rt));
87 }
88 
89 
90 void qZeta::correctNut()
91 {
92  nut_ = Cmu_*fMu()*sqr(k_)/epsilon_;
94 }
95 
96 
97 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
98 
100 (
101  const geometricOneField& alpha,
102  const geometricOneField& rho,
103  const volVectorField& U,
104  const surfaceScalarField& alphaRhoPhi,
105  const surfaceScalarField& phi,
106  const viscosity& viscosity,
107  const word& type
108 )
109 :
110  eddyViscosity<incompressible::RASModel>
111  (
112  type,
113  alpha,
114  rho,
115  U,
116  alphaRhoPhi,
117  phi,
118  viscosity
119  ),
120 
121  Cmu_("Cmu", typeDict(type), 0.09),
122  C1_("C1", typeDict(type), 1.44),
123  C2_("C2", typeDict(type), 1.92),
124  sigmaZeta_("sigmaZeta", typeDict(type), 1.3),
125  anisotropic_(typeDict(type).lookupOrDefault<Switch>("anisotropic", false)),
126  qMin_("qMin", sqrt(kMin_)),
127 
128  k_
129  (
130  IOobject
131  (
132  this->groupName("k"),
133  runTime_.name(),
134  mesh_,
137  ),
138  mesh_,
140  ),
141 
142  epsilon_
143  (
144  IOobject
145  (
146  this->groupName("epsilon"),
147  runTime_.name(),
148  mesh_,
151  ),
152  mesh_,
154  ),
155 
156  q_
157  (
158  IOobject
159  (
160  this->groupName("q"),
161  runTime_.name(),
162  mesh_,
165  ),
166  sqrt(max(k_, kMin_)),
167  k_.boundaryField().types()
168  ),
169 
170  zeta_
171  (
172  IOobject
173  (
174  this->groupName("zeta"),
175  runTime_.name(),
176  mesh_,
179  ),
180  epsilon_/(2.0*q_),
181  epsilon_.boundaryField().types()
182  )
183 {
184  boundZeta();
185 }
186 
187 
188 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
189 
190 bool qZeta::read()
191 {
193  {
194  Cmu_.readIfPresent(typeDict());
195  C1_.readIfPresent(typeDict());
196  C2_.readIfPresent(typeDict());
197  sigmaZeta_.readIfPresent(typeDict());
198  anisotropic_.readIfPresent("anisotropic", typeDict());
199 
200  qMin_.readIfPresent(*this);
201 
202  return true;
203  }
204  else
205  {
206  return false;
207  }
208 }
209 
210 
211 void qZeta::correct()
212 {
213  if (!turbulence_)
214  {
215  return;
216  }
217 
219 
220  volScalarField G(GName(), nut_/(2.0*q_)*2*magSqr(symm(fvc::grad(U_))));
221  const volScalarField E(nu()*nut_/q_*fvc::magSqrGradGrad(U_));
222 
223  // Zeta equation
224  tmp<fvScalarMatrix> zetaEqn
225  (
226  fvm::ddt(zeta_)
227  + fvm::div(phi_, zeta_)
229  ==
230  (2.0*C1_ - 1)*G*zeta_/q_
231  - fvm::SuSp((2.0*C2_*f2() - dimensionedScalar(1.0))*zeta_/q_, zeta_)
232  + E
233  );
234 
235  zetaEqn.ref().relax();
236  solve(zetaEqn);
237  boundZeta();
238 
239 
240  // q equation
241  tmp<fvScalarMatrix> qEqn
242  (
243  fvm::ddt(q_)
244  + fvm::div(phi_, q_)
245  - fvm::laplacian(DqEff(), q_)
246  ==
247  G - fvm::Sp(zeta_/q_, q_)
248  );
249 
250  qEqn.ref().relax();
251  solve(qEqn);
252  bound(q_, qMin_);
253  boundZeta();
254 
255  // Re-calculate k and epsilon
256  k_ = sqr(q_);
258 
259  epsilon_ = 2*q_*zeta_;
261 
262  correctNut();
263 }
264 
265 
266 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
267 
268 } // End namespace RASModels
269 } // End namespace incompressible
270 } // End namespace Foam
271 
272 // ************************************************************************* //
Bound the given scalar field where it is below the specified minimum.
void correctBoundaryConditions()
Correct boundary field.
bool readIfPresent(const word &, const dictionary &)
Update the value of the Switch if it is found in the dictionary.
Definition: Switch.C:124
bool readIfPresent(const dictionary &, const unitSet &defaultUnits=NullObjectRef< unitSet >())
Update the value of dimensioned<Type> if found in the dictionary.
virtual bool read()=0
Re-read model coefficients if they have changed.
Definition: eddyViscosity.C:75
virtual void correct()=0
Solve the turbulence equations and correct the turbulence viscosity.
virtual void correctNut()
Correct the eddy-viscosity nut.
tmp< volScalarField > f2() const
qZeta(const geometricOneField &alpha, const geometricOneField &rho, const volVectorField &U, const surfaceScalarField &alphaRhoPhi, const surfaceScalarField &phi, const viscosity &viscosity, const word &type=typeName)
Construct from components.
void boundZeta()
Bound epsilon and return Cmu*sqr(k) for nut.
tmp< volScalarField > DqEff() const
Return the effective diffusivity for q.
Definition: qZeta.H:142
dimensionedScalar sigmaZeta_
Definition: qZeta.H:84
dimensionedScalar qMin_
Lower limit of q.
Definition: qZeta.H:88
virtual void correct()
Solve the turbulence equations and correct the turbulence viscosity.
virtual bool read()
Read RASProperties dictionary.
tmp< volScalarField > fMu() const
tmp< volScalarField > DzetaEff() const
Return the effective diffusivity for epsilon.
Definition: qZeta.H:152
Calculate the magnitude of the square of the gradient of the gradient of the given volField.
U
Definition: pEqn.H:72
rho
Definition: pEqn.H:1
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
const dimensionedScalar G
Newtonian constant of gravitation.
const dimensionSet turbulentKineticEnergy
const dimensionSet turbulentEpsilon
tmp< volScalarField > magSqrGradGrad(const VolField< Type > &vf)
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 > > div(const surfaceScalarField &flux, const VolField< Type > &vf, const word &name)
Definition: fvmDiv.C:48
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const VolField< Type > &)
tmp< fvMatrix< Type > > SuSp(const volScalarField::Internal &, const VolField< Type > &)
tmp< fvMatrix< Type > > ddt(const VolField< Type > &vf)
Definition: fvmDdt.C:46
Namespace for OpenFOAM.
dimensionedScalar exp(const dimensionedScalar &ds)
VolField< vector > volVectorField
Definition: volFieldsFwd.H:63
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
SurfaceField< scalar > surfaceScalarField
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
void symm(pointPatchField< tensor > &, const pointPatchField< tensor > &)
bool bound(volScalarField &, const dimensionedScalar &min)
Bound the given scalar field where it is below the specified min value.
Definition: bound.C:31
void pow3(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
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.
makeMomentumTransportModelTypes(geometricOneField, geometricOneField, incompressibleMomentumTransportModel)
Definition: qZeta.C:32
Info<< "Reading field U\n"<< endl;volVectorField U(IOobject("U", runTime.name(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE), mesh);Info<< "Creating face flux\n"<< endl;surfaceScalarField phi(IOobject("phi", runTime.name(), mesh, IOobject::NO_READ, IOobject::NO_WRITE), mesh, dimensionedScalar(mesh.Sf().dimensions() *U.dimensions(), 0));autoPtr< viscosityModel > viscosity(viscosityModel::New(mesh))