00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00042
00043 defineTypeNameAndDebug(LaunderGibsonRSTM, 0);
00044 addToRunTimeSelectionTable(RASModel, LaunderGibsonRSTM, dictionary);
00045
00046
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
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
00359 mut_ = rho_*Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_);
00360 mut_.correctBoundaryConditions();
00361
00362
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
00380 epsilon_.boundaryField().updateCoeffs();
00381
00382
00383 tmp<fvScalarMatrix> epsEqn
00384 (
00385 fvm::ddt(rho_, epsilon_)
00386 + fvm::div(phi_, epsilon_)
00387
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
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
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
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
00467 mut_ = Cmu_*rho_*sqr(k_)/epsilon_;
00468 mut_.correctBoundaryConditions();
00469
00470
00471 alphat_ = mut_/Prt_;
00472 alphat_.correctBoundaryConditions();
00473
00474
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
00498 tensor gradUw
00499 = (faceAreas[facei]/magFaceAreas[facei])*snGradU[facei];
00500
00501
00502 tensor tauw = -(mutw[facei]/rhow[facei])*2*dev(symm(gradUw));
00503
00504
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 }
00517 }
00518 }
00519
00520