Merge branch 'master' of /home/dm4/OpenFOAM/OpenFOAM-dev

This commit is contained in:
mattijs
2013-10-29 09:18:25 +00:00
40 changed files with 573 additions and 958 deletions

View File

@ -220,6 +220,7 @@ fields/surfaceFields/surfaceFields.C
fvMatrices/fvMatrices.C
fvMatrices/fvScalarMatrix/fvScalarMatrix.C
fvMatrices/solvers/MULES/MULES.C
fvMatrices/solvers/MULES/CMULES.C
fvMatrices/solvers/MULES/IMULES.C
fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C

View File

@ -38,7 +38,7 @@ interstitialInletVelocityFvPatchVectorField
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchField<vector>(p, iF),
fixedValueFvPatchVectorField(p, iF),
inletVelocity_(p.size(), vector::zero),
alphaName_("alpha")
{}
@ -53,8 +53,8 @@ interstitialInletVelocityFvPatchVectorField
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchField<vector>(ptf, p, iF, mapper),
inletVelocity_(ptf.inletVelocity_),
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
inletVelocity_(ptf.inletVelocity_, mapper),
alphaName_(ptf.alphaName_)
{}
@ -67,7 +67,7 @@ interstitialInletVelocityFvPatchVectorField
const dictionary& dict
)
:
fixedValueFvPatchField<vector>(p, iF, dict),
fixedValueFvPatchVectorField(p, iF, dict),
inletVelocity_("inletVelocity", dict, p.size()),
alphaName_(dict.lookupOrDefault<word>("alpha", "alpha"))
{}
@ -79,7 +79,7 @@ interstitialInletVelocityFvPatchVectorField
const interstitialInletVelocityFvPatchVectorField& ptf
)
:
fixedValueFvPatchField<vector>(ptf),
fixedValueFvPatchVectorField(ptf),
inletVelocity_(ptf.inletVelocity_),
alphaName_(ptf.alphaName_)
{}
@ -92,7 +92,7 @@ interstitialInletVelocityFvPatchVectorField
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchField<vector>(ptf, iF),
fixedValueFvPatchVectorField(ptf, iF),
inletVelocity_(ptf.inletVelocity_),
alphaName_(ptf.alphaName_)
{}
@ -100,6 +100,31 @@ interstitialInletVelocityFvPatchVectorField
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::interstitialInletVelocityFvPatchVectorField::autoMap
(
const fvPatchFieldMapper& m
)
{
fixedValueFvPatchVectorField::autoMap(m);
inletVelocity_.autoMap(m);
}
void Foam::interstitialInletVelocityFvPatchVectorField::rmap
(
const fvPatchVectorField& ptf,
const labelList& addr
)
{
fixedValueFvPatchVectorField::rmap(ptf, addr);
const interstitialInletVelocityFvPatchVectorField& tiptf =
refCast<const interstitialInletVelocityFvPatchVectorField>(ptf);
inletVelocity_.rmap(tiptf.inletVelocity_, addr);
}
void Foam::interstitialInletVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
@ -111,7 +136,7 @@ void Foam::interstitialInletVelocityFvPatchVectorField::updateCoeffs()
patch().lookupPatchField<volScalarField, scalar>(alphaName_);
operator==(inletVelocity_/alphap);
fixedValueFvPatchField<vector>::updateCoeffs();
fixedValueFvPatchVectorField::updateCoeffs();
}

View File

@ -141,8 +141,26 @@ public:
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchVectorField&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;

View File

