TurbulenceModels::kOmegaSSTLM: New correlation-based turbulent transition model
Description
Langtry-Menter 4-equation transitional SST model
based on the k-omega-SST RAS model.
References:
Langtry, R. B., & Menter, F. R. (2009).
Correlation-based transition modeling for unstructured parallelized
computational fluid dynamics codes.
AIAA journal, 47(12), 2894-2906.
Menter, F. R., Langtry, R., & Volker, S. (2006).
Transition modelling for general purpose CFD codes.
Flow, turbulence and combustion, 77(1-4), 277-303.
Langtry, R. B. (2006).
A correlation-based transition model using local variables for
unstructured parallelized CFD codes.
Phd. Thesis, Universität Stuttgart.
Implemented by Henry G. Weller, CFD Direct in collaboration with Florian
Schwertfirm, Kreuzinger und Manhart Turbulenz GmbH.
This commit is contained in:
parent
c8f8a6c162
commit
4ad0f529a0
4 changed files with 940 additions and 0 deletions
|
|
@ -88,6 +88,9 @@ makeRASModel(kOmegaSST);
|
|||
#include "kOmegaSSTSAS.H"
|
||||
makeRASModel(kOmegaSSTSAS);
|
||||
|
||||
#include "kOmegaSSTLM.H"
|
||||
makeRASModel(kOmegaSSTLM);
|
||||
|
||||
#include "v2f.H"
|
||||
makeRASModel(v2f);
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ makeRASModel(kOmegaSST);
|
|||
#include "kOmegaSSTSAS.H"
|
||||
makeRASModel(kOmegaSSTSAS);
|
||||
|
||||
#include "kOmegaSSTLM.H"
|
||||
makeRASModel(kOmegaSSTLM);
|
||||
|
||||
#include "v2f.H"
|
||||
makeRASModel(v2f);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,627 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "kOmegaSSTLM.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField> kOmegaSSTLM<BasicTurbulenceModel>::F1
|
||||
(
|
||||
const volScalarField& CDkOmega
|
||||
) const
|
||||
{
|
||||
const volScalarField Ry(this->y_*sqrt(this->k_)/this->nu());
|
||||
const volScalarField F3(exp(-pow(Ry/120.0, 8)));
|
||||
|
||||
return max(kOmegaSST<BasicTurbulenceModel>::F1(CDkOmega), F3);
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField::Internal> kOmegaSSTLM<BasicTurbulenceModel>::Pk
|
||||
(
|
||||
const volScalarField::Internal& G
|
||||
) const
|
||||
{
|
||||
return gammaIntEff_*kOmegaSST<BasicTurbulenceModel>::Pk(G);
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField::Internal> kOmegaSSTLM<BasicTurbulenceModel>::epsilonByk
|
||||
(
|
||||
const volScalarField::Internal& F1,
|
||||
const volScalarField::Internal& F2
|
||||
) const
|
||||
{
|
||||
return
|
||||
min(max(gammaIntEff_, scalar(0.1)), scalar(1))
|
||||
*kOmegaSST<BasicTurbulenceModel>::epsilonByk(F1, F2);
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField::Internal> kOmegaSSTLM<BasicTurbulenceModel>::Fthetat
|
||||
(
|
||||
const volScalarField::Internal& Us,
|
||||
const volScalarField::Internal& Omega,
|
||||
const volScalarField::Internal& nu
|
||||
) const
|
||||
{
|
||||
const volScalarField::Internal& omega = this->omega_();
|
||||
const volScalarField::Internal& y = this->y_();
|
||||
|
||||
const volScalarField::Internal delta(375*Omega*nu*ReThetat_()*y/sqr(Us));
|
||||
const volScalarField::Internal ReOmega(sqr(y)*omega/nu);
|
||||
const volScalarField::Internal Fwake(exp(-sqr(ReOmega/1e5)));
|
||||
|
||||
return tmp<volScalarField::Internal>
|
||||
(
|
||||
new volScalarField::Internal
|
||||
(
|
||||
IOobject::groupName("Fthetat", this->U_.group()),
|
||||
min
|
||||
(
|
||||
max
|
||||
(
|
||||
Fwake*exp(-pow4((y/delta))),
|
||||
(1 - sqr((gammaInt_() - 1.0/ce2_)/(1 - 1.0/ce2_)))
|
||||
),
|
||||
scalar(1)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField::Internal>
|
||||
kOmegaSSTLM<BasicTurbulenceModel>::ReThetac() const
|
||||
{
|
||||
tmp<volScalarField::Internal> tReThetac
|
||||
(
|
||||
new volScalarField::Internal
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("ReThetac", this->U_.group()),
|
||||
this->runTime_.timeName(),
|
||||
this->mesh_
|
||||
),
|
||||
this->mesh_,
|
||||
dimless
|
||||
)
|
||||
);
|
||||
volScalarField::Internal& ReThetac = tReThetac.ref();
|
||||
|
||||
forAll(ReThetac, celli)
|
||||
{
|
||||
const scalar ReThetat = ReThetat_[celli];
|
||||
|
||||
ReThetac[celli] =
|
||||
ReThetat <= 1870
|
||||
?
|
||||
ReThetat
|
||||
- 396.035e-2
|
||||
+ 120.656e-4*ReThetat
|
||||
- 868.230e-6*sqr(ReThetat)
|
||||
+ 696.506e-9*pow3(ReThetat)
|
||||
- 174.105e-12*pow4(ReThetat)
|
||||
:
|
||||
ReThetat - 593.11 - 0.482*(ReThetat - 1870);
|
||||
}
|
||||
|
||||
return tReThetac;
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField::Internal> kOmegaSSTLM<BasicTurbulenceModel>::Flength
|
||||
(
|
||||
const volScalarField::Internal& nu
|
||||
) const
|
||||
{
|
||||
tmp<volScalarField::Internal> tFlength
|
||||
(
|
||||
new volScalarField::Internal
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("Flength", this->U_.group()),
|
||||
this->runTime_.timeName(),
|
||||
this->mesh_
|
||||
),
|
||||
this->mesh_,
|
||||
dimless
|
||||
)
|
||||
);
|
||||
volScalarField::Internal& Flength = tFlength.ref();
|
||||
|
||||
const volScalarField::Internal& omega = this->omega_();
|
||||
const volScalarField::Internal& y = this->y_();
|
||||
|
||||
forAll(ReThetat_, celli)
|
||||
{
|
||||
const scalar ReThetat = ReThetat_[celli];
|
||||
|
||||
if (ReThetat < 400)
|
||||
{
|
||||
Flength[celli] =
|
||||
398.189e-1
|
||||
- 119.270e-4*ReThetat
|
||||
- 132.567e-6*sqr(ReThetat);
|
||||
}
|
||||
else if (ReThetat < 596)
|
||||
{
|
||||
Flength[celli] =
|
||||
263.404
|
||||
- 123.939e-2*ReThetat
|
||||
+ 194.548e-5*sqr(ReThetat)
|
||||
- 101.695e-8*pow3(ReThetat);
|
||||
}
|
||||
else if (ReThetat < 1200)
|
||||
{
|
||||
Flength[celli] = 0.5 - 3e-4*(ReThetat - 596);
|
||||
}
|
||||
else
|
||||
{
|
||||
Flength[celli] = 0.3188;
|
||||
}
|
||||
|
||||
const scalar Fsublayer =
|
||||
exp(-sqr(sqr(y[celli])*omega[celli]/(300*nu[celli])));
|
||||
|
||||
Flength[celli] = Flength[celli]*(1 - Fsublayer) + 40*Fsublayer;
|
||||
}
|
||||
|
||||
return tFlength;
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField::Internal> kOmegaSSTLM<BasicTurbulenceModel>::ReThetat0
|
||||
(
|
||||
const volScalarField::Internal& Us,
|
||||
const volScalarField::Internal& dUsds,
|
||||
const volScalarField::Internal& nu
|
||||
) const
|
||||
{
|
||||
tmp<volScalarField::Internal> tReThetat0
|
||||
(
|
||||
new volScalarField::Internal
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("ReThetat0", this->U_.group()),
|
||||
this->runTime_.timeName(),
|
||||
this->mesh_
|
||||
),
|
||||
this->mesh_,
|
||||
dimless
|
||||
)
|
||||
);
|
||||
volScalarField::Internal& ReThetat0 = tReThetat0.ref();
|
||||
|
||||
const volScalarField& k = this->k_;
|
||||
|
||||
label maxIter = 0;
|
||||
|
||||
forAll(ReThetat0, celli)
|
||||
{
|
||||
const scalar Tu
|
||||
(
|
||||
max(100*sqrt((2.0/3.0)*k[celli])/Us[celli], scalar(0.027))
|
||||
);
|
||||
|
||||
// Initialize lambda to zero.
|
||||
// If lambda were cached between time-steps convergence would be faster
|
||||
// starting from the previous time-step value.
|
||||
scalar lambda = 0;
|
||||
|
||||
scalar lambdaErr;
|
||||
scalar thetat;
|
||||
label iter = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// Previous iteration lambda for convergence test
|
||||
const scalar lambda0 = lambda;
|
||||
|
||||
if (Tu <= 1.3)
|
||||
{
|
||||
const scalar Flambda =
|
||||
dUsds[celli] <= 0
|
||||
?
|
||||
1
|
||||
- (
|
||||
- 12.986*lambda
|
||||
- 123.66*sqr(lambda)
|
||||
- 405.689*pow3(lambda)
|
||||
)*exp(-pow(Tu/1.5, 1.5))
|
||||
:
|
||||
1
|
||||
+ 0.275*(1 - exp(-35*lambda))
|
||||
*exp(-Tu/0.5);
|
||||
|
||||
thetat =
|
||||
(1173.51 - 589.428*Tu + 0.2196/sqr(Tu))
|
||||
*Flambda*nu[celli]
|
||||
/Us[celli];
|
||||
}
|
||||
else
|
||||
{
|
||||
const scalar Flambda =
|
||||
dUsds[celli] <= 0
|
||||
?
|
||||
1
|
||||
- (
|
||||
-12.986*lambda
|
||||
-123.66*sqr(lambda)
|
||||
-405.689*pow3(lambda)
|
||||
)*exp(-pow(Tu/1.5, 1.5))
|
||||
:
|
||||
1
|
||||
+ 0.275*(1 - exp(-35*lambda))
|
||||
*exp(-2*Tu);
|
||||
|
||||
thetat =
|
||||
331.50*pow((Tu - 0.5658), -0.671)
|
||||
*Flambda*nu[celli]/Us[celli];
|
||||
}
|
||||
|
||||
lambda = sqr(thetat)/nu[celli]*dUsds[celli];
|
||||
lambda = max(min(lambda, 0.1), -0.1);
|
||||
|
||||
lambdaErr = mag(lambda - lambda0);
|
||||
|
||||
maxIter = max(maxIter, ++iter);
|
||||
|
||||
} while (lambdaErr > lambdaErr_);
|
||||
|
||||
ReThetat0[celli] = max(thetat*Us[celli]/nu[celli], scalar(20));
|
||||
}
|
||||
|
||||
if (maxIter > maxLambdaIter_)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Number of lambda iterations exceeds maxLambdaIter("
|
||||
<< maxLambdaIter_ << ')'<< endl;
|
||||
}
|
||||
|
||||
return tReThetat0;
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
tmp<volScalarField::Internal> kOmegaSSTLM<BasicTurbulenceModel>::Fonset
|
||||
(
|
||||
const volScalarField::Internal& Rev,
|
||||
const volScalarField::Internal& ReThetac,
|
||||
const volScalarField::Internal& RT
|
||||
) const
|
||||
{
|
||||
const volScalarField::Internal Fonset1(Rev/(2.193*ReThetac));
|
||||
|
||||
const volScalarField::Internal Fonset2
|
||||
(
|
||||
min(max(Fonset1, pow4(Fonset1)), scalar(2))
|
||||
);
|
||||
|
||||
const volScalarField::Internal Fonset3(max(1 - pow3(RT/2.5), scalar(0)));
|
||||
|
||||
return tmp<volScalarField::Internal>
|
||||
(
|
||||
new volScalarField::Internal
|
||||
(
|
||||
IOobject::groupName("Fonset", this->U_.group()),
|
||||
max(Fonset2 - Fonset3, scalar(0))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
kOmegaSSTLM<BasicTurbulenceModel>::kOmegaSSTLM
|
||||
(
|
||||
const alphaField& alpha,
|
||||
const rhoField& rho,
|
||||
const volVectorField& U,
|
||||
const surfaceScalarField& alphaRhoPhi,
|
||||
const surfaceScalarField& phi,
|
||||
const transportModel& transport,
|
||||
const word& propertiesName,
|
||||
const word& type
|
||||
)
|
||||
:
|
||||
kOmegaSST<BasicTurbulenceModel>
|
||||
(
|
||||
alpha,
|
||||
rho,
|
||||
U,
|
||||
alphaRhoPhi,
|
||||
phi,
|
||||
transport,
|
||||
propertiesName
|
||||
),
|
||||
|
||||
ca1_
|
||||
(
|
||||
dimensionedScalar::lookupOrAddToDict
|
||||
(
|
||||
"ca1",
|
||||
this->coeffDict_,
|
||||
2
|
||||
)
|
||||
),
|
||||
ca2_
|
||||
(
|
||||
dimensionedScalar::lookupOrAddToDict
|
||||
(
|
||||
"ca2",
|
||||
this->coeffDict_,
|
||||
0.06
|
||||
)
|
||||
),
|
||||
ce1_
|
||||
(
|
||||
dimensionedScalar::lookupOrAddToDict
|
||||
(
|
||||
"ce1",
|
||||
this->coeffDict_,
|
||||
1
|
||||
)
|
||||
),
|
||||
ce2_
|
||||
(
|
||||
dimensionedScalar::lookupOrAddToDict
|
||||
(
|
||||
"ce2",
|
||||
this->coeffDict_,
|
||||
50
|
||||
)
|
||||
),
|
||||
cThetat_
|
||||
(
|
||||
dimensionedScalar::lookupOrAddToDict
|
||||
(
|
||||
"cThetat",
|
||||
this->coeffDict_,
|
||||
0.03
|
||||
)
|
||||
),
|
||||
sigmaThetat_
|
||||
(
|
||||
dimensionedScalar::lookupOrAddToDict
|
||||
(
|
||||
"sigmaThetat",
|
||||
this->coeffDict_,
|
||||
2
|
||||
)
|
||||
),
|
||||
lambdaErr_
|
||||
(
|
||||
this->coeffDict_.lookupOrDefault("lambdaErr", 1e-6)
|
||||
),
|
||||
maxLambdaIter_
|
||||
(
|
||||
this->coeffDict_.lookupOrDefault("maxLambdaIter", 10)
|
||||
),
|
||||
deltaU_("deltaU", dimVelocity, SMALL),
|
||||
|
||||
ReThetat_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("ReThetat", U.group()),
|
||||
this->runTime_.timeName(),
|
||||
this->mesh_,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
this->mesh_
|
||||
),
|
||||
|
||||
gammaInt_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("gammaInt", U.group()),
|
||||
this->runTime_.timeName(),
|
||||
this->mesh_,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
this->mesh_
|
||||
),
|
||||
|
||||
gammaIntEff_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("gammaIntEff", U.group()),
|
||||
this->runTime_.timeName(),
|
||||
this->mesh_
|
||||
),
|
||||
this->mesh_,
|
||||
dimensionedScalar("0", dimless, 0)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
bool kOmegaSSTLM<BasicTurbulenceModel>::read()
|
||||
{
|
||||
if (kOmegaSST<BasicTurbulenceModel>::read())
|
||||
{
|
||||
ca1_.readIfPresent(this->coeffDict());
|
||||
ca2_.readIfPresent(this->coeffDict());
|
||||
ce1_.readIfPresent(this->coeffDict());
|
||||
ce2_.readIfPresent(this->coeffDict());
|
||||
sigmaThetat_.readIfPresent(this->coeffDict());
|
||||
cThetat_.readIfPresent(this->coeffDict());
|
||||
this->coeffDict().readIfPresent("lambdaErr", lambdaErr_);
|
||||
this->coeffDict().readIfPresent("maxLambdaIter", maxLambdaIter_);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
void kOmegaSSTLM<BasicTurbulenceModel>::correctReThetatGammaInt()
|
||||
{
|
||||
// Local references
|
||||
const alphaField& alpha = this->alpha_;
|
||||
const rhoField& rho = this->rho_;
|
||||
const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_;
|
||||
const volVectorField& U = this->U_;
|
||||
const volScalarField& k = this->k_;
|
||||
const volScalarField& omega = this->omega_;
|
||||
const tmp<volScalarField> tnu = this->nu();
|
||||
const volScalarField::Internal& nu = tnu()();
|
||||
const volScalarField::Internal& y = this->y_();
|
||||
fv::options& fvOptions(fv::options::New(this->mesh_));
|
||||
|
||||
// Fields derived from the velocity gradient
|
||||
tmp<volTensorField> tgradU = fvc::grad(U);
|
||||
const volScalarField::Internal Omega(sqrt(2*magSqr(skew(tgradU()()))));
|
||||
const volScalarField::Internal S(sqrt(2*magSqr(symm(tgradU()()))));
|
||||
const volScalarField::Internal Us(max(mag(U()), deltaU_));
|
||||
const volScalarField::Internal dUsds((U() & (U() & tgradU()()))/sqr(Us));
|
||||
tgradU.clear();
|
||||
|
||||
const volScalarField::Internal Fthetat(this->Fthetat(Us, Omega, nu));
|
||||
|
||||
{
|
||||
const volScalarField::Internal t(500*nu/sqr(Us));
|
||||
const volScalarField::Internal Pthetat
|
||||
(
|
||||
alpha()*rho()*(cThetat_/t)*(1 - Fthetat)
|
||||
);
|
||||
|
||||
// Transition onset momentum-thickness Reynolds number equation
|
||||
tmp<fvScalarMatrix> ReThetatEqn
|
||||
(
|
||||
fvm::ddt(alpha, rho, ReThetat_)
|
||||
+ fvm::div(alphaRhoPhi, ReThetat_)
|
||||
- fvm::laplacian(alpha*rho*DReThetatEff(), ReThetat_)
|
||||
==
|
||||
Pthetat*ReThetat0(Us, dUsds, nu) - fvm::Sp(Pthetat, ReThetat_)
|
||||
+ fvOptions(alpha, rho, ReThetat_)
|
||||
);
|
||||
|
||||
ReThetatEqn.ref().relax();
|
||||
fvOptions.constrain(ReThetatEqn.ref());
|
||||
solve(ReThetatEqn);
|
||||
fvOptions.correct(ReThetat_);
|
||||
bound(ReThetat_, 0);
|
||||
}
|
||||
|
||||
const volScalarField::Internal ReThetac(this->ReThetac());
|
||||
const volScalarField::Internal Rev(sqr(y)*S/nu);
|
||||
const volScalarField::Internal RT(k()/(nu*omega()));
|
||||
|
||||
{
|
||||
const volScalarField::Internal Pgamma
|
||||
(
|
||||
alpha()*rho()
|
||||
*ca1_*Flength(nu)*S*sqrt(gammaInt_()*Fonset(Rev, ReThetac, RT))
|
||||
);
|
||||
|
||||
const volScalarField::Internal Fturb(exp(-pow4(0.25*RT)));
|
||||
|
||||
const volScalarField::Internal Egamma
|
||||
(
|
||||
alpha()*rho()*ca2_*Omega*Fturb*gammaInt_()
|
||||
);
|
||||
|
||||
// Intermittency equation
|
||||
tmp<fvScalarMatrix> gammaIntEqn
|
||||
(
|
||||
fvm::ddt(alpha, rho, gammaInt_)
|
||||
+ fvm::div(alphaRhoPhi, gammaInt_)
|
||||
- fvm::laplacian(alpha*rho*DgammaIntEff(), gammaInt_)
|
||||
==
|
||||
Pgamma - fvm::Sp(ce1_*Pgamma, gammaInt_)
|
||||
+ Egamma - fvm::Sp(ce2_*Egamma, gammaInt_)
|
||||
+ fvOptions(alpha, rho, gammaInt_)
|
||||
);
|
||||
|
||||
gammaIntEqn.ref().relax();
|
||||
fvOptions.constrain(gammaIntEqn.ref());
|
||||
solve(gammaIntEqn);
|
||||
fvOptions.correct(gammaInt_);
|
||||
bound(gammaInt_, 0);
|
||||
}
|
||||
|
||||
const volScalarField::Internal Freattach(exp(-pow4(RT/20.0)));
|
||||
const volScalarField::Internal gammaSep
|
||||
(
|
||||
min(2*max(Rev/(3.235*ReThetac) - 1, scalar(0))*Freattach, scalar(2))
|
||||
*Fthetat
|
||||
);
|
||||
|
||||
gammaIntEff_ = max(gammaInt_(), gammaSep);
|
||||
}
|
||||
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
void kOmegaSSTLM<BasicTurbulenceModel>::correct()
|
||||
{
|
||||
if (!this->turbulence_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Correct ReThetat and gammaInt
|
||||
correctReThetatGammaInt();
|
||||
|
||||
// Correct k and omega
|
||||
kOmegaSST<BasicTurbulenceModel>::correct();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::RASModels::kOmegaSSTLM
|
||||
|
||||
Group
|
||||
grpLESTurbulence
|
||||
|
||||
Description
|
||||
Langtry-Menter 4-equation transitional SST model
|
||||
based on the k-omega-SST RAS model.
|
||||
|
||||
References:
|
||||
\verbatim
|
||||
Langtry, R. B., & Menter, F. R. (2009).
|
||||
Correlation-based transition modeling for unstructured parallelized
|
||||
computational fluid dynamics codes.
|
||||
AIAA journal, 47(12), 2894-2906.
|
||||
|
||||
Menter, F. R., Langtry, R., & Volker, S. (2006).
|
||||
Transition modelling for general purpose CFD codes.
|
||||
Flow, turbulence and combustion, 77(1-4), 277-303.
|
||||
|
||||
Langtry, R. B. (2006).
|
||||
A correlation-based transition model using local variables for
|
||||
unstructured parallelized CFD codes.
|
||||
Phd. Thesis, Universität Stuttgart.
|
||||
\endverbatim
|
||||
|
||||
The model coefficients are
|
||||
\verbatim
|
||||
kOmegaSSTCoeffs
|
||||
{
|
||||
// Default SST coefficients
|
||||
alphaK1 0.85;
|
||||
alphaK2 1;
|
||||
alphaOmega1 0.5;
|
||||
alphaOmega2 0.856;
|
||||
beta1 0.075;
|
||||
beta2 0.0828;
|
||||
betaStar 0.09;
|
||||
gamma1 5/9;
|
||||
gamma2 0.44;
|
||||
a1 0.31;
|
||||
b1 1;
|
||||
c1 10;
|
||||
F3 no;
|
||||
|
||||
// Default LM coefficients
|
||||
ca1 2;
|
||||
ca2 0.06;
|
||||
ce1 1;
|
||||
ce2 50;
|
||||
cThetat 0.03;
|
||||
sigmaThetat 2;
|
||||
|
||||
lambdaErr 1e-6;
|
||||
maxLambdaIter 10;
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
SourceFiles
|
||||
kOmegaSSTLM.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef kOmegaSSTLM_H
|
||||
#define kOmegaSSTLM_H
|
||||
|
||||
#include "kOmegaSST.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class kOmegaSSTLM Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class BasicTurbulenceModel>
|
||||
class kOmegaSSTLM
|
||||
:
|
||||
public kOmegaSST<BasicTurbulenceModel>
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
// Disallow default bitwise copy construct and assignment
|
||||
kOmegaSSTLM(const kOmegaSSTLM&);
|
||||
void operator=(const kOmegaSSTLM&);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
// Model constants
|
||||
|
||||
dimensionedScalar ca1_;
|
||||
dimensionedScalar ca2_;
|
||||
|
||||
dimensionedScalar ce1_;
|
||||
dimensionedScalar ce2_;
|
||||
|
||||
dimensionedScalar cThetat_;
|
||||
dimensionedScalar sigmaThetat_;
|
||||
|
||||
//- Convergence criterion for the lambda/thetat loop
|
||||
scalar lambdaErr_;
|
||||
|
||||
//- Maximum number of iterations to converge the lambda/thetat loop
|
||||
label maxLambdaIter_;
|
||||
|
||||
//- Stabilization for division by the magnitude of the velocity
|
||||
const dimensionedScalar deltaU_;
|
||||
|
||||
|
||||
// Fields
|
||||
|
||||
//- Transition onset momentum-thickness Reynolds number
|
||||
volScalarField ReThetat_;
|
||||
|
||||
//- Intermittency
|
||||
volScalarField gammaInt_;
|
||||
|
||||
//- Effective intermittency
|
||||
volScalarField::Internal gammaIntEff_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Modified form of the k-omega SST F1 function
|
||||
virtual tmp<volScalarField> F1(const volScalarField& CDkOmega) const;
|
||||
|
||||
//- Modified form of the k-omega SST k production rate
|
||||
virtual tmp<volScalarField::Internal> Pk
|
||||
(
|
||||
const volScalarField::Internal& G
|
||||
) const;
|
||||
|
||||
//- Modified form of the k-omega SST epsilon/k
|
||||
virtual tmp<volScalarField::Internal> epsilonByk
|
||||
(
|
||||
const volScalarField::Internal& F1,
|
||||
const volScalarField::Internal& F2
|
||||
) const;
|
||||
|
||||
//- Freestream blending-function
|
||||
tmp<volScalarField::Internal> Fthetat
|
||||
(
|
||||
const volScalarField::Internal& Us,
|
||||
const volScalarField::Internal& Omega,
|
||||
const volScalarField::Internal& nu
|
||||
) const;
|
||||
|
||||
//- Empirical correlation for critical Reynolds number where the
|
||||
// intermittency first starts to increase in the boundary layer
|
||||
tmp<volScalarField::Internal> ReThetac() const;
|
||||
|
||||
//- Empirical correlation that controls the length of the
|
||||
// transition region
|
||||
tmp<volScalarField::Internal> Flength
|
||||
(
|
||||
const volScalarField::Internal& nu
|
||||
) const;
|
||||
|
||||
//- Transition onset location control function
|
||||
tmp<volScalarField::Internal> Fonset
|
||||
(
|
||||
const volScalarField::Internal& Rev,
|
||||
const volScalarField::Internal& ReThetac,
|
||||
const volScalarField::Internal& RT
|
||||
) const;
|
||||
|
||||
//- Return the transition onset momentum-thickness Reynolds number
|
||||
// (based on freestream conditions)
|
||||
tmp<volScalarField::Internal> ReThetat0
|
||||
(
|
||||
const volScalarField::Internal& Us,
|
||||
const volScalarField::Internal& dUsds,
|
||||
const volScalarField::Internal& nu
|
||||
) const;
|
||||
|
||||
//- Solve the turbulence equations and correct the turbulence viscosity
|
||||
void correctReThetatGammaInt();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef typename BasicTurbulenceModel::alphaField alphaField;
|
||||
typedef typename BasicTurbulenceModel::rhoField rhoField;
|
||||
typedef typename BasicTurbulenceModel::transportModel transportModel;
|
||||
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("kOmegaSSTLM");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
kOmegaSSTLM
|
||||
(
|
||||
const alphaField& alpha,
|
||||
const rhoField& rho,
|
||||
const volVectorField& U,
|
||||
const surfaceScalarField& alphaRhoPhi,
|
||||
const surfaceScalarField& phi,
|
||||
const transportModel& transport,
|
||||
const word& propertiesName = turbulenceModel::propertiesName,
|
||||
const word& type = typeName
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~kOmegaSSTLM()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Re-read model coefficients if they have changed
|
||||
virtual bool read();
|
||||
|
||||
//- Access function transition onset momentum-thickness Reynolds number
|
||||
const volScalarField& ReThetat() const
|
||||
{
|
||||
return ReThetat_;
|
||||
}
|
||||
|
||||
//- Access function to intermittency
|
||||
const volScalarField& gammaInt() const
|
||||
{
|
||||
return gammaInt_;
|
||||
}
|
||||
|
||||
//- Return the effective diffusivity for transition onset
|
||||
// momentum-thickness Reynolds number
|
||||
tmp<volScalarField> DReThetatEff() const
|
||||
{
|
||||
return tmp<volScalarField>
|
||||
(
|
||||
new volScalarField
|
||||
(
|
||||
"DReThetatEff",
|
||||
sigmaThetat_*(this->nut_ + this->nu())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//- Return the effective diffusivity for intermittency
|
||||
tmp<volScalarField> DgammaIntEff() const
|
||||
{
|
||||
return tmp<volScalarField>
|
||||
(
|
||||
new volScalarField
|
||||
(
|
||||
"DgammaIntEff",
|
||||
this->nut_ + this->nu()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//- Solve the turbulence equations and correct the turbulence viscosity
|
||||
virtual void correct();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "kOmegaSSTLM.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
Loading…
Add table
Reference in a new issue