1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
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"
29 #include "wallFvPatch.H"
31 #include "backwardsCompatibilityWallFunctions.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 namespace incompressible
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 defineTypeNameAndDebug(LRR, 0);
45 addToRunTimeSelectionTable(RASModel, LRR, dictionary);
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
51 const volVectorField& U,
52 const surfaceScalarField& phi,
53 transportModel& lamTransportModel
56 RASModel(typeName, U, phi, lamTransportModel),
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
150 autoCreateR("R", mesh_)
162 autoCreateK("k", mesh_)
174 autoCreateEpsilon("epsilon", mesh_)
186 autoCreateNut("nut", mesh_)
189 nut_ = Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_);
190 nut_.correctBoundaryConditions();
192 if (couplingFactor_.value() < 0.0 || couplingFactor_.value() > 1.0)
197 "(const volVectorField& U, const surfaceScalarField& phi,"
198 "transportModel& lamTransportModel)"
199 ) << "couplingFactor = " << couplingFactor_
200 << " is not in range 0 - 1" << nl
208 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
210 tmp<volSymmTensorField> LRR::devReff() const
212 return tmp<volSymmTensorField>
214 new volSymmTensorField
224 R_ - nu()*dev(twoSymm(fvc::grad(U_)))
230 tmp<fvVectorMatrix> LRR::divDevReff(volVectorField& U) const
232 if (couplingFactor_.value() > 0.0)
236 fvc::div(R_ + couplingFactor_*nut_*fvc::grad(U), "div(R)")
239 (1.0 - couplingFactor_)*nut_,
243 - fvm::laplacian(nuEff(), U)
251 + fvc::laplacian(nut_, U, "laplacian(nuEff,U)")
252 - fvm::laplacian(nuEff(), U)
260 if (RASModel::read())
262 Cmu_.readIfPresent(coeffDict());
263 Clrr1_.readIfPresent(coeffDict());
264 Clrr2_.readIfPresent(coeffDict());
265 C1_.readIfPresent(coeffDict());
266 C2_.readIfPresent(coeffDict());
267 Cs_.readIfPresent(coeffDict());
268 Ceps_.readIfPresent(coeffDict());
269 sigmaEps_.readIfPresent(coeffDict());
271 couplingFactor_.readIfPresent(coeffDict());
273 if (couplingFactor_.value() < 0.0 || couplingFactor_.value() > 1.0)
275 FatalErrorIn("LRR::read()")
276 << "couplingFactor = " << couplingFactor_
277 << " is not in range 0 - 1"
299 volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_));
300 volScalarField G("RASModel::G", 0.5*mag(tr(P)));
302 // Update espsilon and G at the wall
303 epsilon_.boundaryField().updateCoeffs();
305 // Dissipation equation
306 tmp<fvScalarMatrix> epsEqn
309 + fvm::div(phi_, epsilon_)
310 - fvm::Sp(fvc::div(phi_), epsilon_)
311 //- fvm::laplacian(Ceps*(K/epsilon_)*R, epsilon_)
312 - fvm::laplacian(DepsilonEff(), epsilon_)
315 - fvm::Sp(C2_*epsilon_/k_, epsilon_)
320 epsEqn().boundaryManipulate(epsilon_.boundaryField());
323 bound(epsilon_, epsilon0_);
326 // Reynolds stress equation
328 const fvPatchList& patches = mesh_.boundary();
330 forAll(patches, patchi)
332 const fvPatch& curPatch = patches[patchi];
334 if (typeid(curPatch) == typeid(wallFvPatch))
336 forAll(curPatch, facei)
338 label faceCelli = curPatch.faceCells()[facei];
340 *= min(G[faceCelli]/(0.5*mag(tr(P[faceCelli])) + SMALL), 1.0);
346 tmp<fvSymmTensorMatrix> REqn
350 - fvm::Sp(fvc::div(phi_), R_)
351 //- fvm::laplacian(Cs*(k_/epsilon_)*R_, R_)
352 - fvm::laplacian(DREff(), R_)
353 + fvm::Sp(Clrr1_*epsilon_/k_, R_)
356 - (2.0/3.0*(1 - Clrr1_)*I)*epsilon_
365 dimensionedSymmTensor
371 k0_.value(), -GREAT, -GREAT,
382 // Re-calculate viscosity
383 nut_ = Cmu_*sqr(k_)/epsilon_;
384 nut_.correctBoundaryConditions();
387 // Correct wall shear stresses
389 forAll(patches, patchi)
391 const fvPatch& curPatch = patches[patchi];
393 if (typeid(curPatch) == typeid(wallFvPatch))
395 symmTensorField& Rw = R_.boundaryField()[patchi];
397 const scalarField& nutw = nut_.boundaryField()[patchi];
399 vectorField snGradU = U_.boundaryField()[patchi].snGrad();
401 const vectorField& faceAreas
402 = mesh_.Sf().boundaryField()[patchi];
404 const scalarField& magFaceAreas
405 = mesh_.magSf().boundaryField()[patchi];
407 forAll(curPatch, facei)
409 // Calculate near-wall velocity gradient
411 = (faceAreas[facei]/magFaceAreas[facei])*snGradU[facei];
413 // Calculate near-wall shear-stress tensor
414 tensor tauw = -nutw[facei]*2*symm(gradUw);
416 // Reset the shear components of the stress tensor
417 Rw[facei].xy() = tauw.xy();
418 Rw[facei].xz() = tauw.xz();
419 Rw[facei].yz() = tauw.yz();
426 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
428 } // End namespace RASModels
429 } // End namespace incompressible
430 } // End namespace Foam
432 // ************************************************************************* //