@ -198,7 +198,6 @@ tmp<surfaceScalarField> CoEulerDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> CoEulerDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -206,6 +205,13 @@ tmp<surfaceScalarField> CoEulerDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> CoEulerDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> CoEulerDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -270,7 +270,6 @@ tmp<surfaceScalarField> CrankNicolsonDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> CrankNicolsonDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -278,6 +277,13 @@ tmp<surfaceScalarField> CrankNicolsonDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> CrankNicolsonDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> CrankNicolsonDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -176,7 +176,6 @@ tmp<surfaceScalarField> EulerDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> EulerDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -184,6 +183,13 @@ tmp<surfaceScalarField> EulerDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> EulerDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> EulerDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -199,7 +199,6 @@ tmp<surfaceScalarField> SLTSDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> SLTSDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -207,6 +206,13 @@ tmp<surfaceScalarField> SLTSDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> SLTSDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> SLTSDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -187,7 +187,6 @@ tmp<surfaceScalarField> backwardDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> backwardDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -195,6 +194,13 @@ tmp<surfaceScalarField> backwardDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> backwardDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> backwardDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -185,7 +185,6 @@ tmp<surfaceScalarField> boundedDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> boundedDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -193,6 +192,13 @@ tmp<surfaceScalarField> boundedDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> boundedDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> boundedDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -91,6 +91,13 @@ public:
// Constructors
//- Construct from mesh and name of the rDeltaT field
localEulerDdtScheme(const fvMesh& mesh, const word& rDeltaTName)
:
ddtScheme<Type>(mesh),
rDeltaTName_(rDeltaTName)
{}
//- Construct from mesh and Istream
localEulerDdtScheme(const fvMesh& mesh, Istream& is)
:
@ -188,7 +195,6 @@ tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -196,6 +202,13 @@ tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -175,7 +175,6 @@ tmp<surfaceScalarField> steadyStateDdtScheme<scalar>::fvcDdtUfCorr
const GeometricField<scalar, fvsPatchField, surfaceMesh>& Uf
);
template<>
tmp<surfaceScalarField> steadyStateDdtScheme<scalar>::fvcDdtPhiCorr
(
@ -183,6 +182,13 @@ tmp<surfaceScalarField> steadyStateDdtScheme<scalar>::fvcDdtPhiCorr
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> steadyStateDdtScheme<scalar>::fvcDdtUfCorr
(
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& Uf
);
template<>
tmp<surfaceScalarField> steadyStateDdtScheme<scalar>::fvcDdtPhiCorr

View File

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "CMULES.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::MULES::correct
(
volScalarField& psi,
surfaceScalarField& phiPsiCorr,
const scalar psiMax,
const scalar psiMin
)
{
correct
(
geometricOneField(),
psi,
phiPsiCorr,
zeroField(), zeroField(),
psiMax, psiMin
);
}
void Foam::MULES::LTScorrect
(
volScalarField& psi,
surfaceScalarField& phiPsiCorr,
const scalar psiMax,
const scalar psiMin
)
{
LTScorrect
(
geometricOneField(),
psi,
phiPsiCorr,
zeroField(), zeroField(),
psiMax, psiMin
);
}
// ************************************************************************* //

View File

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Global
MULES
Description
CMULES: Multidimensional universal limiter for
explicit corrected implicit solution.
Solve a convective-only transport equation using an explicit universal
multi-dimensional limiter to correct an implicit conservative bounded
obtained using rigorously bounded schemes such as Euler-implicit in time
upwind in space.
Parameters are the variable to solve, the normal convective flux and the
actual explicit flux of the variable which is also used to return limited
flux used in the bounded-solution.
SourceFiles
CMULES.C
CMULESTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef CMULES_H
#define CMULES_H
#include "MULES.H"
#include "EulerDdtScheme.H"
#include "localEulerDdtScheme.H"
#include "gaussConvectionScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace MULES
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void correct
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su
);
template<class RhoType, class SpType, class SuType>
void correct
(
const RhoType& rho,
volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin
);
void correct
(
volScalarField& psi,
surfaceScalarField& phiCorr,
const scalar psiMax,
const scalar psiMin
);
template<class RhoType, class SpType, class SuType>
void LTScorrect
(
const RhoType& rho,
volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin
);
void LTScorrect
(
volScalarField& psi,
surfaceScalarField& phiCorr,
const scalar psiMax,
const scalar psiMin
);
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void limiterCorr
(
scalarField& allLambda,
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
);
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void limitCorr
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace MULES
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "CMULESTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,493 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "CMULES.H"
#include "fvcSurfaceIntegrate.H"
#include "slicedSurfaceFields.H"
#include "wedgeFvPatch.H"
#include "syncTools.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void Foam::MULES::correct
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su
)
{
Info<< "MULES: Correcting " << psi.name() << endl;
const fvMesh& mesh = psi.mesh();
scalarField psiIf(psi.size(), 0);
fvc::surfaceIntegrate(psiIf, phiCorr);
if (mesh.moving())
{
psi.internalField() =
(
rho.field()*psi.internalField()*rDeltaT
+ Su.field()
- psiIf
)/(rho.field()*rDeltaT - Sp.field());
}
else
{
psi.internalField() =
(
rho.field()*psi.internalField()*rDeltaT
+ Su.field()
- psiIf
)/(rho.field()*rDeltaT - Sp.field());
}
psi.correctBoundaryConditions();
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::correct
(
const RhoType& rho,
volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin
)
{
const fvMesh& mesh = psi.mesh();
const scalar rDeltaT = 1.0/mesh.time().deltaTValue();
const dictionary& MULEScontrols = mesh.solverDict(psi.name());
label nLimiterIter
(
readLabel(MULEScontrols.lookup("nLimiterIter"))
);
limitCorr(rDeltaT, rho, psi, phiCorr, Sp, Su, psiMax, psiMin, nLimiterIter);
correct(rDeltaT, rho, psi, phiCorr, Sp, Su);
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::LTScorrect
(
const RhoType& rho,
volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin
)
{
const fvMesh& mesh = psi.mesh();
const volScalarField& rDeltaT =
mesh.objectRegistry::lookupObject<volScalarField>("rSubDeltaT");
const dictionary& MULEScontrols = mesh.solverDict(psi.name());
label nLimiterIter
(
readLabel(MULEScontrols.lookup("nLimiterIter"))
);
limitCorr(rDeltaT, rho, psi, phiCorr, Sp, Su, psiMax, psiMin, nLimiterIter);
correct(rDeltaT, rho, psi, phiCorr, Sp, Su);
}
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void Foam::MULES::limiterCorr
(
scalarField& allLambda,
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
)
{
const scalarField& psiIf = psi;
const volScalarField::GeometricBoundaryField& psiBf = psi.boundaryField();
const fvMesh& mesh = psi.mesh();
const labelUList& owner = mesh.owner();
const labelUList& neighb = mesh.neighbour();
tmp<volScalarField::DimensionedInternalField> tVsc = mesh.Vsc();
const scalarField& V = tVsc();
const scalarField& phiCorrIf = phiCorr;
const surfaceScalarField::GeometricBoundaryField& phiCorrBf =
phiCorr.boundaryField();
slicedSurfaceScalarField lambda
(
IOobject
(
"lambda",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimless,
allLambda,
false // Use slices for the couples
);
scalarField& lambdaIf = lambda;
surfaceScalarField::GeometricBoundaryField& lambdaBf =
lambda.boundaryField();
scalarField psiMaxn(psiIf.size(), psiMin);
scalarField psiMinn(psiIf.size(), psiMax);
scalarField sumPhip(psiIf.size(), VSMALL);
scalarField mSumPhim(psiIf.size(), VSMALL);
forAll(phiCorrIf, facei)
{
label own = owner[facei];
label nei = neighb[facei];
psiMaxn[own] = max(psiMaxn[own], psiIf[nei]);
psiMinn[own] = min(psiMinn[own], psiIf[nei]);
psiMaxn[nei] = max(psiMaxn[nei], psiIf[own]);
psiMinn[nei] = min(psiMinn[nei], psiIf[own]);
scalar phiCorrf = phiCorrIf[facei];
if (phiCorrf > 0.0)
{
sumPhip[own] += phiCorrf;
mSumPhim[nei] += phiCorrf;
}
else
{
mSumPhim[own] -= phiCorrf;
sumPhip[nei] -= phiCorrf;
}
}
forAll(phiCorrBf, patchi)
{
const fvPatchScalarField& psiPf = psiBf[patchi];
const scalarField& phiCorrPf = phiCorrBf[patchi];
const labelList& pFaceCells = mesh.boundary()[patchi].faceCells();
if (psiPf.coupled())
{
const scalarField psiPNf(psiPf.patchNeighbourField());
forAll(phiCorrPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
psiMaxn[pfCelli] = max(psiMaxn[pfCelli], psiPNf[pFacei]);
psiMinn[pfCelli] = min(psiMinn[pfCelli], psiPNf[pFacei]);
}
}
else
{
forAll(phiCorrPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
psiMaxn[pfCelli] = max(psiMaxn[pfCelli], psiPf[pFacei]);
psiMinn[pfCelli] = min(psiMinn[pfCelli], psiPf[pFacei]);
}
}
forAll(phiCorrPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
scalar phiCorrf = phiCorrPf[pFacei];
if (phiCorrf > 0.0)
{
sumPhip[pfCelli] += phiCorrf;
}
else
{
mSumPhim[pfCelli] -= phiCorrf;
}
}
}
psiMaxn = min(psiMaxn, psiMax);
psiMinn = max(psiMinn, psiMin);
// scalar smooth = 0.5;
// psiMaxn = min((1.0 - smooth)*psiIf + smooth*psiMaxn, psiMax);
// psiMinn = max((1.0 - smooth)*psiIf + smooth*psiMinn, psiMin);
psiMaxn =
V
*(
(rho.field()*rDeltaT - Sp.field())*psiMaxn
- Su.field()
- rho.field()*psi.internalField()*rDeltaT
);
psiMinn =
V
*(
Su.field()
- (rho.field()*rDeltaT - Sp.field())*psiMinn
+ rho.field()*psi.internalField()*rDeltaT
);
scalarField sumlPhip(psiIf.size());
scalarField mSumlPhim(psiIf.size());
for (int j=0; j<nLimiterIter; j++)
{
sumlPhip = 0.0;
mSumlPhim = 0.0;
forAll(lambdaIf, facei)
{
label own = owner[facei];
label nei = neighb[facei];
scalar lambdaPhiCorrf = lambdaIf[facei]*phiCorrIf[facei];
if (lambdaPhiCorrf > 0.0)
{
sumlPhip[own] += lambdaPhiCorrf;
mSumlPhim[nei] += lambdaPhiCorrf;
}
else
{
mSumlPhim[own] -= lambdaPhiCorrf;
sumlPhip[nei] -= lambdaPhiCorrf;
}
}
forAll(lambdaBf, patchi)
{
scalarField& lambdaPf = lambdaBf[patchi];
const scalarField& phiCorrfPf = phiCorrBf[patchi];
const labelList& pFaceCells = mesh.boundary()[patchi].faceCells();
forAll(lambdaPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
scalar lambdaPhiCorrf = lambdaPf[pFacei]*phiCorrfPf[pFacei];
if (lambdaPhiCorrf > 0.0)
{
sumlPhip[pfCelli] += lambdaPhiCorrf;
}
else
{
mSumlPhim[pfCelli] -= lambdaPhiCorrf;
}
}
}
forAll(sumlPhip, celli)
{
sumlPhip[celli] =
max(min
(
(sumlPhip[celli] + psiMaxn[celli])
/(mSumPhim[celli] - SMALL),
1.0), 0.0
);
mSumlPhim[celli] =
max(min
(
(mSumlPhim[celli] + psiMinn[celli])
/(sumPhip[celli] + SMALL),
1.0), 0.0
);
}
const scalarField& lambdam = sumlPhip;
const scalarField& lambdap = mSumlPhim;
forAll(lambdaIf, facei)
{
if (phiCorrIf[facei] > 0.0)
{
lambdaIf[facei] = min
(
lambdaIf[facei],
min(lambdap[owner[facei]], lambdam[neighb[facei]])
);
}
else
{
lambdaIf[facei] = min
(
lambdaIf[facei],
min(lambdam[owner[facei]], lambdap[neighb[facei]])
);
}
}
forAll(lambdaBf, patchi)
{
fvsPatchScalarField& lambdaPf = lambdaBf[patchi];
const scalarField& phiCorrfPf = phiCorrBf[patchi];
const fvPatchScalarField& psiPf = psiBf[patchi];
if (isA<wedgeFvPatch>(mesh.boundary()[patchi]))
{
lambdaPf = 0;
}
else if (psiPf.coupled())
{
const labelList& pFaceCells =
mesh.boundary()[patchi].faceCells();
forAll(lambdaPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
if (phiCorrfPf[pFacei] > 0.0)
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdap[pfCelli]);
}
else
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdam[pfCelli]);
}
}
}
else
{
const labelList& pFaceCells =
mesh.boundary()[patchi].faceCells();
const scalarField& phiCorrPf = phiCorrBf[patchi];
forAll(lambdaPf, pFacei)
{
// Limit outlet faces only
if (phiCorrPf[pFacei] > SMALL*SMALL)
{
label pfCelli = pFaceCells[pFacei];
if (phiCorrfPf[pFacei] > 0.0)
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdap[pfCelli]);
}
else
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdam[pfCelli]);
}
}
}
}
}
syncTools::syncFaceList(mesh, allLambda, minEqOp<scalar>());
}
}
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void Foam::MULES::limitCorr
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
)
{
const fvMesh& mesh = psi.mesh();
scalarField allLambda(mesh.nFaces(), 1.0);
slicedSurfaceScalarField lambda
(
IOobject
(
"lambda",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimless,
allLambda,
false // Use slices for the couples
);
limiterCorr
(
allLambda,
rDeltaT,
rho,
psi,
phiCorr,
Sp,
Su,
psiMax,
psiMin,
nLimiterIter
);
phiCorr *= lambda;
}
// ************************************************************************* //

View File

@ -25,7 +25,14 @@ Global
IMULES
Description
IMULES: Multidimensional universal limiter with implicit solution.
IMULES: Multidimensional universal limiter for implicit solution.
Solve a convective-only transport equation using an explicit universal
multi-dimensional limiter applied to an implicit formulation requiring
iteration to guarantee boundedness. The number of iterations required
to obtain boundedness increases with the Courant number of the simulation.
It may be more efficient to use CMULES.
SourceFiles
IMULES.C

View File

@ -179,6 +179,7 @@ void Foam::MULES::implicitSolve
limiter
(
allLambda,
1.0/mesh.time().deltaTValue(),
rho,
psi,
phiBD,

View File

@ -48,19 +48,21 @@ void Foam::MULES::explicitSolve
}
void Foam::MULES::correct
void Foam::MULES::explicitLTSSolve
(
volScalarField& psi,
surfaceScalarField& phiPsiCorr,
const surfaceScalarField& phi,
surfaceScalarField& phiPsi,
const scalar psiMax,
const scalar psiMin
)
{
correct
explicitLTSSolve
(
geometricOneField(),
psi,
phiPsiCorr,
phi,
phiPsi,
zeroField(), zeroField(),
psiMax, psiMin
);

View File

@ -25,7 +25,7 @@ Global
MULES
Description
MULES: Multidimensional universal limiter with explicit solution.
MULES: Multidimensional universal limiter for explicit solution.
Solve a convective-only transport equation using an explicit universal
multi-dimensional limiter.
@ -60,6 +60,17 @@ namespace MULES
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void explicitSolve
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
volScalarField& psi,
const surfaceScalarField& phiPsi,
const SpType& Sp,
const SuType& Su
);
template<class RhoType, class SpType, class SuType>
void explicitSolve
(
@ -92,42 +103,34 @@ void explicitSolve
const scalar psiMin
);
template<class RhoType, class SpType, class SuType>
void correct
void explicitLTSSolve
(
const RhoType& rho,
volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su
);
template<class RhoType, class SpType, class SuType>
void correct
(
const RhoType& rho,
volScalarField& psi,
surfaceScalarField& phiCorr,
const surfaceScalarField& phiBD,
surfaceScalarField& phiPsi,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin
);
void correct
void explicitLTSSolve
(
volScalarField& psi,
surfaceScalarField& phiCorr,
const surfaceScalarField& phiBD,
surfaceScalarField& phiPsi,
const scalar psiMax,
const scalar psiMin
);
template<class RhoType, class SpType, class SuType>
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void limiter
(
scalarField& allLambda,
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phiBD,
@ -139,9 +142,10 @@ void limiter
const label nLimiterIter
);
template<class RhoType, class SpType, class SuType>
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void limit
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phi,
@ -155,39 +159,12 @@ void limit
);
template<class RhoType, class SpType, class SuType>
void limiterCorr
(
scalarField& allLambda,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
);
template<class RhoType, class SpType, class SuType>
void limitCorr
(
const RhoType& rho,
const volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
);
void limitSum(UPtrList<scalarField>& phiPsiCorrs);
template<class SurfaceScalarFieldList>
void limitSum(SurfaceScalarFieldList& phiPsiCorrs);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace MULES

