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 \*---------------------------------------------------------------------------*/
28 #include "addToRunTimeSelectionTable.H"
30 #include "backwardsCompatibilityWallFunctions.H"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 namespace compressible
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 defineTypeNameAndDebug(LRR, 0);
44 addToRunTimeSelectionTable(RASModel, LRR, dictionary);
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
50 const volScalarField& rho,
51 const volVectorField& U,
52 const surfaceScalarField& phi,
53 const basicThermo& thermophysicalModel
56 RASModel(typeName, rho, U, phi, thermophysicalModel),
60 dimensioned<scalar>::lookupOrAddToDict
69 dimensioned<scalar>::lookupOrAddToDict
78 dimensioned<scalar>::lookupOrAddToDict
87 dimensioned<scalar>::lookupOrAddToDict
96 dimensioned<scalar>::lookupOrAddToDict
105 dimensioned<scalar>::lookupOrAddToDict
114 dimensioned<scalar>::lookupOrAddToDict
123 dimensioned<scalar>::lookupOrAddToDict
132 dimensioned<scalar>::lookupOrAddToDict
141 dimensioned<scalar>::lookupOrAddToDict
150 dimensioned<scalar>::lookupOrAddToDict
168 autoCreateR("R", mesh_)
180 autoCreateK("k", mesh_)
192 autoCreateEpsilon("epsilon", mesh_)
204 autoCreateMut("mut", mesh_)
216 autoCreateAlphat("alphat", mesh_)
219 if (couplingFactor_.value() < 0.0 || couplingFactor_.value() > 1.0)
224 "( const volScalarField&, const volVectorField&"
225 ", const surfaceScalarField&, incompressibleTransportModel&)"
226 ) << "couplingFactor = " << couplingFactor_
227 << " is not in range 0 - 1" << nl
231 mut_ = Cmu_*rho_*sqr(k_)/(epsilon_ + epsilonSmall_);
232 mut_.correctBoundaryConditions();
235 alphat_.correctBoundaryConditions();
241 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
243 tmp<volSymmTensorField> LRR::devRhoReff() const
245 return tmp<volSymmTensorField>
247 new volSymmTensorField
257 rho_*R_ - mu()*dev(twoSymm(fvc::grad(U_)))
263 tmp<fvVectorMatrix> LRR::divDevRhoReff(volVectorField& U) const
265 if (couplingFactor_.value() > 0.0)
269 fvc::div(rho_*R_ + couplingFactor_*mut_*fvc::grad(U))
270 + fvc::laplacian((1.0 - couplingFactor_)*mut_, U)
271 - fvm::laplacian(muEff(), U)
272 - fvc::div(mu()*dev2(fvc::grad(U)().T()))
280 + fvc::laplacian(mut_, U)
281 - fvm::laplacian(muEff(), U)
282 - fvc::div(mu()*dev2(fvc::grad(U)().T()))
290 if (RASModel::read())
292 Cmu_.readIfPresent(coeffDict());
293 Clrr1_.readIfPresent(coeffDict());
294 Clrr2_.readIfPresent(coeffDict());
295 C1_.readIfPresent(coeffDict());
296 C2_.readIfPresent(coeffDict());
297 Cs_.readIfPresent(coeffDict());
298 Ceps_.readIfPresent(coeffDict());
299 sigmaR_.readIfPresent(coeffDict());
300 sigmaEps_.readIfPresent(coeffDict());
301 Prt_.readIfPresent(coeffDict());
302 couplingFactor_.readIfPresent(coeffDict());
304 if (couplingFactor_.value() < 0.0 || couplingFactor_.value() > 1.0)
306 FatalErrorIn("LRR::read()")
307 << "couplingFactor = " << couplingFactor_
308 << " is not in range 0 - 1" << nl
323 // Bound in case of topological change
325 if (mesh_.changing())
328 bound(epsilon_, epsilon0_);
333 // Re-calculate viscosity
334 mut_ = rho_*Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_);
335 mut_.correctBoundaryConditions();
337 // Re-calculate thermal diffusivity
339 alphat_.correctBoundaryConditions();
346 volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_));
347 volScalarField G("RASModel::G", 0.5*mag(tr(P)));
349 // Update epsilon and G at the wall
350 epsilon_.boundaryField().updateCoeffs();
352 // Dissipation equation
353 tmp<fvScalarMatrix> epsEqn
355 fvm::ddt(rho_, epsilon_)
356 + fvm::div(phi_, epsilon_)
357 //- fvm::laplacian(Ceps*rho_*(k_/epsilon_)*R_, epsilon_)
358 - fvm::laplacian(DepsilonEff(), epsilon_)
360 C1_*rho_*G*epsilon_/k_
361 - fvm::Sp(C2_*rho_*epsilon_/k_, epsilon_)
366 epsEqn().boundaryManipulate(epsilon_.boundaryField());
369 bound(epsilon_, epsilon0_);
372 // Reynolds stress equation
374 const fvPatchList& patches = mesh_.boundary();
376 forAll(patches, patchi)
378 const fvPatch& curPatch = patches[patchi];
380 if (curPatch.isWall())
382 forAll(curPatch, facei)
384 label faceCelli = curPatch.faceCells()[facei];
386 *= min(G[faceCelli]/(0.5*mag(tr(P[faceCelli])) + SMALL), 100.0);
392 tmp<fvSymmTensorMatrix> REqn
396 //- fvm::laplacian(Cs*rho_*(k_/epsilon_)*R_, R_)
397 - fvm::laplacian(DREff(), R_)
398 + fvm::Sp(Clrr1_*rho_*epsilon_/k_, R_)
401 - (2.0/3.0*(1 - Clrr1_)*I)*rho_*epsilon_
410 dimensionedSymmTensor
416 k0_.value(), -GREAT, -GREAT,
427 // Re-calculate viscosity
428 mut_ = rho_*Cmu_*sqr(k_)/epsilon_;
429 mut_.correctBoundaryConditions();
431 // Re-calculate thermal diffusivity
433 alphat_.correctBoundaryConditions();
436 // Correct wall shear stresses
438 forAll(patches, patchi)
440 const fvPatch& curPatch = patches[patchi];
442 if (curPatch.isWall())
444 symmTensorField& Rw = R_.boundaryField()[patchi];
446 const scalarField& rhow = rho_.boundaryField()[patchi];
447 const scalarField& mutw = mut_.boundaryField()[patchi];
449 vectorField snGradU = U_.boundaryField()[patchi].snGrad();
451 const vectorField& faceAreas
452 = mesh_.Sf().boundaryField()[patchi];
454 const scalarField& magFaceAreas
455 = mesh_.magSf().boundaryField()[patchi];
457 forAll(curPatch, facei)
459 // Calculate near-wall velocity gradient
461 = (faceAreas[facei]/magFaceAreas[facei])*snGradU[facei];
463 // Calculate near-wall shear-stress tensor
464 tensor tauw = -(mutw[facei]/rhow[facei])*2*dev(symm(gradUw));
466 // Reset the shear components of the stress tensor
467 Rw[facei].xy() = tauw.xy();
468 Rw[facei].xz() = tauw.xz();
469 Rw[facei].yz() = tauw.yz();
476 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
478 } // End namespace RASModels
479 } // End namespace compressible
480 } // End namespace Foam
482 // ************************************************************************* //