limited gradient schemes in openfoam
Post on 19-Jan-2015
1.523 Views
Preview:
DESCRIPTION
TRANSCRIPT
OpenFOAM
Limited Version of Gradient Schemes
Fumiya Nozaki
Last Updated: 17 June 2014
English
Keywords: • cellLimited
2
Cell or Face limited version of gradient schemes
Four different types of limiters are available for the gradient schemes
• cellLimited • cellMDLimited • faceLimited • faceMDLimited
Usage
gradSchemes { grad(p) cellLimited Gauss linear 1; }
Four choices k: A parameter to control the degree of limiting operation
3
Effects of the controlling parameter k
gradSchemes { grad(p) cellLimited Gauss linear 1; }
0 1
This parameter ranges from 0 to 1
No limiting operations
Full limiting operations
Stability
Accuracy
4
Let’s look into the code!
5
1. CellLimited Scheme
Source code: OpenFOAM-2.3.x/src/finiteVolume/finiteVolume/ gradSchemes/limitedGradSchemes/cellLimitedGrad
6
tmp<volVectorField> tGrad = basicGradScheme_().calcGrad(vsf, name);
if (k_ < SMALL)
{
return tGrad;
}
volVectorField& g = tGrad();
const labelUList& owner = mesh.owner(); Label list of owner cells
const labelUList& neighbour = mesh.neighbour();
Label list of neighbour cells
const volVectorField& C = mesh.C(); Cell center coordinates
const surfaceVectorField& Cf = mesh.Cf(); Face center coordinates
scalarField maxVsf(vsf.internalField());
scalarField minVsf(vsf.internalField());
If the parameter value is set to “0”, the limiting operation is completely deactivated.
SMALL = 1.0e-15
Gradient value without limiting operations
Variable declarations
They are used to calculate the limiter.
7
forAll(owner, facei)
{
label own = owner[facei];
label nei = neighbour[facei];
scalar vsfOwn = vsf[own];
scalar vsfNei = vsf[nei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
maxVsf[nei] = max(maxVsf[nei], vsfOwn);
minVsf[nei] = min(minVsf[nei], vsfOwn);
}
Calculation of “maxVsf” and “minVsf” (Internal face loop)
Loop through the internal faces
vsfOwn vsfNei
Values at cell centers
facei
maxVsf [N-th cell] = max vsf[cellI]
• At the end of the above loop we get the following relationships:
cellI ∈ SN
minVsf [N-th cell] = min vsf[cellI]
cellI ∈ SN
N
SN includes N-th cell and adjacent cells
8
Calculation of “maxVsf” and “minVsf” (Boundary face loop)
const volScalarField::GeometricBoundaryField& bsf = vsf.boundaryField();
forAll(bsf, patchi)
{
const fvPatchScalarField& psf = bsf[patchi];
const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
if (psf.coupled())
{
const scalarField psfNei(psf.patchNeighbourField());
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
scalar vsfNei = psfNei[pFacei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
}
}
else
{
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
scalar vsfNei = psf[pFacei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
}
}
}
Loop through the boundary faces on the coupled patches
Loop through the boundary faces on the other patches
• Put Then ... (Cont’d)
9
maxVsf -= vsf;
minVsf -= vsf;
if (k_ < 1.0)
{
const scalarField maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
maxVsf += maxMinVsf;
minVsf -= maxMinVsf;
//maxVsf *= 1.0/k_;
//minVsf *= 1.0/k_;
}
Calculation of the final values of “maxVsf” and “minVsf”
maxV[N] = max { max vsf[cellI],max psf[pFacei] } cellI ∈ SN
N
pFacei ∈ PN
PN: Set of the faces of N-th cell that are also boundary faces
minV[N] = min { min vsf[cellI],min psf[pFacei] }
cellI ∈ SN pFacei ∈ PN
pFacei
10
Then we can write as shown below:
maxVsf[N] = maxV[N] – vsf[N] + 1
𝑘− 1 × (maxV[N] – minV[N])
minVsf[N] = minV[N] – vsf[N] - 1
𝑘− 1 × (maxV[N] – minV[N])
• maxVsf[N] ≧ 0 and minVsf[N] ≦ 0
• As the parameter k_ approaches 0, the absolute values of maxVsf[N]
and minVsf[N] increase.
maxVsf -= vsf;
minVsf -= vsf;
if (k_ < 1.0)
{
const scalarField maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
maxVsf += maxMinVsf;
minVsf -= maxMinVsf;
//maxVsf *= 1.0/k_;
//minVsf *= 1.0/k_;
}
11
// create limiter
scalarField limiter(vsf.internalField().size(), 1.0);
forAll(owner, facei)
{
label own = owner[facei];
label nei = neighbour[facei];
// owner side
limitFace
(
limiter[own],
maxVsf[own],
minVsf[own],
(Cf[facei] - C[own]) & g[own]
);
// neighbour side
limitFace
(
limiter[nei],
maxVsf[nei],
minVsf[nei],
(Cf[facei] - C[nei]) & g[nei]
);
}
Calculation of “limiter”
Initial value
Loop through the internal faces
Call limitFace() and calculate limiter values
C[own] C[nei]
facei Cf[facei]
12
limitFace
template<>
inline void cellLimitedGrad<scalar>::limitFace
(
scalar& limiter,
const scalar& maxDelta,
const scalar& minDelta,
const scalar& extrapolate
)
{
if (extrapolate > maxDelta + VSMALL)
{
limiter = min(limiter, maxDelta/extrapolate);
}
else if (extrapolate < minDelta - VSMALL)
{
limiter = min(limiter, minDelta/extrapolate);
}
}
cellLimitedGrad.H
13
limitFace
maxDelta
minDelta
extrapolate
extrapolate > maxDelta
limiter = min(limiter, maxDelta/extrapolate)
Then, limiter × extrapolate ≦ maxDelta.
14
limitFace
r & g[own] > maxVsf[own]
limiter[own] = min(limiter[own], maxVsf[own]/r & g[own])
Then, r & g[own]*limiter[own] ≦ maxVsf[own]
maxVsf[own]
minVsf[own]
r & g[own]
𝒓
Cf[facei] C[own]
vsf[own]
vsf[nei]
15
maxVsf[own]
r & g[own]
vsf[own]
vsf[nei]
Clipped part
Visualization of effects of k
As k approaches 1, maxVsf[own] decreases
16
maxVsf[own]
r & g[own]
vsf[own]
vsf[nei]
Clipped part
As k approaches 1, the limiter has further limiting effect
Visualization of effects of k
17
g.internalField() *= limiter;
g.correctBoundaryConditions();
gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
return tGrad;
Calculation of limited gradient
Limited gradient value = Gradient value without limiting operations * limiter
g * limiter
Limiter equally clips each component of the gradient
18 18
2. CellMDLimited Scheme
Source code: OpenFOAM-2.3.x/src/finiteVolume/finiteVolume/ gradSchemes/limitedGradSchemes/cellMDLimitedGrad
19
This chapter will be updated as
soon as possible.
top related