ENH: exact restart. Fixes #1172.

This commit is contained in:
mattijs
2019-02-06 12:13:52 +00:00
parent 6922deb9fb
commit 4d82589841
2 changed files with 74 additions and 9 deletions

View File

@ -53,11 +53,39 @@ tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcNut() const
const tmp<scalarField> tnuw = turbModel.nu(patchi); const tmp<scalarField> tnuw = turbModel.nu(patchi);
const scalarField& nuw = tnuw(); const scalarField& nuw = tnuw();
return max
// Calculate new viscosity
tmp<scalarField> tnutw
( (
scalar(0), max
sqr(calcUTau(magGradU))/(magGradU + ROOTVSMALL) - nuw (
scalar(0),
sqr(calcUTau(magGradU))/(magGradU + ROOTVSMALL) - nuw
)
); );
if (tolerance_ != 0.01)
{
// User-specified tolerance. Find out if current nut already satisfies
// eqns.
// Run ut for one iteration
scalarField err;
tmp<scalarField> UTau(calcUTau(magGradU, 1, err));
// Preserve nutw if the initial error (err) already lower than the
// tolerance.
scalarField& nutw = tnutw.ref();
forAll(err, facei)
{
if (err[facei] < tolerance_)
{
nutw[facei] = this->operator[](facei);
}
}
}
return tnutw;
} }
@ -65,6 +93,18 @@ tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcUTau
( (
const scalarField& magGradU const scalarField& magGradU
) const ) const
{
scalarField err;
return calcUTau(magGradU, maxIter_, err);
}
tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcUTau
(
const scalarField& magGradU,
const label maxIter,
scalarField& err
) const
{ {
const label patchi = patch().index(); const label patchi = patch().index();
@ -89,6 +129,9 @@ tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcUTau
tmp<scalarField> tuTau(new scalarField(patch().size(), Zero)); tmp<scalarField> tuTau(new scalarField(patch().size(), Zero));
scalarField& uTau = tuTau.ref(); scalarField& uTau = tuTau.ref();
err.setSize(uTau.size());
err = 0.0;
forAll(uTau, facei) forAll(uTau, facei)
{ {
scalar ut = sqrt((nutw[facei] + nuw[facei])*magGradU[facei]); scalar ut = sqrt((nutw[facei] + nuw[facei])*magGradU[facei]);
@ -98,7 +141,6 @@ tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcUTau
if (ut > ROOTVSMALL) if (ut > ROOTVSMALL)
{ {
int iter = 0; int iter = 0;
scalar err = GREAT;
do do
{ {
@ -116,12 +158,17 @@ tmp<scalarField> nutUSpaldingWallFunctionFvPatchScalarField::calcUTau
+ 1/E_*kUu*fkUu/ut; + 1/E_*kUu*fkUu/ut;
scalar uTauNew = ut + f/df; scalar uTauNew = ut + f/df;
err = mag((ut - uTauNew)/ut); err[facei] = mag((ut - uTauNew)/ut);
ut = uTauNew; ut = uTauNew;
//iterations_++; //iterations_++;
} while (ut > ROOTVSMALL && err > tolerance_ && ++iter < maxIter_); } while
(
ut > ROOTVSMALL
&& err[facei] > tolerance_
&& ++iter < maxIter
);
uTau[facei] = max(0.0, ut); uTau[facei] = max(0.0, ut);

View File

@ -71,9 +71,18 @@ Note
Suffers from non-exact restart since correctNut() (called through Suffers from non-exact restart since correctNut() (called through
turbulence->validate) returns a slightly different value every time turbulence->validate) returns a slightly different value every time
it is called. This is since the seed for the Newton-Raphson iteration it is called. This is since the seed for the Newton-Raphson iteration
uses the current value of *this (= nut). Can be avoided by seeding the uses the current value of *this (= nut).
NR with e.g. the laminar viscosity or tightening the convergence tolerance
to e.g. 1e-7 and the max number of iterations to 100. This can be avoided by overriding the tolerance. This also switches on
a pre-detection whether the current nut already satisfies the turbulence
conditions and if so does not change it at all. This means that the nut
only changes if it 'has really changed'. This probably should be used with
a tight tolerance, e.g.
maxIter 100;
tolerance 1e-7;
to make sure to kick every iteration.
SourceFiles SourceFiles
nutUSpaldingWallFunctionFvPatchScalarField.C nutUSpaldingWallFunctionFvPatchScalarField.C
@ -123,6 +132,15 @@ protected:
//- Calculate the friction velocity //- Calculate the friction velocity
virtual tmp<scalarField> calcUTau(const scalarField& magGradU) const; virtual tmp<scalarField> calcUTau(const scalarField& magGradU) const;
//- Calculate the friction velocity and number of iterations for
// convergence
virtual tmp<scalarField> calcUTau
(
const scalarField& magGradU,
const label maxIter,
scalarField& err
) const;
//- Write local wall function variables //- Write local wall function variables
virtual void writeLocalEntries(Ostream&) const; virtual void writeLocalEntries(Ostream&) const;