incompressiblePhase, compressiblePhase: Refactored using the new phase base-class

used in the incompressibleMultiphaseMixture and compressibleMultiphaseMixture
respectively which are used in multiphaseInterFoam and
compressibleMultiphaseInterFoam respectively.

Also the PtrDictionary of phases has been replaced by PtrListDictionary of
phases and iterations over the linked-list replaced by forAll loops which is
easier to use and consistent with the multiphaseEuler solver module.
This commit is contained in:
Henry Weller
2023-01-08 16:22:06 +00:00
parent 9e51bb48ce
commit 167c207e49
28 changed files with 1015 additions and 366 deletions

View File

@ -0,0 +1,12 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Parse arguments for library compilation
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
multiphaseInterFoam/Allwmake $targetType $*
compressibleMultiphaseInterFoam/Allwmake $targetType $*
driftFluxFoam/Allwmake $targetType $*
wmake $targetType cavitatingFoam
#------------------------------------------------------------------------------

View File

@ -1,6 +1,5 @@
EXE_INC = \
-I. \
-I../interFoam \
-I$(FOAM_SOLVERS)/multiphase/multiphaseInterFoam/incompressibleMultiphaseMixture/lnInclude \
-IcompressibleMultiphaseMixture/lnInclude \
-I$(LIB_SRC)/physicalProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \

View File

@ -1,4 +1,4 @@
phaseModel/phaseModel.C
compressiblePhase/compressiblePhase.C
compressibleMultiphaseMixture.C
LIB = $(FOAM_LIBBIN)/libcompressibleMultiphaseMixture

View File

@ -1,4 +1,5 @@
EXE_INC = \
-I$(FOAM_SOLVERS)/multiphase/multiphaseInterFoam/incompressibleMultiphaseMixture/lnInclude \
-I$(LIB_SRC)/physicalProperties/lnInclude \
-I$(LIB_SRC)/multiphaseModels/multiphaseProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
@ -6,6 +7,7 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude
LIB_LIBS = \
-lincompressibleMultiphaseMixture \
-lfluidThermophysicalModels \
-lmultiphaseProperties \
-lspecie \

View File

@ -51,9 +51,9 @@ void Foam::compressibleMultiphaseMixture::calcAlphas()
scalar level = 0.0;
alphas_ == 0.0;
forAllIter(PtrDictionary<phaseModel>, phases_, phase)
forAll(phases_, phasei)
{
alphas_ += level*phase();
alphas_ += level*phases_[phasei];
level += 1.0;
}
}
@ -107,7 +107,7 @@ Foam::compressibleMultiphaseMixture::compressibleMultiphaseMixture
U.mesh()
),
phases_(lookup("phases"), phaseModel::iNew(p_, T_)),
phases_(lookup("phases"), compressiblePhase::iNew(T_)),
rho_
(
@ -173,49 +173,46 @@ Foam::compressibleMultiphaseMixture::compressibleMultiphaseMixture
void Foam::compressibleMultiphaseMixture::correctThermo()
{
forAllIter(PtrDictionary<phaseModel>, phases_, phasei)
forAll(phases_, phasei)
{
phasei().correct();
phases_[phasei].correct(p_, T_);
}
}
void Foam::compressibleMultiphaseMixture::correct()
{
PtrDictionary<phaseModel>::iterator phasei = phases_.begin();
rho_ = phases_[0]*phases_[0].thermo().rho();
rho_ = phasei()*phasei().thermo().rho();
for (++phasei; phasei != phases_.end(); ++phasei)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
rho_ += phasei()*phasei().thermo().rho();
rho_ += phases_[phasei]*phases_[phasei].thermo().rho();
}
forAllIter(PtrDictionary<phaseModel>, phases_, phasei)
forAll(phases_, phasei)
{
phasei().Alpha() = phasei()*phasei().thermo().rho()/rho_;
phases_[phasei].Alpha() =
phases_[phasei]*phases_[phasei].thermo().rho()/rho_;
}
}
void Foam::compressibleMultiphaseMixture::correctRho(const volScalarField& dp)
{
forAllIter(PtrDictionary<phaseModel>, phases_, phasei)
forAll(phases_, phasei)
{
phasei().thermo().rho() += phasei().thermo().psi()*dp;
phases_[phasei].thermo().rho() += phases_[phasei].thermo().psi()*dp;
}
}
Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::nu() const
{
PtrDictionary<phaseModel>::const_iterator phasei = phases_.begin();
volScalarField mu(phases_[0].Alpha()*phases_[0].thermo().mu());
volScalarField mu(phasei().Alpha()*phasei().thermo().mu());
for (++phasei; phasei != phases_.end(); ++phasei)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
mu += phasei().Alpha()*phasei().thermo().mu();
mu += phases_[phasei].Alpha()*phases_[phasei].thermo().mu();
}
return mu/rho_;
@ -227,18 +224,17 @@ Foam::tmp<Foam::scalarField> Foam::compressibleMultiphaseMixture::nu
const label patchi
) const
{
PtrDictionary<phaseModel>::const_iterator phasei = phases_.begin();
scalarField mu
(
phasei().Alpha().boundaryField()[patchi]*phasei().thermo().mu(patchi)
phases_[0].Alpha().boundaryField()[patchi]
*phases_[0].thermo().mu(patchi)
);
for (++phasei; phasei != phases_.end(); ++phasei)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
mu +=
phasei().Alpha().boundaryField()[patchi]
*phasei().thermo().mu(patchi);
phases_[phasei].Alpha().boundaryField()[patchi]
*phases_[phasei].thermo().mu(patchi);
}
return mu/rho_.boundaryField()[patchi];
@ -250,25 +246,23 @@ Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::alphaEff
const volScalarField& nut
) const
{
PtrDictionary<phaseModel>::const_iterator phasei = phases_.begin();
tmp<volScalarField> talphaEff
(
phasei()
phases_[0]
*(
phasei().thermo().kappa()
+ phasei().thermo().rho()*phasei().thermo().Cp()*nut
)/phasei().thermo().Cv()
phases_[0].thermo().kappa()
+ phases_[0].thermo().rho()*phases_[0].thermo().Cp()*nut
)/phases_[0].thermo().Cv()
);
for (++phasei; phasei != phases_.end(); ++phasei)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
talphaEff.ref() +=
phasei()
phases_[phasei]
*(
phasei().thermo().kappa()
+ phasei().thermo().rho()*phasei().thermo().Cp()*nut
)/phasei().thermo().Cv();
phases_[phasei].thermo().kappa()
+ phases_[phasei].thermo().rho()*phases_[phasei].thermo().Cp()*nut
)/phases_[phasei].thermo().Cv();
}
return talphaEff;
@ -277,13 +271,11 @@ Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::alphaEff
Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::rCv() const
{
PtrDictionary<phaseModel>::const_iterator phasei = phases_.begin();
tmp<volScalarField> trCv(phases_[0]/phases_[0].thermo().Cv());
tmp<volScalarField> trCv(phasei()/phasei().thermo().Cv());
for (++phasei; phasei != phases_.end(); ++phasei)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
trCv.ref() += phasei()/phasei().thermo().Cv();
trCv.ref() += phases_[phasei]/phases_[phasei].thermo().Cv();
}
return trCv;
@ -305,16 +297,13 @@ Foam::compressibleMultiphaseMixture::surfaceTensionForce() const
surfaceScalarField& stf = tstf.ref();
forAllConstIter(PtrDictionary<phaseModel>, phases_, phase1)
forAll(phases_, phasei)
{
const phaseModel& alpha1 = phase1();
const compressiblePhase& alpha1 = phases_[phasei];
PtrDictionary<phaseModel>::const_iterator phase2 = phase1;
++phase2;
for (; phase2 != phases_.end(); ++phase2)
for (label phasej = phasei+1; phasej<phases_.size(); phasej++)
{
const phaseModel& alpha2 = phase2();
const compressiblePhase& alpha2 = phases_[phasej];
sigmaTable::const_iterator sigma =
sigmas_.find(interfacePair(alpha1, alpha2));
@ -348,16 +337,24 @@ void Foam::compressibleMultiphaseMixture::solve()
label nAlphaSubCycles(alphaControls.lookup<label>("nAlphaSubCycles"));
scalar cAlpha(alphaControls.lookup<scalar>("cAlpha"));
volScalarField& alpha = phases_.first();
if (nAlphaSubCycles > 1)
{
surfaceScalarField rhoPhiSum(0.0*rhoPhi_);
dimensionedScalar totalDeltaT = runTime.deltaT();
List<volScalarField*> alphaPtrs(phases_.size());
forAll(phases_, phasei)
{
alphaPtrs[phasei] = &phases_[phasei];
}
for
(
subCycle<volScalarField> alphaSubCycle(alpha, nAlphaSubCycles);
subCycle<volScalarField, subCycleFields> alphaSubCycle
(
alphaPtrs,
nAlphaSubCycles
);
!(++alphaSubCycle).end();
)
{
@ -415,8 +412,8 @@ Foam::tmp<Foam::surfaceScalarField> Foam::compressibleMultiphaseMixture::nHatf
Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::K
(
const phaseModel& alpha1,
const phaseModel& alpha2
const phase& alpha1,
const phase& alpha2
) const
{
tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
@ -448,10 +445,13 @@ Foam::compressibleMultiphaseMixture::nearInterface() const
)
);
forAllConstIter(PtrDictionary<phaseModel>, phases_, phase)
forAll(phases_, phasei)
{
tnearInt.ref() =
max(tnearInt(), pos0(phase() - 0.01)*pos0(0.99 - phase()));
tnearInt.ref() = max
(
tnearInt(),
pos0(phases_[phasei] - 0.01)*pos0(0.99 - phases_[phasei])
);
}
return tnearInt;
@ -471,11 +471,10 @@ void Foam::compressibleMultiphaseMixture::solveAlphas
UPtrList<const volScalarField> alphas(phases_.size());
PtrList<surfaceScalarField> alphaPhis(phases_.size());
int phasei = 0;
forAllIter(PtrDictionary<phaseModel>, phases_, phase)
forAll(phases_, phasei)
{
const phaseModel& alpha = phase();
const compressiblePhase& alpha = phases_[phasei];
alphas.set(phasei, &alpha);
@ -496,9 +495,9 @@ void Foam::compressibleMultiphaseMixture::solveAlphas
surfaceScalarField& alphaPhi = alphaPhis[phasei];
forAllIter(PtrDictionary<phaseModel>, phases_, phase2)
forAll(phases_, phasej)
{
phaseModel& alpha2 = phase2();
compressiblePhase& alpha2 = phases_[phasej];
if (&alpha2 == &alpha) continue;
@ -526,8 +525,6 @@ void Foam::compressibleMultiphaseMixture::solveAlphas
zeroField(),
false
);
phasei++;
}
MULES::limitSum(alphas, alphaPhis, phi_);
@ -548,11 +545,9 @@ void Foam::compressibleMultiphaseMixture::solveAlphas
volScalarField divU(fvc::div(fvc::absolute(phi_, U_)));
phasei = 0;
forAllIter(PtrDictionary<phaseModel>, phases_, phase)
forAll(phases_, phasei)
{
phaseModel& alpha = phase();
compressiblePhase& alpha = phases_[phasei];
surfaceScalarField& alphaPhi = alphaPhis[phasei];
@ -598,9 +593,9 @@ void Foam::compressibleMultiphaseMixture::solveAlphas
}
}
forAllConstIter(PtrDictionary<phaseModel>, phases_, phase2)
forAll(phases_, phasej)
{
const phaseModel& alpha2 = phase2();
const compressiblePhase& alpha2 = phases_[phasej];
if (&alpha2 == &alpha) continue;
@ -638,8 +633,6 @@ void Foam::compressibleMultiphaseMixture::solveAlphas
<< endl;
sumAlpha += alpha;
phasei++;
}
Info<< "Phase-sum volume fraction, min, max = "

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -34,8 +34,8 @@ SourceFiles
#ifndef compressibleMultiphaseMixture_H
#define compressibleMultiphaseMixture_H
#include "phaseModel.H"
#include "PtrDictionary.H"
#include "compressiblePhase.H"
#include "PtrListDictionary.H"
#include "volFields.H"
#include "surfaceFields.H"
@ -87,7 +87,7 @@ public:
Pair<word>(alpha1Name, alpha2Name)
{}
interfacePair(const phaseModel& alpha1, const phaseModel& alpha2)
interfacePair(const phase& alpha1, const phase& alpha2)
:
Pair<word>(alpha1.name(), alpha2.name())
{}
@ -132,7 +132,7 @@ private:
volScalarField T_;
//- Dictionary of phases
PtrDictionary<phaseModel> phases_;
PtrListDictionary<compressiblePhase> phases_;
volScalarField rho_;
@ -173,8 +173,8 @@ private:
tmp<volScalarField> K
(
const phaseModel& alpha1,
const phaseModel& alpha2
const phase& alpha1,
const phase& alpha2
) const;
@ -202,13 +202,13 @@ public:
// Member Functions
//- Return the phases
const PtrDictionary<phaseModel>& phases() const
const PtrListDictionary<compressiblePhase>& phases() const
{
return phases_;
}
//- Return non-const access to the phases
PtrDictionary<phaseModel>& phases()
PtrListDictionary<compressiblePhase>& phases()
{
return phases_;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,82 +23,69 @@ License
\*---------------------------------------------------------------------------*/
#include "phaseModel.H"
#include "compressiblePhase.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::phaseModel::phaseModel
Foam::compressiblePhase::compressiblePhase
(
const word& phaseName,
const volScalarField& p,
const word& name,
const volScalarField& T
)
:
volScalarField
(
IOobject
(
IOobject::groupName("alpha", phaseName),
p.mesh().time().name(),
p.mesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
p.mesh()
),
name_(phaseName),
p_(p),
T_(T),
phase(name, T.mesh()),
thermo_(nullptr),
Alpha_
(
IOobject
(
IOobject::groupName("Alpha", phaseName),
p.mesh().time().name(),
p.mesh()
IOobject::groupName("Alpha", name),
T.mesh().time().name(),
T.mesh()
),
p.mesh(),
T.mesh(),
dimensionedScalar(dimless, 0)
),
dgdt_
(
IOobject
(
IOobject::groupName("dgdt", phaseName),
p.mesh().time().name(),
p.mesh(),
IOobject::groupName("dgdt", name),
T.mesh().time().name(),
T.mesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
p.mesh(),
T.mesh(),
dimensionedScalar(dimless/dimTime, 0)
)
{
{
volScalarField Tp(IOobject::groupName("T", phaseName), T);
volScalarField Tp(IOobject::groupName("T", name), T);
Tp.write();
}
thermo_ = rhoThermo::New(p.mesh(), phaseName);
thermo_->validate(phaseName, "e");
correct();
thermo_ = rhoThermo::New(T.mesh(), name);
thermo_->validate(name, "e");
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::phaseModel> Foam::phaseModel::clone() const
Foam::autoPtr<Foam::compressiblePhase> Foam::compressiblePhase::clone() const
{
NotImplemented;
return autoPtr<phaseModel>(nullptr);
return autoPtr<compressiblePhase>(nullptr);
}
void Foam::phaseModel::correct()
void Foam::compressiblePhase::correct
(
const volScalarField& p,
const volScalarField& T
)
{
thermo_->he() = thermo_->he(p_, T_);
thermo_->he() = thermo_->he(p, T);
thermo_->correct();
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::phaseModel
Foam::compressiblePhase
Description
Single incompressible phase derived from the phase-fraction.
@ -30,17 +30,16 @@ Description
simulations.
SourceFiles
phaseModel.C
compressiblePhase.C
\*---------------------------------------------------------------------------*/
#ifndef phaseModel_H
#define phaseModel_H
#ifndef compressiblePhase_H
#define compressiblePhase_H
#include "rhoThermo.H"
#include "volFields.H"
#include "phase.H"
#include "dictionaryEntry.H"
#include "rhoThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -48,18 +47,15 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class phaseModel Declaration
Class compressiblePhase Declaration
\*---------------------------------------------------------------------------*/
class phaseModel
class compressiblePhase
:
public volScalarField
public phase
{
// Private Data
word name_;
const volScalarField& p_;
const volScalarField& T_;
autoPtr<rhoThermo> thermo_;
volScalarField Alpha_;
volScalarField::Internal dgdt_;
@ -70,54 +66,43 @@ public:
// Constructors
//- Construct from components
phaseModel
compressiblePhase
(
const word& phaseName,
const volScalarField& p,
const volScalarField& T
);
//- Return clone
autoPtr<phaseModel> clone() const;
autoPtr<compressiblePhase> clone() const;
//- Return a pointer to a new phaseModel created on freestore
//- Return a pointer to a new compressiblePhase created on freestore
// from Istream
class iNew
{
const volScalarField& p_;
const volScalarField& T_;
public:
iNew
(
const volScalarField& p,
const volScalarField& T
)
:
p_(p),
T_(T)
{}
autoPtr<phaseModel> operator()(Istream& is) const
autoPtr<compressiblePhase> operator()(Istream& is) const
{
return autoPtr<phaseModel>(new phaseModel(is, p_, T_));
return autoPtr<compressiblePhase>
(
new compressiblePhase(is, T_)
);
}
};
// Member Functions
const word& name() const
{
return name_;
}
const word& keyword() const
{
return name();
}
//- Return const-access to phase rhoThermo
const rhoThermo& thermo() const
{
@ -154,7 +139,11 @@ public:
return dgdt_;
}
void correct();
void correct
(
const volScalarField& p,
const volScalarField& T
);
};

View File

@ -3,13 +3,8 @@ volScalarField::Internal contErr
(fvc::ddt(rho) + fvc::div(mixture.rhoPhi()))()
);
forAllConstIter
(
PtrDictionary<phaseModel>,
mixture.phases(),
phase
)
forAll(mixture.phases(), phasei)
{
const volScalarField& rho = phase().thermo().rho()();
contErr -= (fvModels.source(phase(), rho)&rho);
const volScalarField& rho = mixture.phases()[phasei].thermo().rho();
contErr -= (fvModels.source(mixture.phases()[phasei], rho)&rho);
}

View File

@ -24,15 +24,10 @@
PtrList<fvScalarMatrix> p_rghEqnComps(mixture.phases().size());
label phasei = 0;
forAllConstIter
(
PtrDictionary<phaseModel>,
mixture.phases(),
phase
)
forAll(mixture.phases(), phasei)
{
const rhoThermo& thermo = phase().thermo();
const compressiblePhase& phase = mixture.phases()[phasei];
const rhoThermo& thermo = phase.thermo();
const volScalarField& rho = thermo.rho()();
p_rghEqnComps.set
@ -41,11 +36,9 @@
(
fvc::ddt(rho) + thermo.psi()*correction(fvm::ddt(p_rgh))
+ fvc::div(phi, rho) - fvc::Sp(fvc::div(phi), rho)
- (fvModels.source(phase(), rho)&rho)
- (fvModels.source(phase, rho)&rho)
).ptr()
);
phasei++;
}
// Cache p_rgh prior to solve for density update
@ -61,17 +54,13 @@
tmp<fvScalarMatrix> p_rghEqnComp;
phasei = 0;
forAllConstIter
(
PtrDictionary<phaseModel>,
mixture.phases(),
phase
)
forAll(mixture.phases(), phasei)
{
const compressiblePhase& phase = mixture.phases()[phasei];
tmp<fvScalarMatrix> p_rghEqnCompi
(
(max(phase(), scalar(0))/phase().thermo().rho())
(max(phase, scalar(0))/phase.thermo().rho())
*p_rghEqnComps[phasei]
);
@ -83,8 +72,6 @@
{
p_rghEqnComp.ref() += p_rghEqnCompi;
}
phasei++;
}
solve(p_rghEqnComp + p_rghEqnIncomp);
@ -94,19 +81,13 @@
p = max(p_rgh + mixture.rho()*gh, pMin);
p_rgh = p - rho*gh;
phasei = 0;
forAllIter
(
PtrDictionary<phaseModel>,
mixture.phases(),
phase
)
forAll(mixture.phases(), phasei)
{
phase().dgdt() =
pos0(phase())
*(p_rghEqnComps[phasei] & p_rgh)/phase().thermo().rho();
compressiblePhase& phase = mixture.phases()[phasei];
phasei++;
phase.dgdt() =
pos0(phase)
*(p_rghEqnComps[phasei] & p_rgh)/phase.thermo().rho();
}
phi = phiHbyA + p_rghEqnIncomp.flux();

View File

@ -1,7 +1,7 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
wclean libso multiphaseMixture
wclean libso incompressibleMultiphaseMixture
wclean
#------------------------------------------------------------------------------

View File

@ -4,7 +4,7 @@ cd ${0%/*} || exit 1 # Run from this directory
# Parse arguments for library compilation
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
wmake $targetType multiphaseMixture
wmake $targetType incompressibleMultiphaseMixture
wmake $targetType
#------------------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
EXE_INC = \
-ImultiphaseMixture/lnInclude \
-IincompressibleMultiphaseMixture/lnInclude \
-I$(LIB_SRC)/physicalProperties/lnInclude \
-I$(LIB_SRC)/twoPhaseModels/VoF \
-I$(LIB_SRC)/twoPhaseModels/interfaceCompression/lnInclude \
@ -11,7 +11,7 @@ EXE_INC = \
-I$(LIB_SRC)/sampling/lnInclude
EXE_LIBS = \
-lmultiphaseInterFoam \
-lincompressibleMultiphaseMixture \
-lphysicalProperties \
-linterfaceCompression \
-linterfaceProperties \

View File

@ -28,7 +28,7 @@ volVectorField U
#include "createPhi.H"
multiphaseMixture mixture(U, phi);
incompressibleMultiphaseMixture mixture(U, phi);
// Need to store rho for ddt(rho, U)
volScalarField rho

View File

@ -0,0 +1,5 @@
phase/phase.C
incompressiblePhase/incompressiblePhase.C
incompressibleMultiphaseMixture.C
LIB = $(FOAM_LIBBIN)/libincompressibleMultiphaseMixture

View File

@ -23,7 +23,7 @@ License
\*---------------------------------------------------------------------------*/
#include "multiphaseMixture.H"
#include "incompressibleMultiphaseMixture.H"
#include "alphaContactAngleFvPatchScalarField.H"
#include "correctContactAngle.H"
#include "Time.H"
@ -38,14 +38,14 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::multiphaseMixture::calcAlphas()
void Foam::incompressibleMultiphaseMixture::calcAlphas()
{
scalar level = 0.0;
alphas_ == 0.0;
forAllIter(PtrDictionary<phase>, phases_, iter)
forAll(phases_, phasei)
{
alphas_ += level*iter();
alphas_ += level*phases_[phasei];
level += 1.0;
}
}
@ -53,7 +53,7 @@ void Foam::multiphaseMixture::calcAlphas()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::multiphaseMixture::multiphaseMixture
Foam::incompressibleMultiphaseMixture::incompressibleMultiphaseMixture
(
const volVectorField& U,
const surfaceScalarField& phi
@ -71,7 +71,7 @@ Foam::multiphaseMixture::multiphaseMixture
)
),
phases_(lookup("phases"), phase::iNew(U.mesh())),
phases_(lookup("phases"), incompressiblePhase::iNew(U.mesh())),
mesh_(U.mesh()),
U_(U),
@ -132,16 +132,17 @@ Foam::multiphaseMixture::multiphaseMixture
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::rho() const
Foam::incompressibleMultiphaseMixture::rho() const
{
PtrDictionary<phase>::const_iterator iter = phases_.begin();
tmp<volScalarField> trho = iter()*iter().rho();
tmp<volScalarField> trho
(
phases_[0]*phases_[0].rho()
);
volScalarField& rho = trho.ref();
for (++iter; iter != phases_.end(); ++iter)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
rho += iter()*iter().rho();
rho += phases_[phasei]*phases_[phasei].rho();
}
return trho;
@ -149,16 +150,19 @@ Foam::multiphaseMixture::rho() const
Foam::tmp<Foam::scalarField>
Foam::multiphaseMixture::rho(const label patchi) const
Foam::incompressibleMultiphaseMixture::rho(const label patchi) const
{
PtrDictionary<phase>::const_iterator iter = phases_.begin();
tmp<scalarField> trho = iter().boundaryField()[patchi]*iter().rho().value();
tmp<scalarField> trho
(
phases_[0].boundaryField()[patchi]*phases_[0].rho().value()
);
scalarField& rho = trho.ref();
for (++iter; iter != phases_.end(); ++iter)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
rho += iter().boundaryField()[patchi]*iter().rho().value();
rho +=
phases_[phasei].boundaryField()[patchi]
*phases_[phasei].rho().value();
}
return trho;
@ -166,16 +170,17 @@ Foam::multiphaseMixture::rho(const label patchi) const
Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::mu() const
Foam::incompressibleMultiphaseMixture::mu() const
{
PtrDictionary<phase>::const_iterator iter = phases_.begin();
tmp<volScalarField> tmu = iter()*iter().rho()*iter().nu();
tmp<volScalarField> tmu
(
phases_[0]*phases_[0].rho()*phases_[0].nu()
);
volScalarField& mu = tmu.ref();
for (++iter; iter != phases_.end(); ++iter)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
mu += iter()*iter().rho()*iter().nu();
mu += phases_[phasei]*phases_[phasei].rho()*phases_[phasei].nu();
}
return tmu;
@ -183,22 +188,22 @@ Foam::multiphaseMixture::mu() const
Foam::tmp<Foam::scalarField>
Foam::multiphaseMixture::mu(const label patchi) const
Foam::incompressibleMultiphaseMixture::mu(const label patchi) const
{
PtrDictionary<phase>::const_iterator iter = phases_.begin();
tmp<scalarField> tmu =
iter().boundaryField()[patchi]
*iter().rho().value()
*iter().nu(patchi);
tmp<scalarField> tmu
(
phases_[0].boundaryField()[patchi]
*phases_[0].rho().value()
*phases_[0].nu(patchi)
);
scalarField& mu = tmu.ref();
for (++iter; iter != phases_.end(); ++iter)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
mu +=
iter().boundaryField()[patchi]
*iter().rho().value()
*iter().nu(patchi);
phases_[phasei].boundaryField()[patchi]
*phases_[phasei].rho().value()
*phases_[phasei].nu(patchi);
}
return tmu;
@ -206,18 +211,20 @@ Foam::multiphaseMixture::mu(const label patchi) const
Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::muf() const
Foam::incompressibleMultiphaseMixture::muf() const
{
PtrDictionary<phase>::const_iterator iter = phases_.begin();
tmp<surfaceScalarField> tmuf =
fvc::interpolate(iter())*iter().rho()*fvc::interpolate(iter().nu());
tmp<surfaceScalarField> tmuf
(
fvc::interpolate(phases_[0])
*phases_[0].rho()*fvc::interpolate(phases_[0].nu())
);
surfaceScalarField& muf = tmuf.ref();
for (++iter; iter != phases_.end(); ++iter)
for (label phasei=1; phasei<phases_.size(); phasei++)
{
muf +=
fvc::interpolate(iter())*iter().rho()*fvc::interpolate(iter().nu());
fvc::interpolate(phases_[phasei])
*phases_[phasei].rho()*fvc::interpolate(phases_[phasei].nu());
}
return tmuf;
@ -225,28 +232,28 @@ Foam::multiphaseMixture::muf() const
Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::nu() const
Foam::incompressibleMultiphaseMixture::nu() const
{
return nu_;
}
Foam::tmp<Foam::scalarField>
Foam::multiphaseMixture::nu(const label patchi) const
Foam::incompressibleMultiphaseMixture::nu(const label patchi) const
{
return nu_.boundaryField()[patchi];
}
Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::nuf() const
Foam::incompressibleMultiphaseMixture::nuf() const
{
return muf()/fvc::interpolate(rho());
}
Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::surfaceTensionForce() const
Foam::incompressibleMultiphaseMixture::surfaceTensionForce() const
{
tmp<surfaceScalarField> tstf
(
@ -260,16 +267,13 @@ Foam::multiphaseMixture::surfaceTensionForce() const
surfaceScalarField& stf = tstf.ref();
forAllConstIter(PtrDictionary<phase>, phases_, iter1)
forAll(phases_, phasei)
{
const phase& alpha1 = iter1();
const incompressiblePhase& alpha1 = phases_[phasei];
PtrDictionary<phase>::const_iterator iter2 = iter1;
++iter2;
for (; iter2 != phases_.end(); ++iter2)
for (label phasej = phasei+1; phasej<phases_.size(); phasej++)
{
const phase& alpha2 = iter2();
const incompressiblePhase& alpha2 = phases_[phasej];
sigmaTable::const_iterator sigma =
sigmas_.find(interfacePair(alpha1, alpha2));
@ -295,14 +299,12 @@ Foam::multiphaseMixture::surfaceTensionForce() const
}
void Foam::multiphaseMixture::solve()
void Foam::incompressibleMultiphaseMixture::solve()
{
correct();
const Time& runTime = mesh_.time();
volScalarField& alpha = phases_.first();
const dictionary& alphaControls = mesh_.solution().solverDict("alpha");
label nAlphaSubCycles(alphaControls.lookup<label>("nAlphaSubCycles"));
scalar cAlpha(alphaControls.lookup<scalar>("cAlpha"));
@ -323,9 +325,19 @@ void Foam::multiphaseMixture::solve()
dimensionedScalar totalDeltaT = runTime.deltaT();
List<volScalarField*> alphaPtrs(phases_.size());
forAll(phases_, phasei)
{
alphaPtrs[phasei] = &phases_[phasei];
}
for
(
subCycle<volScalarField> alphaSubCycle(alpha, nAlphaSubCycles);
subCycle<volScalarField, subCycleFields> alphaSubCycle
(
alphaPtrs,
nAlphaSubCycles
);
!(++alphaSubCycle).end();
)
{
@ -345,16 +357,17 @@ void Foam::multiphaseMixture::solve()
}
void Foam::multiphaseMixture::correct()
void Foam::incompressibleMultiphaseMixture::correct()
{
forAllIter(PtrDictionary<phase>, phases_, iter)
forAll(phases_, phasei)
{
iter().correct();
phases_[phasei].correct();
}
}
Foam::tmp<Foam::surfaceVectorField> Foam::multiphaseMixture::nHatfv
Foam::tmp<Foam::surfaceVectorField>
Foam::incompressibleMultiphaseMixture::nHatfv
(
const volScalarField& alpha1,
const volScalarField& alpha2
@ -380,7 +393,7 @@ Foam::tmp<Foam::surfaceVectorField> Foam::multiphaseMixture::nHatfv
}
Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseMixture::nHatf
Foam::tmp<Foam::surfaceScalarField> Foam::incompressibleMultiphaseMixture::nHatf
(
const volScalarField& alpha1,
const volScalarField& alpha2
@ -391,7 +404,7 @@ Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseMixture::nHatf
}
Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K
Foam::tmp<Foam::volScalarField> Foam::incompressibleMultiphaseMixture::K
(
const phase& alpha1,
const phase& alpha2
@ -414,7 +427,7 @@ Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K
Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::nearInterface() const
Foam::incompressibleMultiphaseMixture::nearInterface() const
{
tmp<volScalarField> tnearInt
(
@ -426,17 +439,20 @@ Foam::multiphaseMixture::nearInterface() const
)
);
forAllConstIter(PtrDictionary<phase>, phases_, iter)
forAll(phases_, phasei)
{
tnearInt.ref() =
max(tnearInt(), pos0(iter() - 0.01)*pos0(0.99 - iter()));
tnearInt.ref() = max
(
tnearInt(),
pos0(phases_[phasei] - 0.01)*pos0(0.99 - phases_[phasei])
);
}
return tnearInt;
}
void Foam::multiphaseMixture::solveAlphas
void Foam::incompressibleMultiphaseMixture::solveAlphas
(
const scalar cAlpha
)
@ -449,11 +465,10 @@ void Foam::multiphaseMixture::solveAlphas
UPtrList<const volScalarField> alphas(phases_.size());
PtrList<surfaceScalarField> alphaPhis(phases_.size());
int phasei = 0;
forAllIter(PtrDictionary<phase>, phases_, iter)
forAll(phases_, phasei)
{
const phase& alpha = iter();
const incompressiblePhase& alpha = phases_[phasei];
alphas.set(phasei, &alpha);
@ -474,9 +489,9 @@ void Foam::multiphaseMixture::solveAlphas
surfaceScalarField& alphaPhi = alphaPhis[phasei];
forAllIter(PtrDictionary<phase>, phases_, iter2)
forAll(phases_, phasej)
{
phase& alpha2 = iter2();
incompressiblePhase& alpha2 = phases_[phasej];
if (&alpha2 == &alpha) continue;
@ -504,8 +519,6 @@ void Foam::multiphaseMixture::solveAlphas
zeroField(),
false
);
phasei++;
}
MULES::limitSum(alphas, alphaPhis, phi_);
@ -524,11 +537,9 @@ void Foam::multiphaseMixture::solveAlphas
dimensionedScalar(dimless, 0)
);
phasei = 0;
forAllIter(PtrDictionary<phase>, phases_, iter)
forAll(phases_, phasei)
{
phase& alpha = iter();
incompressiblePhase& alpha = phases_[phasei];
surfaceScalarField& alphaPhi = alphaPhis[phasei];
MULES::explicitSolve
@ -547,8 +558,6 @@ void Foam::multiphaseMixture::solveAlphas
<< endl;
sumAlpha += alpha;
phasei++;
}
Info<< "Phase-sum volume fraction, min, max = "
@ -559,9 +568,9 @@ void Foam::multiphaseMixture::solveAlphas
// Correct the sum of the phase-fractions to avoid 'drift'
volScalarField sumCorr(1.0 - sumAlpha);
forAllIter(PtrDictionary<phase>, phases_, iter)
forAll(phases_, phasei)
{
phase& alpha = iter();
incompressiblePhase& alpha = phases_[phasei];
alpha += alpha*sumCorr;
}
@ -569,7 +578,7 @@ void Foam::multiphaseMixture::solveAlphas
}
bool Foam::multiphaseMixture::read()
bool Foam::incompressibleMultiphaseMixture::read()
{
if (regIOobject::read())
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,10 +22,10 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::multiphaseMixture
Foam::incompressibleMultiphaseMixture
Description
Incompressible multi-phase mixture with built in solution for the
Incompressible multiphase mixture with built in solution for the
phase fractions with interface compression for interface-capturing.
Derived from viscosity so that it can be used in conjunction
@ -35,17 +35,17 @@ Description
between each phase-pair.
SourceFiles
multiphaseMixture.C
incompressibleMultiphaseMixture.C
\*---------------------------------------------------------------------------*/
#ifndef multiphaseMixture_H
#define multiphaseMixture_H
#ifndef incompressibleMultiphaseMixture_H
#define incompressibleMultiphaseMixture_H
#include "viscosity.H"
#include "IOdictionary.H"
#include "phase.H"
#include "PtrDictionary.H"
#include "incompressiblePhase.H"
#include "PtrListDictionary.H"
#include "volFields.H"
#include "surfaceFields.H"
@ -55,10 +55,10 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class multiphaseMixture Declaration
Class incompressibleMultiphaseMixture Declaration
\*---------------------------------------------------------------------------*/
class multiphaseMixture
class incompressibleMultiphaseMixture
:
public IOdictionary,
public viscosity
@ -134,7 +134,7 @@ private:
// Private Data
//- Dictionary of phases
PtrDictionary<phase> phases_;
PtrListDictionary<incompressiblePhase> phases_;
const fvMesh& mesh_;
const volVectorField& U_;
@ -181,7 +181,7 @@ public:
// Constructors
//- Construct from components
multiphaseMixture
incompressibleMultiphaseMixture
(
const volVectorField& U,
const surfaceScalarField& phi
@ -189,14 +189,14 @@ public:
//- Destructor
virtual ~multiphaseMixture()
virtual ~incompressibleMultiphaseMixture()
{}
// Member Functions
//- Return the phases
const PtrDictionary<phase>& phases() const
const PtrListDictionary<incompressiblePhase>& phases() const
{
return phases_;
}

View File

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-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 "incompressiblePhase.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::incompressiblePhase::incompressiblePhase
(
const word& name,
const fvMesh& mesh
)
:
phase(name, mesh),
nuModel_(viscosityModel::New(mesh, name)),
rho_("rho", dimDensity, nuModel_())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::incompressiblePhase>
Foam::incompressiblePhase::clone() const
{
NotImplemented;
return autoPtr<incompressiblePhase>(nullptr);
}
void Foam::incompressiblePhase::correct()
{
nuModel_->correct();
}
bool Foam::incompressiblePhase::read(const dictionary& dict)
{
dict.lookup("rho") >> rho_;
return true;
}
// ************************************************************************* //

View File

@ -22,22 +22,23 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::phase
Foam::incompressiblePhase
Description
Single incompressible phase derived from the phase-fraction.
Used as part of the multiPhaseMixture for interface-capturing multi-phase
simulations.
Single incompressible phase derived from the phase.
Used as part of the multiphaseMixture for interface-capturing
multiphase simulations.
SourceFiles
phase.C
incompressiblePhase.C
\*---------------------------------------------------------------------------*/
#ifndef phase_H
#define phase_H
#ifndef incompressiblePhase_H
#define incompressiblePhase_H
#include "volFields.H"
#include "phase.H"
#include "dictionaryEntry.H"
#include "viscosityModel.H"
@ -47,16 +48,15 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class phase Declaration
Class incompressiblePhase Declaration
\*---------------------------------------------------------------------------*/
class phase
class incompressiblePhase
:
public volScalarField
public phase
{
// Private Data
word name_;
autoPtr<viscosityModel> nuModel_;
dimensionedScalar rho_;
@ -66,16 +66,16 @@ public:
// Constructors
//- Construct from components
phase
incompressiblePhase
(
const word& name,
const fvMesh& mesh
);
//- Return clone
autoPtr<phase> clone() const;
autoPtr<incompressiblePhase> clone() const;
//- Return a pointer to a new phase created on freestore
//- Return a pointer to a new incompressiblePhase created on freestore
// from Istream
class iNew
{
@ -88,27 +88,21 @@ public:
mesh_(mesh)
{}
autoPtr<phase> operator()(Istream& is) const
autoPtr<incompressiblePhase> operator()(Istream& is) const
{
const word name(is);
return autoPtr<phase>(new phase(name, mesh_));
return autoPtr<incompressiblePhase>
(
new incompressiblePhase(name, mesh_)
);
}
};
// Member Functions
const word& name() const
{
return name_;
}
const word& keyword() const
{
return name();
}
//- Return const-access to phase1 viscosityModel
//- Return const-access to incompressiblePhase1 viscosityModel
const viscosityModel& nuModel() const
{
return nuModel_();
@ -126,20 +120,20 @@ public:
return nuModel_->nu(patchi);
}
//- Return const-access to phase1 density
//- Return const-access to incompressiblePhase1 density
const dimensionedScalar& rho() const
{
return rho_;
}
//- Correct the phase properties
//- Correct the incompressiblePhase properties
void correct();
//-Inherit read from volScalarField
using volScalarField::read;
//- Inherit read from phase
using phase::read;
//- Read base phaseProperties dictionary
bool read(const dictionary& phaseDict);
//- Read base incompressiblePhaseProperties dictionary
bool read(const dictionary& incompressiblePhaseDict);
};

View File

@ -0,0 +1,256 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-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 "multiphaseMixture.H"
#include "alphaContactAngleFvPatchScalarField.H"
#include "correctContactAngle.H"
#include "surfaceInterpolate.H"
#include "fvcGrad.H"
#include "fvcSnGrad.H"
#include "fvcDiv.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::multiphaseMixture::calcAlphas()
{
scalar level = 0.0;
alphas_ == 0.0;
forAll(phases_, phasei)
{
alphas_ += level*phases_[phasei];
level += 1.0;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::multiphaseMixture::multiphaseMixture(const fvMesh& mesh)
:
IOdictionary
(
IOobject
(
"phaseProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
),
phases_(PtrListDictionary<phase>(10)),
// phases_(lookup("phases"), phase::iNew(mesh)),
mesh_(mesh),
alphas_
(
IOobject
(
"alphas",
mesh_.time().name(),
mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedScalar(dimless, 0)
),
sigmas_(lookup("sigmas")),
dimSigma_(1, 0, -2, 0, 0),
deltaN_
(
"deltaN",
1e-8/pow(average(mesh_.V()), 1.0/3.0)
)
{
calcAlphas();
alphas_.write();
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::surfaceTensionForce(const volVectorField& U) const
{
tmp<surfaceScalarField> tstf
(
surfaceScalarField::New
(
"surfaceTensionForce",
mesh_,
dimensionedScalar(dimensionSet(1, -2, -2, 0, 0), 0)
)
);
surfaceScalarField& stf = tstf.ref();
forAll(phases_, phasei)
{
const incompressiblePhase& alpha1 = phases_[phasei];
for (label phasej = phasei+1; phasej<phases_.size(); phasej++)
{
const incompressiblePhase& alpha2 = phases_[phasej];
sigmaTable::const_iterator sigma =
sigmas_.find(interfacePair(alpha1, alpha2));
if (sigma == sigmas_.end())
{
FatalErrorInFunction
<< "Cannot find interface " << interfacePair(alpha1, alpha2)
<< " in list of sigma values"
<< exit(FatalError);
}
stf += dimensionedScalar(dimSigma_, sigma())
*fvc::interpolate(K(alpha1, alpha2))*
(
fvc::interpolate(alpha2)*fvc::snGrad(alpha1)
- fvc::interpolate(alpha1)*fvc::snGrad(alpha2)
);
}
}
return tstf;
}
void Foam::multiphaseMixture::correct()
{
forAll(phases_, phasei)
{
// iter()->correct();
}
}
Foam::tmp<Foam::surfaceVectorField> Foam::multiphaseMixture::nHatfv
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const
{
/*
// Cell gradient of alpha
volVectorField gradAlpha =
alpha2*fvc::grad(alpha1) - alpha1*fvc::grad(alpha2);
// Interpolated face-gradient of alpha
surfaceVectorField gradAlphaf = fvc::interpolate(gradAlpha);
*/
surfaceVectorField gradAlphaf
(
fvc::interpolate(alpha2)*fvc::interpolate(fvc::grad(alpha1))
- fvc::interpolate(alpha1)*fvc::interpolate(fvc::grad(alpha2))
);
// Face unit interface normal
return gradAlphaf/(mag(gradAlphaf) + deltaN_);
}
Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseMixture::nHatf
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const
{
// Face unit interface normal flux
return nHatfv(alpha1, alpha2) & mesh_.Sf();
}
Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K
(
const phase& alpha1,
const phase& alpha2,
const volVectorField& U
) const
{
tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
correctContactAngle
(
alpha1,
alpha2,
U.boundaryField(),
deltaN_,
tnHatfv.ref().boundaryFieldRef()
);
// Simple expression for curvature
return -fvc::div(tnHatfv & mesh_.Sf());
}
Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::nearInterface() const
{
tmp<volScalarField> tnearInt
(
volScalarField::New
(
"nearInterface",
mesh_,
dimensionedScalar(dimless, 0)
)
);
forAll(phases_, phasei)
{
tnearInt.ref() = max
(
tnearInt(),
pos0(phases_[phasei] - 0.01)*pos0(0.99 - phases_[phasei])
);
}
return tnearInt;
}
bool Foam::multiphaseMixture::read()
{
if (regIOobject::read())
{
lookup("sigmas") >> sigmas_;
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,222 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-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::multiphaseMixture
Description
Incompressible multiphase mixture with built in solution for the
phase fractions with interface compression for interface-capturing.
Derived from viscosity so that it can be used in conjunction
with the incompressible turbulence models.
Surface tension and contact-angle is handled for the interface
between each phase-pair.
SourceFiles
multiphaseMixture.C
\*---------------------------------------------------------------------------*/
#ifndef multiphaseMixture_H
#define multiphaseMixture_H
#include "viscosity.H"
#include "IOdictionary.H"
#include "phase.H"
#include "UPtrListDictionary.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class multiphaseMixture Declaration
\*---------------------------------------------------------------------------*/
class multiphaseMixture
:
public IOdictionary
{
public:
class interfacePair
:
public Pair<word>
{
public:
class hash
:
public Hash<interfacePair>
{
public:
hash()
{}
label operator()(const interfacePair& key) const
{
return word::hash()(key.first()) + word::hash()(key.second());
}
};
// Constructors
interfacePair()
{}
interfacePair(const word& alpha1Name, const word& alpha2Name)
:
Pair<word>(alpha1Name, alpha2Name)
{}
interfacePair(const phase& alpha1, const phase& alpha2)
:
Pair<word>(alpha1.name(), alpha2.name())
{}
// Friend Operators
friend bool operator==
(
const interfacePair& a,
const interfacePair& b
)
{
return
(
((a.first() == b.first()) && (a.second() == b.second()))
|| ((a.first() == b.second()) && (a.second() == b.first()))
);
}
friend bool operator!=
(
const interfacePair& a,
const interfacePair& b
)
{
return (!(a == b));
}
};
private:
// Private Data
//- Dictionary of phases
UPtrListDictionary<phase> phases_;
const fvMesh& mesh_;
volScalarField alphas_;
typedef HashTable<scalar, interfacePair, interfacePair::hash>
sigmaTable;
sigmaTable sigmas_;
dimensionSet dimSigma_;
//- Stabilisation for normalisation of the interface normal
const dimensionedScalar deltaN_;
// Private Member Functions
void calcAlphas();
tmp<surfaceVectorField> nHatfv
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const;
tmp<surfaceScalarField> nHatf
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const;
tmp<volScalarField> K
(
const phase& alpha1,
const phase& alpha2,
const volVectorField& U
) const;
public:
// Constructors
//- Construct from fvMesh
multiphaseMixture(const fvMesh& mesh);
//- Destructor
virtual ~multiphaseMixture()
{}
// Member Functions
//- Return the phases
const UPtrListDictionary<phase>& phases() const
{
return phases_;
}
tmp<surfaceScalarField> surfaceTensionForce
(
const volVectorField& U
) const;
//- Indicator of the proximity of the interface
// Field values are 1 near and 0 away for the interface.
tmp<volScalarField> nearInterface() const;
//- Correct the mixture properties
void correct();
//- Read base phaseProperties dictionary
bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -41,33 +41,8 @@ Foam::phase::phase(const word& phaseName, const fvMesh& mesh)
),
mesh
),
name_(phaseName),
nuModel_(viscosityModel::New(mesh, phaseName)),
rho_("rho", dimDensity, nuModel_())
name_(phaseName)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::phase> Foam::phase::clone() const
{
NotImplemented;
return autoPtr<phase>(nullptr);
}
void Foam::phase::correct()
{
nuModel_->correct();
}
bool Foam::phase::read(const dictionary& phaseDict)
{
phaseDict.lookup("rho") >> rho_;
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,94 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-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::phase
Description
Single incompressible phase derived from the phase-fraction.
Used as part of the multiPhaseMixture for interface-capturing multi-phase
simulations.
SourceFiles
phase.C
\*---------------------------------------------------------------------------*/
#ifndef phase_H
#define phase_H
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class phase Declaration
\*---------------------------------------------------------------------------*/
class phase
:
public volScalarField
{
// Private Data
word name_;
public:
// Constructors
//- Construct from components
phase
(
const word& name,
const fvMesh& mesh
);
// Member Functions
const word& name() const
{
return name_;
}
const word& keyword() const
{
return name();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -34,7 +34,7 @@ Description
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "multiphaseMixture.H"
#include "incompressibleMultiphaseMixture.H"
#include "incompressibleMomentumTransportModels.H"
#include "pimpleControl.H"
#include "pressureReference.H"

View File

@ -1,4 +0,0 @@
phase/phase.C
multiphaseMixture.C
LIB = $(FOAM_LIBBIN)/libmultiphaseInterFoam