View File

@ -32,9 +32,10 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class RhoType, class SpType, class SuType>
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void Foam::MULES::explicitSolve
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
volScalarField& psi,
const surfaceScalarField& phiPsi,
@ -48,7 +49,6 @@ void Foam::MULES::explicitSolve
scalarField& psiIf = psi;
const scalarField& psi0 = psi.oldTime();
const scalar deltaT = mesh.time().deltaTValue();
psiIf = 0.0;
fvc::surfaceIntegrate(psiIf, phiPsi);
@ -58,25 +58,41 @@ void Foam::MULES::explicitSolve
psiIf =
(
mesh.Vsc0()().field()*rho.oldTime().field()
*psi0/(deltaT*mesh.Vsc()().field())
*psi0*rDeltaT/mesh.Vsc()().field()
+ Su.field()
- psiIf
)/(rho.field()/deltaT - Sp.field());
)/(rho.field()*rDeltaT - Sp.field());
}
else
{
psiIf =
(
rho.oldTime().field()*psi0/deltaT
rho.oldTime().field()*psi0*rDeltaT
+ Su.field()
- psiIf
)/(rho.field()/deltaT - Sp.field());
)/(rho.field()*rDeltaT - Sp.field());
}
psi.correctBoundaryConditions();
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::explicitSolve
(
const RhoType& rho,
volScalarField& psi,
const surfaceScalarField& phiPsi,
const SpType& Sp,
const SuType& Su
)
{
const fvMesh& mesh = psi.mesh();
const scalar rDeltaT = 1.0/mesh.time().deltaTValue();
explicitSolve(rDeltaT, rho, psi, phiPsi, Sp, Su);
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::explicitSolve
(
@ -90,60 +106,21 @@ void Foam::MULES::explicitSolve
const scalar psiMin
)
{
psi.correctBoundaryConditions();
limit(rho, psi, phi, phiPsi, Sp, Su, psiMax, psiMin, 3, false);
explicitSolve(rho, psi, phiPsi, Sp, Su);
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::correct
(
const RhoType& rho,
volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su
)
{
Info<< "MULES: Correcting " << psi.name() << endl;
const fvMesh& mesh = psi.mesh();
const scalar deltaT = mesh.time().deltaTValue();
scalarField psiIf(psi.size(), 0);
fvc::surfaceIntegrate(psiIf, phiCorr);
if (mesh.moving())
{
psi.internalField() =
(
rho.field()*psi.internalField()/deltaT
+ Su.field()
- psiIf
)/(rho.field()/deltaT - Sp.field());
}
else
{
psi.internalField() =
(
rho.field()*psi.internalField()/deltaT
+ Su.field()
- psiIf
)/(rho.field()/deltaT - Sp.field());
}
const scalar rDeltaT = 1.0/mesh.time().deltaTValue();
psi.correctBoundaryConditions();
limit(rDeltaT, rho, psi, phi, phiPsi, Sp, Su, psiMax, psiMin, 3, false);
explicitSolve(rDeltaT, rho, psi, phiPsi, Sp, Su);
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::correct
void Foam::MULES::explicitLTSSolve
(
const RhoType& rho,
volScalarField& psi,
surfaceScalarField& phiCorr,
const surfaceScalarField& phi,
surfaceScalarField& phiPsi,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
@ -152,22 +129,20 @@ void Foam::MULES::correct
{
const fvMesh& mesh = psi.mesh();
const dictionary& MULEScontrols = mesh.solverDict(psi.name());
const volScalarField& rDeltaT =
mesh.objectRegistry::lookupObject<volScalarField>("rSubDeltaT");
label nLimiterIter
(
readLabel(MULEScontrols.lookup("nLimiterIter"))
);
limitCorr(rho, psi, phiCorr, Sp, Su, psiMax, psiMin, nLimiterIter);
correct(rho, psi, phiCorr, Sp, Su);
psi.correctBoundaryConditions();
limit(rDeltaT, rho, psi, phi, phiPsi, Sp, Su, psiMax, psiMin, 3, false);
explicitSolve(rDeltaT, rho, psi, phiPsi, Sp, Su);
}
template<class RhoType, class SpType, class SuType>
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void Foam::MULES::limiter
(
scalarField& allLambda,
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phiBD,
@ -190,7 +165,6 @@ void Foam::MULES::limiter
const labelUList& neighb = mesh.neighbour();
tmp<volScalarField::DimensionedInternalField> tVsc = mesh.Vsc();
const scalarField& V = tVsc();
const scalar deltaT = mesh.time().deltaTValue();
const scalarField& phiBDIf = phiBD;
const surfaceScalarField::GeometricBoundaryField& phiBDBf =
@ -321,19 +295,19 @@ void Foam::MULES::limiter
psiMaxn =
V
*(
(rho.field()/deltaT - Sp.field())*psiMaxn
(rho.field()*rDeltaT - Sp.field())*psiMaxn
- Su.field()
)
- (V0().field()/deltaT)*rho.oldTime().field()*psi0
- (V0().field()*rDeltaT)*rho.oldTime().field()*psi0
+ sumPhiBD;
psiMinn =
V
*(
Su.field()
- (rho.field()/deltaT - Sp.field())*psiMinn
- (rho.field()*rDeltaT - Sp.field())*psiMinn
)
+ (V0().field()/deltaT)*rho.oldTime().field()*psi0
+ (V0().field()*rDeltaT)*rho.oldTime().field()*psi0
- sumPhiBD;
}
else
@ -341,9 +315,9 @@ void Foam::MULES::limiter
psiMaxn =
V
*(
(rho.field()/deltaT - Sp.field())*psiMaxn
(rho.field()*rDeltaT - Sp.field())*psiMaxn
- Su.field()
- (rho.oldTime().field()/deltaT)*psi0
- (rho.oldTime().field()*rDeltaT)*psi0
)
+ sumPhiBD;
@ -351,8 +325,8 @@ void Foam::MULES::limiter
V
*(
Su.field()
- (rho.field()/deltaT - Sp.field())*psiMinn
+ (rho.oldTime().field()/deltaT)*psi0
- (rho.field()*rDeltaT - Sp.field())*psiMinn
+ (rho.oldTime().field()*rDeltaT)*psi0
)
- sumPhiBD;
}
@ -413,14 +387,16 @@ void Foam::MULES::limiter
sumlPhip[celli] =
max(min
(
(sumlPhip[celli] + psiMaxn[celli])/mSumPhim[celli],
(sumlPhip[celli] + psiMaxn[celli])
/(mSumPhim[celli] - SMALL),
1.0), 0.0
);
mSumlPhim[celli] =
max(min
(
(mSumlPhim[celli] + psiMinn[celli])/sumPhip[celli],
(mSumlPhim[celli] + psiMinn[celli])
/(sumPhip[celli] + SMALL),
1.0), 0.0
);
}
@ -514,9 +490,10 @@ void Foam::MULES::limiter
}
template<class RhoType, class SpType, class SuType>
template<class RdeltaTType, class RhoType, class SpType, class SuType>
void Foam::MULES::limit
(
const RdeltaTType& rDeltaT,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phi,
@ -558,6 +535,7 @@ void Foam::MULES::limit
limiter
(
allLambda,
rDeltaT,
rho,
psi,
phiBD,
@ -580,364 +558,6 @@ void Foam::MULES::limit
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::limiterCorr
(
scalarField& allLambda,
const RhoType& rho,
const volScalarField& psi,
const surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
)
{
const scalarField& psiIf = psi;
const volScalarField::GeometricBoundaryField& psiBf = psi.boundaryField();
const fvMesh& mesh = psi.mesh();
const labelUList& owner = mesh.owner();
const labelUList& neighb = mesh.neighbour();
tmp<volScalarField::DimensionedInternalField> tVsc = mesh.Vsc();
const scalarField& V = tVsc();
const scalar deltaT = mesh.time().deltaTValue();
const scalarField& phiCorrIf = phiCorr;
const surfaceScalarField::GeometricBoundaryField& phiCorrBf =
phiCorr.boundaryField();
slicedSurfaceScalarField lambda
(
IOobject
(
"lambda",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimless,
allLambda,
false // Use slices for the couples
);
scalarField& lambdaIf = lambda;
surfaceScalarField::GeometricBoundaryField& lambdaBf =
lambda.boundaryField();
scalarField psiMaxn(psiIf.size(), psiMin);
scalarField psiMinn(psiIf.size(), psiMax);
scalarField sumPhip(psiIf.size(), VSMALL);
scalarField mSumPhim(psiIf.size(), VSMALL);
forAll(phiCorrIf, facei)
{
label own = owner[facei];
label nei = neighb[facei];
psiMaxn[own] = max(psiMaxn[own], psiIf[nei]);
psiMinn[own] = min(psiMinn[own], psiIf[nei]);
psiMaxn[nei] = max(psiMaxn[nei], psiIf[own]);
psiMinn[nei] = min(psiMinn[nei], psiIf[own]);
scalar phiCorrf = phiCorrIf[facei];
if (phiCorrf > 0.0)
{
sumPhip[own] += phiCorrf;
mSumPhim[nei] += phiCorrf;
}
else
{
mSumPhim[own] -= phiCorrf;
sumPhip[nei] -= phiCorrf;
}
}
forAll(phiCorrBf, patchi)
{
const fvPatchScalarField& psiPf = psiBf[patchi];
const scalarField& phiCorrPf = phiCorrBf[patchi];
const labelList& pFaceCells = mesh.boundary()[patchi].faceCells();
if (psiPf.coupled())
{
const scalarField psiPNf(psiPf.patchNeighbourField());
forAll(phiCorrPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
psiMaxn[pfCelli] = max(psiMaxn[pfCelli], psiPNf[pFacei]);
psiMinn[pfCelli] = min(psiMinn[pfCelli], psiPNf[pFacei]);
}
}
else
{
forAll(phiCorrPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
psiMaxn[pfCelli] = max(psiMaxn[pfCelli], psiPf[pFacei]);
psiMinn[pfCelli] = min(psiMinn[pfCelli], psiPf[pFacei]);
}
}
forAll(phiCorrPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
scalar phiCorrf = phiCorrPf[pFacei];
if (phiCorrf > 0.0)
{
sumPhip[pfCelli] += phiCorrf;
}
else
{
mSumPhim[pfCelli] -= phiCorrf;
}
}
}
psiMaxn = min(psiMaxn, psiMax);
psiMinn = max(psiMinn, psiMin);
// scalar smooth = 0.5;
// psiMaxn = min((1.0 - smooth)*psiIf + smooth*psiMaxn, psiMax);
// psiMinn = max((1.0 - smooth)*psiIf + smooth*psiMinn, psiMin);
psiMaxn =
V
*(
(rho.field()/deltaT - Sp.field())*psiMaxn
- Su.field()
- rho.field()*psi.internalField()/deltaT
);
psiMinn =
V
*(
Su.field()
- (rho.field()/deltaT - Sp.field())*psiMinn
+ rho.field()*psi.internalField()/deltaT
);
scalarField sumlPhip(psiIf.size());
scalarField mSumlPhim(psiIf.size());
for (int j=0; j<nLimiterIter; j++)
{
sumlPhip = 0.0;
mSumlPhim = 0.0;
forAll(lambdaIf, facei)
{
label own = owner[facei];
label nei = neighb[facei];
scalar lambdaPhiCorrf = lambdaIf[facei]*phiCorrIf[facei];
if (lambdaPhiCorrf > 0.0)
{
sumlPhip[own] += lambdaPhiCorrf;
mSumlPhim[nei] += lambdaPhiCorrf;
}
else
{
mSumlPhim[own] -= lambdaPhiCorrf;
sumlPhip[nei] -= lambdaPhiCorrf;
}
}
forAll(lambdaBf, patchi)
{
scalarField& lambdaPf = lambdaBf[patchi];
const scalarField& phiCorrfPf = phiCorrBf[patchi];
const labelList& pFaceCells = mesh.boundary()[patchi].faceCells();
forAll(lambdaPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
scalar lambdaPhiCorrf = lambdaPf[pFacei]*phiCorrfPf[pFacei];
if (lambdaPhiCorrf > 0.0)
{
sumlPhip[pfCelli] += lambdaPhiCorrf;
}
else
{
mSumlPhim[pfCelli] -= lambdaPhiCorrf;
}
}
}
forAll(sumlPhip, celli)
{
sumlPhip[celli] =
max(min
(
(sumlPhip[celli] + psiMaxn[celli])/mSumPhim[celli],
1.0), 0.0
);
mSumlPhim[celli] =
max(min
(
(mSumlPhim[celli] + psiMinn[celli])/sumPhip[celli],
1.0), 0.0
);
}
const scalarField& lambdam = sumlPhip;
const scalarField& lambdap = mSumlPhim;
forAll(lambdaIf, facei)
{
if (phiCorrIf[facei] > 0.0)
{
lambdaIf[facei] = min
(
lambdaIf[facei],
min(lambdap[owner[facei]], lambdam[neighb[facei]])
);
}
else
{
lambdaIf[facei] = min
(
lambdaIf[facei],
min(lambdam[owner[facei]], lambdap[neighb[facei]])
);
}
}
forAll(lambdaBf, patchi)
{
fvsPatchScalarField& lambdaPf = lambdaBf[patchi];
const scalarField& phiCorrfPf = phiCorrBf[patchi];
const fvPatchScalarField& psiPf = psiBf[patchi];
if (isA<wedgeFvPatch>(mesh.boundary()[patchi]))
{
lambdaPf = 0;
}
else if (psiPf.coupled())
{
const labelList& pFaceCells =
mesh.boundary()[patchi].faceCells();
forAll(lambdaPf, pFacei)
{
label pfCelli = pFaceCells[pFacei];
if (phiCorrfPf[pFacei] > 0.0)
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdap[pfCelli]);
}
else
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdam[pfCelli]);
}
}
}
else
{
const labelList& pFaceCells =
mesh.boundary()[patchi].faceCells();
const scalarField& phiCorrPf = phiCorrBf[patchi];
forAll(lambdaPf, pFacei)
{
// Limit outlet faces only
if (phiCorrPf[pFacei] > SMALL*SMALL)
{
label pfCelli = pFaceCells[pFacei];
if (phiCorrfPf[pFacei] > 0.0)
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdap[pfCelli]);
}
else
{
lambdaPf[pFacei] =
min(lambdaPf[pFacei], lambdam[pfCelli]);
}
}
}
}
}
syncTools::syncFaceList(mesh, allLambda, minEqOp<scalar>());
}
}
template<class RhoType, class SpType, class SuType>
void Foam::MULES::limitCorr
(
const RhoType& rho,
const volScalarField& psi,
surfaceScalarField& phiCorr,
const SpType& Sp,
const SuType& Su,
const scalar psiMax,
const scalar psiMin,
const label nLimiterIter
)
{
const fvMesh& mesh = psi.mesh();
scalarField allLambda(mesh.nFaces(), 1.0);
slicedSurfaceScalarField lambda
(
IOobject
(
"lambda",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimless,
allLambda,
false // Use slices for the couples
);
limiterCorr
(
allLambda,
rho,
psi,
phiCorr,
Sp,
Su,
psiMax,
psiMin,
nLimiterIter
);
phiCorr *= lambda;
}
template<class SurfaceScalarFieldList>
void Foam::MULES::limitSum(SurfaceScalarFieldList& phiPsiCorrs)
{