FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

LaunderGibsonRSTM.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "LaunderGibsonRSTM.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <finiteVolume/wallFvPatch.H>
00029 
00030 #include <compressibleRASModels/backwardsCompatibilityWallFunctions.H>
00031 
00032 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00033 
00034 namespace Foam
00035 {
00036 namespace compressible
00037 {
00038 namespace RASModels
00039 {
00040 
00041 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00042 
00043 defineTypeNameAndDebug(LaunderGibsonRSTM, 0);
00044 addToRunTimeSelectionTable(RASModel, LaunderGibsonRSTM, dictionary);
00045 
00046 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00047 
00048 LaunderGibsonRSTM::LaunderGibsonRSTM
00049 (
00050     const volScalarField& rho,
00051     const volVectorField& U,
00052     const surfaceScalarField& phi,
00053     const basicThermo& thermophysicalModel
00054 )
00055 :
00056     RASModel(typeName, rho, U, phi, thermophysicalModel),
00057 
00058     Cmu_
00059     (
00060         dimensioned<scalar>::lookupOrAddToDict
00061         (
00062             "Cmu",
00063             coeffDict_,
00064             0.09
00065         )
00066     ),
00067     kappa_
00068     (
00069         dimensioned<scalar>::lookupOrAddToDict
00070         (
00071             "kappa",
00072             coeffDict_,
00073             0.41
00074         )
00075     ),
00076     Clg1_
00077     (
00078         dimensioned<scalar>::lookupOrAddToDict
00079         (
00080             "Clg1",
00081             coeffDict_,
00082             1.8
00083         )
00084     ),
00085     Clg2_
00086     (
00087         dimensioned<scalar>::lookupOrAddToDict
00088         (
00089             "Clg2",
00090             coeffDict_,
00091             0.6
00092         )
00093     ),
00094     C1_
00095     (
00096         dimensioned<scalar>::lookupOrAddToDict
00097         (
00098             "C1",
00099             coeffDict_,
00100             1.44
00101         )
00102     ),
00103     C2_
00104     (
00105         dimensioned<scalar>::lookupOrAddToDict
00106         (
00107             "C2",
00108             coeffDict_,
00109             1.92
00110         )
00111     ),
00112     Cs_
00113     (
00114         dimensioned<scalar>::lookupOrAddToDict
00115         (
00116             "Cs",
00117             coeffDict_,
00118             0.25
00119         )
00120     ),
00121     Ceps_
00122     (
00123         dimensioned<scalar>::lookupOrAddToDict
00124         (
00125             "Ceps",
00126             coeffDict_,
00127             0.15
00128         )
00129     ),
00130     C1Ref_
00131     (
00132         dimensioned<scalar>::lookupOrAddToDict
00133         (
00134             "C1Ref",
00135             coeffDict_,
00136             0.5
00137         )
00138     ),
00139     C2Ref_
00140     (
00141         dimensioned<scalar>::lookupOrAddToDict
00142         (
00143             "C2Ref",
00144             coeffDict_,
00145             0.3
00146         )
00147     ),
00148     couplingFactor_
00149     (
00150         dimensioned<scalar>::lookupOrAddToDict
00151         (
00152             "couplingFactor",
00153             coeffDict_,
00154             0.0
00155         )
00156     ),
00157     sigmaR_
00158     (
00159         dimensioned<scalar>::lookupOrAddToDict
00160         (
00161             "sigmaR",
00162             coeffDict_,
00163             0.81967
00164         )
00165     ),
00166     sigmaEps_
00167     (
00168         dimensioned<scalar>::lookupOrAddToDict
00169         (
00170             "sigmaEps",
00171             coeffDict_,
00172             1.3
00173         )
00174     ),
00175     Prt_
00176     (
00177         dimensioned<scalar>::lookupOrAddToDict
00178         (
00179             "Prt",
00180             coeffDict_,
00181             1.0
00182         )
00183     ),
00184 
00185     y_(mesh_),
00186 
00187     R_
00188     (
00189         IOobject
00190         (
00191             "R",
00192             runTime_.timeName(),
00193             mesh_,
00194             IOobject::MUST_READ,
00195             IOobject::AUTO_WRITE
00196         ),
00197         autoCreateR("R", mesh_)
00198     ),
00199     k_
00200     (
00201         IOobject
00202         (
00203             "k",
00204             runTime_.timeName(),
00205             mesh_,
00206             IOobject::NO_READ,
00207             IOobject::AUTO_WRITE
00208         ),
00209         autoCreateK("k", mesh_)
00210     ),
00211     epsilon_
00212     (
00213         IOobject
00214         (
00215             "epsilon",
00216             runTime_.timeName(),
00217             mesh_,
00218             IOobject::NO_READ,
00219             IOobject::AUTO_WRITE
00220         ),
00221         autoCreateEpsilon("epsilon", mesh_)
00222     ),
00223     mut_
00224     (
00225         IOobject
00226         (
00227             "mut",
00228             runTime_.timeName(),
00229             mesh_,
00230             IOobject::NO_READ,
00231             IOobject::AUTO_WRITE
00232         ),
00233         autoCreateMut("mut", mesh_)
00234     ),
00235     alphat_
00236     (
00237         IOobject
00238         (
00239             "alphat",
00240             runTime_.timeName(),
00241             mesh_,
00242             IOobject::NO_READ,
00243             IOobject::AUTO_WRITE
00244         ),
00245         autoCreateAlphat("alphat", mesh_)
00246     )
00247 {
00248     if (couplingFactor_.value() < 0.0 || couplingFactor_.value() > 1.0)
00249     {
00250         FatalErrorIn
00251         (
00252             "LaunderGibsonRSTM::LaunderGibsonRSTM"
00253             "(const volScalarField&, const volVectorField&"
00254             ", const surfaceScalarField&, basicThermo&)"
00255         )   << "couplingFactor = " << couplingFactor_
00256             << " is not in range 0 - 1" << nl
00257             << exit(FatalError);
00258     }
00259 
00260     mut_ = Cmu_*rho_*sqr(k_)/(epsilon_ + epsilonSmall_);
00261     mut_.correctBoundaryConditions();
00262 
00263     alphat_ = mut_/Prt_;
00264     alphat_.correctBoundaryConditions();
00265 
00266     printCoeffs();
00267 }
00268 
00269 
00270 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00271 
00272 tmp<volSymmTensorField> LaunderGibsonRSTM::devRhoReff() const
00273 {
00274     return tmp<volSymmTensorField>
00275     (
00276         new volSymmTensorField
00277         (
00278             IOobject
00279             (
00280                 "devRhoReff",
00281                 runTime_.timeName(),
00282                 mesh_,
00283                 IOobject::NO_READ,
00284                 IOobject::NO_WRITE
00285             ),
00286             rho_*R_ - mu()*dev(twoSymm(fvc::grad(U_)))
00287         )
00288     );
00289 }
00290 
00291 
00292 tmp<fvVectorMatrix> LaunderGibsonRSTM::divDevRhoReff(volVectorField& U) const
00293 {
00294     if (couplingFactor_.value() > 0.0)
00295     {
00296         return
00297         (
00298             fvc::div(rho_*R_ + couplingFactor_*mut_*fvc::grad(U))
00299           + fvc::laplacian((1.0 - couplingFactor_)*mut_, U)
00300           - fvm::laplacian(muEff(), U)
00301           - fvc::div(mu()*dev2(fvc::grad(U)().T()))
00302         );
00303     }
00304     else
00305     {
00306         return
00307         (
00308             fvc::div(rho_*R_)
00309           + fvc::laplacian(mut_, U)
00310           - fvm::laplacian(muEff(), U)
00311           - fvc::div(mu()*dev2(fvc::grad(U)().T()))
00312         );
00313     }
00314 }
00315 
00316 
00317 bool LaunderGibsonRSTM::read()
00318 {
00319     if (RASModel::read())
00320     {
00321         Cmu_.readIfPresent(coeffDict());
00322         kappa_.readIfPresent(coeffDict());
00323         Clg1_.readIfPresent(coeffDict());
00324         Clg2_.readIfPresent(coeffDict());
00325         C1_.readIfPresent(coeffDict());
00326         C2_.readIfPresent(coeffDict());
00327         Cs_.readIfPresent(coeffDict());
00328         Ceps_.readIfPresent(coeffDict());
00329         C1Ref_.readIfPresent(coeffDict());
00330         C2Ref_.readIfPresent(coeffDict());
00331         sigmaR_.readIfPresent(coeffDict());
00332         sigmaEps_.readIfPresent(coeffDict());
00333         Prt_.readIfPresent(coeffDict());
00334 
00335         couplingFactor_.readIfPresent(coeffDict());
00336 
00337         if (couplingFactor_.value() < 0.0 || couplingFactor_.value() > 1.0)
00338         {
00339             FatalErrorIn("LaunderGibsonRSTM::read()")
00340                 << "couplingFactor = " << couplingFactor_
00341                 << " is not in range 0 - 1" << nl
00342                 << exit(FatalError);
00343         }
00344 
00345         return true;
00346     }
00347     else
00348     {
00349         return false;
00350     }
00351 }
00352 
00353 
00354 void LaunderGibsonRSTM::correct()
00355 {
00356     if (!turbulence_)
00357     {
00358         // Re-calculate viscosity
00359         mut_ = rho_*Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_);
00360         mut_.correctBoundaryConditions();
00361 
00362         // Re-calculate thermal diffusivity
00363         alphat_ = mut_/Prt_;
00364         alphat_.correctBoundaryConditions();
00365 
00366         return;
00367     }
00368 
00369     RASModel::correct();
00370 
00371     if (mesh_.changing())
00372     {
00373         y_.correct();
00374     }
00375 
00376     volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_));
00377     volScalarField G("RASModel::G", 0.5*mag(tr(P)));
00378 
00379     // Update espsilon and G at the wall
00380     epsilon_.boundaryField().updateCoeffs();
00381 
00382     // Dissipation equation
00383     tmp<fvScalarMatrix> epsEqn
00384     (
00385         fvm::ddt(rho_, epsilon_)
00386       + fvm::div(phi_, epsilon_)
00387     //- fvm::laplacian(Ceps*rho_*(k_/epsilon_)*R_, epsilon_)
00388       - fvm::laplacian(DepsilonEff(), epsilon_)
00389      ==
00390         C1_*rho_*G*epsilon_/k_
00391       - fvm::Sp(C2_*rho_*epsilon_/k_, epsilon_)
00392     );
00393 
00394     epsEqn().relax();
00395 
00396     epsEqn().boundaryManipulate(epsilon_.boundaryField());
00397 
00398     solve(epsEqn);
00399     bound(epsilon_, epsilon0_);
00400 
00401 
00402     // Reynolds stress equation
00403 
00404     const fvPatchList& patches = mesh_.boundary();
00405 
00406     forAll(patches, patchi)
00407     {
00408         const fvPatch& curPatch = patches[patchi];
00409 
00410         if (isA<wallFvPatch>(curPatch))
00411         {
00412             forAll(curPatch, facei)
00413             {
00414                 label faceCelli = curPatch.faceCells()[facei];
00415                 P[faceCelli] *=
00416                     min(G[faceCelli]/(0.5*mag(tr(P[faceCelli])) + SMALL), 100.0);
00417             }
00418         }
00419     }
00420 
00421     volSymmTensorField reflect = C1Ref_*epsilon_/k_*R_ - C2Ref_*Clg2_*dev(P);
00422 
00423     tmp<fvSymmTensorMatrix> REqn
00424     (
00425         fvm::ddt(rho_, R_)
00426       + fvm::div(phi_, R_)
00427     //- fvm::laplacian(Cs*rho_*(k_/epsilon_)*R_, R_)
00428       - fvm::laplacian(DREff(), R_)
00429       + fvm::Sp(Clg1_*rho_*epsilon_/k_, R_)
00430      ==
00431         rho_*P
00432       + (2.0/3.0*(Clg1_ - 1)*I)*rho_*epsilon_
00433       - Clg2_*rho_*dev(P)
00434 
00435         // wall reflection terms
00436       + symm
00437         (
00438             I*((y_.n() & reflect) & y_.n())
00439           - 1.5*(y_.n()*(reflect & y_.n())
00440           + (y_.n() & reflect)*y_.n())
00441         )*pow(Cmu_, 0.75)*rho_*pow(k_, 1.5)/(kappa_*y_*epsilon_)
00442     );
00443 
00444     REqn().relax();
00445     solve(REqn);
00446 
00447     R_.max
00448     (
00449         dimensionedSymmTensor
00450         (
00451             "zero",
00452             R_.dimensions(),
00453             symmTensor
00454             (
00455                 k0_.value(), -GREAT, -GREAT,
00456                 k0_.value(), -GREAT,
00457                 k0_.value()
00458             )
00459         )
00460     );
00461 
00462     k_ == 0.5*tr(R_);
00463     bound(k_, k0_);
00464 
00465 
00466     // Re-calculate turbulent viscosity
00467     mut_ = Cmu_*rho_*sqr(k_)/epsilon_;
00468     mut_.correctBoundaryConditions();
00469 
00470     // Re-calculate thermal diffusivity
00471     alphat_ = mut_/Prt_;
00472     alphat_.correctBoundaryConditions();
00473 
00474     // Correct wall shear stresses
00475 
00476     forAll(patches, patchi)
00477     {
00478         const fvPatch& curPatch = patches[patchi];
00479 
00480         if (isA<wallFvPatch>(curPatch))
00481         {
00482             symmTensorField& Rw = R_.boundaryField()[patchi];
00483 
00484             const scalarField& mutw = mut_.boundaryField()[patchi];
00485             const scalarField& rhow = rho_.boundaryField()[patchi];
00486 
00487             vectorField snGradU = U_.boundaryField()[patchi].snGrad();
00488 
00489             const vectorField& faceAreas
00490                 = mesh_.Sf().boundaryField()[patchi];
00491 
00492             const scalarField& magFaceAreas
00493                 = mesh_.magSf().boundaryField()[patchi];
00494 
00495             forAll(curPatch, facei)
00496             {
00497                 // Calculate near-wall velocity gradient
00498                 tensor gradUw
00499                     = (faceAreas[facei]/magFaceAreas[facei])*snGradU[facei];
00500 
00501                 // Calculate near-wall shear-stress tensor
00502                 tensor tauw = -(mutw[facei]/rhow[facei])*2*dev(symm(gradUw));
00503 
00504                 // Reset the shear components of the stress tensor
00505                 Rw[facei].xy() = tauw.xy();
00506                 Rw[facei].xz() = tauw.xz();
00507                 Rw[facei].yz() = tauw.yz();
00508             }
00509         }
00510     }
00511 }
00512 
00513 
00514 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00515 
00516 } // End namespace RASModels
00517 } // End namespace compressible
00518 } // End namespace Foam
00519 
00520 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines