solvers::twoPhaseSolver: new base-class for twoPhaseVoFSolver and incompressibleDriftFlux
to separate the interface treatment between VoF and drift-flux and avoid code duplication.
This commit is contained in:
6
applications/solvers/modules/twoPhaseSolver/Make/files
Normal file
6
applications/solvers/modules/twoPhaseSolver/Make/files
Normal file
@ -0,0 +1,6 @@
|
||||
twoPhaseVoFMixture/twoPhaseVoFMixture.C
|
||||
alphaPredictor.C
|
||||
pressureCorrector.C
|
||||
twoPhaseSolver.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libtwoPhaseSolver
|
||||
23
applications/solvers/modules/twoPhaseSolver/Make/options
Normal file
23
applications/solvers/modules/twoPhaseSolver/Make/options
Normal file
@ -0,0 +1,23 @@
|
||||
EXE_INC = \
|
||||
-I$(FOAM_SOLVERS)/modules/VoFSolver/lnInclude \
|
||||
-I$(FOAM_SOLVERS)/modules/fluidSolver/lnInclude \
|
||||
-I$(LIB_SRC)/physicalProperties/lnInclude \
|
||||
-I$(LIB_SRC)/twoPhaseModels/VoF \
|
||||
-I$(LIB_SRC)/twoPhaseModels/interfaceCompression/lnInclude \
|
||||
-I$(LIB_SRC)/twoPhaseModels/interfaceProperties/lnInclude \
|
||||
-I$(LIB_SRC)/twoPhaseModels/twoPhaseMixture/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
-lVoFSolver \
|
||||
-lphysicalProperties \
|
||||
-linterfaceCompression \
|
||||
-linterfaceProperties \
|
||||
-ltwoPhaseMixture \
|
||||
-lfiniteVolume \
|
||||
-lmeshTools \
|
||||
-lfvModels \
|
||||
-lfvConstraints \
|
||||
-lsampling
|
||||
421
applications/solvers/modules/twoPhaseSolver/alphaPredictor.C
Normal file
421
applications/solvers/modules/twoPhaseSolver/alphaPredictor.C
Normal file
@ -0,0 +1,421 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 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 "twoPhaseSolver.H"
|
||||
#include "subCycle.H"
|
||||
#include "interfaceCompression.H"
|
||||
#include "CMULES.H"
|
||||
#include "CrankNicolsonDdtScheme.H"
|
||||
#include "fvcFlux.H"
|
||||
#include "fvmSup.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::surfaceScalarField> Foam::solvers::twoPhaseSolver::alphaPhi
|
||||
(
|
||||
const surfaceScalarField& phi,
|
||||
const volScalarField& alpha,
|
||||
const dictionary& alphaControls
|
||||
)
|
||||
{
|
||||
const word alphaScheme(mesh.schemes().div(divAlphaName)[1].wordToken());
|
||||
|
||||
ITstream compressionScheme
|
||||
(
|
||||
compressionSchemes.found(alphaScheme)
|
||||
? mesh.schemes().div(divAlphaName)
|
||||
: ITstream
|
||||
(
|
||||
divAlphaName,
|
||||
tokenList
|
||||
{
|
||||
word("Gauss"),
|
||||
word("interfaceCompression"),
|
||||
alphaScheme,
|
||||
alphaControls.lookup<scalar>("cAlpha")
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return fvc::flux
|
||||
(
|
||||
phi,
|
||||
alpha,
|
||||
compressionScheme
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void Foam::solvers::twoPhaseSolver::alphaSolve
|
||||
(
|
||||
const dictionary& alphaControls
|
||||
)
|
||||
{
|
||||
const label nAlphaSubCycles(alphaControls.lookup<label>("nAlphaSubCycles"));
|
||||
|
||||
const label nAlphaCorr(alphaControls.lookup<label>("nAlphaCorr"));
|
||||
|
||||
const bool MULESCorr
|
||||
(
|
||||
alphaControls.lookupOrDefault<Switch>("MULESCorr", false)
|
||||
);
|
||||
|
||||
// Apply the compression correction from the previous iteration
|
||||
// Improves efficiency for steady-simulations but can only be applied
|
||||
// once the alpha field is reasonably steady, i.e. fully developed
|
||||
const bool alphaApplyPrevCorr
|
||||
(
|
||||
alphaControls.lookupOrDefault<Switch>("alphaApplyPrevCorr", false)
|
||||
);
|
||||
|
||||
|
||||
// Set the off-centering coefficient according to ddt scheme
|
||||
scalar ocCoeff = 0;
|
||||
{
|
||||
tmp<fv::ddtScheme<scalar>> tddtAlpha
|
||||
(
|
||||
fv::ddtScheme<scalar>::New
|
||||
(
|
||||
mesh,
|
||||
mesh.schemes().ddt("ddt(alpha)")
|
||||
)
|
||||
);
|
||||
const fv::ddtScheme<scalar>& ddtAlpha = tddtAlpha();
|
||||
|
||||
if
|
||||
(
|
||||
isType<fv::EulerDdtScheme<scalar>>(ddtAlpha)
|
||||
|| isType<fv::localEulerDdtScheme<scalar>>(ddtAlpha)
|
||||
)
|
||||
{
|
||||
ocCoeff = 0;
|
||||
}
|
||||
else if (isType<fv::CrankNicolsonDdtScheme<scalar>>(ddtAlpha))
|
||||
{
|
||||
if (nAlphaSubCycles > 1)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Sub-cycling is not supported "
|
||||
"with the CrankNicolson ddt scheme"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
alphaRestart
|
||||
|| mesh.time().timeIndex() > mesh.time().startTimeIndex() + 1
|
||||
)
|
||||
{
|
||||
ocCoeff =
|
||||
refCast<const fv::CrankNicolsonDdtScheme<scalar>>(ddtAlpha)
|
||||
.ocCoeff();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Only Euler and CrankNicolson ddt schemes are supported"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the time blending factor, 1 for Euler
|
||||
scalar cnCoeff = 1.0/(1.0 + ocCoeff);
|
||||
|
||||
tmp<surfaceScalarField> phiCN(phi);
|
||||
|
||||
// Calculate the Crank-Nicolson off-centred volumetric flux
|
||||
if (ocCoeff > 0)
|
||||
{
|
||||
phiCN = surfaceScalarField::New
|
||||
(
|
||||
"phiCN",
|
||||
cnCoeff*phi + (1.0 - cnCoeff)*phi.oldTime()
|
||||
);
|
||||
}
|
||||
|
||||
tmp<volScalarField> divU;
|
||||
|
||||
if (divergent())
|
||||
{
|
||||
divU =
|
||||
(
|
||||
mesh.moving()
|
||||
? fvc::div(phiCN + mesh.phi())
|
||||
: fvc::div(phiCN)
|
||||
);
|
||||
}
|
||||
|
||||
tmp<volScalarField::Internal> Su;
|
||||
tmp<volScalarField::Internal> Sp;
|
||||
|
||||
alphaSuSp(Su, Sp);
|
||||
|
||||
if (MULESCorr)
|
||||
{
|
||||
fvScalarMatrix alpha1Eqn
|
||||
(
|
||||
(
|
||||
LTS
|
||||
? fv::localEulerDdtScheme<scalar>(mesh).fvmDdt(alpha1)
|
||||
: fv::EulerDdtScheme<scalar>(mesh).fvmDdt(alpha1)
|
||||
)
|
||||
+ fv::gaussConvectionScheme<scalar>
|
||||
(
|
||||
mesh,
|
||||
phiCN,
|
||||
upwind<scalar>(mesh, phiCN)
|
||||
).fvmDiv(phiCN, alpha1)
|
||||
);
|
||||
|
||||
if (divU.valid())
|
||||
{
|
||||
alpha1Eqn -= Su() + fvm::Sp(Sp() + divU(), alpha1);
|
||||
}
|
||||
|
||||
alpha1Eqn.solve();
|
||||
|
||||
Info<< "Phase-1 volume fraction = "
|
||||
<< alpha1.weightedAverage(mesh.Vsc()).value()
|
||||
<< " Min(" << alpha1.name() << ") = " << min(alpha1).value()
|
||||
<< " Max(" << alpha1.name() << ") = " << max(alpha1).value()
|
||||
<< endl;
|
||||
|
||||
tmp<surfaceScalarField> talphaPhi1UD(alpha1Eqn.flux());
|
||||
alphaPhi1 = talphaPhi1UD();
|
||||
|
||||
if (alphaApplyPrevCorr && talphaPhi1Corr0.valid())
|
||||
{
|
||||
Info<< "Applying the previous iteration compression flux" << endl;
|
||||
MULES::correct
|
||||
(
|
||||
geometricOneField(),
|
||||
alpha1,
|
||||
alphaPhi1,
|
||||
talphaPhi1Corr0.ref(),
|
||||
oneField(),
|
||||
zeroField()
|
||||
);
|
||||
|
||||
alphaPhi1 += talphaPhi1Corr0();
|
||||
}
|
||||
|
||||
// Cache the upwind-flux
|
||||
talphaPhi1Corr0 = talphaPhi1UD;
|
||||
|
||||
alpha2 = 1.0 - alpha1;
|
||||
|
||||
correctInterface();
|
||||
}
|
||||
|
||||
for (int aCorr=0; aCorr<nAlphaCorr; aCorr++)
|
||||
{
|
||||
// Split operator
|
||||
tmp<surfaceScalarField> talphaPhi1Un
|
||||
(
|
||||
alphaPhi
|
||||
(
|
||||
phiCN(),
|
||||
(cnCoeff*alpha1 + (1.0 - cnCoeff)*alpha1.oldTime())(),
|
||||
alphaControls
|
||||
)
|
||||
);
|
||||
|
||||
if (MULESCorr)
|
||||
{
|
||||
tmp<surfaceScalarField> talphaPhi1Corr(talphaPhi1Un() - alphaPhi1);
|
||||
volScalarField alpha10("alpha10", alpha1);
|
||||
|
||||
if (divU.valid())
|
||||
{
|
||||
MULES::correct
|
||||
(
|
||||
geometricOneField(),
|
||||
alpha1,
|
||||
talphaPhi1Un(),
|
||||
talphaPhi1Corr.ref(),
|
||||
Sp(),
|
||||
(-Sp()*alpha1)(),
|
||||
oneField(),
|
||||
zeroField()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
MULES::correct
|
||||
(
|
||||
geometricOneField(),
|
||||
alpha1,
|
||||
talphaPhi1Un(),
|
||||
talphaPhi1Corr.ref(),
|
||||
oneField(),
|
||||
zeroField()
|
||||
);
|
||||
}
|
||||
|
||||
// Under-relax the correction for all but the 1st corrector
|
||||
if (aCorr == 0)
|
||||
{
|
||||
alphaPhi1 += talphaPhi1Corr();
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha1 = 0.5*alpha1 + 0.5*alpha10;
|
||||
alphaPhi1 += 0.5*talphaPhi1Corr();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alphaPhi1 = talphaPhi1Un;
|
||||
|
||||
if (divU.valid())
|
||||
{
|
||||
MULES::explicitSolve
|
||||
(
|
||||
geometricOneField(),
|
||||
alpha1,
|
||||
phiCN,
|
||||
alphaPhi1,
|
||||
Sp(),
|
||||
(Su() + divU()*min(alpha1(), scalar(1)))(),
|
||||
oneField(),
|
||||
zeroField()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
MULES::explicitSolve
|
||||
(
|
||||
geometricOneField(),
|
||||
alpha1,
|
||||
phiCN,
|
||||
alphaPhi1,
|
||||
oneField(),
|
||||
zeroField()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
alpha2 = 1.0 - alpha1;
|
||||
|
||||
// Correct only the mixture interface for the interface compression flux
|
||||
correctInterface();
|
||||
}
|
||||
|
||||
if (alphaApplyPrevCorr && MULESCorr)
|
||||
{
|
||||
talphaPhi1Corr0 = alphaPhi1 - talphaPhi1Corr0;
|
||||
|
||||
// Register alphaPhiCorr0.<phase1> for redistribution
|
||||
talphaPhi1Corr0.ref().rename
|
||||
(
|
||||
IOobject::groupName("alphaPhiCorr0", alpha1.group())
|
||||
);
|
||||
talphaPhi1Corr0.ref().checkIn();
|
||||
}
|
||||
else
|
||||
{
|
||||
talphaPhi1Corr0.clear();
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
word(mesh.schemes().ddt("ddt(rho,U)"))
|
||||
!= fv::EulerDdtScheme<vector>::typeName
|
||||
&& word(mesh.schemes().ddt("ddt(rho,U)"))
|
||||
!= fv::localEulerDdtScheme<vector>::typeName
|
||||
)
|
||||
{
|
||||
if (ocCoeff > 0)
|
||||
{
|
||||
// Calculate the end-of-time-step alpha flux
|
||||
alphaPhi1 =
|
||||
(alphaPhi1 - (1.0 - cnCoeff)*alphaPhi1.oldTime())/cnCoeff;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Phase-1 volume fraction = "
|
||||
<< alpha1.weightedAverage(mesh.Vsc()).value()
|
||||
<< " Min(" << alpha1.name() << ") = " << min(alpha1).value()
|
||||
<< " Max(" << alpha1.name() << ") = " << max(alpha1).value()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
void Foam::solvers::twoPhaseSolver::alphaPredictor()
|
||||
{
|
||||
const dictionary& alphaControls = mesh.solution().solverDict(alpha1.name());
|
||||
|
||||
const label nAlphaSubCycles(alphaControls.lookup<label>("nAlphaSubCycles"));
|
||||
|
||||
|
||||
if (nAlphaSubCycles > 1)
|
||||
{
|
||||
dimensionedScalar totalDeltaT = runTime.deltaT();
|
||||
tmp<volScalarField> trSubDeltaT;
|
||||
|
||||
if (LTS)
|
||||
{
|
||||
trSubDeltaT =
|
||||
fv::localEulerDdt::localRSubDeltaT(mesh, nAlphaSubCycles);
|
||||
}
|
||||
|
||||
// Create a temporary alphaPhi1 to accumulate the sub-cycled alphaPhi1
|
||||
tmp<surfaceScalarField> talphaPhi1
|
||||
(
|
||||
surfaceScalarField::New
|
||||
(
|
||||
"alphaPhi1",
|
||||
mesh,
|
||||
dimensionedScalar(alphaPhi1.dimensions(), 0)
|
||||
)
|
||||
);
|
||||
|
||||
List<volScalarField*> alphaPtrs({&alpha1, &alpha2});
|
||||
|
||||
for
|
||||
(
|
||||
subCycle<volScalarField, subCycleFields> alphaSubCycle
|
||||
(
|
||||
alphaPtrs,
|
||||
nAlphaSubCycles
|
||||
);
|
||||
!(++alphaSubCycle).end();
|
||||
)
|
||||
{
|
||||
alphaSolve(alphaControls);
|
||||
talphaPhi1.ref() += (runTime.deltaT()/totalDeltaT)*alphaPhi1;
|
||||
}
|
||||
|
||||
alphaPhi1 = talphaPhi1();
|
||||
}
|
||||
else
|
||||
{
|
||||
alphaSolve(alphaControls);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
158
applications/solvers/modules/twoPhaseSolver/pressureCorrector.C
Normal file
158
applications/solvers/modules/twoPhaseSolver/pressureCorrector.C
Normal file
@ -0,0 +1,158 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 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 "twoPhaseSolver.H"
|
||||
#include "constrainHbyA.H"
|
||||
#include "constrainPressure.H"
|
||||
#include "adjustPhi.H"
|
||||
#include "findRefCell.H"
|
||||
#include "fvcMeshPhi.H"
|
||||
#include "fvcFlux.H"
|
||||
#include "fvcDdt.H"
|
||||
#include "fvcDiv.H"
|
||||
#include "fvcSnGrad.H"
|
||||
#include "fvcReconstruct.H"
|
||||
#include "fvmLaplacian.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::solvers::twoPhaseSolver::incompressiblePressureCorrector
|
||||
(
|
||||
volScalarField& p
|
||||
)
|
||||
{
|
||||
volVectorField& U = U_;
|
||||
surfaceScalarField& phi(phi_);
|
||||
|
||||
fvVectorMatrix& UEqn = tUEqn.ref();
|
||||
setrAU(UEqn);
|
||||
|
||||
const surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU()));
|
||||
|
||||
while (pimple.correct())
|
||||
{
|
||||
volVectorField HbyA(constrainHbyA(rAU()*UEqn.H(), U, p_rgh));
|
||||
surfaceScalarField phiHbyA
|
||||
(
|
||||
"phiHbyA",
|
||||
fvc::flux(HbyA)
|
||||
+ fvc::interpolate(rho*rAU())*fvc::ddtCorr(U, phi, Uf)
|
||||
);
|
||||
|
||||
MRF.makeRelative(phiHbyA);
|
||||
|
||||
if (p_rgh.needReference())
|
||||
{
|
||||
fvc::makeRelative(phiHbyA, U);
|
||||
adjustPhi(phiHbyA, U, p_rgh);
|
||||
fvc::makeAbsolute(phiHbyA, U);
|
||||
}
|
||||
|
||||
surfaceScalarField phig
|
||||
(
|
||||
(
|
||||
surfaceTensionForce()
|
||||
- buoyancy.ghf*fvc::snGrad(rho)
|
||||
)*rAUf*mesh.magSf()
|
||||
);
|
||||
|
||||
phiHbyA += phig;
|
||||
|
||||
// Update the pressure BCs to ensure flux consistency
|
||||
constrainPressure(p_rgh, U, phiHbyA, rAUf, MRF);
|
||||
|
||||
// Cache the phase change pressure source
|
||||
fvScalarMatrix Sp_rgh
|
||||
(
|
||||
fvModels().source
|
||||
(
|
||||
volScalarField::New
|
||||
(
|
||||
"1",
|
||||
mesh,
|
||||
dimensionedScalar(dimless/dimPressure, 1)
|
||||
),
|
||||
p_rgh
|
||||
)
|
||||
);
|
||||
|
||||
while (pimple.correctNonOrthogonal())
|
||||
{
|
||||
fvScalarMatrix p_rghEqn
|
||||
(
|
||||
fvc::div(phiHbyA) - fvm::laplacian(rAUf, p_rgh)
|
||||
== Sp_rgh
|
||||
);
|
||||
|
||||
p_rghEqn.setReference
|
||||
(
|
||||
pressureReference().refCell(),
|
||||
getRefCellValue(p_rgh, pressureReference().refCell())
|
||||
);
|
||||
|
||||
p_rghEqn.solve();
|
||||
|
||||
if (pimple.finalNonOrthogonalIter())
|
||||
{
|
||||
phi = phiHbyA + p_rghEqn.flux();
|
||||
|
||||
p_rgh.relax();
|
||||
|
||||
U = HbyA
|
||||
+ rAU()*fvc::reconstruct((phig + p_rghEqn.flux())/rAUf);
|
||||
U.correctBoundaryConditions();
|
||||
fvConstraints().constrain(U);
|
||||
}
|
||||
}
|
||||
|
||||
continuityErrors();
|
||||
|
||||
// Correct Uf if the mesh is moving
|
||||
fvc::correctUf(Uf, U, phi, MRF);
|
||||
|
||||
// Make the fluxes relative to the mesh motion
|
||||
fvc::makeRelative(phi, U);
|
||||
|
||||
p == p_rgh + rho*buoyancy.gh;
|
||||
|
||||
if (p_rgh.needReference())
|
||||
{
|
||||
p += dimensionedScalar
|
||||
(
|
||||
"p",
|
||||
p.dimensions(),
|
||||
pressureReference().refValue()
|
||||
- getRefCellValue(p, pressureReference().refCell())
|
||||
);
|
||||
p_rgh = p - rho*buoyancy.gh;
|
||||
}
|
||||
}
|
||||
|
||||
clearrAU();
|
||||
tUEqn.clear();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
117
applications/solvers/modules/twoPhaseSolver/twoPhaseSolver.C
Normal file
117
applications/solvers/modules/twoPhaseSolver/twoPhaseSolver.C
Normal file
@ -0,0 +1,117 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 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 "twoPhaseSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace solvers
|
||||
{
|
||||
defineTypeNameAndDebug(twoPhaseSolver, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::solvers::twoPhaseSolver::twoPhaseSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
autoPtr<twoPhaseVoFMixture> mixturePtr
|
||||
)
|
||||
:
|
||||
VoFSolver(mesh, autoPtr<VoFMixture>(mixturePtr.ptr())),
|
||||
|
||||
mixture(refCast<twoPhaseVoFMixture>(VoFSolver::mixture_)),
|
||||
|
||||
alpha1(mixture.alpha1()),
|
||||
alpha2(mixture.alpha2()),
|
||||
|
||||
alphaRestart
|
||||
(
|
||||
typeIOobject<surfaceScalarField>
|
||||
(
|
||||
IOobject::groupName("alphaPhi", alpha1.group()),
|
||||
runTime.name(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
).headerOk()
|
||||
),
|
||||
|
||||
alphaPhi1
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("alphaPhi", alpha1.group()),
|
||||
runTime.name(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
phi*fvc::interpolate(alpha1)
|
||||
)
|
||||
{
|
||||
mesh.schemes().setFluxRequired(alpha1.name());
|
||||
|
||||
if (alphaRestart)
|
||||
{
|
||||
Info << "Restarting alpha" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::solvers::twoPhaseSolver::~twoPhaseSolver()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::solvers::twoPhaseSolver::preSolve()
|
||||
{
|
||||
VoFSolver::preSolve();
|
||||
|
||||
// Do not apply previous time-step mesh compression flux
|
||||
// if the mesh topology changed
|
||||
if (mesh().topoChanged())
|
||||
{
|
||||
talphaPhi1Corr0.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::solvers::twoPhaseSolver::prePredictor()
|
||||
{
|
||||
VoFSolver::prePredictor();
|
||||
alphaPredictor();
|
||||
mixture.correct();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
190
applications/solvers/modules/twoPhaseSolver/twoPhaseSolver.H
Normal file
190
applications/solvers/modules/twoPhaseSolver/twoPhaseSolver.H
Normal file
@ -0,0 +1,190 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 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::solvers::twoPhaseSolver
|
||||
|
||||
Description
|
||||
Solver module base-class for for 2 immiscible fluids, with optional
|
||||
mesh motion and mesh topology changes including adaptive re-meshing.
|
||||
|
||||
The momentum and other fluid properties are of the "mixture" and a single
|
||||
momentum equation is solved.
|
||||
|
||||
Either mixture or two-phase transport modelling may be selected. In the
|
||||
mixture approach a single laminar, RAS or LES model is selected to model the
|
||||
momentum stress. In the Euler-Euler two-phase approach separate laminar,
|
||||
RAS or LES selected models are selected for each of the phases.
|
||||
|
||||
Uses the flexible PIMPLE (PISO-SIMPLE) solution for time-resolved and
|
||||
pseudo-transient and steady simulations.
|
||||
|
||||
Optional fvModels and fvConstraints are provided to enhance the simulation
|
||||
in many ways including adding various sources, Lagrangian
|
||||
particles, surface film etc. and constraining or limiting the solution.
|
||||
|
||||
SourceFiles
|
||||
twoPhaseSolver.C
|
||||
|
||||
See also
|
||||
Foam::solvers::fluidSolver
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef twoPhaseSolver_H
|
||||
#define twoPhaseSolver_H
|
||||
|
||||
#include "VoFSolver.H"
|
||||
#include "twoPhaseVoFMixture.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace solvers
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class twoPhaseSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class twoPhaseSolver
|
||||
:
|
||||
public VoFSolver
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Phase properties
|
||||
|
||||
//- Reference to the twoPhaseVoFMixture
|
||||
twoPhaseVoFMixture& mixture;
|
||||
|
||||
//- Reference to the phase1-fraction
|
||||
volScalarField& alpha1;
|
||||
|
||||
//- Reference to the phase2-fraction
|
||||
volScalarField& alpha2;
|
||||
|
||||
//- Switch indicating if this is a restart
|
||||
bool alphaRestart;
|
||||
|
||||
|
||||
// Kinematic properties
|
||||
|
||||
// Phase-1 volumetric flux
|
||||
surfaceScalarField alphaPhi1;
|
||||
|
||||
|
||||
// Cached temporary fields
|
||||
|
||||
//- MULES Correction
|
||||
tmp<surfaceScalarField> talphaPhi1Corr0;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Solve for the phase-fractions
|
||||
void alphaSolve(const dictionary& alphaControls);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
virtual tmp<surfaceScalarField> alphaPhi
|
||||
(
|
||||
const surfaceScalarField& phi,
|
||||
const volScalarField& alpha,
|
||||
const dictionary& alphaControls
|
||||
);
|
||||
|
||||
//- Solve for the phase-fractions
|
||||
void alphaPredictor();
|
||||
|
||||
//- Calculate the alpha equation sources
|
||||
virtual void alphaSuSp
|
||||
(
|
||||
tmp<volScalarField::Internal>& Su,
|
||||
tmp<volScalarField::Internal>& Sp
|
||||
) = 0;
|
||||
|
||||
//- Correct the interface properties following mesh-change
|
||||
// and phase-fraction update
|
||||
virtual void correctInterface() = 0;
|
||||
|
||||
//- Return the interface surface tension force for the momentum equation
|
||||
virtual tmp<surfaceScalarField> surfaceTensionForce() const = 0;
|
||||
|
||||
//- Construct and solve the incompressible pressure equation
|
||||
// in the PISO loop
|
||||
void incompressiblePressureCorrector(volScalarField& p);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("twoPhaseSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from region mesh
|
||||
twoPhaseSolver(fvMesh& mesh, autoPtr<twoPhaseVoFMixture>);
|
||||
|
||||
//- Disallow default bitwise copy construction
|
||||
twoPhaseSolver(const twoPhaseSolver&) = delete;
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~twoPhaseSolver();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Called at the start of the time-step, before the PIMPLE loop
|
||||
virtual void preSolve();
|
||||
|
||||
//- Called at the start of the PIMPLE loop
|
||||
virtual void prePredictor();
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const twoPhaseSolver&) = delete;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace solvers
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 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 "twoPhaseVoFMixture.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(twoPhaseVoFMixture, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::twoPhaseVoFMixture::twoPhaseVoFMixture(const fvMesh& mesh)
|
||||
:
|
||||
VoFMixture(mesh),
|
||||
twoPhaseMixture(mesh)
|
||||
{}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,93 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 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::twoPhaseVoFMixture
|
||||
|
||||
Description
|
||||
Class to represent a VoF mixture
|
||||
|
||||
SourceFiles
|
||||
twoPhaseVoFMixture.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef twoPhaseVoFMixture_H
|
||||
#define twoPhaseVoFMixture_H
|
||||
|
||||
#include "VoFMixture.H"
|
||||
#include "twoPhaseMixture.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class twoPhaseVoFMixture Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class twoPhaseVoFMixture
|
||||
:
|
||||
public VoFMixture,
|
||||
public twoPhaseMixture
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
TypeName("twoPhaseVoFMixture");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
twoPhaseVoFMixture(const fvMesh& mesh);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~twoPhaseVoFMixture()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the mixture density
|
||||
using twoPhaseMixture::rho;
|
||||
|
||||
//- Correct the mixture properties
|
||||
using twoPhaseMixture::correct;
|
||||
|
||||
//- Read base phaseProperties dictionary
|
||||
using twoPhaseMixture::read;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user