Merge branch 'develop' of develop.openfoam.com:Development/OpenFOAM-plus into develop

This commit is contained in:
sergio
2019-06-10 10:17:00 -07:00
committed by Andrew Heather
1115 changed files with 70167 additions and 12870 deletions

View File

@ -24,7 +24,7 @@ command -v mpirun 2>/dev/null || true
echo "========================================"
date "+%Y-%m-%d %H:%M:%S %z" 2>/dev/null || echo "date is unknown"
echo "Starting compile ${WM_PROJECT_DIR##*/} ${0##*}"
echo "Starting compile ${WM_PROJECT_DIR##*/} ${0##*/}"
echo " $WM_COMPILER $WM_COMPILER_TYPE compiler"
echo " ${WM_OPTIONS}, with ${WM_MPLIB} ${FOAM_MPI}"
echo "========================================"

View File

@ -17,6 +17,32 @@ Please [contact OpenCFD](http://www.openfoam.com/contact) if you have any questi
Violations of the Trademark are continuously monitored, and will be duly prosecuted.
# Compiling OpenFOAM
Please see the relevant guides:
| Location | Readme | Requirements | Build |
|-------------|-----------|--------------|-------|
| [OpenFOAM][repo openfoam] | [readme][link openfoam-readme] | [system requirements][link openfoam-require] | [build][link openfoam-build] |
| [ThirdParty][repo third] | [readme][link third-readme] | [system requirements][link third-require] | [build][link third-build] |
<!-- OpenFOAM -->
[repo openfoam]: https://develop.openfoam.com/Development/OpenFOAM-plus/
[repo third]: https://develop.openfoam.com/Development/ThirdParty-plus/
[link openfoam-issues]: https://develop.openfoam.com/Development/OpenFOAM-plus/blob/develop/BuildIssues.txt
[link openfoam-readme]: https://develop.openfoam.com/Development/OpenFOAM-plus/blob/develop/README.md
[link openfoam-config]: https://develop.openfoam.com/Development/OpenFOAM-plus/blob/develop/etc/README.md
[link openfoam-build]: https://develop.openfoam.com/Development/OpenFOAM-plus/blob/develop/doc/Build.md
[link openfoam-require]: https://develop.openfoam.com/Development/OpenFOAM-plus/blob/develop/doc/Requirements.md
[link third-readme]: https://develop.openfoam.com/Development/ThirdParty-plus/blob/develop/README.md
[link third-build]: https://develop.openfoam.com/Development/ThirdParty-plus/blob/develop/BUILD.md
[link third-require]: https://develop.openfoam.com/Development/ThirdParty-plus/blob/develop/Requirements.md
# Useful Links
- [Download and installation instructions](http://www.openfoam.com/download/)
- [Documentation](http://www.openfoam.com/documentation)
@ -24,4 +50,4 @@ Violations of the Trademark are continuously monitored, and will be duly prosecu
- [OpenFOAM Community](http://www.openfoam.com/community/)
- [Contacting OpenCFD](http://www.openfoam.com/contact/)
Copyright 2016-2018 OpenCFD Ltd
Copyright 2016-2019 OpenCFD Ltd

View File

@ -57,9 +57,6 @@ forAll(U.boundaryField(), patchi)
}
}
// Note that registerObject is false for the pressure field. The pressure
// field in this solver doesn't have a physical value during the solution.
// It shouldn't be looked up and used by sub models or boundary conditions.
Info<< "Constructing pressure field " << pName << nl << endl;
volScalarField p
(
@ -69,8 +66,7 @@ volScalarField p
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
IOobject::NO_WRITE
),
mesh,
dimensionedScalar(sqr(dimVelocity), Zero),

View File

@ -0,0 +1,5 @@
derivedFvPatchFields/turbulentTemperatureTwoPhaseRadCoupledMixed/turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.C
../solid/solidRegionDiffNo.C
chtMultiRegionTwoPhaseEulerFoam.C
EXE = $(FOAM_APPBIN)/chtMultiRegionTwoPhaseEulerFoam

View File

@ -0,0 +1,41 @@
EXE_INC = \
-I. \
-I.. \
-I$(FOAM_SOLVERS)/multiphase/reactingEulerFoam/reactingTwoPhaseEulerFoam \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/reactingTwoPhaseEulerFoam/twoPhaseSystem/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/reactingTwoPhaseEulerFoam/twoPhaseCompressibleTurbulenceModels/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/phaseSystems/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/interfacialModels/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/interfacialCompositionModels/lnInclude \
-I./fluid \
-I../solid \
-I../fluid \
-I../include \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/phaseCompressible/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude
EXE_LIBS = \
-lcompressibleTransportModels \
-lfluidThermophysicalModels \
-lspecie \
-lsolidThermo \
-ltwoPhaseReactingTurbulenceModels \
-lmeshTools \
-lfiniteVolume \
-lfvOptions \
-lradiationModels \
-lregionModels \
-lsampling \
-lreactingTwoPhaseSystem \

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ 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/>.
Application
chtMultiRegionTwoPhaseEulerFoam
Group
grpHeatTransferSolvers
Description
Transient solver for buoyant, turbulent fluid flow and solid heat
conduction with conjugate heat transfer between solid and fluid regions.
It solves a two-phase Euler approach on the fluid region.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "turbulentFluidThermoModel.H"
#include "twoPhaseSystem.H"
#include "phaseCompressibleTurbulenceModel.H"
#include "pimpleControl.H"
#include "fixedGradientFvPatchFields.H"
#include "regionProperties.H"
#include "solidRegionDiffNo.H"
#include "solidThermo.H"
#include "radiationModel.H"
#include "fvOptions.H"
#include "coordinateSystem.H"
#include "loopControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Transient solver for buoyant, turbulent two phase fluid flow and"
"solid heat conduction with conjugate heat transfer "
"between solid and fluid regions."
);
#define NO_CONTROL
#define CREATE_MESH createMeshesPostProcess.H
#include "postProcess.H"
#include "setRootCase.H"
#include "createTime.H"
#include "createMeshes.H"
#include "createFields.H"
#include "initContinuityErrs.H"
#include "createTimeControls.H"
#include "readSolidTimeControls.H"
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setInitialMultiRegionDeltaT.H"
while (runTime.run())
{
#include "readTimeControls.H"
#include "readSolidTimeControls.H"
#include "readPIMPLEControls.H"
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setMultiRegionDeltaT.H"
++runTime;
Info<< "Time = " << runTime.timeName() << nl << endl;
if (nOuterCorr != 1)
{
forAll(fluidRegions, i)
{
#include "storeOldFluidFields.H"
}
}
// --- PIMPLE loop
for (int oCorr=0; oCorr<nOuterCorr; ++oCorr)
{
const bool finalIter = (oCorr == nOuterCorr-1);
forAll(fluidRegions, i)
{
Info<< "\nSolving for fluid region "
<< fluidRegions[i].name() << endl;
#include "setRegionFluidFields.H"
#include "readFluidMultiRegionPIMPLEControls.H"
#include "solveFluid.H"
}
forAll(solidRegions, i)
{
Info<< "\nSolving for solid region "
<< solidRegions[i].name() << endl;
#include "setRegionSolidFields.H"
#include "readSolidMultiRegionPIMPLEControls.H"
#include "solveSolid.H"
}
// Additional loops for energy solution only
if (!oCorr && nOuterCorr > 1)
{
loopControl looping(runTime, pimple, "energyCoupling");
while (looping.loop())
{
Info<< nl << looping << nl;
forAll(fluidRegions, i)
{
Info<< "\nSolving for fluid region "
<< fluidRegions[i].name() << endl;
#include "setRegionFluidFields.H"
#include "readFluidMultiRegionPIMPLEControls.H"
frozenFlow = true;
#include "solveFluid.H"
}
forAll(solidRegions, i)
{
Info<< "\nSolving for solid region "
<< solidRegions[i].name() << endl;
#include "setRegionSolidFields.H"
#include "readSolidMultiRegionPIMPLEControls.H"
#include "solveSolid.H"
}
}
}
}
runTime.write();
runTime.printExecutionTime(Info);
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,516 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd
\\/ 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 "turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "phaseSystem.H"
#include "mappedPatchBase.H"
#include "solidThermo.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::Enum
<
Foam::compressible::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::regionType
>
Foam::compressible::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::regionTypeNames_
{
{ regionType::solid, "solid" },
{ regionType::fluid, "fluid" },
};
const Foam::Enum
<
Foam::compressible::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::KMethodType
>
Foam::compressible::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::KMethodTypeNames_
{
{ KMethodType::mtSolidThermo, "solidThermo" },
{ KMethodType::mtLookup, "lookup" },
{ KMethodType::mtPhaseSystem, "phaseSystem" }
};
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::tmp<Foam::scalarField> Foam::compressible::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
kappa
(
const scalarField& Tp
) const
{
const polyMesh& mesh = patch().boundaryMesh().mesh();
const label patchi = patch().index();
switch (method_)
{
case mtSolidThermo:
{
const solidThermo& thermo =
mesh.lookupObject<solidThermo>(basicThermo::dictName);
return thermo.kappa(patchi);
break;
}
case mtLookup:
{
if (mesh.foundObject<volScalarField>(kappaName_))
{
return patch().lookupPatchField<volScalarField, scalar>
(
kappaName_
);
}
else if (mesh.foundObject<volSymmTensorField>(kappaName_))
{
const symmTensorField& KWall =
patch().lookupPatchField<volSymmTensorField, scalar>
(
kappaName_
);
const vectorField n(patch().nf());
return n & KWall & n;
}
else
{
FatalErrorInFunction
<< "Did not find field " << kappaName_
<< " on mesh " << mesh.name() << " patch " << patch().name()
<< nl
<< " Please set 'kappa' to the name of a volScalarField"
<< " or volSymmTensorField."
<< exit(FatalError);
}
break;
}
case mtPhaseSystem:
{
// Lookup the fluid model
const phaseSystem& fluid =
(
mesh.lookupObject<phaseSystem>("phaseProperties")
);
tmp<scalarField> kappaEff
(
new scalarField(patch().size(), 0.0)
);
forAll(fluid.phases(), phasei)
{
const phaseModel& phase = fluid.phases()[phasei];
const fvPatchScalarField& alpha = phase.boundaryField()[patchi];
kappaEff.ref() += alpha*phase.kappaEff(patchi)();
}
return kappaEff;
break;
}
default:
{
FatalErrorInFunction
<< "Unimplemented method " << KMethodTypeNames_[method_] << nl
<< "Please set 'kappaMethod' to one of "
<< flatOutput(KMethodTypeNames_.sortedToc()) << nl
<< "and 'kappa' to the name of the volScalar"
<< exit(FatalError);
}
}
return scalarField(0);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace compressible
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(p, iF),
regionType_(fluid),
method_(mtLookup),
kappaName_("none"),
otherPhaseName_("vapor"),
TnbrName_("undefined-Tnbr"),
qrNbrName_("undefined-qrNbr"),
qrName_("undefined-qr")
{
this->refValue() = 0.0;
this->refGrad() = 0.0;
this->valueFraction() = 1.0;
}
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField& psf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchScalarField(psf, p, iF, mapper),
regionType_(psf.regionType_),
method_(psf.method_),
kappaName_(psf.kappaName_),
otherPhaseName_(psf.otherPhaseName_),
TnbrName_(psf.TnbrName_),
qrNbrName_(psf.qrNbrName_),
qrName_(psf.qrName_)
{}
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchScalarField(p, iF),
regionType_(regionTypeNames_.read(dict.lookup("region"))),
method_(KMethodTypeNames_.get("kappaMethod", dict)),
kappaName_(dict.lookupOrDefault<word>("kappa", "none")),
otherPhaseName_(dict.lookup("otherPhase")),
TnbrName_(dict.lookupOrDefault<word>("Tnbr", "T")),
qrNbrName_(dict.lookupOrDefault<word>("qrNbr", "none")),
qrName_(dict.lookupOrDefault<word>("qr", "none"))
{
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
if (dict.found("refValue"))
{
// Full restart
refValue() = scalarField("refValue", dict, p.size());
refGrad() = scalarField("refGradient", dict, p.size());
valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume fixedValue.
refValue() = *this;
refGrad() = 0.0;
valueFraction() = 1.0;
}
}
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField& psf,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(psf, iF),
regionType_(psf.regionType_),
method_(psf.method_),
kappaName_(psf.kappaName_),
otherPhaseName_(psf.otherPhaseName_),
TnbrName_(psf.TnbrName_),
qrNbrName_(psf.qrNbrName_),
qrName_(psf.qrName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
updateCoeffs()
{
if (updated())
{
return;
}
const polyMesh& mesh = patch().boundaryMesh().mesh();
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
// Get the coupling information from the mappedPatchBase
const label patchi = patch().index();
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const polyMesh& nbrMesh = mpp.sampleMesh();
const label samplePatchi = mpp.samplePolyPatch().index();
const fvPatch& nbrPatch =
refCast<const fvMesh>(nbrMesh).boundary()[samplePatchi];
scalarField& Tp = *this;
const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField&
nbrField = refCast
<const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField>
(
nbrPatch.lookupPatchField<volScalarField, scalar>(TnbrName_)
);
// Swap to obtain full local values of neighbour internal field
scalarField TcNbr(nbrField.patchInternalField());
mpp.distribute(TcNbr);
// Swap to obtain full local values of neighbour K*delta
scalarField KDeltaNbr;
KDeltaNbr = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs();
mpp.distribute(KDeltaNbr);
scalarField KDelta(kappa(Tp)*patch().deltaCoeffs());
scalarField qr(Tp.size(), 0.0);
if (qrName_ != "none")
{
qr = patch().lookupPatchField<volScalarField, scalar>(qrName_);
}
scalarField qrNbr(Tp.size(), 0.0);
if (qrNbrName_ != "none")
{
qrNbr = nbrPatch.lookupPatchField<volScalarField, scalar>(qrNbrName_);
mpp.distribute(qrNbr);
}
if (regionType_ == solid)
{
// Lookup the fluid model in the nbrFvMesh
const phaseSystem& fluid =
(
nbrMesh.lookupObject<phaseSystem>("phaseProperties")
);
// The BC is applied to the liquid phase of the fluid
const phaseModel& liquid
(
fluid.phases()[nbrField.internalField().group()]
);
const phaseModel& vapor(fluid.phases()[otherPhaseName_]);
scalarField KDeltaLiqNbr;
const fvPatchScalarField& alphal = liquid.boundaryField()[samplePatchi];
KDeltaLiqNbr =
alphal*(liquid.kappaEff(samplePatchi))*nbrPatch.deltaCoeffs();
mpp.distribute(KDeltaLiqNbr);
scalarField KDeltaVapNbr;
const fvPatchScalarField& alphav = vapor.boundaryField()[samplePatchi];
KDeltaVapNbr =
alphav*(vapor.kappaEff(samplePatchi))*nbrPatch.deltaCoeffs();
mpp.distribute(KDeltaVapNbr);
scalarField TvNbr;
const fvPatchScalarField& Tv =
vapor.thermo().T().boundaryField()[samplePatchi];
TvNbr = Tv.patchInternalField();
mpp.distribute(TvNbr);
// TcNbr: liquid Tp
// TvNbr: vapour Tp
scalarField c(TcNbr*KDeltaLiqNbr + TvNbr*KDeltaVapNbr);
valueFraction() = KDeltaNbr/(KDeltaNbr + KDelta);
refValue() = c/KDeltaNbr;
refGrad() = (qr + qrNbr)/kappa(Tp);
if (debug)
{
scalar Q = gSum(kappa(Tp)*patch().magSf()*snGrad());
Info<< "T solid : " << nl << endl;
Info
<< " heat transfer rate from solid:" << Q
<< " walltemperature "
<< " min:" << gMin(Tp)
<< " max:" << gMax(Tp)
<< " avg:" << gAverage(Tp)
<< endl;
}
}
else if (regionType_ == fluid)
{
const phaseSystem& fluid =
(
mesh.lookupObject<phaseSystem>("phaseProperties")
);
const phaseModel& liquid
(
fluid.phases()[internalField().group()]
);
const phaseModel& vapor(fluid.phases()[otherPhaseName_]);
const fvPatchScalarField& Tv =
vapor.thermo().T().boundaryField()[patchi];
const fvPatchScalarField& alphav = vapor.boundaryField()[patchi];
const scalarField KdeltaVap
(
alphav*(vapor.kappaEff(patchi))*patch().deltaCoeffs()
);
const fvPatchScalarField& alphal = liquid.boundaryField()[patchi];
const scalarField KdeltaLiq
(
alphal*(liquid.kappaEff(patchi))*patch().deltaCoeffs()
);
// TcNbr: solid Tp
// Tv: vapour Tp
const scalarField c(TcNbr*KDeltaNbr + Tv.patchInternalField()*KdeltaVap);
const scalarField a(KdeltaVap + KDeltaNbr);
valueFraction() = a/(a + KdeltaLiq);
refValue() = c/a;
refGrad() = (qr + qrNbr)/kappa(Tp);
if (debug)
{
scalarField Tc(patchInternalField());
scalarField qLiq((Tp - Tc)*KdeltaLiq);
scalarField qVap((Tp - Tv.patchInternalField())*KdeltaVap);
Info<< "T flow : " << nl << endl;
Info<< " qLiq: " << gMin(qLiq) << " - " << gMax(qLiq) << endl;
Info<< " qVap: " << gMin(qVap) << " - " << gMax(qVap) << endl;
scalar QLiq = gSum(qLiq*patch().magSf());
scalar QVap = gSum(qVap*patch().magSf());
Info<< " Heat transfer to Liq: " << QLiq << endl;
Info<< " Heat transfer to Vap: " << QVap << endl;
Info<< " walltemperature "
<< " min:" << gMin(Tp)
<< " max:" << gMax(Tp)
<< " avg:" << gAverage(Tp)
<< endl;
}
}
else
{
FatalErrorInFunction
<< "Unknown phase type. Valid types are: "
<< regionTypeNames_ << nl << exit(FatalError);
}
mixedFvPatchScalarField::updateCoeffs();
// Restore tag
UPstream::msgType() = oldTag;
}
void turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::write
(
Ostream& os
) const
{
mixedFvPatchScalarField::write(os);
os.writeEntry("kappaMethod", KMethodTypeNames_[method_]);
os.writeEntryIfDifferent<word>("kappa","none", kappaName_);
os.writeEntry("Tnbr", TnbrName_);
os.writeEntryIfDifferent<word>("qrNbr", "none", qrNbrName_);
os.writeEntryIfDifferent<word>("qr", "none", qrName_);
os.writeKeyword("region") << regionTypeNames_[regionType_]
<< token::END_STATEMENT << nl;
os.writeKeyword("otherPhase") << otherPhaseName_ << token::END_STATEMENT
<< nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace compressible
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,252 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd
\\/ 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::compressible::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
Description
Mixed boundary condition for temperature and radiation heat transfer
to be used for in multiregion cases with two phase Euler system
Usage
\table
Property | Description | Required | Default value
Tnbr | name of the field | no | T
qrNbr | name of the radiative flux in the nbr region | no | none
qr | name of the radiative flux in this region | no | none
region | region to which this BC belongs | yes
otherPhase | name of the vapour phase in the fluid region | yes
kappaMethod | inherited from temperatureCoupledBase | inherited |
kappa | inherited from temperatureCoupledBase | inherited |
\endtable
Example of the boundary condition specification on the fluid region:
\verbatim
<patchName>
{
type compressible::turbulentTemperatureTwoPhaseRadCoupledMixed;
Tnbr T;
qrNbr none;
qr none;
kappaMethod phaseSystem;
region fluid;
otherPhase gas;
value uniform 300;
}
\endverbatim
Example of the boundary condition specification on the solid region:
\verbatim
<patchName>
{
type compressible::turbulentTemperatureTwoPhaseRadCoupledMixed;
Tnbr T.liquid;
qrNbr none;
qr none;
kappaMethod solidThermo;
region solid;
otherPhase gas;
value uniform 300;
}
\endverbatim
Needs to be on underlying mapped(Wall)FvPatch.
SourceFiles
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField_H
#define turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField_H
#include "mixedFvPatchFields.H"
#include "scalarList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace compressible
{
/*---------------------------------------------------------------------------*\
Class turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField Declaration
\*---------------------------------------------------------------------------*/
class turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
:
public mixedFvPatchScalarField
{
public:
// Public enumerations
//- Type of supplied Kappa
enum KMethodType
{
mtSolidThermo,
mtLookup,
mtPhaseSystem
};
// Data types
//- Enumeration listing the region
enum regionType
{
solid,
fluid
};
private:
// Private data
//- Heat source type names
static const Enum<regionType> regionTypeNames_;
//- Kappa method types
static const Enum<KMethodType> KMethodTypeNames_;
//- Heat source type
regionType regionType_;
//- How to get K
const KMethodType method_;
//- Name of thermal conductivity field (if looked up from database)
const word kappaName_;
//- name of the other phase (vapor/liquid phase)
word otherPhaseName_;
//- Name of field on the neighbour region
const word TnbrName_;
//- Name of the radiative heat flux in the neighbour region
const word qrNbrName_;
//- Name of the radiative heat flux in local region
const word qrName_;
// Private members
//- Given patch temperature calculate corresponding K field
tmp<scalarField> kappa(const scalarField& Tp) const;
public:
//- Runtime type information
TypeName("compressible::turbulentTemperatureTwoPhaseRadCoupledMixed");
// Constructors
//- Construct from patch and internal field
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// turbulentTemperatureCoupledBaffleMixedFvPatchScalarField onto a
// new patch
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
*this
)
);
}
//- Construct as copy setting internal field reference
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
*this,
iF
)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace compressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
scalar CoNum = -GREAT;
forAll(fluidRegions, regioni)
{
if (fluidRegions[regioni].nInternalFaces())
{
const surfaceScalarField& phi =
phaseSystemFluid[regioni].phi();
scalarField sumPhi
(
fvc::surfaceSum(mag(phi))().primitiveField()
);
const surfaceScalarField& phi1 =
phaseSystemFluid[regioni].phase1().phiRef();
const surfaceScalarField& phi2 =
phaseSystemFluid[regioni].phase2().phiRef();
sumPhi = max
(
sumPhi,
fvc::surfaceSum(mag(phi1))().primitiveField()
);
sumPhi = max
(
sumPhi,
fvc::surfaceSum(mag(phi2))().primitiveField()
);
CoNum =
0.5*gMax
(
sumPhi/fluidRegions[regioni].V().field()
)*runTime.deltaTValue();
scalar UrCoNum = 0.5*gMax
(
fvc::surfaceSum(mag(phi1 - phi2))().primitiveField()
/ fluidRegions[regioni].V().field()
)*runTime.deltaTValue(),
CoNum = max(UrCoNum, CoNum);
}
}
Info<< "Courant Number max: " << CoNum << endl;

View File

@ -0,0 +1,147 @@
// Initialise fluid field pointer lists
PtrList<twoPhaseSystem> phaseSystemFluid(fluidRegions.size());
PtrList<volScalarField> ghFluid(fluidRegions.size());
PtrList<surfaceScalarField> ghfFluid(fluidRegions.size());
PtrList<uniformDimensionedScalarField> hRefFluid(fluidRegions.size());
PtrList<volScalarField> p_rghFluid(fluidRegions.size());
PtrList<multivariateSurfaceInterpolationScheme<scalar>::fieldTable>
fieldsFluid(fluidRegions.size());
List<scalar> initialMassFluid(fluidRegions.size());
List<bool> frozenFlowFluid(fluidRegions.size(), false);
List<label> pRefCellFluid(fluidRegions.size());
List<scalar> pRefValueFluid(fluidRegions.size());
PtrList<dimensionedScalar> pMinFluid(fluidRegions.size());
const uniformDimensionedVectorField& g = meshObjects::gravity::New(runTime);
PtrList<pimpleControl> pimpleFluid(fluidRegions.size());
// Populate fluid field pointer lists
forAll(fluidRegions, i)
{
Info<< "*** Reading fluid mesh thermophysical properties for region "
<< fluidRegions[i].name() << nl << endl;
pimpleFluid.set
(
i,
new pimpleControl(fluidRegions[i])
);
Info<< " Adding to phaseSystemFluid\n" << endl;
phaseSystemFluid.set(i, twoPhaseSystem::New(fluidRegions[i]).ptr());
Info<< " Adding hRefFluid\n" << endl;
hRefFluid.set
(
i,
new uniformDimensionedScalarField
(
IOobject
(
"hRef",
runTime.constant(),
fluidRegions[i],
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
dimensionedScalar("hRef", dimLength, Zero)
)
);
Info<< " Adding ghRef\n" << endl;
dimensionedScalar ghRef
(
mag(g.value()) > SMALL
? g & (cmptMag(g.value())/mag(g.value()))*hRefFluid[i]
: dimensionedScalar("ghRef", g.dimensions()*dimLength, 0)
);
ghFluid.set
(
i,
new volScalarField
(
"gh",
(g & fluidRegions[i].C()) - ghRef
)
);
ghfFluid.set
(
i,
new surfaceScalarField
(
"ghf",
(g & fluidRegions[i].Cf()) - ghRef
)
);
Info<< " Adding p_rghFluid\n" << endl;
p_rghFluid.set
(
i,
new volScalarField
(
IOobject
(
"p_rgh",
runTime.timeName(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluidRegions[i]
)
);
Info<< " Correcting p_rghFluid\n" << endl;
// Force p_rgh to be consistent with p
p_rghFluid[i] =
phaseSystemFluid[i].phase1().thermo().p()
- phaseSystemFluid[i].phase1().thermo().rho()*ghFluid[i];
fluidRegions[i].setFluxRequired(p_rghFluid[i].name());
Info<< " Correcting initialMassFluid\n" << endl;
initialMassFluid[i] =
fvc::domainIntegrate(phaseSystemFluid[i].rho()).value();
const dictionary& pimpleDict =
fluidRegions[i].solutionDict().subDict("PIMPLE");
pimpleDict.readIfPresent("frozenFlow", frozenFlowFluid[i]);
pRefCellFluid[i] = -1;
pRefValueFluid[i] = 0.0;
Info<< " Setting reference\n" << endl;
if (p_rghFluid[i].needReference())
{
setRefCell
(
phaseSystemFluid[i].phase1().thermoRef().p(),
p_rghFluid[i],
pimpleDict,
pRefCellFluid[i],
pRefValueFluid[i]
);
}
pMinFluid.set
(
i,
new dimensionedScalar
(
"pMin",
dimPressure,
phaseSystemFluid[i]
)
);
}

View File

@ -0,0 +1,28 @@
PtrList<uniformDimensionedScalarField> cumulativeContErrIO(fluidRegions.size());
forAll(cumulativeContErrIO, i)
{
#include "setRegionFluidFields.H"
cumulativeContErrIO.set
(
i,
new uniformDimensionedScalarField
(
IOobject
(
"cumulativeContErr",
runTime.timeName(),
"uniform",
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
dimensionedScalar(dimless, Zero)
)
);
}
UPtrList<scalar> cumulativeContErr(cumulativeContErrIO.size());
forAll(cumulativeContErrIO, i)
{
cumulativeContErr.set(i, &cumulativeContErrIO[i].value());
}

View File

@ -0,0 +1,11 @@
const dictionary& pimpleDict = mesh.solutionDict().subDict("PIMPLE");
Switch faceMomentum
(
pimpleDict.lookupOrDefault<Switch>("faceMomentum", false)
);
int nEnergyCorrectors
(
pimpleDict.lookupOrDefault<int>("nEnergyCorrectors", 1)
);

View File

@ -0,0 +1,58 @@
fvMesh& mesh = fluidRegions[i];
twoPhaseSystem& fluid = phaseSystemFluid[i];
phaseModel& phase1 = fluid.phase1();
phaseModel& phase2 = fluid.phase2();
const volScalarField& alpha1 = phase1;
const volScalarField& alpha2 = phase2;
volVectorField& U1 = phase1.URef();
surfaceScalarField& phi1 = phase1.phiRef();
const surfaceScalarField& alphaPhi1 = phase1.alphaPhi();
volVectorField& U2 = phase2.URef();
surfaceScalarField& phi2 = phase2.phiRef();
const surfaceScalarField& alphaPhi2 = phase2.alphaPhi();
surfaceScalarField& phi = fluid.phi();
rhoThermo& thermo1 = phase1.thermoRef();
rhoThermo& thermo2 = phase2.thermoRef();
thermo1.validate(args.executable(), "h", "e");
thermo2.validate(args.executable(), "h", "e");
volScalarField& rho1 = thermo1.rho();
const volScalarField& psi1 = thermo1.psi();
volScalarField& rho2 = thermo2.rho();
const volScalarField& psi2 = thermo2.psi();
const IOMRFZoneList& MRF = fluid.MRF();
fv::options& fvOptions = fluid.fvOptions();
volScalarField& p = thermo1.p();
volScalarField& p_rgh = p_rghFluid[i];
//const dimensionedVector& g = gFluid[i];
const volScalarField& gh = ghFluid[i];
const surfaceScalarField& ghf = ghfFluid[i];
const dimensionedScalar initialMass
(
"initialMass",
dimMass,
initialMassFluid[i]
);
bool frozenFlow = frozenFlowFluid[i];
//const label pRefCell = pRefCellFluid[i];
//const scalar pRefValue = pRefValueFluid[i];
pimpleControl& pimple = pimpleFluid[i];
const dimensionedScalar& pMin = pMinFluid[i];

View File

@ -0,0 +1,39 @@
if (finalIter)
{
mesh.data::add("finalIteration", true);
}
if (frozenFlow)
{
#include "EEqns.H"
}
else
{
fluid.solve();
fluid.correct();
#include "YEqns.H"
if (faceMomentum)
{
#include "pUf/UEqns.H"
#include "EEqns.H"
#include "pUf/pEqn.H"
}
else
{
#include "pU/UEqns.H"
#include "EEqns.H"
#include "pU/pEqn.H"
}
fluid.correctKinematics();
// Update alpha's for new U
fluid.correctTurbulence();
}
if (finalIter)
{
mesh.data::remove("finalIteration");
}

View File

@ -0,0 +1,2 @@
p_rghFluid[i].storePrevIter();
//rhoFluid[i].storePrevIter();

View File

@ -137,7 +137,8 @@
alphaPhi10,
talphaPhi1Corr0.ref(),
zeroField(), zeroField(),
1, 0
oneField(),
zeroField()
);
alphaPhi10 += talphaPhi1Corr0();
@ -187,8 +188,8 @@
talphaPhi1Corr.ref(),
Sp,
(-Sp*alpha1)(),
1,
0
oneField(),
zeroField()
);
// Under-relax the correction for all but the 1st corrector
@ -214,8 +215,8 @@
alphaPhi10,
Sp,
(Su + divU*min(alpha1(), scalar(1)))(),
1,
0
oneField(),
zeroField()
);
}

View File

@ -133,7 +133,15 @@
if (alphaApplyPrevCorr && talphaPhi1Corr0.valid())
{
Info<< "Applying the previous iteration compression flux" << endl;
MULES::correct(alpha1, alphaPhi10, talphaPhi1Corr0.ref(), 1, 0);
MULES::correct
(
geometricOneField(),
alpha1,
alphaPhi10,
talphaPhi1Corr0.ref(),
oneField(),
zeroField()
);
alphaPhi10 += talphaPhi1Corr0();
}
@ -182,8 +190,8 @@
talphaPhi1Corr.ref(),
Sp,
(-Sp*alpha1)(),
1,
0
oneField(),
zeroField()
);
// Under-relax the correction for all but the 1st corrector
@ -209,8 +217,8 @@
alphaPhi10,
Sp,
(Su + divU*min(alpha1(), scalar(1)))(),
1,
0
oneField(),
zeroField()
);
}

View File

@ -330,6 +330,25 @@ Foam::tmp<Foam::scalarField> Foam::twoPhaseMixtureThermo::kappa
}
Foam::tmp<Foam::volScalarField> Foam::twoPhaseMixtureThermo::alphahe() const
{
return
alpha1()*thermo1_->alphahe()
+ alpha2()*thermo2_->alphahe();
}
Foam::tmp<Foam::scalarField> Foam::twoPhaseMixtureThermo::alphahe
(
const label patchi
) const
{
return
alpha1().boundaryField()[patchi]*thermo1_->alphahe(patchi)
+ alpha2().boundaryField()[patchi]*thermo2_->alphahe(patchi);
}
Foam::tmp<Foam::volScalarField> Foam::twoPhaseMixtureThermo::kappaEff
(
const volScalarField& alphat

View File

@ -268,6 +268,13 @@ public:
const label patchi
) const;
//- Thermal diffusivity for energy of mixture [kg/m/s]
virtual tmp<volScalarField> alphahe() const;
//- Thermal diffusivity for energy of mixture for patch [kg/m/s]
virtual tmp<scalarField> alphahe(const label patchi) const;
//- Effective thermal diffusivity of mixture [J/m/s/K]
virtual tmp<volScalarField> kappaEff
(

View File

@ -45,6 +45,9 @@ namespace Foam
defineTypeNameAndDebug(multiphaseMixtureThermo, 0);
}
const Foam::scalar Foam::multiphaseMixtureThermo::convertToRad =
Foam::constant::mathematical::pi/180.0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -605,6 +608,45 @@ Foam::tmp<Foam::scalarField> Foam::multiphaseMixtureThermo::kappa
}
Foam::tmp<Foam::volScalarField> Foam::multiphaseMixtureThermo::alphahe() const
{
PtrDictionary<phaseModel>::const_iterator phasei = phases_.begin();
tmp<volScalarField> talphaEff(phasei()*phasei().thermo().alphahe());
for (++phasei; phasei != phases_.end(); ++phasei)
{
talphaEff.ref() += phasei()*phasei().thermo().alphahe();
}
return talphaEff;
}
Foam::tmp<Foam::scalarField> Foam::multiphaseMixtureThermo::alphahe
(
const label patchi
) const
{
PtrDictionary<phaseModel>::const_iterator phasei = phases_.begin();
tmp<scalarField> talphaEff
(
phasei().boundaryField()[patchi]
*phasei().thermo().alphahe(patchi)
);
for (++phasei; phasei != phases_.end(); ++phasei)
{
talphaEff.ref() +=
phasei().boundaryField()[patchi]
*phasei().thermo().alphahe(patchi);
}
return talphaEff;
}
Foam::tmp<Foam::volScalarField> Foam::multiphaseMixtureThermo::kappaEff
(
const volScalarField& alphat
@ -1042,8 +1084,8 @@ void Foam::multiphaseMixtureThermo::solveAlphas
alphaPhiCorr,
zeroField(),
zeroField(),
1,
0,
oneField(),
zeroField(),
true
);

View File

@ -138,6 +138,10 @@ private:
//- Stabilisation for normalisation of the interface normal
const dimensionedScalar deltaN_;
//- Conversion factor for degrees into radians
static const scalar convertToRad;
// Private member functions
@ -388,6 +392,13 @@ public:
const label patchi
) const;
//- Thermal diffusivity for energy of mixture [kg/m/s]
virtual tmp<volScalarField> alphahe() const;
//- Thermal diffusivity for energy of mixture for patch [kg/m/s]
virtual tmp<scalarField> alphahe(const label patchi) const;
//- Effective thermal diffusivity of mixture [J/m/s/K]
virtual tmp<volScalarField> kappaEff
(

View File

@ -32,11 +32,12 @@
MULES::correct
(
geometricOneField(),
alpha1,
alphaPhi,
talphaPhiCorr0.ref(),
mixture.alphaMax(),
0
UniformField<scalar>(mixture.alphaMax()),
zeroField()
);
alphaPhi += talphaPhiCorr0();
@ -71,11 +72,12 @@
MULES::correct
(
geometricOneField(),
alpha1,
talphaPhiUn(),
talphaPhiCorr.ref(),
mixture.alphaMax(),
0
UniformField<scalar>(mixture.alphaMax()),
zeroField()
);
// Under-relax the correction for all but the 1st corrector
@ -95,11 +97,12 @@
MULES::explicitSolve
(
geometricOneField(),
alpha1,
phi,
alphaPhi,
mixture.alphaMax(),
0
UniformField<scalar>(mixture.alphaMax()),
zeroField()
);
}
}

View File

@ -72,7 +72,7 @@ MultiComponentPhaseModel
species_ = thermoPtr_->composition().species();
inertIndex_ = species_[thermoPtr_->getWord("inertSpecie")];
inertIndex_ = species_[thermoPtr_().template get<word>("inertSpecie")];
X_.setSize(thermoPtr_->composition().species().size());
@ -104,6 +104,7 @@ MultiComponentPhaseModel
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class BasePhaseModel, class phaseThermo>
void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>
::calculateVolumeFractions()
@ -190,7 +191,7 @@ void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::solveYi
const dictionary& MULEScontrols = mesh.solverDict(alpha1.name());
scalar cAlpha(MULEScontrols.get<scalar>("cYi"));
scalar cAlpha(readScalar(MULEScontrols.lookup("cYi")));
PtrList<surfaceScalarField> phiYiCorrs(species_.size());
const surfaceScalarField& phi = this->fluid().phi();
@ -201,7 +202,7 @@ void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::solveYi
surfaceScalarField phir(0.0*phi);
forAllConstIters(this->fluid().phases(),iter2)
forAllConstIter(phaseSystem::phaseModelTable,this->fluid().phases(),iter2)
{
const volScalarField& alpha2 = iter2()();
if (&alpha2 == &alpha1)
@ -250,7 +251,10 @@ void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::solveYi
surfaceScalarField& phiYiCorr = phiYiCorrs[i];
forAllConstIters(this->fluid().phases(), iter2)
forAllConstIter
(
phaseSystem::phaseModelTable, this->fluid().phases(), iter2
)
{
//const volScalarField& alpha2 = iter2()().oldTime();
const volScalarField& alpha2 = iter2()();
@ -298,8 +302,8 @@ void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::solveYi
phiYiCorr,
Sp[i],
Su[i],
1,
0,
oneField(),
zeroField(),
true
);
}
@ -354,8 +358,8 @@ void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::solveYi
phiYiCorr,
Sp[i],
Su[i],
1,
0
oneField(),
zeroField()
);
}
}
@ -369,8 +373,8 @@ void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::solveYi
phiYiCorr,
Sp[i],
Su[i],
1,
0
oneField(),
zeroField()
);
}
Yt += Yi;

View File

@ -213,6 +213,18 @@ Foam::tmp<Foam::scalarField> Foam::phaseModel::kappa(const label patchI) const
}
Foam::tmp<Foam::volScalarField> Foam::phaseModel::alphahe() const
{
return thermo().alphahe();
}
Foam::tmp<Foam::scalarField> Foam::phaseModel::alphahe(const label patchI) const
{
return thermo().alphahe(patchI);
}
Foam::tmp<Foam::volScalarField>Foam::phaseModel::kappaEff
(
const volScalarField& kappat

View File

@ -226,6 +226,12 @@ public:
//- Thermal diffusivity for temperature of phase for patch [J/m/s/K]
tmp<scalarField> kappa(const label patchi) const;
//- Thermal diffusivity for energy of mixture [kg/m/s]
tmp<volScalarField> alphahe() const;
//- Thermal diffusivity for energy of mixture for patch [kg/m/s]
tmp<scalarField> alphahe(const label patchi) const;
//- Effective thermal diffusivity for temperature of phase [J/m/s/K]
tmp<volScalarField> kappaEff(const volScalarField&) const;

View File

@ -414,8 +414,8 @@ void Foam::multiphaseSystem::solve()
phiAlphaCorr,
Sp,
Su,
1,
0,
oneField(),
zeroField(),
true
);
++phasei;
@ -485,8 +485,8 @@ void Foam::multiphaseSystem::solve()
phiAlpha,
(alphaSubCycle.index()*Sp)(),
(Su - (alphaSubCycle.index() - 1)*Sp*alpha1)(),
1,
0
oneField(),
zeroField()
);
if (alphaSubCycle.index() == 1)
@ -511,8 +511,8 @@ void Foam::multiphaseSystem::solve()
phiAlpha,
Sp,
Su,
1,
0
oneField(),
zeroField()
);
phase.alphaPhi() = phiAlpha;

View File

@ -649,6 +649,48 @@ Foam::tmp<Foam::scalarField> Foam::phaseSystem::kappa(const label patchI) const
}
Foam::tmp<Foam::volScalarField> Foam::phaseSystem::alphahe() const
{
phaseModelTable::const_iterator phaseModelIter = phaseModels_.begin();
tmp<volScalarField> talphaEff
(
phaseModelIter()()*phaseModelIter()->alphahe()
);
for (; phaseModelIter != phaseModels_.end(); ++phaseModelIter)
{
talphaEff.ref() += phaseModelIter()()*phaseModelIter()->alphahe();
}
return talphaEff;
}
Foam::tmp<Foam::scalarField> Foam::phaseSystem::alphahe
(
const label patchi
) const
{
phaseModelTable::const_iterator phaseModelIter = phaseModels_.begin();
tmp<scalarField> talphaEff
(
phaseModelIter()().boundaryField()[patchi]
*phaseModelIter()->alphahe(patchi)
);
for (; phaseModelIter != phaseModels_.end(); ++phaseModelIter)
{
talphaEff.ref() +=
phaseModelIter()().boundaryField()[patchi]
*phaseModelIter()->alphahe(patchi);
}
return talphaEff;
}
Foam::tmp<Foam::volScalarField>Foam::phaseSystem::kappaEff
(
const volScalarField& kappat

View File

@ -396,6 +396,12 @@ public:
const label patchi
) const;
//- Thermal diffusivity for energy of mixture [kg/m/s]
virtual tmp<volScalarField> alphahe() const;
//- Thermal diffusivity for energy of mixture for patch [kg/m/s]
virtual tmp<scalarField> alphahe(const label patchi) const;
//- Effective thermal diffusivity for temperature
// of mixture [J/m/s/K]
virtual tmp<volScalarField> kappaEff

View File

@ -1,17 +1,11 @@
{
tmp<volScalarField> tcp(thermo->Cp());
const volScalarField& cp = tcp();
rhoCp = rho*cp;
kappaEff = thermo->kappa() + rho*cp*turbulence->nut()/Prt;
pDivU = dimensionedScalar("pDivU", p.dimensions()/dimTime, Zero);
if (thermo->pDivU())
{
pDivU = (p*fvc::div(rhoPhi/fvc::interpolate(rho)));
}
const surfaceScalarField rhoCpPhi(fvc::interpolate(cp)*rhoPhi);
Pair<tmp<volScalarField>> vDotAlphal = mixture->mDot();
@ -23,13 +17,13 @@
fvScalarMatrix TEqn
(
fvm::ddt(rhoCp, T)
+ fvm::div(rhoCpPhi, T, "div(rhoCpPhi,T)")
+ fvm::div(rhoCpPhi, T)
- fvm::Sp(fvc::ddt(rhoCp) + fvc::div(rhoCpPhi), T)
- fvm::laplacian(kappaEff, T)
+ thermo->hc()*vDotvmcAlphal
+ pDivU
);
TEqn.relax();
TEqn.solve();

View File

@ -57,8 +57,7 @@ volScalarField rho
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
alpha1*rho1 + alpha2*rho2,
alpha1.boundaryField().types()
alpha1*rho1 + alpha2*rho2
);
rho.oldTime();
@ -123,19 +122,6 @@ volScalarField kappaEff
thermo->kappa()
);
Info<< "Creating field pDivU\n" << endl;
volScalarField pDivU
(
IOobject
(
"pDivU",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar(p.dimensions()/dimTime, Zero)
);
// Need to store rho for ddt(rhoCp, U)
volScalarField rhoCp
(
@ -149,4 +135,5 @@ volScalarField rhoCp
),
rho*thermo->Cp()
);
rhoCp.oldTime();

View File

@ -118,9 +118,8 @@ int main(int argc, char *argv[])
#include "alphaEqnSubCycle.H"
solve(fvm::ddt(rho) + fvc::div(rhoPhi));
#include "UEqn.H"
#include "eEqn.H"
#include "TEqn.H"
// --- Pressure corrector loop
while (pimple.correct())

View File

@ -490,6 +490,22 @@ Foam::tmp<Foam::scalarField> Foam::twoPhaseMixtureEThermo::kappa
}
Foam::tmp<Foam::volScalarField> Foam::twoPhaseMixtureEThermo::alphahe() const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::scalarField> Foam::twoPhaseMixtureEThermo::alphahe
(
const label patchi
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::volScalarField> Foam::twoPhaseMixtureEThermo::kappaEff
(
const volScalarField& kappat

View File

@ -246,6 +246,12 @@ public:
const label patchi
) const;
//- Thermal diffusivity for energy of mixture [kg/m/s]
virtual tmp<volScalarField> alphahe() const;
//- Thermal diffusivity for energy of mixture for patch [kg/m/s]
virtual tmp<scalarField> alphahe(const label patchi) const;
//- Effective thermal diffusivity for temperature
//- of mixture [J/m/s/K]
virtual tmp<volScalarField> kappaEff

View File

@ -87,8 +87,8 @@
alphaPhi1,
zeroField(),
zeroField(),
1,
0
oneField(),
zeroField()
);
}
else
@ -103,8 +103,8 @@
alphaPhi1,
zeroField(),
zeroField(),
1,
0
oneField(),
zeroField()
);
}
@ -155,8 +155,8 @@
alphaPhi2,
zeroField(),
zeroField(),
1,
0
oneField(),
zeroField()
);
}
else
@ -171,8 +171,8 @@
alphaPhi2,
zeroField(),
zeroField(),
1,
0
oneField(),
zeroField()
);
}

View File

@ -78,8 +78,8 @@
divU*(alpha10 - alpha100)
- vDotvmcAlphal*alpha10
)(),
1,
0
oneField(),
zeroField()
);
// Under-relax the correction for all but the 1st corrector
@ -103,8 +103,8 @@
talphaPhiCorr.ref(),
vDotvmcAlphal,
(divU*alpha1 + vDotcAlphal)(),
1,
0
oneField(),
zeroField()
);
talphaPhi = talphaPhiCorr;

View File

@ -5,7 +5,7 @@
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
| Copyright (C) 2011-2018 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,7 +37,12 @@ License
#include "fvcDiv.H"
#include "fvcFlux.H"
#include "fvcAverage.H"
#include "unitConversion.H"
// * * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * //
const Foam::scalar Foam::multiphaseSystem::convertToRad =
Foam::constant::mathematical::pi/180.0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -124,8 +129,8 @@ void Foam::multiphaseSystem::solveAlphas()
alphaPhiCorr,
zeroField(),
zeroField(),
1,
0,
oneField(),
zeroField(),
true
);
@ -143,7 +148,7 @@ void Foam::multiphaseSystem::solveAlphas()
mesh_
),
mesh_,
dimensionedScalar(dimless, Zero)
dimensionedScalar("sumAlpha", dimless, 0)
);
phasei = 0;
@ -158,9 +163,7 @@ void Foam::multiphaseSystem::solveAlphas()
(
geometricOneField(),
phase,
alphaPhi,
zeroField(),
zeroField()
alphaPhi
);
phase.alphaPhi() = alphaPhi;
@ -278,7 +281,7 @@ void Foam::multiphaseSystem::correctContactAngle
bool matched = (tp.key().first() == phase1.name());
const scalar theta0 = degToRad(tp().theta0(matched));
scalar theta0 = convertToRad*tp().theta0(matched);
scalarField theta(boundary[patchi].size(), theta0);
scalar uTheta = tp().uTheta();
@ -286,8 +289,8 @@ void Foam::multiphaseSystem::correctContactAngle
// Calculate the dynamic contact angle if required
if (uTheta > SMALL)
{
const scalar thetaA = degToRad(tp().thetaA(matched));
const scalar thetaR = degToRad(tp().thetaR(matched));
scalar thetaA = convertToRad*tp().thetaA(matched);
scalar thetaR = convertToRad*tp().thetaR(matched);
// Calculated the component of the velocity parallel to the wall
vectorField Uwall
@ -391,7 +394,7 @@ Foam::multiphaseSystem::multiphaseSystem
IOobject::AUTO_WRITE
),
mesh_,
dimensionedScalar(dimless, Zero)
dimensionedScalar("alphas", dimless, 0.0)
),
sigmas_(lookup("sigmas")),
@ -411,7 +414,7 @@ Foam::multiphaseSystem::multiphaseSystem
forAllConstIters(dragModelsDict, iter)
{
dragModels_.insert
dragModels_.set
(
iter.key(),
dragModel::New
@ -419,7 +422,7 @@ Foam::multiphaseSystem::multiphaseSystem
iter(),
*phases_.lookup(iter.key().first()),
*phases_.lookup(iter.key().second())
)
).ptr()
);
}
@ -583,7 +586,12 @@ Foam::tmp<Foam::volVectorField> Foam::multiphaseSystem::Svm
mesh_
),
mesh_,
dimensionedVector(dimensionSet(1, -2, -2, 0, 0), Zero)
dimensionedVector
(
"Svm",
dimensionSet(1, -2, -2, 0, 0),
Zero
)
)
);
@ -636,7 +644,7 @@ Foam::tmp<Foam::volVectorField> Foam::multiphaseSystem::Svm
Foam::autoPtr<Foam::multiphaseSystem::dragCoeffFields>
Foam::multiphaseSystem::dragCoeffs() const
{
auto dragCoeffsPtr = autoPtr<dragCoeffFields>::New();
autoPtr<dragCoeffFields> dragCoeffsPtr(new dragCoeffFields);
forAllConstIters(dragModels_, iter)
{
@ -702,7 +710,12 @@ Foam::tmp<Foam::volScalarField> Foam::multiphaseSystem::dragCoeff
mesh_
),
mesh_,
dimensionedScalar(dimensionSet(1, -3, -1, 0, 0), Zero)
dimensionedScalar
(
"dragCoeff",
dimensionSet(1, -3, -1, 0, 0),
0
)
)
);
@ -745,7 +758,12 @@ Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseSystem::surfaceTension
mesh_
),
mesh_,
dimensionedScalar(dimensionSet(1, -2, -2, 0, 0), Zero)
dimensionedScalar
(
"surfaceTension",
dimensionSet(1, -2, -2, 0, 0),
0
)
)
);
tSurfaceTension.ref().setOriented();
@ -789,7 +807,7 @@ Foam::multiphaseSystem::nearInterface() const
mesh_
),
mesh_,
dimensionedScalar(dimless, Zero)
dimensionedScalar("nearInterface", dimless, 0.0)
)
);
@ -813,7 +831,7 @@ void Foam::multiphaseSystem::solve()
const Time& runTime = mesh_.time();
const dictionary& alphaControls = mesh_.solverDict("alpha");
label nAlphaSubCycles(alphaControls.get<label>("nAlphaSubCycles"));
label nAlphaSubCycles(readLabel(alphaControls.lookup("nAlphaSubCycles")));
if (nAlphaSubCycles > 1)
{
@ -845,7 +863,7 @@ void Foam::multiphaseSystem::solve()
mesh_
),
mesh_,
dimensionedScalar(dimensionSet(0, 3, -1, 0, 0), Zero)
dimensionedScalar("0", dimensionSet(0, 3, -1, 0, 0), 0)
)
);
@ -912,15 +930,17 @@ bool Foam::multiphaseSystem::read()
readOK &= phase.read(phaseData[phasei++].dict());
}
readEntry("sigmas", sigmas_);
readEntry("interfaceCompression", cAlphas_);
readEntry("virtualMass", Cvms_);
lookup("sigmas") >> sigmas_;
lookup("interfaceCompression") >> cAlphas_;
lookup("virtualMass") >> Cvms_;
return readOK;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -76,16 +76,30 @@ public:
{
public:
struct symmHash
class symmHash
:
public Hash<interfacePair>
{
public:
symmHash()
{}
label operator()(const interfacePair& key) const
{
return word::hash()(key.first()) + word::hash()(key.second());
}
};
struct hash
class hash
:
public Hash<interfacePair>
{
public:
hash()
{}
label operator()(const interfacePair& key) const
{
return word::hash()(key.first(), word::hash()(key.second()));
@ -95,7 +109,8 @@ public:
// Constructors
interfacePair() {} // = default
interfacePair()
{}
interfacePair(const word& alpha1Name, const word& alpha2Name)
:
@ -174,6 +189,9 @@ private:
//- Stabilisation for normalisation of the interface normal
const dimensionedScalar deltaN_;
//- Conversion factor for degrees into radians
static const scalar convertToRad;
// Private member functions
@ -220,7 +238,8 @@ public:
//- Destructor
virtual ~multiphaseSystem() = default;
virtual ~multiphaseSystem()
{}
// Member Functions

View File

@ -613,8 +613,8 @@ void Foam::multiphaseMixture::solveAlphas
alphaPhiCorr,
zeroField(),
zeroField(),
1,
0,
oneField(),
zeroField(),
true
);
@ -648,9 +648,7 @@ void Foam::multiphaseMixture::solveAlphas
(
geometricOneField(),
alpha,
alphaPhi,
zeroField(),
zeroField()
alphaPhi
);
rhoPhi_ += alphaPhi*alpha.rho();

View File

@ -1,10 +1,8 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
wclean libso phaseSystems
wclean libso interfacialModels
wclean libso interfacialCompositionModels
reactingTwoPhaseEulerFoam/Allwclean
reactingMultiphaseEulerFoam/Allwclean
wclean reactingTwoPhaseEulerFoam
wclean reactingMultiphaseEulerFoam
wclean libso functionObjects
#------------------------------------------------------------------------------

View File

@ -4,12 +4,8 @@ cd ${0%/*} || exit 1 # Run from this directory
#------------------------------------------------------------------------------
wmakeLnInclude interfacialModels
wmakeLnInclude interfacialCompositionModels
wmake $targetType phaseSystems
wmake $targetType interfacialModels
wmake $targetType interfacialCompositionModels
reactingTwoPhaseEulerFoam/Allwmake $targetType $*
reactingMultiphaseEulerFoam/Allwmake $targetType $*
wmake $targetType functionObjects
#------------------------------------------------------------------------------

View File

@ -0,0 +1,4 @@
sizeDistribution/sizeDistribution.C
phaseForces/phaseForces.C
LIB = $(FOAM_LIBBIN)/libreactingEulerFoamFunctionObjects

View File

@ -0,0 +1,11 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/functionObjects/field/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/interfacialModels/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/phaseSystems/lnInclude
LIB_LIBS = \
-lfieldFunctionObjects \
-lfiniteVolume

View File

@ -0,0 +1,306 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2018-2019 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 "phaseForces.H"
#include "addToRunTimeSelectionTable.H"
#include "BlendedInterfacialModel.H"
#include "dragModel.H"
#include "virtualMassModel.H"
#include "liftModel.H"
#include "wallLubricationModel.H"
#include "turbulentDispersionModel.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(phaseForces, 0);
addToRunTimeSelectionTable(functionObject, phaseForces, dictionary);
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
template<class modelType>
Foam::tmp<Foam::volVectorField>
Foam::functionObjects::phaseForces::nonDragForce(const phasePair& pair) const
{
const BlendedInterfacialModel<modelType>& model =
fluid_.lookupBlendedSubModel<modelType>(pair);
if (&pair.phase1() == &phase_)
{
return model.template F<vector>();
}
else
{
return -model.template F<vector>();
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::phaseForces::phaseForces
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
phase_
(
mesh_.lookupObject<phaseModel>
(
IOobject::groupName("alpha", dict.get<word>("phase"))
)
),
fluid_(mesh_.lookupObject<phaseSystem>("phaseProperties"))
{
read(dict);
forAllConstIter
(
phaseSystem::phasePairTable,
fluid_.phasePairs(),
iter
)
{
const phasePair& pair = iter();
if (pair.contains(phase_) && !pair.ordered())
{
if (fluid_.foundBlendedSubModel<dragModel>(pair))
{
forceFields_.set
(
dragModel::typeName,
new volVectorField
(
IOobject
(
IOobject::groupName("dragForce", phase_.name()),
mesh_.time().timeName(),
mesh_
),
mesh_,
dimensionedVector(dimForce/dimVolume)
)
);
}
if (fluid_.foundBlendedSubModel<virtualMassModel>(pair))
{
forceFields_.set
(
virtualMassModel::typeName,
new volVectorField
(
IOobject
(
IOobject::groupName
(
"virtualMassForce",
phase_.name()
),
mesh_.time().timeName(),
mesh_
),
mesh_,
dimensionedVector(dimForce/dimVolume)
)
);
}
if (fluid_.foundBlendedSubModel<liftModel>(pair))
{
forceFields_.set
(
liftModel::typeName,
new volVectorField
(
IOobject
(
IOobject::groupName("liftForce", phase_.name()),
mesh_.time().timeName(),
mesh_
),
mesh_,
dimensionedVector(dimForce/dimVolume)
)
);
}
if (fluid_.foundBlendedSubModel<wallLubricationModel>(pair))
{
forceFields_.set
(
wallLubricationModel::typeName,
new volVectorField
(
IOobject
(
IOobject::groupName
(
"wallLubricationForce",
phase_.name()
),
mesh_.time().timeName(),
mesh_
),
mesh_,
dimensionedVector(dimForce/dimVolume)
)
);
}
if (fluid_.foundBlendedSubModel<turbulentDispersionModel>(pair))
{
forceFields_.set
(
turbulentDispersionModel::typeName,
new volVectorField
(
IOobject
(
IOobject::groupName
(
"turbulentDispersionForce",
phase_.name()
),
mesh_.time().timeName(),
mesh_
),
mesh_,
dimensionedVector(dimForce/dimVolume)
)
);
}
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::phaseForces::~phaseForces()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::phaseForces::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
return true;
}
bool Foam::functionObjects::phaseForces::execute()
{
forAllIter
(
HashPtrTable<volVectorField>,
forceFields_,
iter
)
{
const word& type = iter.key();
volVectorField& force = *iter();
force *= 0.0;
forAllConstIter
(
phaseSystem::phasePairTable,
fluid_.phasePairs(),
iter2
)
{
const phasePair& pair = iter2();
if (pair.contains(phase_) && !pair.ordered())
{
if (type == "dragModel")
{
force +=
fluid_.lookupBlendedSubModel<dragModel>(pair).K()
*(pair.otherPhase(phase_).U() - phase_.U());
}
if (type == "virtualMassModel")
{
force +=
fluid_.lookupBlendedSubModel<virtualMassModel>(pair).K()
*(
pair.otherPhase(phase_).DUDt()
- phase_.DUDt()
);
}
if (type == "liftModel")
{
force = nonDragForce<liftModel>(pair);
}
if (type == "wallLubricationModel")
{
force = nonDragForce<wallLubricationModel>(pair);
}
if (type == "turbulentDispersionModel")
{
force = nonDragForce<turbulentDispersionModel>(pair);
}
}
}
}
return true;
}
bool Foam::functionObjects::phaseForces::write()
{
forAllIter
(
HashPtrTable<volVectorField>,
forceFields_,
iter
)
{
writeObject(iter()->name());
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,163 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2018 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::functionObjects::phaseForces
Description
This function object calculates and outputs the blended interfacial forces
acting on a given phase, i.e. drag, virtual mass, lift, wall-lubrication and
turbulent dispersion. Note that it works only in run-time processing mode
and in combination with the reactingEulerFoam solvers.
For a simulation involving more than two phases, the accumulated force is
calculated by looping over all phasePairs involving that phase. The fields
are stored in the database so that they can be processed further, e.g. with
the fieldAveraging functionObject.
Example of function object specification:
\verbatim
phaseForces.water
{
type phaseForces;
libs ("libreactingEulerFoamFunctionObjects.so");
writeControl writeTime;
writeInterval 1;
...
phaseName water;
}
\endverbatim
Usage
\table
Property | Description | Required | Default value
type | type name: phaseForces | yes |
phaseName | Name of evaluated phase | yes |
\endtable
See also
Foam::BlendedInterfacialModel
Foam::functionObjects::fvMeshFunctionObject
Foam::functionObject
SourceFiles
phaseForces.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_phaseForces_H
#define functionObjects_phaseForces_H
#include "fvMeshFunctionObject.H"
#include "phaseSystem.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class phaseForces Declaration
\*---------------------------------------------------------------------------*/
class phaseForces
:
public fvMeshFunctionObject
{
// Private Member Functions
//- Disallow default bitwise copy construct
phaseForces(const phaseForces&);
//- Disallow default bitwise assignment
void operator=(const phaseForces&);
protected:
// Protected data
HashPtrTable<volVectorField> forceFields_;
//- Phase for which forces are evaluated
const phaseModel& phase_;
//- Constant access to phaseSystem
const phaseSystem& fluid_;
// Protected Member Functions
//- Evaluate and return non-drag force
template<class modelType>
tmp<volVectorField> nonDragForce(const phasePair& key) const;
public:
//- Runtime type information
TypeName("phaseForces");
// Constructors
//- Construct from Time and dictionary
phaseForces
(
const word& name,
const Time& runTime,
const dictionary&
);
//- Destructor
virtual ~phaseForces();
// Member Functions
//- Read the input data
virtual bool read(const dictionary& dict);
//- Calculate the force fields
virtual bool execute();
//- Write the force fields
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,585 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2017-2019 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 "sizeDistribution.H"
#include "sizeGroup.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(sizeDistribution, 0);
addToRunTimeSelectionTable(functionObject, sizeDistribution, dictionary);
}
}
const Foam::Enum
<
Foam::functionObjects::sizeDistribution::selectionModeTypes
>
Foam::functionObjects::sizeDistribution::selectionModeTypeNames_
({
{selectionModeTypes::rtCellZone, "cellZone"},
{selectionModeTypes::rtAll, "all"},
});
const Foam::Enum
<
Foam::functionObjects::sizeDistribution::functionTypes
>
Foam::functionObjects::sizeDistribution::functionTypeNames_
({
{functionTypes::ftNdf, "numberDensity"},
{functionTypes::ftVdf, "volumeDensity"},
{functionTypes::ftNc, "numberConcentration"},
{functionTypes::ftMom, "moments"},
});
const Foam::Enum
<
Foam::functionObjects::sizeDistribution::abszissaTypes
>
Foam::functionObjects::sizeDistribution::abszissaTypeNames_
({
{abszissaTypes::atDiameter, "diameter"},
{abszissaTypes::atVolume, "volume"},
});
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::functionObjects::sizeDistribution::initialise
(
const dictionary& dict
)
{
switch (functionType_)
{
case ftNdf:
{
break;
}
case ftVdf:
{
break;
}
case ftNc:
{
break;
}
case ftMom:
{
break;
}
default:
{
FatalIOErrorInFunction(dict)
<< "Unknown functionType. Valid types are:"
<< functionTypeNames_ << nl << exit(FatalIOError);
}
}
switch (abszissaType_)
{
case atDiameter:
{
break;
}
case atVolume:
{
break;
}
default:
{
FatalIOErrorInFunction(dict)
<< "Unknown abszissaType. Valid types are:"
<< abszissaTypeNames_ << nl << exit(FatalIOError);
}
}
setCellZoneCells();
if (nCells_ == 0)
{
FatalIOErrorInFunction(dict)
<< type() << " " << name() << ": "
<< selectionModeTypeNames_[selectionModeType_]
<< "(" << selectionModeTypeName_ << "):" << nl
<< " Selection has no cells" << exit(FatalIOError);
}
volume_ = volume();
Info<< type() << " " << name() << ":"
<< selectionModeTypeNames_[selectionModeType_]
<< "(" << selectionModeTypeName_ << "):" << nl
<< " total cells = " << nCells_ << nl
<< " total volume = " << volume_
<< nl << endl;
}
void Foam::functionObjects::sizeDistribution::setCellZoneCells()
{
switch (selectionModeType_)
{
case rtCellZone:
{
dict().lookup("cellZone") >> selectionModeTypeName_;
label zoneId =
mesh().cellZones().findZoneID(selectionModeTypeName_);
if (zoneId < 0)
{
FatalIOErrorInFunction(dict_)
<< "Unknown cellZone name: " << selectionModeTypeName_
<< ". Valid cellZone names are: "
<< mesh().cellZones().names()
<< nl << exit(FatalIOError);
}
cellId_ = mesh().cellZones()[zoneId];
nCells_ = returnReduce(cellId_.size(), sumOp<label>());
break;
}
case rtAll:
{
cellId_ = identity(mesh().nCells());
nCells_ = returnReduce(cellId_.size(), sumOp<label>());
break;
}
default:
{
FatalIOErrorInFunction(dict_)
<< "Unknown selectionMode type. Valid selectionMode types are:"
<< selectionModeTypeNames_ << nl << exit(FatalIOError);
}
}
}
Foam::scalar Foam::functionObjects::sizeDistribution::volume() const
{
return gSum(filterField(mesh().V()));
}
void Foam::functionObjects::sizeDistribution::combineFields(scalarField& field)
{
List<scalarField> allValues(Pstream::nProcs());
allValues[Pstream::myProcNo()] = field;
Pstream::gatherList(allValues);
if (Pstream::master())
{
field =
ListListOps::combine<scalarField>
(
allValues,
accessOp<scalarField>()
);
}
}
Foam::tmp<Foam::scalarField>
Foam::functionObjects::sizeDistribution::filterField
(
const scalarField& field
) const
{
return tmp<scalarField>(new scalarField(field, cellId_));
}
void Foam::functionObjects::sizeDistribution::writeFileHeader
(
const label i
)
{
OFstream& file = this->file();
switch (functionType_)
{
case ftNdf:
{
writeHeader(file, "Number density function");
break;
}
case ftVdf:
{
writeHeader(file, "Volume density function");
break;
}
case ftNc:
{
writeHeader(file, "Number concentration");
break;
}
case ftMom:
{
writeHeader(file, "Moments");
break;
}
}
switch (abszissaType_)
{
case atVolume:
{
writeCommented(file, "Time/volume");
break;
}
case atDiameter:
{
writeCommented(file, "Time/diameter");
break;
}
}
switch (functionType_)
{
case ftMom:
{
for (label i = 0; i <= momentOrder_; i++)
{
file() << tab << i;
}
break;
}
default:
{
forAll(popBal_.sizeGroups(), sizeGroupi)
{
const diameterModels::sizeGroup& fi =
popBal_.sizeGroups()[sizeGroupi];
switch (abszissaType_)
{
case atDiameter:
{
file() << tab << fi.d().value();
break;
}
case atVolume:
{
file() << tab << fi.x().value();
break;
}
}
}
break;
}
}
file << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::sizeDistribution::sizeDistribution
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
writeFile(obr_, name),
dict_(dict),
selectionModeType_
(
selectionModeTypeNames_.get("selectionMode", dict)
),
selectionModeTypeName_(word::null),
functionType_(functionTypeNames_.get("functionType", dict)),
abszissaType_(abszissaTypeNames_.get("abszissaType", dict)),
nCells_(0),
cellId_(),
volume_(0.0),
writeVolume_(dict.lookupOrDefault("writeVolume", false)),
popBal_
(
obr_.lookupObject<Foam::diameterModels::populationBalanceModel>
(
dict.get<word>("populationBalance")
)
),
N_(popBal_.sizeGroups().size()),
momentOrder_(dict.lookupOrDefault<label>("momentOrder", 0)),
normalize_(dict.lookupOrDefault("normalize", false)),
sumN_(0.0),
sumV_(0.0)
{
read(dict);
resetFile(name);
createFile(name);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::sizeDistribution::~sizeDistribution()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::sizeDistribution::read(const dictionary& dict)
{
if (dict != dict_)
{
dict_ = dict;
}
fvMeshFunctionObject::read(dict);
writeFile::read(dict);
initialise(dict);
return true;
}
bool Foam::functionObjects::sizeDistribution::execute()
{
return true;
}
bool Foam::functionObjects::sizeDistribution::write()
{
writeFileHeader();
writeTime(file());
Log << type() << " " << name() << " write" << nl;
scalarField V(filterField(mesh().V()));
combineFields(V);
sumN_ = 0;
sumV_ = 0;
forAll(N_, i)
{
const Foam::diameterModels::sizeGroup& fi = popBal_.sizeGroups()[i];
const volScalarField& alpha = fi.VelocityGroup().phase();
scalarField Ni(fi*alpha/fi.x());
scalarField values(filterField(Ni));
scalarField V(filterField(mesh().V()));
// Combine onto master
combineFields(values);
combineFields(V);
if (Pstream::master())
{
// Calculate volume-averaged number concentration
N_[i] = sum(V*values)/sum(V);
}
sumN_ += N_[i];
sumV_ += N_[i]*fi.x().value();
}
if (Pstream::master())
{
switch (functionType_)
{
case ftMom:
{
for (label m = 0; m <= momentOrder_; m++)
{
scalar result(0.0);
forAll(N_, i)
{
const Foam::diameterModels::sizeGroup& fi =
popBal_.sizeGroups()[i];
switch (abszissaType_)
{
case atVolume:
{
result += pow(fi.x().value(), m)*N_[i];
break;
}
case atDiameter:
{
result += pow(fi.d().value(), m)*N_[i];
break;
}
}
}
file() << tab << result;
}
break;
}
default:
{
forAll(popBal_.sizeGroups(), i)
{
const Foam::diameterModels::sizeGroup& fi =
popBal_.sizeGroups()[i];
scalar result(0.0);
scalar delta(0.0);
switch (abszissaType_)
{
case atVolume:
{
delta = popBal_.v()[i+1].value()
- popBal_.v()[i].value();
break;
}
case atDiameter:
{
const scalar& formFactor =
fi.VelocityGroup().formFactor().value();
delta =
pow
(
popBal_.v()[i+1].value()
/formFactor,
1.0/3.0
)
- pow
(
popBal_.v()[i].value()
/formFactor,
1.0/3.0
);
break;
}
}
switch (functionType_)
{
case ftNdf:
{
if (normalize_ == true)
{
result = N_[i]/delta/sumN_;
}
else
{
result = N_[i]/delta;
}
break;
}
case ftVdf:
{
if (normalize_ == true)
{
result = N_[i]*fi.x().value()/delta/sumV_;
}
else
{
result = N_[i]*fi.x().value()/delta;
}
break;
}
case ftNc:
{
if (normalize_ == true)
{
result = N_[i]/sumN_;
}
else
{
result = N_[i];
}
break;
}
default:
{
break;
}
}
file()<< tab << result;
}
}
}
}
{
file()<< endl;
}
Log << endl;
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,277 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2017-2019 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::functionObjects::sizeDistribution
Description
This function object calculates and outputs information about the size
distribution of the dispersed phase, such as the number density function or
its moments. It is designed to be used exclusively with the population
balance modeling functionality of the reactingEulerFoam solvers. It can be
applied to a specific cellZone or the entire domain.
Example of function object specification:
\verbatim
box.all.numberDensity.volume.bubbles
{
type sizeDistribution;
libs ("libreactingEulerFoamFunctionObjects.so");
writeControl outputTime;
writeInterval 1;
log true;
...
functionType numberDensity;
abszissaType volume;
selectionMode all;
populationBalanceModel bubbles;
normalize true;
}
\endverbatim
Usage
\table
Property | Description | Required | Default value
type | type name: sizeDistribution | yes |
functionType | numberDensity, volumeDensity, numberConcentration,
moments | yes |
abszissaType | volume, diameter | yes |
momentOrder | Write moment up to given order | no | 0
selectionMode | Evaluate for cellZone or entire mesh | yes |
cellZone | Required if selectionMode is cellZone | |
populationBalanceModel | Respective populationBalanceModel | yes |
normalize | Normalization | no |
\endtable
See also
Foam::diameterModels::populationBalanceModel
Foam::functionObject
Foam::functionObjects::fvMeshFunctionObject
Foam::functionObjects::writeFile
SourceFiles
sizeDistribution.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_sizeDistribution_H
#define functionObjects_sizeDistribution_H
#include "fvMeshFunctionObject.H"
#include "writeFile.H"
#include "populationBalanceModel.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class fvMesh;
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class sizeDistribution Declaration
\*---------------------------------------------------------------------------*/
class sizeDistribution
:
public fvMeshFunctionObject,
public writeFile
{
public:
// Public data types
//- Selection mode type enumeration
enum selectionModeTypes
{
rtCellZone,
rtAll
};
//- Selection mode type names
static const Enum<selectionModeTypes> selectionModeTypeNames_;
//- Function type enumeration
enum functionTypes
{
ftNdf,
ftVdf,
ftNc,
ftMom
};
//- Function type names
static const Enum<functionTypes> functionTypeNames_;
//- abszissa type enumeration
enum abszissaTypes
{
atDiameter,
atVolume,
};
//- Abszissa type names
static const Enum<abszissaTypes> abszissaTypeNames_;
protected:
// Protected data
//- Construction dictionary
dictionary dict_;
//- Selection mode type
selectionModeTypes selectionModeType_;
//- Name of selection
word selectionModeTypeName_;
//- Function type
functionTypes functionType_;
//- Abszissa type
abszissaTypes abszissaType_;
//- Global number of cells
label nCells_;
//- Local list of cell IDs
labelList cellId_;
//- Total volume of the evaluated selection
scalar volume_;
//- Optionally write the volume of the sizeDistribution
bool writeVolume_;
//- PopulationBalance
const Foam::diameterModels::populationBalanceModel& popBal_;
//- Number concentrations
List<scalar> N_;
//- Write moments up to specified order with respect to abszissaType
label momentOrder_;
//- Normalization switch
const Switch normalize_;
//- Sum of number concentrations
scalar sumN_;
//- Volumertic sum
scalar sumV_;
// Protected Member Functions
//- Initialise, e.g. cell addressing
void initialise(const dictionary& dict);
//- Set cells to evaluate based on a cell zone
void setCellZoneCells();
//- Calculate and return volume of the evaluated cell zone
scalar volume() const;
//- Combine fields from all processor domains into single field
void combineFields(scalarField& field);
//- Filter field according to cellIds
tmp<scalarField> filterField(const scalarField& field) const;
//- Output file header information
void writeFileHeader(const label i = 0);
public:
//- Runtime type information
TypeName("sizeDistribution");
// Constructors
//- Construct from Time and dictionary
sizeDistribution
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~sizeDistribution();
// Member Functions
//- Return the reference to the construction dictionary
const dictionary& dict() const
{
return dict_;
}
//- Return the local list of cell IDs
const labelList& cellId() const
{
return cellId_;
}
//- Helper function to return the reference to the mesh
const fvMesh& mesh() const
{
return refCast<const fvMesh>(obr_);
}
//- Read from dictionary
virtual bool read(const dictionary& dict);
//- Execute
virtual bool execute();
//- Write
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,120 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2017 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "interfaceCompositionModel.H"
#include "InterfaceCompositionModel.H"
#include "Henry.H"
#include "NonRandomTwoLiquid.H"
#include "Raoult.H"
#include "Saturated.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "makeReactionThermo.H"
#include "thermoPhysicsTypes.H"
#include "rhoConst.H"
#include "perfectFluid.H"
#include "pureMixture.H"
#include "multiComponentMixture.H"
#include "reactingMixture.H"
#include "SpecieMixture.H"
#include "rhoThermo.H"
#include "rhoReactionThermo.H"
#include "heRhoThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
using namespace interfaceCompositionModels;
// multi-component gas in the presence of a pure liquid
makeInterfaceCompositionType
(
Saturated,
heRhoThermo,
rhoReactionThermo,
multiComponentMixture,
gasEThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
constFluidEThermoPhysics
);
// reacting gas in the presence of a pure liquid
makeInterfaceCompositionType
(
Saturated,
heRhoThermo,
rhoReactionThermo,
reactingMixture,
gasEThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
constFluidEThermoPhysics
);
// multi-component gas in the presence of a multi-component liquid
makeSpecieInterfaceCompositionType
(
Saturated,
heRhoThermo,
rhoReactionThermo,
multiComponentMixture,
constGasEThermoPhysics,
heRhoThermo,
rhoReactionThermo,
multiComponentMixture,
constFluidEThermoPhysics
);
// multi-component liquid in the presence of a multi-component gas
makeSpecieInterfaceCompositionType
(
Henry,
heRhoThermo,
rhoReactionThermo,
multiComponentMixture,
constFluidEThermoPhysics,
heRhoThermo,
rhoReactionThermo,
multiComponentMixture,
constGasEThermoPhysics
);
}
// ************************************************************************* //

View File

@ -1,550 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2014-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "BlendedInterfacialModel.H"
#include "fixedValueFvsPatchFields.H"
#include "surfaceInterpolate.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class ModelType>
template<class GeometricField>
void Foam::BlendedInterfacialModel<ModelType>::correctFixedFluxBCs
(
GeometricField& field
) const
{
typename GeometricField::Boundary& fieldBf =
field.boundaryFieldRef();
forAll(phase1_.phi()().boundaryField(), patchi)
{
if
(
isA<fixedValueFvsPatchScalarField>
(
phase1_.phi()().boundaryField()[patchi]
)
)
{
fieldBf[patchi] = Zero;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class ModelType>
Foam::BlendedInterfacialModel<ModelType>::BlendedInterfacialModel
(
const phaseModel& phase1,
const phaseModel& phase2,
const blendingMethod& blending,
autoPtr<ModelType> model,
autoPtr<ModelType> model1In2,
autoPtr<ModelType> model2In1,
const bool correctFixedFluxBCs
)
:
phase1_(phase1),
phase2_(phase2),
blending_(blending),
model_(model),
model1In2_(model1In2),
model2In1_(model2In1),
correctFixedFluxBCs_(correctFixedFluxBCs)
{}
template<class ModelType>
Foam::BlendedInterfacialModel<ModelType>::BlendedInterfacialModel
(
const phasePair::dictTable& modelTable,
const blendingMethod& blending,
const phasePair& pair,
const orderedPhasePair& pair1In2,
const orderedPhasePair& pair2In1,
const bool correctFixedFluxBCs
)
:
phase1_(pair.phase1()),
phase2_(pair.phase2()),
blending_(blending),
correctFixedFluxBCs_(correctFixedFluxBCs)
{
if (modelTable.found(pair))
{
model_.set
(
ModelType::New
(
modelTable[pair],
pair
).ptr()
);
}
if (modelTable.found(pair1In2))
{
model1In2_.set
(
ModelType::New
(
modelTable[pair1In2],
pair1In2
).ptr()
);
}
if (modelTable.found(pair2In1))
{
model2In1_.set
(
ModelType::New
(
modelTable[pair2In1],
pair2In1
).ptr()
);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class ModelType>
Foam::BlendedInterfacialModel<ModelType>::~BlendedInterfacialModel()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class ModelType>
bool Foam::BlendedInterfacialModel<ModelType>::hasModel
(
const class phaseModel& phase
) const
{
return
&phase == &(phase1_)
? model1In2_.valid()
: model2In1_.valid();
}
template<class ModelType>
const ModelType& Foam::BlendedInterfacialModel<ModelType>::model
(
const class phaseModel& phase
) const
{
return &phase == &(phase1_) ? model1In2_ : model2In1_;
}
template<class ModelType>
Foam::tmp<Foam::volScalarField>
Foam::BlendedInterfacialModel<ModelType>::K() const
{
tmp<volScalarField> f1, f2;
if (model_.valid() || model1In2_.valid())
{
f1 = blending_.f1(phase1_, phase2_);
}
if (model_.valid() || model2In1_.valid())
{
f2 = blending_.f2(phase1_, phase2_);
}
tmp<volScalarField> x
(
new volScalarField
(
IOobject
(
ModelType::typeName + ":K",
phase1_.mesh().time().timeName(),
phase1_.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
phase1_.mesh(),
dimensionedScalar(ModelType::dimK, Zero)
)
);
if (model_.valid())
{
x.ref() += model_->K()*(scalar(1) - f1() - f2());
}
if (model1In2_.valid())
{
x.ref() += model1In2_->K()*f1;
}
if (model2In1_.valid())
{
x.ref() += model2In1_->K()*f2;
}
if
(
correctFixedFluxBCs_
&& (model_.valid() || model1In2_.valid() || model2In1_.valid())
)
{
correctFixedFluxBCs(x.ref());
}
return x;
}
template<class ModelType>
Foam::tmp<Foam::volScalarField>
Foam::BlendedInterfacialModel<ModelType>::K(const scalar residualAlpha) const
{
tmp<volScalarField> f1, f2;
if (model_.valid() || model1In2_.valid())
{
f1 = blending_.f1(phase1_, phase2_);
}
if (model_.valid() || model2In1_.valid())
{
f2 = blending_.f2(phase1_, phase2_);
}
tmp<volScalarField> x
(
new volScalarField
(
IOobject
(
ModelType::typeName + ":K",
phase1_.mesh().time().timeName(),
phase1_.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
phase1_.mesh(),
dimensionedScalar(ModelType::dimK, Zero)
)
);
if (model_.valid())
{
x.ref() += model_->K(residualAlpha)*(scalar(1) - f1() - f2());
}
if (model1In2_.valid())
{
x.ref() += model1In2_->K(residualAlpha)*f1;
}
if (model2In1_.valid())
{
x.ref() += model2In1_->K(residualAlpha)*f2;
}
if
(
correctFixedFluxBCs_
&& (model_.valid() || model1In2_.valid() || model2In1_.valid())
)
{
correctFixedFluxBCs(x.ref());
}
return x;
}
template<class ModelType>
Foam::tmp<Foam::surfaceScalarField>
Foam::BlendedInterfacialModel<ModelType>::Kf() const
{
tmp<surfaceScalarField> f1, f2;
if (model_.valid() || model1In2_.valid())
{
f1 = fvc::interpolate
(
blending_.f1(phase1_, phase2_)
);
}
if (model_.valid() || model2In1_.valid())
{
f2 = fvc::interpolate
(
blending_.f2(phase1_, phase2_)
);
}
tmp<surfaceScalarField> x
(
new surfaceScalarField
(
IOobject
(
ModelType::typeName + ":Kf",
phase1_.mesh().time().timeName(),
phase1_.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
phase1_.mesh(),
dimensionedScalar(ModelType::dimK, Zero)
)
);
if (model_.valid())
{
x.ref() += model_->Kf()*(scalar(1) - f1() - f2());
}
if (model1In2_.valid())
{
x.ref() += model1In2_->Kf()*f1;
}
if (model2In1_.valid())
{
x.ref() += model2In1_->Kf()*f2;
}
if
(
correctFixedFluxBCs_
&& (model_.valid() || model1In2_.valid() || model2In1_.valid())
)
{
correctFixedFluxBCs(x.ref());
}
return x;
}
template<class ModelType>
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::BlendedInterfacialModel<ModelType>::F() const
{
tmp<volScalarField> f1, f2;
if (model_.valid() || model1In2_.valid())
{
f1 = blending_.f1(phase1_, phase2_);
}
if (model_.valid() || model2In1_.valid())
{
f2 = blending_.f2(phase1_, phase2_);
}
tmp<GeometricField<Type, fvPatchField, volMesh>> x
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
ModelType::typeName + ":F",
phase1_.mesh().time().timeName(),
phase1_.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
phase1_.mesh(),
dimensioned<Type>(ModelType::dimF, Zero)
)
);
if (model_.valid())
{
x.ref() += model_->F()*(scalar(1) - f1() - f2());
}
if (model1In2_.valid())
{
x.ref() += model1In2_->F()*f1;
}
if (model2In1_.valid())
{
x.ref() -= model2In1_->F()*f2; // note : subtraction
}
if
(
correctFixedFluxBCs_
&& (model_.valid() || model1In2_.valid() || model2In1_.valid())
)
{
correctFixedFluxBCs(x.ref());
}
return x;
}
template<class ModelType>
Foam::tmp<Foam::surfaceScalarField>
Foam::BlendedInterfacialModel<ModelType>::Ff() const
{
tmp<surfaceScalarField> f1, f2;
if (model_.valid() || model1In2_.valid())
{
f1 = fvc::interpolate
(
blending_.f1(phase1_, phase2_)
);
}
if (model_.valid() || model2In1_.valid())
{
f2 = fvc::interpolate
(
blending_.f2(phase1_, phase2_)
);
}
tmp<surfaceScalarField> x
(
new surfaceScalarField
(
IOobject
(
ModelType::typeName + ":Ff",
phase1_.mesh().time().timeName(),
phase1_.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
phase1_.mesh(),
dimensionedScalar(ModelType::dimF*dimArea, Zero)
)
);
x.ref().setOriented();
if (model_.valid())
{
x.ref() += model_->Ff()*(scalar(1) - f1() - f2());
}
if (model1In2_.valid())
{
x.ref() += model1In2_->Ff()*f1;
}
if (model2In1_.valid())
{
x.ref() -= model2In1_->Ff()*f2; // note : subtraction
}
if
(
correctFixedFluxBCs_
&& (model_.valid() || model1In2_.valid() || model2In1_.valid())
)
{
correctFixedFluxBCs(x.ref());
}
return x;
}
template<class ModelType>
Foam::tmp<Foam::volScalarField>
Foam::BlendedInterfacialModel<ModelType>::D() const
{
tmp<volScalarField> f1, f2;
if (model_.valid() || model1In2_.valid())
{
f1 = blending_.f1(phase1_, phase2_);
}
if (model_.valid() || model2In1_.valid())
{
f2 = blending_.f2(phase1_, phase2_);
}
tmp<volScalarField> x
(
new volScalarField
(
IOobject
(
ModelType::typeName + ":D",
phase1_.mesh().time().timeName(),
phase1_.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
phase1_.mesh(),
dimensionedScalar(ModelType::dimD, Zero)
)
);
if (model_.valid())
{
x.ref() += model_->D()*(scalar(1) - f1() - f2());
}
if (model1In2_.valid())
{
x.ref() += model1In2_->D()*f1;
}
if (model2In1_.valid())
{
x.ref() += model2In1_->D()*f2;
}
if
(
correctFixedFluxBCs_
&& (model_.valid() || model1In2_.valid() || model2In1_.valid())
)
{
correctFixedFluxBCs(x.ref());
}
return x;
}
// ************************************************************************* //

View File

@ -1,24 +0,0 @@
phaseModel/phaseModel/phaseModel.C
phaseModel/phaseModel/newPhaseModel.C
phaseModel/phaseModel/phaseModels.C
phasePair/phasePairKey/phasePairKey.C
phasePair/phasePair/phasePair.C
phasePair/orderedPhasePair/orderedPhasePair.C
phaseSystem/phaseSystem.C
diameterModels/diameterModel/diameterModel.C
diameterModels/diameterModel/newDiameterModel.C
diameterModels/constantDiameter/constantDiameter.C
diameterModels/isothermalDiameter/isothermalDiameter.C
BlendedInterfacialModel/blendingMethods/blendingMethod/blendingMethod.C
BlendedInterfacialModel/blendingMethods/blendingMethod/newBlendingMethod.C
BlendedInterfacialModel/blendingMethods/noBlending/noBlending.C
BlendedInterfacialModel/blendingMethods/linear/linear.C
BlendedInterfacialModel/blendingMethods/hyperbolic/hyperbolic.C
reactionThermo/hRefConstThermos.C
LIB = $(FOAM_LIBBIN)/libreactingPhaseSystem

View File

@ -1,371 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "HeatAndMassTransferPhaseSystem.H"
#include "BlendedInterfacialModel.H"
#include "heatTransferModel.H"
#include "massTransferModel.H"
#include "HashPtrTable.H"
#include "fvcDiv.H"
#include "fvmSup.H"
#include "fvMatrix.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::
HeatAndMassTransferPhaseSystem
(
const fvMesh& mesh
)
:
BasePhaseSystem(mesh)
{
this->generatePairsAndSubModels
(
"heatTransfer",
heatTransferModels_
);
this->generatePairsAndSubModels
(
"massTransfer",
massTransferModels_
);
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
// Initially assume no mass transfer
dmdt_.set
(
pair,
new volScalarField
(
IOobject
(
IOobject::groupName("dmdt", pair.name()),
this->mesh().time().timeName(),
this->mesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime, Zero)
)
);
dmdtExplicit_.set
(
pair,
new volScalarField
(
IOobject
(
IOobject::groupName("dmdtExplicit", pair.name()),
this->mesh().time().timeName(),
this->mesh()
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime, Zero)
)
);
volScalarField H1(heatTransferModels_[pair][pair.first()]->K());
volScalarField H2(heatTransferModels_[pair][pair.second()]->K());
Tf_.set
(
pair,
new volScalarField
(
IOobject
(
IOobject::groupName("Tf", pair.name()),
this->mesh().time().timeName(),
this->mesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
(
H1*pair.phase1().thermo().T()
+ H2*pair.phase2().thermo().T()
)
/max
(
H1 + H2,
dimensionedScalar("small", heatTransferModel::dimK, SMALL)
),
zeroGradientFvPatchScalarField::typeName
)
);
Tf_[pair]->correctBoundaryConditions();
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::
~HeatAndMassTransferPhaseSystem()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
bool Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::transfersMass
(
const phaseModel& phase
) const
{
return true;
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::dmdt
(
const phasePairKey& key
) const
{
const scalar dmdtSign(Pair<word>::compare(dmdt_.find(key).key(), key));
return dmdtSign**dmdt_[key];
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::dmdt
(
const Foam::phaseModel& phase
) const
{
tmp<volScalarField> tdmdt
(
new volScalarField
(
IOobject
(
IOobject::groupName("dmdt", phase.name()),
this->mesh_.time().timeName(),
this->mesh_
),
this->mesh_,
dimensionedScalar(dimDensity/dimTime, Zero)
)
);
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const phaseModel* phase1 = &pair.phase1();
const phaseModel* phase2 = &pair.phase2();
forAllConstIters(pair, iter)
{
if (phase1 == &phase)
{
tdmdt.ref() += this->dmdt(pair);
}
Swap(phase1, phase2);
}
}
return tdmdt;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::momentumTransferTable>
Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::momentumTransfer() const
{
autoPtr<phaseSystem::momentumTransferTable>
eqnsPtr(BasePhaseSystem::momentumTransfer());
phaseSystem::momentumTransferTable& eqns = eqnsPtr();
// Source term due to mass transfer
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const volVectorField& U1(pair.phase1().U());
const volVectorField& U2(pair.phase2().U());
const volScalarField dmdt(this->dmdt(pair));
const volScalarField dmdt21(posPart(dmdt));
const volScalarField dmdt12(negPart(dmdt));
*eqns[pair.phase1().name()] += dmdt21*U2 - fvm::Sp(dmdt21, U1);
*eqns[pair.phase2().name()] -= dmdt12*U1 - fvm::Sp(dmdt12, U2);
}
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::heatTransferTable>
Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::heatTransfer() const
{
auto eqnsPtr = autoPtr<phaseSystem::heatTransferTable>::New();
auto& eqns = *eqnsPtr;
for (const phaseModel& phase : this->phaseModels_)
{
eqns.set
(
phase.name(),
new fvScalarMatrix(phase.thermo().he(), dimEnergy/dimTime)
);
}
// Heat transfer with the interface
forAllConstIters(heatTransferModels_, heatTransferModelIter)
{
const phasePair& pair =
*(this->phasePairs_[heatTransferModelIter.key()]);
const phaseModel* phase = &pair.phase1();
const phaseModel* otherPhase = &pair.phase2();
const volScalarField& Tf(*Tf_[pair]);
const volScalarField K1
(
heatTransferModelIter()[pair.first()]->K()
);
const volScalarField K2
(
heatTransferModelIter()[pair.second()]->K()
);
const volScalarField KEff
(
K1*K2
/max
(
K1 + K2,
dimensionedScalar("small", heatTransferModel::dimK, SMALL)
)
);
const volScalarField* K = &K1;
const volScalarField* otherK = &K2;
forAllConstIters(pair, iter)
{
const volScalarField& he(phase->thermo().he());
volScalarField Cpv(phase->thermo().Cpv());
*eqns[phase->name()] +=
(*K)*(Tf - phase->thermo().T())
+ KEff/Cpv*he - fvm::Sp(KEff/Cpv, he);
Swap(phase, otherPhase);
Swap(K, otherK);
}
}
// Source term due to mass transfer
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const phaseModel& phase1 = pair.phase1();
const phaseModel& phase2 = pair.phase2();
const volScalarField& he1(phase1.thermo().he());
const volScalarField& he2(phase2.thermo().he());
const volScalarField& K1(phase1.K());
const volScalarField& K2(phase2.K());
const volScalarField dmdt(this->dmdt(pair));
const volScalarField dmdt21(posPart(dmdt));
const volScalarField dmdt12(negPart(dmdt));
const volScalarField& Tf(*Tf_[pair]);
*eqns[phase1.name()] +=
dmdt21*(phase1.thermo().he(phase1.thermo().p(), Tf))
- fvm::Sp(dmdt21, he1)
+ dmdt21*(K2 - K1);
*eqns[phase2.name()] -=
dmdt12*(phase2.thermo().he(phase2.thermo().p(), Tf))
- fvm::Sp(dmdt12, he2)
+ dmdt12*(K1 - K2);
}
return eqnsPtr;
}
template<class BasePhaseSystem>
bool Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::read()
{
if (BasePhaseSystem::read())
{
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -1,176 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "HeatTransferPhaseSystem.H"
#include "BlendedInterfacialModel.H"
#include "heatTransferModel.H"
#include "HashPtrTable.H"
#include "fvcDiv.H"
#include "fvmSup.H"
#include "fvMatrix.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::HeatTransferPhaseSystem<BasePhaseSystem>::HeatTransferPhaseSystem
(
const fvMesh& mesh
)
:
BasePhaseSystem(mesh)
{
this->generatePairsAndSubModels("heatTransfer", heatTransferModels_);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::HeatTransferPhaseSystem<BasePhaseSystem>::~HeatTransferPhaseSystem()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
bool Foam::HeatTransferPhaseSystem<BasePhaseSystem>::transfersMass
(
const phaseModel& phase
) const
{
return false;
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::HeatTransferPhaseSystem<BasePhaseSystem>::dmdt
(
const phasePairKey& key
) const
{
return tmp<volScalarField>::New
(
IOobject
(
IOobject::groupName
(
"dmdt",
this->phasePairs_[key]->name()
),
this->mesh().time().timeName(),
this->mesh().time()
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime, Zero)
);
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::HeatTransferPhaseSystem<BasePhaseSystem>::dmdt
(
const Foam::phaseModel& phase
) const
{
return tmp<volScalarField>(nullptr);
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::heatTransferTable>
Foam::HeatTransferPhaseSystem<BasePhaseSystem>::heatTransfer() const
{
auto eqnsPtr = autoPtr<phaseSystem::heatTransferTable>::New();
auto& eqns = *eqnsPtr;
for (const phaseModel& phase : this->phaseModels_)
{
eqns.set
(
phase.name(),
new fvScalarMatrix(phase.thermo().he(), dimEnergy/dimTime)
);
}
forAllConstIters(heatTransferModels_, heatTransferModelIter)
{
const phasePair& pair =
*(this->phasePairs_[heatTransferModelIter.key()]);
const volScalarField K(heatTransferModelIter()->K());
const phaseModel* phase = &pair.phase1();
const phaseModel* otherPhase = &pair.phase2();
forAllConstIters(pair, iter)
{
const volScalarField& he(phase->thermo().he());
volScalarField Cpv(phase->thermo().Cpv());
*eqns[phase->name()] +=
K*(otherPhase->thermo().T() - phase->thermo().T() + he/Cpv)
- fvm::Sp(K/Cpv, he);
Swap(phase, otherPhase);
}
}
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::massTransferTable>
Foam::HeatTransferPhaseSystem<BasePhaseSystem>::massTransfer() const
{
autoPtr<phaseSystem::massTransferTable> eqnsPtr
(
new phaseSystem::massTransferTable()
);
return eqnsPtr;
}
template<class BasePhaseSystem>
bool Foam::HeatTransferPhaseSystem<BasePhaseSystem>::read()
{
if (BasePhaseSystem::read())
{
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -1,294 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "InterfaceCompositionPhaseChangePhaseSystem.H"
#include "interfaceCompositionModel.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::InterfaceCompositionPhaseChangePhaseSystem<BasePhaseSystem>::
InterfaceCompositionPhaseChangePhaseSystem
(
const fvMesh& mesh
)
:
HeatAndMassTransferPhaseSystem<BasePhaseSystem>(mesh)
{
this->generatePairsAndSubModels
(
"interfaceComposition",
interfaceCompositionModels_
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::InterfaceCompositionPhaseChangePhaseSystem<BasePhaseSystem>::
~InterfaceCompositionPhaseChangePhaseSystem()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::massTransferTable>
Foam::InterfaceCompositionPhaseChangePhaseSystem<BasePhaseSystem>::
massTransfer() const
{
// Create a mass transfer matrix for each species of each phase
auto eqnsPtr = autoPtr<phaseSystem::massTransferTable>::New();
auto& eqns = *eqnsPtr;
for (const phaseModel& phase : this->phaseModels_)
{
const PtrList<volScalarField>& Yi = phase.Y();
forAll(Yi, i)
{
eqns.set
(
Yi[i].name(),
new fvScalarMatrix(Yi[i], dimMass/dimTime)
);
}
}
// Reset the interfacial mass flow rates
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
*this->dmdt_[pair] =
*this->dmdtExplicit_[pair];
*this->dmdtExplicit_[pair] =
dimensionedScalar(dimDensity/dimTime, Zero);
}
// Sum up the contribution from each interface composition model
forAllConstIters(interfaceCompositionModels_, modelIter)
{
const phasePair& pair = *(this->phasePairs_[modelIter.key()]);
const interfaceCompositionModel& compositionModel = *(modelIter.val());
const phaseModel& phase = pair.phase1();
const phaseModel& otherPhase = pair.phase2();
const phasePairKey key(phase.name(), otherPhase.name());
const volScalarField& Tf(*this->Tf_[key]);
volScalarField& dmdtExplicit(*this->dmdtExplicit_[key]);
volScalarField& dmdt(*this->dmdt_[key]);
scalar dmdtSign(Pair<word>::compare(this->dmdt_.find(key).key(), key));
const volScalarField K
(
this->massTransferModels_[key][phase.name()]->K()
);
for (const word& member : compositionModel.species())
{
const word name
(
IOobject::groupName(member, phase.name())
);
const word otherName
(
IOobject::groupName(member, otherPhase.name())
);
const volScalarField KD
(
K*compositionModel.D(member)
);
const volScalarField Yf
(
compositionModel.Yf(member, Tf)
);
// Implicit transport through the phase
*eqns[name] +=
phase.rho()*KD*Yf
- fvm::Sp(phase.rho()*KD, eqns[name]->psi());
// Sum the mass transfer rate
dmdtExplicit += dmdtSign*phase.rho()*KD*Yf;
dmdt -= dmdtSign*phase.rho()*KD*eqns[name]->psi();
// Explicit transport out of the other phase
if (eqns.found(otherName))
{
*eqns[otherName] -=
otherPhase.rho()*KD*compositionModel.dY(member, Tf);
}
}
}
return eqnsPtr;
}
template<class BasePhaseSystem>
void Foam::InterfaceCompositionPhaseChangePhaseSystem<BasePhaseSystem>::
correctThermo()
{
BasePhaseSystem::correctThermo();
// This loop solves for the interface temperatures, Tf, and updates the
// interface composition models.
//
// The rate of heat transfer to the interface must equal the latent heat
// consumed at the interface, i.e.:
//
// H1*(T1 - Tf) + H2*(T2 - Tf) == mDotL
// == K*rho*(Yfi - Yi)*Li
//
// Yfi is likely to be a strong non-linear (typically exponential) function
// of Tf, so the solution for the temperature is newton-accelerated
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const phasePairKey key12(pair.first(), pair.second(), true);
const phasePairKey key21(pair.second(), pair.first(), true);
volScalarField H1(this->heatTransferModels_[pair][pair.first()]->K());
volScalarField H2(this->heatTransferModels_[pair][pair.second()]->K());
dimensionedScalar HSmall("small", heatTransferModel::dimK, SMALL);
volScalarField mDotL
(
IOobject
(
"mDotL",
this->mesh().time().timeName(),
this->mesh()
),
this->mesh(),
dimensionedScalar(dimEnergy/dimVolume/dimTime, Zero)
);
volScalarField mDotLPrime
(
IOobject
(
"mDotLPrime",
this->mesh().time().timeName(),
this->mesh()
),
this->mesh(),
dimensionedScalar(mDotL.dimensions()/dimTemperature, Zero)
);
volScalarField& Tf = *this->Tf_[pair];
// Add latent heats from forward and backward models
if (this->interfaceCompositionModels_.found(key12))
{
this->interfaceCompositionModels_[key12]->addMDotL
(
this->massTransferModels_[pair][pair.first()]->K(),
Tf,
mDotL,
mDotLPrime
);
}
if (this->interfaceCompositionModels_.found(key21))
{
this->interfaceCompositionModels_[key21]->addMDotL
(
this->massTransferModels_[pair][pair.second()]->K(),
Tf,
mDotL,
mDotLPrime
);
}
// Update the interface temperature by applying one step of newton's
// method to the interface relation
Tf -=
(
H1*(Tf - pair.phase1().thermo().T())
+ H2*(Tf - pair.phase2().thermo().T())
+ mDotL
)
/(
max(H1 + H2 + mDotLPrime, HSmall)
);
Tf.correctBoundaryConditions();
Info<< "Tf." << pair.name()
<< ": min = " << min(Tf.primitiveField())
<< ", mean = " << average(Tf.primitiveField())
<< ", max = " << max(Tf.primitiveField())
<< endl;
// Update the interface compositions
if (this->interfaceCompositionModels_.found(key12))
{
this->interfaceCompositionModels_[key12]->update(Tf);
}
if (this->interfaceCompositionModels_.found(key21))
{
this->interfaceCompositionModels_[key21]->update(Tf);
}
}
}
template<class BasePhaseSystem>
bool Foam::InterfaceCompositionPhaseChangePhaseSystem<BasePhaseSystem>::read()
{
if (BasePhaseSystem::read())
{
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -1,604 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "MomentumTransferPhaseSystem.H"
#include "BlendedInterfacialModel.H"
#include "dragModel.H"
#include "virtualMassModel.H"
#include "liftModel.H"
#include "wallLubricationModel.H"
#include "turbulentDispersionModel.H"
#include "HashPtrTable.H"
#include "fvmDdt.H"
#include "fvmDiv.H"
#include "fvmSup.H"
#include "fvcDiv.H"
#include "fvcSnGrad.H"
#include "fvMatrix.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::
MomentumTransferPhaseSystem
(
const fvMesh& mesh
)
:
BasePhaseSystem(mesh)
{
this->generatePairsAndSubModels
(
"drag",
dragModels_
);
this->generatePairsAndSubModels
(
"virtualMass",
virtualMassModels_
);
this->generatePairsAndSubModels
(
"lift",
liftModels_
);
this->generatePairsAndSubModels
(
"wallLubrication",
wallLubricationModels_
);
this->generatePairsAndSubModels
(
"turbulentDispersion",
turbulentDispersionModels_
);
forAllConstIters(dragModels_, dragModelIter)
{
const phasePair& pair =
*(this->phasePairs_[dragModelIter.key()]);
Kds_.set
(
pair,
new volScalarField
(
IOobject::groupName("Kd", pair.name()),
dragModelIter()->K()
)
);
}
forAllConstIters(virtualMassModels_, virtualMassModelIter)
{
const phasePair& pair =
*(this->phasePairs_[virtualMassModelIter.key()]);
Vms_.set
(
pair,
new volScalarField
(
IOobject::groupName("Vm", pair.name()),
virtualMassModelIter()->K()
)
);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::
~MomentumTransferPhaseSystem()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::Kd
(
const phasePairKey& key
) const
{
return dragModels_[key]->K();
}
template<class BasePhaseSystem>
Foam::tmp<Foam::surfaceScalarField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::Kdf
(
const phasePairKey& key
) const
{
return dragModels_[key]->Kf();
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::Kd
(
const Foam::phaseModel& phase
) const
{
tmp<volScalarField> tKd
(
new volScalarField
(
IOobject
(
IOobject::groupName("Kd", phase.name()),
this->mesh_.time().timeName(),
this->mesh_
),
this->mesh_,
dimensionedScalar(dimensionSet(1, -3, -1, 0, 0), Zero)
)
);
forAllConstIters(Kds_, KdIter)
{
const phasePair& pair = *(this->phasePairs_[KdIter.key()]);
const volScalarField& K(*KdIter());
const phaseModel* phase1 = &pair.phase1();
const phaseModel* phase2 = &pair.phase2();
forAllConstIters(pair, iter)
{
if (phase1 == &phase)
{
tKd.ref() += K;
}
Swap(phase1, phase2);
}
}
return tKd;
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::Vm
(
const phasePairKey& key
) const
{
if (virtualMassModels_.found(key))
{
return virtualMassModels_[key]->K();
}
return tmp<volScalarField>::New
(
IOobject
(
virtualMassModel::typeName + ":K",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh_,
dimensionedScalar(virtualMassModel::dimK, Zero)
);
}
template<class BasePhaseSystem>
Foam::tmp<Foam::surfaceScalarField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::Vmf
(
const phasePairKey& key
) const
{
if (virtualMassModels_.found(key))
{
return virtualMassModels_[key]->Kf();
}
return tmp<surfaceScalarField>::New
(
IOobject
(
virtualMassModel::typeName + ":Kf",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh_,
dimensionedScalar(virtualMassModel::dimK, Zero)
);
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volVectorField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::F
(
const phasePairKey& key
) const
{
if (liftModels_.found(key) && wallLubricationModels_.found(key))
{
return
liftModels_[key]->template F<vector>()
+ wallLubricationModels_[key]->template F<vector>();
}
else if (liftModels_.found(key))
{
return liftModels_[key]->template F<vector>();
}
else if (wallLubricationModels_.found(key))
{
return wallLubricationModels_[key]->template F<vector>();
}
return tmp<volVectorField>::New
(
IOobject
(
liftModel::typeName + ":F",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh_,
dimensionedVector(liftModel::dimF, Zero)
);
}
template<class BasePhaseSystem>
Foam::tmp<Foam::surfaceScalarField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::Ff
(
const phasePairKey& key
) const
{
if (liftModels_.found(key) && wallLubricationModels_.found(key))
{
return
liftModels_[key]->Ff()
+ wallLubricationModels_[key]->Ff();
}
else if (liftModels_.found(key))
{
return liftModels_[key]->Ff();
}
else if (wallLubricationModels_.found(key))
{
return wallLubricationModels_[key]->Ff();
}
else
{
tmp<surfaceScalarField> tFf
(
new surfaceScalarField
(
IOobject
(
liftModel::typeName + ":Ff",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh_,
dimensionedScalar(liftModel::dimF*dimArea, Zero)
)
);
tFf.ref().setOriented();
return tFf;
}
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::D
(
const phasePairKey& key
) const
{
if (turbulentDispersionModels_.found(key))
{
return turbulentDispersionModels_[key]->D();
}
return tmp<volScalarField>::New
(
IOobject
(
turbulentDispersionModel::typeName + ":D",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh_,
dimensionedScalar(turbulentDispersionModel::dimD, Zero)
);
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::momentumTransferTable>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::momentumTransfer() const
{
// Create a momentum transfer matrix for each phase
auto eqnsPtr = autoPtr<phaseSystem::momentumTransferTable>::New();
auto& eqns = *eqnsPtr;
for (const phaseModel& phase : this->phaseModels_)
{
eqns.set
(
phase.name(),
new fvVectorMatrix(phase.U(), dimMass*dimVelocity/dimTime)
);
}
// Update the drag coefficients
forAllConstIters(dragModels_, dragModelIter)
{
*Kds_[dragModelIter.key()] = dragModelIter()->K();
}
// Add the implicit part of the drag force
forAllConstIters(Kds_, KdIter)
{
const phasePair& pair = *(this->phasePairs_[KdIter.key()]);
const volScalarField& K(*KdIter());
const phaseModel* phase = &pair.phase1();
const phaseModel* otherPhase = &pair.phase2();
forAllConstIters(pair, iter)
{
const volVectorField& U = phase->U();
*eqns[phase->name()] -= fvm::Sp(K, U);
Swap(phase, otherPhase);
}
}
// Update the virtual mass coefficients
forAllConstIters(virtualMassModels_, virtualMassModelIter)
{
*Vms_[virtualMassModelIter.key()] = virtualMassModelIter()->K();
}
// Add the virtual mass force
forAllConstIters(Vms_, VmIter)
{
const phasePair& pair = *(this->phasePairs_[VmIter.key()]);
const volScalarField& Vm(*VmIter());
const phaseModel* phase = &pair.phase1();
const phaseModel* otherPhase = &pair.phase2();
forAllConstIters(pair, iter)
{
const volVectorField& U = phase->U();
const surfaceScalarField& phi = phase->phi();
*eqns[phase->name()] -=
Vm
*(
fvm::ddt(U)
+ fvm::div(phi, U)
- fvm::Sp(fvc::div(phi), U)
- otherPhase->DUDt()
)
+ this->MRF_.DDt(Vm, U - otherPhase->U());
Swap(phase, otherPhase);
}
}
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::volVectorField& Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::setF
(
PtrList<volVectorField>& Fs, const label phasei
) const
{
if (!Fs.set(phasei))
{
Fs.set
(
phasei,
new volVectorField
(
IOobject
(
liftModel::typeName + ":F",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh_,
dimensionedVector(liftModel::dimF, Zero)
)
);
}
return Fs[phasei];
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::PtrList<Foam::volVectorField>>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::Fs() const
{
auto tFs = autoPtr<PtrList<volVectorField>>::New(this->phases().size());
auto& Fs = *tFs;
// Add the lift force
forAllConstIters(liftModels_, modelIter)
{
const phasePair& pair = *(this->phasePairs_[modelIter.key()]);
const volVectorField F(modelIter()->template F<vector>());
setF(Fs, pair.phase1().index()) += F;
setF(Fs, pair.phase2().index()) -= F;
}
// Add the wall lubrication force
forAllConstIters(wallLubricationModels_, modelIter)
{
const phasePair& pair = *(this->phasePairs_[modelIter.key()]);
const volVectorField F(modelIter()->template F<vector>());
setF(Fs, pair.phase1().index()) += F;
setF(Fs, pair.phase2().index()) -= F;
}
return tFs;
}
template<class BasePhaseSystem>
Foam::surfaceScalarField&
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::setPhiD
(
PtrList<surfaceScalarField>& phiDs, const label phasei
) const
{
if (!phiDs.set(phasei))
{
phiDs.set
(
phasei,
new surfaceScalarField
(
IOobject
(
turbulentDispersionModel::typeName + ":phiD",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh_,
dimensionedScalar
(
dimTime*dimArea*turbulentDispersionModel::dimF/dimDensity,
Zero
)
)
);
phiDs[phasei].setOriented();
}
return phiDs[phasei];
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::PtrList<Foam::surfaceScalarField>>
Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::phiDs
(
const PtrList<volScalarField>& rAUs
) const
{
auto tphiDs =
autoPtr<PtrList<surfaceScalarField>>::New(this->phases().size());
auto& phiDs = *tphiDs;
// Add the turbulent dispersion force
forAllConstIters(turbulentDispersionModels_, turbulentDispersionModelIter)
{
const phasePair& pair =
*(this->phasePairs_[turbulentDispersionModelIter.key()]);
const volScalarField D(turbulentDispersionModelIter()->D());
const surfaceScalarField snGradAlpha1
(
fvc::snGrad(pair.phase1())*this->mesh_.magSf()
);
setPhiD(phiDs, pair.phase1().index()) +=
fvc::interpolate(rAUs[pair.phase1().index()]*D)*snGradAlpha1;
setPhiD(phiDs, pair.phase2().index()) -=
fvc::interpolate(rAUs[pair.phase2().index()]*D)*snGradAlpha1;
}
return tphiDs;
}
template<class BasePhaseSystem>
bool Foam::MomentumTransferPhaseSystem<BasePhaseSystem>::read()
{
if (BasePhaseSystem::read())
{
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -1,497 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2017 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "ThermalPhaseChangePhaseSystem.H"
#include "alphatPhaseChangeWallFunctionFvPatchScalarField.H"
#include "fvcVolumeIntegrate.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::
ThermalPhaseChangePhaseSystem
(
const fvMesh& mesh
)
:
HeatAndMassTransferPhaseSystem<BasePhaseSystem>(mesh),
volatile_(this->lookup("volatile")),
saturationModel_(saturationModel::New(this->subDict("saturationModel"))),
massTransfer_(this->template get<bool>("massTransfer"))
{
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
// Initially assume no mass transfer
iDmdt_.set
(
pair,
new volScalarField
(
IOobject
(
IOobject::groupName("iDmdt", pair.name()),
this->mesh().time().timeName(),
this->mesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime, Zero)
)
);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::
~ThermalPhaseChangePhaseSystem()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
const Foam::saturationModel&
Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::saturation() const
{
return *saturationModel_;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::heatTransferTable>
Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::heatTransfer() const
{
typedef compressible::alphatPhaseChangeWallFunctionFvPatchScalarField
alphatPhaseChangeWallFunction;
autoPtr<phaseSystem::heatTransferTable> eqnsPtr =
Foam::HeatAndMassTransferPhaseSystem<BasePhaseSystem>::heatTransfer();
phaseSystem::heatTransferTable& eqns = eqnsPtr();
// Accumulate mDotL contributions from boundaries
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const phaseModel& phase = pair.phase1();
const phaseModel& otherPhase = pair.phase2();
volScalarField mDotL
(
IOobject
(
"mDotL",
phase.mesh().time().timeName(),
phase.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
phase.mesh(),
dimensionedScalar(dimensionSet(1,-1,-3,0,0), Zero)
);
const volScalarField* alphatPtr =
otherPhase.mesh().findObject<volScalarField>
(
"alphat." + otherPhase.name()
);
if (alphatPtr)
{
const volScalarField& alphat = *alphatPtr;
const fvPatchList& patches = this->mesh().boundary();
forAll(patches, patchi)
{
const fvPatch& currPatch = patches[patchi];
if
(
isA<alphatPhaseChangeWallFunction>
(
alphat.boundaryField()[patchi]
)
)
{
const scalarField& patchMDotL =
refCast<const alphatPhaseChangeWallFunction>
(
alphat.boundaryField()[patchi]
).mDotL();
forAll(patchMDotL,facei)
{
label faceCelli = currPatch.faceCells()[facei];
mDotL[faceCelli] = patchMDotL[facei];
}
}
}
}
*eqns[otherPhase.name()] -= mDotL;
}
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::massTransferTable>
Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::massTransfer() const
{
// Create a mass transfer matrix for each species of each phase
auto eqnsPtr = autoPtr<phaseSystem::massTransferTable>::New();
auto& eqns = *eqnsPtr;
for (const phaseModel& phase : this->phaseModels_)
{
const PtrList<volScalarField>& Yi = phase.Y();
forAll(Yi, i)
{
eqns.set
(
Yi[i].name(),
new fvScalarMatrix(Yi[i], dimMass/dimTime)
);
}
}
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const phaseModel& phase = pair.phase1();
const phaseModel& otherPhase = pair.phase2();
const word thisName
(
IOobject::groupName(volatile_, phase.name())
);
const word otherName
(
IOobject::groupName(volatile_, otherPhase.name())
);
const volScalarField dmdt(this->dmdt(pair));
const volScalarField dmdt12(posPart(dmdt));
const volScalarField dmdt21(negPart(dmdt));
*eqns[thisName] += fvm::Sp(dmdt21, eqns[thisName]->psi()) - dmdt21;
*eqns[otherName] += dmdt12 - fvm::Sp(dmdt12, eqns[otherName]->psi());
}
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::iDmdt
(
const phasePairKey& key
) const
{
const scalar dmdtSign(Pair<word>::compare(iDmdt_.find(key).key(), key));
return dmdtSign**iDmdt_[key];
}
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::iDmdt
(
const Foam::phaseModel& phase
) const
{
tmp<volScalarField> tiDmdt
(
new volScalarField
(
IOobject
(
IOobject::groupName("iDmdt", phase.name()),
this->mesh_.time().timeName(),
this->mesh_
),
this->mesh_,
dimensionedScalar(dimDensity/dimTime, Zero)
)
);
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const phaseModel* phase1 = &pair.phase1();
const phaseModel* phase2 = &pair.phase2();
forAllConstIters(pair, iter)
{
if (phase1 == &phase)
{
tiDmdt.ref() += this->iDmdt(pair);
}
Swap(phase1, phase2);
}
}
return tiDmdt;
}
template<class BasePhaseSystem>
void Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::correctThermo()
{
typedef compressible::alphatPhaseChangeWallFunctionFvPatchScalarField
alphatPhaseChangeWallFunction;
BasePhaseSystem::correctThermo();
forAllConstIters(this->phasePairs_, phasePairIter)
{
const phasePair& pair = *(phasePairIter.val());
if (pair.ordered())
{
continue;
}
const phaseModel& phase1 = pair.phase1();
const phaseModel& phase2 = pair.phase2();
Info<< phase1.name() << " min/max T "
<< min(phase1.thermo().T()).value()
<< " - "
<< max(phase1.thermo().T()).value()
<< endl;
Info<< phase2.name() << " min/max T "
<< min(phase2.thermo().T()).value()
<< " - "
<< max(phase2.thermo().T()).value()
<< endl;
const volScalarField& T1(phase1.thermo().T());
const volScalarField& T2(phase2.thermo().T());
const volScalarField& he1(phase1.thermo().he());
const volScalarField& he2(phase2.thermo().he());
volScalarField& dmdt(*this->dmdt_[pair]);
volScalarField& iDmdt(*this->iDmdt_[pair]);
volScalarField& Tf = *this->Tf_[pair];
volScalarField hef1(phase1.thermo().he(phase1.thermo().p(), Tf));
volScalarField hef2(phase2.thermo().he(phase2.thermo().p(), Tf));
volScalarField L
(
min
(
(pos0(iDmdt)*he2 + neg(iDmdt)*hef2)
- (neg(iDmdt)*he1 + pos0(iDmdt)*hef1),
0.3*mag(hef2 - hef1)
)
);
volScalarField iDmdtNew(iDmdt);
if (massTransfer_)
{
volScalarField H1
(
this->heatTransferModels_[pair][pair.first()]->K(0)
);
volScalarField H2
(
this->heatTransferModels_[pair][pair.second()]->K(0)
);
Tf = saturationModel_->Tsat(phase1.thermo().p());
iDmdtNew =
(H1*(Tf - T1) + H2*(Tf - T2))/L;
}
else
{
iDmdtNew == dimensionedScalar(dmdt.dimensions(), Zero);
}
volScalarField H1(this->heatTransferModels_[pair][pair.first()]->K());
volScalarField H2(this->heatTransferModels_[pair][pair.second()]->K());
// Limit the H[12] boundary field to avoid /0
const scalar HLimit = 1e-4;
H1.boundaryFieldRef() =
max(H1.boundaryField(), phase1.boundaryField()*HLimit);
H2.boundaryFieldRef() =
max(H2.boundaryField(), phase2.boundaryField()*HLimit);
Tf = (H1*T1 + H2*T2 + iDmdtNew*L)/(H1 + H2);
Info<< "Tf." << pair.name()
<< ": min = " << min(Tf.primitiveField())
<< ", mean = " << average(Tf.primitiveField())
<< ", max = " << max(Tf.primitiveField())
<< endl;
scalar iDmdtRelax(this->mesh().fieldRelaxationFactor("iDmdt"));
iDmdt = (1 - iDmdtRelax)*iDmdt + iDmdtRelax*iDmdtNew;
if (massTransfer_ )
{
Info<< "iDmdt." << pair.name()
<< ": min = " << min(iDmdt.primitiveField())
<< ", mean = " << average(iDmdt.primitiveField())
<< ", max = " << max(iDmdt.primitiveField())
<< ", integral = " << fvc::domainIntegrate(iDmdt).value()
<< endl;
}
// Accumulate dmdt contributions from boundaries
volScalarField wDmdt
(
IOobject
(
IOobject::groupName("wDmdt", pair.name()),
this->mesh().time().timeName(),
this->mesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime, Zero)
);
const volScalarField* alphatPtr =
phase2.mesh().findObject<volScalarField>
(
"alphat." + phase2.name()
);
if (alphatPtr)
{
const volScalarField& alphat = *alphatPtr;
const fvPatchList& patches = this->mesh().boundary();
forAll(patches, patchi)
{
const fvPatch& currPatch = patches[patchi];
if
(
isA<alphatPhaseChangeWallFunction>
(
alphat.boundaryField()[patchi]
)
)
{
const scalarField& patchDmdt =
refCast<const alphatPhaseChangeWallFunction>
(
alphat.boundaryField()[patchi]
).dmdt();
forAll(patchDmdt,facei)
{
label faceCelli = currPatch.faceCells()[facei];
wDmdt[faceCelli] += patchDmdt[facei];
}
}
}
Info<< "wDmdt." << pair.name()
<< ": min = " << min(wDmdt.primitiveField())
<< ", mean = " << average(wDmdt.primitiveField())
<< ", max = " << max(wDmdt.primitiveField())
<< ", integral = " << fvc::domainIntegrate(wDmdt).value()
<< endl;
}
dmdt = wDmdt + iDmdt;
Info<< "dmdt." << pair.name()
<< ": min = " << min(dmdt.primitiveField())
<< ", mean = " << average(dmdt.primitiveField())
<< ", max = " << max(dmdt.primitiveField())
<< ", integral = " << fvc::domainIntegrate(dmdt).value()
<< endl;
}
}
template<class BasePhaseSystem>
bool Foam::ThermalPhaseChangePhaseSystem<BasePhaseSystem>::read()
{
if (BasePhaseSystem::read())
{
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -1,377 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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::phaseSystem
Description
Class to represent a system of phases and model interfacial transfers
between them.
SourceFiles
phaseSystem.C
\*---------------------------------------------------------------------------*/
#ifndef phaseSystem_H
#define phaseSystem_H
#include "IOdictionary.H"
#include "phaseModel.H"
#include "phasePair.H"
#include "orderedPhasePair.H"
#include "HashPtrTable.H"
#include "PtrListDictionary.H"
#include "IOMRFZoneList.H"
#include "fvOptions.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvMatricesFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class blendingMethod;
template<class modelType> class BlendedInterfacialModel;
class surfaceTensionModel;
class aspectRatioModel;
/*---------------------------------------------------------------------------*\
Class phaseSystem Declaration
\*---------------------------------------------------------------------------*/
class phaseSystem
:
public IOdictionary
{
public:
// Public typedefs
typedef
HashPtrTable
<
volScalarField,
phasePairKey,
phasePairKey::hash
>
KdTable;
typedef
HashPtrTable
<
volScalarField,
phasePairKey,
phasePairKey::hash
>
VmTable;
typedef
HashPtrTable
<
fvVectorMatrix,
word,
string::hash
>
momentumTransferTable;
typedef
HashPtrTable
<
fvScalarMatrix,
word,
string::hash
>
heatTransferTable;
typedef
HashPtrTable
<
fvScalarMatrix,
word,
string::hash
>
massTransferTable;
typedef PtrListDictionary<phaseModel> phaseModelList;
protected:
// Protected typedefs
typedef
HashTable<dictionary, phasePairKey, phasePairKey::hash>
dictTable;
typedef
HashTable<autoPtr<phasePair>, phasePairKey, phasePairKey::hash>
phasePairTable;
typedef
HashTable<autoPtr<blendingMethod>>
blendingMethodTable;
typedef
HashTable
<
autoPtr<surfaceTensionModel>,
phasePairKey,
phasePairKey::hash
>
surfaceTensionModelTable;
typedef
HashTable
<
autoPtr<aspectRatioModel>,
phasePairKey,
phasePairKey::hash
>
aspectRatioModelTable;
// Protected data
//- Reference to the mesh
const fvMesh& mesh_;
//- Phase models
phaseModelList phaseModels_;
//- Phase pairs
phasePairTable phasePairs_;
//- Total volumetric flux
surfaceScalarField phi_;
//- Rate of change of pressure
volScalarField dpdt_;
//- Optional MRF zones
IOMRFZoneList MRF_;
//- Blending methods
blendingMethodTable blendingMethods_;
// Sub Models
//- Surface tension models
surfaceTensionModelTable surfaceTensionModels_;
//- Aspect ratio models
aspectRatioModelTable aspectRatioModels_;
// Protected member functions
//- Calculate and return the mixture flux
tmp<surfaceScalarField> calcPhi
(
const phaseModelList& phaseModels
) const;
//- Generate pairs
void generatePairs
(
const dictTable& modelDicts
);
//- Generate pairs and sub-model tables
template<class modelType>
void createSubModels
(
const dictTable& modelDicts,
HashTable
<
autoPtr<modelType>,
phasePairKey,
phasePairKey::hash
>& models
);
//- Generate pairs and sub-model tables
template<class modelType>
void generatePairsAndSubModels
(
const word& modelName,
HashTable
<
autoPtr<modelType>,
phasePairKey,
phasePairKey::hash
>& models
);
//- Generate pairs and blended sub-model tables
template<class modelType>
void generatePairsAndSubModels
(
const word& modelName,
HashTable
<
autoPtr<BlendedInterfacialModel<modelType>>,
phasePairKey,
phasePairKey::hash
>& models
);
//- Generate pairs and per-phase sub-model tables
template<class modelType>
void generatePairsAndSubModels
(
const word& modelName,
HashTable
<
HashTable<autoPtr<modelType>>,
phasePairKey,
phasePairKey::hash
>& models
);
public:
//- Runtime type information
TypeName("phaseSystem");
//- Default name of the phase properties dictionary
static const word propertiesName;
// Constructors
//- Construct from fvMesh
phaseSystem(const fvMesh& mesh);
//- Destructor
virtual ~phaseSystem();
// Member Functions
//- Constant access the mesh
inline const fvMesh& mesh() const;
//- Constant access the phase models
inline const phaseModelList& phases() const;
//- Access the phase models
inline phaseModelList& phases();
//- Constant access the phase pairs
inline const phasePairTable& phasePairs() const;
//- Return the mixture density
tmp<volScalarField> rho() const;
//- Return the mixture velocity
tmp<volVectorField> U() const;
//- Constant access the mixture flux
inline const surfaceScalarField& phi() const;
//- Access the mixture flux
inline surfaceScalarField& phi();
//- Constant access the rate of change of the pressure
inline const volScalarField& dpdt() const;
//- Access the rate of change of the pressure
inline volScalarField& dpdt();
//- Return the aspect-ratio
tmp<volScalarField> E(const phasePairKey& key) const;
//- Return the surface tension coefficient
tmp<volScalarField> sigma(const phasePairKey& key) const;
//- Return MRF zones
inline const IOMRFZoneList& MRF() const;
//- Optional FV-options
inline fv::options& fvOptions() const;
//- Access a sub model between a phase pair
template<class modelType>
const modelType& lookupSubModel(const phasePair& key) const;
//- Access a sub model between two phases
template<class modelType>
const modelType& lookupSubModel
(
const phaseModel& dispersed,
const phaseModel& continuous
) const;
//- Solve for the phase fractions
virtual void solve();
//- Correct the fluid properties other than the thermo and turbulence
virtual void correct();
//- Correct the kinematics
virtual void correctKinematics();
//- Correct the thermodynamics
virtual void correctThermo();
//- Correct the turbulence
virtual void correctTurbulence();
//- Correct the energy transport e.g. alphat
virtual void correctEnergyTransport();
//- Read base phaseProperties dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "phaseSystemI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "phaseSystemTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,225 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2017 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "BlendedInterfacialModel.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class modelType>
void Foam::phaseSystem::createSubModels
(
const dictTable& modelDicts,
HashTable
<
autoPtr<modelType>,
phasePairKey,
phasePairKey::hash
>& models
)
{
forAllConstIters(modelDicts, iter)
{
const phasePairKey& key = iter.key();
models.insert
(
key,
modelType::New
(
iter.val(),
phasePairs_[key]()
)
);
}
}
template<class modelType>
void Foam::phaseSystem::generatePairsAndSubModels
(
const word& modelName,
HashTable
<
autoPtr<modelType>,
phasePairKey,
phasePairKey::hash
>& models
)
{
dictTable modelDicts(lookup(modelName));
generatePairs(modelDicts);
createSubModels(modelDicts, models);
}
template<class modelType>
void Foam::phaseSystem::generatePairsAndSubModels
(
const word& modelName,
HashTable
<
autoPtr<BlendedInterfacialModel<modelType>>,
phasePairKey,
phasePairKey::hash
>& models
)
{
typedef
HashTable<autoPtr<modelType>, phasePairKey, phasePairKey::hash>
modelTypeTable;
modelTypeTable tempModels;
generatePairsAndSubModels(modelName, tempModels);
const blendingMethod& blending
(
blendingMethods_.found(modelName)
? *(blendingMethods_[modelName])
: *(blendingMethods_["default"])
);
autoPtr<modelType> noModel;
forAllConstIters(tempModels, iter)
{
if (!iter().valid())
{
continue;
}
const phasePairKey key(iter.key().first(), iter.key().second());
const phasePairKey key1In2(key.first(), key.second(), true);
const phasePairKey key2In1(key.second(), key.first(), true);
models.insert
(
key,
autoPtr<BlendedInterfacialModel<modelType>>
(
new BlendedInterfacialModel<modelType>
(
phaseModels_[key.first()],
phaseModels_[key.second()],
blending,
tempModels.found(key ) ? tempModels[key ] : noModel,
tempModels.found(key1In2) ? tempModels[key1In2] : noModel,
tempModels.found(key2In1) ? tempModels[key2In1] : noModel
)
)
);
if (!phasePairs_.found(key))
{
phasePairs_.insert
(
key,
autoPtr<phasePair>
(
new phasePair
(
phaseModels_[key.first()],
phaseModels_[key.second()]
)
)
);
}
}
}
template<class modelType>
void Foam::phaseSystem::generatePairsAndSubModels
(
const word& modelName,
HashTable
<
HashTable<autoPtr<modelType>>,
phasePairKey,
phasePairKey::hash
>& models
)
{
typedef
HashTable<autoPtr<modelType>, phasePairKey, phasePairKey::hash>
modelTypeTable;
for (const phaseModel& phase : phaseModels_)
{
modelTypeTable tempModels;
generatePairsAndSubModels
(
IOobject::groupName(modelName, phase.name()),
tempModels
);
forAllConstIters(tempModels, tempModelIter)
{
const phasePairKey& key = tempModelIter.key();
if (!models.found(key))
{
models.insert
(
key,
HashTable<autoPtr<modelType>>()
);
}
models[tempModelIter.key()].insert
(
phase.name(),
*tempModelIter
);
}
}
}
template<class modelType>
const modelType& Foam::phaseSystem::lookupSubModel(const phasePair& key) const
{
return
mesh().lookupObject<modelType>
(
IOobject::groupName(modelType::typeName, key.name())
);
}
template<class modelType>
const modelType& Foam::phaseSystem::lookupSubModel
(
const phaseModel& dispersed,
const phaseModel& continuous
) const
{
return lookupSubModel<modelType>(orderedPhasePair(dispersed, continuous));
}
// ************************************************************************* //

View File

@ -1,11 +1,9 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Parse arguments for library compilation
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
#------------------------------------------------------------------------------
wmake $targetType multiphaseSystem
wmake $targetType multiphaseCompressibleTurbulenceModels
wmake $targetType
#------------------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
| Copyright (C) 2011-2018 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.

View File

@ -7,32 +7,27 @@ for (int Ecorr=0; Ecorr<nEnergyCorrectors; Ecorr++)
phaseSystem::heatTransferTable& heatTransfer = heatTransferPtr();
forAll(phases, phasei)
forAll(fluid.anisothermalPhases(), anisothermalPhasei)
{
phaseModel& phase = phases[phasei];
phaseModel& phase = fluid.anisothermalPhases()[anisothermalPhasei];
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
const volVectorField& U = phase.U();
tmp<fvScalarMatrix> EEqn(phase.heEqn());
if (EEqn.valid())
{
EEqn =
fvScalarMatrix EEqn
(
EEqn
phase.heEqn()
==
*heatTransfer[phase.name()]
+ alpha*rho*(U&g)
+ fvOptions(alpha, rho, phase.thermo().he())
+ fvOptions(alpha, rho, phase.thermoRef().he())
);
EEqn->relax();
fvOptions.constrain(EEqn.ref());
EEqn->solve();
fvOptions.correct(phase.thermo().he());
}
EEqn.relax();
fvOptions.constrain(EEqn);
EEqn.solve();
fvOptions.correct(phase.thermoRef().he());
}
fluid.correctThermo();

View File

@ -1,15 +1,17 @@
EXE_INC = \
-ImultiphaseSystem/lnInclude \
-I../phaseSystems/lnInclude \
-I../interfacialModels/lnInclude \
-I../interfacialCompositionModels/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/reactingMultiphaseEulerFoam/multiphaseSystem/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/phaseSystems/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/interfacialModels/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/interfacialCompositionModels/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/reactingMultiphaseEulerFoam/multiphaseCompressibleTurbulenceModels/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/turbulentFluidThermoModels/turbulentFluidFvPatchFields/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/phaseCompressible/lnInclude
EXE_LIBS = \

View File

@ -5,33 +5,26 @@
phaseSystem::massTransferTable&
massTransfer(massTransferPtr());
forAll(phases, phasei)
forAll(fluid.multiComponentPhases(), multiComponentPhasei)
{
phaseModel& phase = phases[phasei];
phaseModel& phase = fluid.multiComponentPhases()[multiComponentPhasei];
PtrList<volScalarField>& Y = phase.Y();
UPtrList<volScalarField>& Y = phase.YActiveRef();
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
forAll(Y, i)
{
tmp<fvScalarMatrix> YiEqn(phase.YiEqn(Y[i]));
if (YiEqn.valid())
{
YiEqn =
fvScalarMatrix YiEqn
(
YiEqn
phase.YiEqn(Y[i])
==
*massTransfer[Y[i].name()]
+ fvOptions(alpha, rho, Y[i])
);
YiEqn->relax();
YiEqn->solve(mesh.solver("Yi"));
YiEqn.relax();
YiEqn.solve(mesh.solver("Yi"));
}
}
}
fluid.massTransfer(); // updates interfacial mass flow rates
}

View File

@ -20,7 +20,7 @@ dimensionedScalar pMin
#include "gh.H"
volScalarField& p = phases[0].thermo().p();
volScalarField& p = phases[0].thermoRef().p();
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh

View File

@ -9,17 +9,17 @@ PtrList<fvVectorMatrix> UEqns(phases.size());
phaseSystem::momentumTransferTable&
momentumTransfer(momentumTransferPtr());
forAll(phases, phasei)
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = phases[phasei];
phaseModel& phase = fluid.movingPhases()[movingPhasei];
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
volVectorField& U = phase.U();
volVectorField& U = phase.URef();
UEqns.set
(
phasei,
phase.index(),
new fvVectorMatrix
(
phase.UEqn()
@ -29,8 +29,8 @@ PtrList<fvVectorMatrix> UEqns(phases.size());
)
);
UEqns[phasei].relax();
fvOptions.constrain(UEqns[phasei]);
UEqns[phase.index()].relax();
fvOptions.constrain(UEqns[phase.index()]);
fvOptions.correct(U);
}
}

View File

@ -1,7 +1,5 @@
// Face volume fractions
PtrList<surfaceScalarField> alphafs(phases.size());
PtrList<volScalarField> rAUs(phases.size());
PtrList<surfaceScalarField> alpharAUfs(phases.size());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
@ -9,21 +7,37 @@ forAll(phases, phasei)
alphafs.set(phasei, fvc::interpolate(alpha).ptr());
alphafs[phasei].rename("pEqn" + alphafs[phasei].name());
}
// Diagonal coefficients
PtrList<volScalarField> rAUs(phases.size());
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
const volScalarField& alpha = phase;
rAUs.set
(
phasei,
phase.index(),
new volScalarField
(
IOobject::groupName("rAU", phase.name()),
1.0
/(
UEqns[phasei].A()
+ max(phase.residualAlpha() - alpha, scalar(0))
*phase.rho()/runTime.deltaT()
UEqns[phase.index()].A()
+ byDt(max(phase.residualAlpha() - alpha, scalar(0))*phase.rho())
)
)
);
}
fluid.fillFields("rAU", dimTime/dimDensity, rAUs);
// Phase diagonal coefficients
PtrList<surfaceScalarField> alpharAUfs(phases.size());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
const volScalarField& alpha = phase;
alpharAUfs.set
(
@ -34,57 +48,8 @@ forAll(phases, phasei)
);
}
// Lift, wall-lubrication and turbulent diffusion fluxes
PtrList<surfaceScalarField> phiFs(phases.size());
{
autoPtr<PtrList<volVectorField>> Fs = fluid.Fs();
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
if (Fs().set(phasei))
{
phiFs.set
(
phasei,
new surfaceScalarField
(
IOobject::groupName("phiF", phase.name()),
fvc::flux(rAUs[phasei]*Fs()[phasei])
)
);
}
}
}
{
autoPtr<PtrList<surfaceScalarField>> phiDs = fluid.phiDs(rAUs);
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
if (phiDs().set(phasei))
{
if (phiFs.set(phasei))
{
phiFs[phasei] += phiDs()[phasei];
}
else
{
phiFs.set
(
phasei,
new surfaceScalarField
(
IOobject::groupName("phiF", phase.name()),
phiDs()[phasei]
)
);
}
}
}
}
// Explicit force fluxes
PtrList<surfaceScalarField> phiFs(fluid.phiFs(rAUs));
// --- Pressure corrector loop
while (pimple.correct())
@ -94,42 +59,22 @@ while (pimple.correct())
// Correct p_rgh for consistency with p and the updated densities
p_rgh = p - rho*gh;
PtrList<volVectorField> HbyAs(phases.size());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
const volScalarField& alpha = phase;
// Correct fixed-flux BCs to be consistent with the velocity BCs
MRF.correctBoundaryFlux(phase.U(), phase.phi());
HbyAs.set
(
phasei,
new volVectorField
(
IOobject::groupName("HbyA", phase.name()),
phase.U()
)
);
HbyAs[phasei] =
rAUs[phasei]
*(
UEqns[phasei].H()
+ max(phase.residualAlpha() - alpha, scalar(0))
*phase.rho()*phase.U().oldTime()/runTime.deltaT()
);
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
MRF.correctBoundaryFlux(phase.U(), phase.phiRef());
}
surfaceScalarField ghSnGradRho
// Combined buoyancy and force fluxes
PtrList<surfaceScalarField> phigFs(phases.size());
{
const surfaceScalarField ghSnGradRho
(
"ghSnGradRho",
ghf*fvc::snGrad(rho)*mesh.magSf()
);
PtrList<surfaceScalarField> phigFs(phases.size());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
@ -152,9 +97,78 @@ while (pimple.correct())
phigFs[phasei] += phiFs[phasei];
}
}
}
// Predicted velocities and fluxes for each phase
PtrList<volVectorField> HbyAs(phases.size());
PtrList<surfaceScalarField> phiHbyAs(phases.size());
{
// Correction force fluxes
PtrList<surfaceScalarField> ddtCorrByAs(fluid.ddtCorrByAs(rAUs));
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
const volScalarField& alpha = phase;
HbyAs.set
(
phase.index(),
new volVectorField
(
IOobject::groupName("HbyA", phase.name()),
phase.U()
)
);
HbyAs[phase.index()] =
rAUs[phase.index()]
*(
UEqns[phase.index()].H()
+ byDt
(
max(phase.residualAlpha() - alpha, scalar(0))
*phase.rho()
)
*phase.U()().oldTime()
);
phiHbyAs.set
(
phase.index(),
new surfaceScalarField
(
IOobject::groupName("phiHbyA", phase.name()),
fvc::flux(HbyAs[phase.index()])
- phigFs[phase.index()]
- ddtCorrByAs[phase.index()]
)
);
}
}
fluid.fillFields("HbyA", dimVelocity, HbyAs);
fluid.fillFields("phiHbyA", dimForce/dimDensity/dimVelocity, phiHbyAs);
// Add explicit drag forces and fluxes if not doing partial elimination
if (!partialElimination)
{
PtrList<volVectorField> KdUByAs(fluid.KdUByAs(rAUs));
PtrList<surfaceScalarField> phiKdPhis(fluid.phiKdPhis(rAUs));
forAll(phases, phasei)
{
if (KdUByAs.set(phasei))
{
HbyAs[phasei] -= KdUByAs[phasei];
}
if (phiKdPhis.set(phasei))
{
phiHbyAs[phasei] -= phiKdPhis[phasei];
}
}
}
// Total predicted flux
surfaceScalarField phiHbyA
(
IOobject
@ -166,84 +180,28 @@ while (pimple.correct())
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar(dimArea*dimVelocity, Zero)
dimensionedScalar("phiHbyA", dimArea*dimVelocity, 0)
);
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
const volScalarField& alpha = phase;
// ddtPhiCorr filter -- only apply in pure(ish) phases
surfaceScalarField alphafBar
(
fvc::interpolate(fvc::average(alphafs[phasei]))
);
surfaceScalarField phiCorrCoeff(pos0(alphafBar - 0.99));
surfaceScalarField::Boundary& phiCorrCoeffBf =
phiCorrCoeff.boundaryFieldRef();
forAll(mesh.boundary(), patchi)
{
// Set ddtPhiCorr to 0 on non-coupled boundaries
if
(
!mesh.boundary()[patchi].coupled()
|| isA<cyclicAMIFvPatch>(mesh.boundary()[patchi])
)
{
phiCorrCoeffBf[patchi] = 0;
}
}
phiHbyAs.set
(
phasei,
new surfaceScalarField
(
IOobject::groupName("phiHbyA", phase.name()),
fvc::flux(HbyAs[phasei])
+ phiCorrCoeff
*fvc::interpolate
(
alpha.oldTime()*phase.rho()().oldTime()*rAUs[phasei]
)
*(
MRF.absolute(phase.phi().oldTime())
- fvc::flux(phase.U().oldTime())
)/runTime.deltaT()
- phigFs[phasei]
)
);
forAllConstIters(fluid.Kds(), KdIter)
{
const volScalarField& K(*KdIter());
const phasePair& pair = *(fluid.phasePairs()[KdIter.key()]);
const phaseModel* phase1 = &pair.phase1();
const phaseModel* phase2 = &pair.phase2();
forAllConstIters(pair, iter)
{
if (phase1 == &phase)
{
phiHbyAs[phasei] +=
fvc::interpolate(rAUs[phasei]*K)
*MRF.absolute(phase2->phi());
HbyAs[phasei] += rAUs[phasei]*K*phase2->U();
}
Swap(phase1, phase2);
}
}
phiHbyA += alphafs[phasei]*phiHbyAs[phasei];
}
// Add explicit drag fluxes if doing partial elimination
if (partialElimination)
{
PtrList<surfaceScalarField> phiKdPhis(fluid.phiKdPhis(rAUs));
forAll(phases, phasei)
{
if (phiKdPhis.set(phasei))
{
phiHbyA -= alphafs[phasei]*phiKdPhis[phasei];
}
}
}
MRF.makeRelative(phiHbyA);
// Construct pressure "diffusivity"
@ -256,15 +214,15 @@ while (pimple.correct())
mesh
),
mesh,
dimensionedScalar(dimensionSet(-1, 3, 1, 0, 0), Zero)
dimensionedScalar("rAUf", dimensionSet(-1, 3, 1, 0, 0), 0)
);
forAll(phases, phasei)
{
rAUf += alphafs[phasei]*alpharAUfs[phasei];
}
rAUf = mag(rAUf);
rAUf = mag(rAUf);
// Update the fixedFluxPressure BCs to ensure flux consistency
{
@ -273,7 +231,8 @@ while (pimple.correct())
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
phib += alphafs[phasei].boundaryField()*phase.phi().boundaryField();
phib +=
alphafs[phasei].boundaryField()*phase.phi()().boundaryField();
}
setSnGrad<fixedFluxPressureFvPatchScalarField>
@ -285,12 +244,14 @@ while (pimple.correct())
);
}
// Compressible pressure equations
PtrList<fvScalarMatrix> pEqnComps(phases.size());
PtrList<volScalarField> dmdts(fluid.dmdts());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
const volScalarField& alpha = phase;
volScalarField& rho = phase.thermo().rho();
volScalarField& rho = phase.thermoRef().rho();
if (phase.compressible())
{
@ -307,7 +268,7 @@ while (pimple.correct())
phasei,
(
(
phase.continuityError()
fvc::ddt(alpha, rho) + fvc::div(phase.alphaRhoPhi())
- fvc::Sp
(
fvc::ddt(alpha) + fvc::div(phase.alphaPhi()),
@ -335,7 +296,7 @@ while (pimple.correct())
phasei,
(
(
phase.continuityError()
fvc::ddt(alpha, rho) + fvc::div(phase.alphaRhoPhi())
- fvc::Sp
(
(fvc::ddt(alpha) + fvc::div(phase.alphaPhi())),
@ -348,27 +309,38 @@ while (pimple.correct())
);
}
}
// Add option sources
if (fvOptions.appliesToField(rho.name()))
{
tmp<fvScalarMatrix> optEqn = fvOptions(alpha, rho);
if (pEqnComps.set(phasei))
{
pEqnComps[phasei] -= (optEqn&rho)/rho;
}
else
{
pEqnComps.set
(
phasei,
fvm::Su(-(fvOptions(alpha, rho)&rho)/rho, p_rgh).ptr()
fvm::Su(- (optEqn&rho)/rho, p_rgh).ptr()
);
}
}
if (fluid.transfersMass(phase))
// Add mass transfer
if (dmdts.set(phasei))
{
if (pEqnComps.set(phasei))
{
pEqnComps[phasei] -= fluid.dmdt(phase)/rho;
pEqnComps[phasei] -= dmdts[phasei]/rho;
}
else
{
pEqnComps.set
(
phasei,
fvm::Su(-fluid.dmdt(phase)/rho, p_rgh)
fvm::Su(- dmdts[phasei]/rho, p_rgh)
);
}
}
@ -412,16 +384,18 @@ while (pimple.correct())
surfaceScalarField mSfGradp("mSfGradp", pEqnIncomp.flux()/rAUf);
forAll(phases, phasei)
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = phases[phasei];
phaseModel& phase = fluid.movingPhases()[movingPhasei];
phase.phi() = phiHbyAs[phasei] + alpharAUfs[phasei]*mSfGradp;
phase.phiRef() =
phiHbyAs[phase.index()]
+ alpharAUfs[phase.index()]*mSfGradp;
// Set the phase dilatation rates
if (pEqnComps.set(phasei))
if (pEqnComps.set(phase.index()))
{
phase.divU(-pEqnComps[phasei] & p_rgh);
phase.divU(-pEqnComps[phase.index()] & p_rgh);
}
}
@ -430,19 +404,30 @@ while (pimple.correct())
mSfGradp = pEqnIncomp.flux()/rAUf;
forAll(phases, phasei)
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = phases[phasei];
phaseModel& phase = fluid.movingPhases()[movingPhasei];
phase.U() =
HbyAs[phasei]
phase.URef() =
HbyAs[phase.index()]
+ fvc::reconstruct
(
alpharAUfs[phasei]*mSfGradp
- phigFs[phasei]
alpharAUfs[phase.index()]*mSfGradp
- phigFs[phase.index()]
);
phase.U().correctBoundaryConditions();
fvOptions.correct(phase.U());
}
if (partialElimination)
{
fluid.partialElimination(rAUs);
}
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
phase.URef().correctBoundaryConditions();
fvOptions.correct(phase.URef());
}
}
}
@ -457,7 +442,7 @@ while (pimple.correct())
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
phase.thermo().rho() += phase.thermo().psi()*(p_rgh - p_rgh_0);
phase.thermoRef().rho() += phase.thermo().psi()*(p_rgh - p_rgh_0);
}
// Correct p_rgh for consistency with p and the updated densities

View File

@ -0,0 +1,40 @@
Info<< "Constructing face momentum equations" << endl;
PtrList<fvVectorMatrix> UEqns(phases.size());
{
fluid.momentumTransfer(); // !!! Update coefficients shouldn't be necessary
// This should be done on demand
autoPtr<phaseSystem::momentumTransferTable>
momentumTransferPtr(fluid.momentumTransferf());
phaseSystem::momentumTransferTable&
momentumTransfer(momentumTransferPtr());
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
volVectorField& U = phase.URef();
UEqns.set
(
phase.index(),
new fvVectorMatrix
(
phase.UfEqn()
==
*momentumTransfer[phase.name()]
+ fvOptions(alpha, rho, U)
)
);
UEqns[phase.index()].relax();
fvOptions.constrain(UEqns[phase.index()]);
U.correctBoundaryConditions();
fvOptions.correct(U);
}
}

View File

@ -0,0 +1,428 @@
// Face volume fractions
PtrList<surfaceScalarField> alphafs(phases.size());
PtrList<surfaceScalarField> alphaRho0fs(phases.size());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
const volScalarField& alpha = phase;
alphafs.set(phasei, fvc::interpolate(alpha).ptr());
alphafs[phasei].rename("pEqn" + alphafs[phasei].name());
alphaRho0fs.set
(
phasei,
(
fvc::interpolate
(
max(alpha.oldTime(), phase.residualAlpha())
*phase.rho()().oldTime()
)
).ptr()
);
}
// Diagonal coefficients
PtrList<surfaceScalarField> rAUfs(phases.size());
{
PtrList<surfaceScalarField> AFfs(fluid.AFfs());
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
rAUfs.set
(
phase.index(),
new surfaceScalarField
(
IOobject::groupName("rAUf", phase.name()),
1.0
/(
byDt(alphaRho0fs[phase.index()])
+ fvc::interpolate(UEqns[phase.index()].A())
+ AFfs[phase.index()]
)
)
);
}
}
fluid.fillFields("rAUf", dimTime/dimDensity, rAUfs);
// Phase diagonal coefficients
PtrList<surfaceScalarField> alpharAUfs(phases.size());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
alpharAUfs.set
(
phase.index(),
(
max(alphafs[phase.index()], phase.residualAlpha())
*rAUfs[phase.index()]
).ptr()
);
}
// Explicit force fluxes
PtrList<surfaceScalarField> phiFfs(fluid.phiFfs(rAUfs));
// --- Pressure corrector loop
while (pimple.correct())
{
volScalarField rho("rho", fluid.rho());
// Correct p_rgh for consistency with p and the updated densities
p_rgh = p - rho*gh;
// Correct fixed-flux BCs to be consistent with the velocity BCs
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
MRF.correctBoundaryFlux(phase.U(), phase.phiRef());
}
// Combined buoyancy and force fluxes
PtrList<surfaceScalarField> phigFs(phases.size());
{
const surfaceScalarField ghSnGradRho
(
"ghSnGradRho",
ghf*fvc::snGrad(rho)*mesh.magSf()
);
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
phigFs.set
(
phasei,
(
alpharAUfs[phasei]
*(
ghSnGradRho
- (fvc::interpolate(phase.rho() - rho))*(g & mesh.Sf())
- fluid.surfaceTension(phase)*mesh.magSf()
)
).ptr()
);
if (phiFfs.set(phasei))
{
phigFs[phasei] += phiFfs[phasei];
}
}
}
// Predicted fluxes for each phase
PtrList<surfaceScalarField> phiHbyAs(phases.size());
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
phiHbyAs.set
(
phase.index(),
new surfaceScalarField
(
IOobject::groupName("phiHbyA", phase.name()),
rAUfs[phase.index()]
*(
fvc::flux(UEqns[phase.index()].H())
+ alphaRho0fs[phase.index()]
*byDt(MRF.absolute(phase.phi()().oldTime()))
)
- phigFs[phase.index()]
)
);
}
fluid.fillFields("phiHbyA", dimForce/dimDensity/dimVelocity, phiHbyAs);
// Add explicit drag forces and fluxes if not doing partial elimination
if (!partialElimination)
{
PtrList<surfaceScalarField> phiKdPhifs(fluid.phiKdPhifs(rAUfs));
forAll(phases, phasei)
{
if (phiKdPhifs.set(phasei))
{
phiHbyAs[phasei] -= phiKdPhifs[phasei];
}
}
}
// Total predicted flux
surfaceScalarField phiHbyA
(
IOobject
(
"phiHbyA",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("phiHbyA", dimArea*dimVelocity, 0)
);
forAll(phases, phasei)
{
phiHbyA += alphafs[phasei]*phiHbyAs[phasei];
}
// Add explicit drag fluxes if doing partial elimination
if (partialElimination)
{
PtrList<surfaceScalarField> phiKdPhifs(fluid.phiKdPhifs(rAUfs));
forAll(phases, phasei)
{
if (phiKdPhifs.set(phasei))
{
phiHbyA -= alphafs[phasei]*phiKdPhifs[phasei];
}
}
}
MRF.makeRelative(phiHbyA);
// Construct pressure "diffusivity"
surfaceScalarField rAUf
(
IOobject
(
"rAUf",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar("rAUf", dimensionSet(-1, 3, 1, 0, 0), 0)
);
forAll(phases, phasei)
{
rAUf += alphafs[phasei]*alpharAUfs[phasei];
}
rAUf = mag(rAUf);
// Update the fixedFluxPressure BCs to ensure flux consistency
{
surfaceScalarField::Boundary phib(phi.boundaryField());
phib = 0;
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
phib +=
alphafs[phasei].boundaryField()*phase.phi()().boundaryField();
}
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryFieldRef(),
(
phiHbyA.boundaryField() - phib
)/(mesh.magSf().boundaryField()*rAUf.boundaryField())
);
}
// Compressible pressure equations
PtrList<fvScalarMatrix> pEqnComps(phases.size());
PtrList<volScalarField> dmdts(fluid.dmdts());
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
const volScalarField& alpha = phase;
volScalarField& rho = phase.thermoRef().rho();
if (phase.compressible())
{
if (pimple.transonic())
{
surfaceScalarField phid
(
IOobject::groupName("phid", phase.name()),
fvc::interpolate(phase.thermo().psi())*phase.phi()
);
pEqnComps.set
(
phasei,
(
(
fvc::ddt(alpha, rho) + fvc::div(phase.alphaRhoPhi())
- fvc::Sp
(
fvc::ddt(alpha) + fvc::div(phase.alphaPhi()),
rho
)
)/rho
+ correction
(
(alpha/rho)*
(
phase.thermo().psi()*fvm::ddt(p_rgh)
+ fvm::div(phid, p_rgh)
- fvm::Sp(fvc::div(phid), p_rgh)
)
)
).ptr()
);
deleteDemandDrivenData
(
pEqnComps[phasei].faceFluxCorrectionPtr()
);
pEqnComps[phasei].relax();
}
else
{
pEqnComps.set
(
phasei,
(
(
fvc::ddt(alpha, rho) + fvc::div(phase.alphaRhoPhi())
- fvc::Sp
(
(fvc::ddt(alpha) + fvc::div(phase.alphaPhi())),
rho
)
)/rho
+ (alpha*phase.thermo().psi()/rho)
*correction(fvm::ddt(p_rgh))
).ptr()
);
}
}
if (fvOptions.appliesToField(rho.name()))
{
tmp<fvScalarMatrix> optEqn = fvOptions(alpha, rho);
if (pEqnComps.set(phasei))
{
pEqnComps[phasei] -= (optEqn&rho)/rho;
}
else
{
pEqnComps.set
(
phasei,
fvm::Su(- (optEqn&rho)/rho, p_rgh).ptr()
);
}
}
if (dmdts.set(phasei))
{
if (pEqnComps.set(phasei))
{
pEqnComps[phasei] -= dmdts[phasei]/rho;
}
else
{
pEqnComps.set
(
phasei,
fvm::Su(- dmdts[phasei]/rho, p_rgh)
);
}
}
}
// Cache p prior to solve for density update
volScalarField p_rgh_0(p_rgh);
// Iterate over the pressure equation to correct for non-orthogonality
while (pimple.correctNonOrthogonal())
{
// Construct the transport part of the pressure equation
fvScalarMatrix pEqnIncomp
(
fvc::div(phiHbyA)
- fvm::laplacian(rAUf, p_rgh)
);
{
fvScalarMatrix pEqn(pEqnIncomp);
forAll(phases, phasei)
{
if (pEqnComps.set(phasei))
{
pEqn += pEqnComps[phasei];
}
}
solve
(
pEqn,
mesh.solver(p_rgh.select(pimple.finalInnerIter()))
);
}
// Correct fluxes and velocities on last non-orthogonal iteration
if (pimple.finalNonOrthogonalIter())
{
phi = phiHbyA + pEqnIncomp.flux();
surfaceScalarField mSfGradp("mSfGradp", pEqnIncomp.flux()/rAUf);
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
phase.phiRef() =
phiHbyAs[phase.index()]
+ alpharAUfs[phase.index()]*mSfGradp;
// Set the phase dilatation rates
if (pEqnComps.set(phase.index()))
{
phase.divU(-pEqnComps[phase.index()] & p_rgh);
}
}
if (partialElimination)
{
fluid.partialEliminationf(rAUfs);
}
// Optionally relax pressure for velocity correction
p_rgh.relax();
mSfGradp = pEqnIncomp.flux()/rAUf;
forAll(fluid.movingPhases(), movingPhasei)
{
phaseModel& phase = fluid.movingPhases()[movingPhasei];
phase.URef() = fvc::reconstruct(MRF.absolute(phase.phi()));
phase.URef().correctBoundaryConditions();
fvOptions.correct(phase.URef());
}
}
}
// Update and limit the static pressure
p = max(p_rgh + rho*gh, pMin);
// Limit p_rgh
p_rgh = p - rho*gh;
// Update densities from change in p_rgh
forAll(phases, phasei)
{
phaseModel& phase = phases[phasei];
phase.thermoRef().rho() += phase.thermo().psi()*(p_rgh - p_rgh_0);
}
// Correct p_rgh for consistency with p and the updated densities
rho = fluid.rho();
p_rgh = p - rho*gh;
p_rgh.correctBoundaryConditions();
}

View File

@ -5,7 +5,7 @@
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
| Copyright (C) 2011-2018 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,9 +26,6 @@ License
Application
reactingMultiphaseEulerFoam
Group
grpMultiphaseSolvers
Description
Solver for a system of any number of compressible fluid phases with a
common pressure, but otherwise separate properties. The type of phase model
@ -40,6 +37,7 @@ Description
#include "fvCFD.H"
#include "multiphaseSystem.H"
#include "phaseCompressibleTurbulenceModel.H"
#include "pimpleControl.H"
#include "localEulerDdtScheme.H"
#include "fvcSmooth.H"
@ -48,16 +46,10 @@ Description
int main(int argc, char *argv[])
{
argList::addNote
(
"Solver for a system of any number of compressible fluid phases with a"
" common pressure, but otherwise separate properties."
);
#include "postProcess.H"
#include "addCheckCaseOptions.H"
#include "setRootCaseLists.H"
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createControl.H"
@ -71,20 +63,14 @@ int main(int argc, char *argv[])
#include "setInitialDeltaT.H"
}
// bool faceMomentum
// (
// pimple.dict().lookupOrDefault("faceMomentum", false)
// );
// bool implicitPhasePressure
// (
// mesh.solverDict(alpha1.name()).lookupOrDefault
// (
// "implicitPhasePressure", false
// )
// );
//#include "pUf/createDDtU.H"
Switch faceMomentum
(
pimple.dict().lookupOrDefault<Switch>("faceMomentum", false)
);
Switch partialElimination
(
pimple.dict().lookupOrDefault<Switch>("partialElimination", false)
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -109,7 +95,7 @@ int main(int argc, char *argv[])
#include "setDeltaT.H"
}
++runTime;
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
// --- Pressure-velocity PIMPLE corrector loop
@ -120,14 +106,13 @@ int main(int argc, char *argv[])
#include "YEqns.H"
// if (faceMomentum)
// {
// #include "pUf/UEqns.H"
// #include "EEqns.H"
// #include "pUf/pEqn.H"
// #include "pUf/DDtU.H"
// }
// else
if (faceMomentum)
{
#include "pUf/UEqns.H"
#include "EEqns.H"
#include "pUf/pEqn.H"
}
else
{
#include "pU/UEqns.H"
#include "EEqns.H"
@ -144,7 +129,9 @@ int main(int argc, char *argv[])
runTime.write();
runTime.printExecutionTime(Info);
Info<< "ExecutionTime = "
<< runTime.elapsedCpuTime()
<< " s\n\n" << endl;
}
Info<< "End\n" << endl;

View File

@ -1,8 +1,6 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
wclean libso twoPhaseSystem
wclean libso twoPhaseCompressibleTurbulenceModels
wclean
#------------------------------------------------------------------------------

View File

@ -4,8 +4,6 @@ cd ${0%/*} || exit 1 # Run from this directory
#------------------------------------------------------------------------------
wmake $targetType twoPhaseSystem
wmake $targetType twoPhaseCompressibleTurbulenceModels
wmake $targetType
#------------------------------------------------------------------------------

View File

@ -8,46 +8,38 @@ for (int Ecorr=0; Ecorr<nEnergyCorrectors; Ecorr++)
phaseSystem::heatTransferTable&
heatTransfer = heatTransferPtr();
if (!phase1.isothermal())
{
tmp<fvScalarMatrix> E1Eqn(phase1.heEqn());
if (E1Eqn.valid())
{
E1Eqn =
fvScalarMatrix E1Eqn
(
E1Eqn
phase1.heEqn()
==
*heatTransfer[phase1.name()]
+ alpha1*rho1*(U1&g)
+ fvOptions(alpha1, rho1, phase1.thermo().he())
+ fvOptions(alpha1, rho1, thermo1.he())
);
E1Eqn->relax();
fvOptions.constrain(E1Eqn.ref());
E1Eqn->solve();
fvOptions.correct(phase1.thermo().he());
}
E1Eqn.relax();
fvOptions.constrain(E1Eqn);
E1Eqn.solve();
fvOptions.correct(thermo1.he());
}
if (!phase2.isothermal())
{
tmp<fvScalarMatrix> E2Eqn(phase2.heEqn());
if (E2Eqn.valid())
{
E2Eqn =
fvScalarMatrix E2Eqn
(
E2Eqn
phase2.heEqn()
==
*heatTransfer[phase2.name()]
+ alpha2*rho2*(U2&g)
+ fvOptions(alpha2, rho2, phase2.thermo().he())
+ fvOptions(alpha2, rho2, phase2.thermoRef().he())
);
E2Eqn->relax();
fvOptions.constrain(E2Eqn.ref());
E2Eqn->solve();
fvOptions.correct(phase2.thermo().he());
}
E2Eqn.relax();
fvOptions.constrain(E2Eqn);
E2Eqn.solve();
fvOptions.correct(thermo2.he());
}
fluid.correctThermo();

View File

@ -1,12 +1,12 @@
EXE_INC = \
-ItwoPhaseSystem/lnInclude \
-I../phaseSystems/lnInclude \
-I../interfacialModels/lnInclude \
-I../interfacialCompositionModels/lnInclude \
-ItwoPhaseCompressibleTurbulenceModels/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/reactingTwoPhaseEulerFoam/twoPhaseSystem/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/interfacialCompositionModels/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/phaseSystems/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/interfacialModels/lnInclude \
-I$(LIB_SRC)/phaseSystemModels/reactingEulerFoam/reactingTwoPhaseEulerFoam/twoPhaseCompressibleTurbulenceModels/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \

View File

@ -5,46 +5,41 @@
phaseSystem::massTransferTable&
massTransfer(massTransferPtr());
PtrList<volScalarField>& Y1 = phase1.Y();
PtrList<volScalarField>& Y2 = phase2.Y();
if (!phase1.pure())
{
UPtrList<volScalarField>& Y1 = phase1.YActiveRef();
forAll(Y1, i)
{
tmp<fvScalarMatrix> Y1iEqn(phase1.YiEqn(Y1[i]));
if (Y1iEqn.valid())
{
Y1iEqn =
fvScalarMatrix Y1iEqn
(
Y1iEqn
phase1.YiEqn(Y1[i])
==
*massTransfer[Y1[i].name()]
+ fvOptions(alpha1, rho1, Y1[i])
);
Y1iEqn->relax();
Y1iEqn->solve(mesh.solver("Yi"));
Y1iEqn.relax();
Y1iEqn.solve(mesh.solver("Yi"));
}
}
if (!phase2.pure())
{
UPtrList<volScalarField>& Y2 = phase2.YActiveRef();
forAll(Y2, i)
{
tmp<fvScalarMatrix> Y2iEqn(phase2.YiEqn(Y2[i]));
if (Y2iEqn.valid())
{
Y2iEqn =
fvScalarMatrix Y2iEqn
(
Y2iEqn
phase2.YiEqn(Y2[i])
==
*massTransfer[Y2[i].name()]
+ fvOptions(alpha2, rho2, Y2[i])
);
Y2iEqn->relax();
Y2iEqn->solve(mesh.solver("Yi"));
Y2iEqn.relax();
Y2iEqn.solve(mesh.solver("Yi"));
}
}
fluid.massTransfer(); // updates interfacial mass flow rates
}

View File

@ -1,22 +1,21 @@
phaseModel& phase1 = fluid.phase1();
phaseModel& phase2 = fluid.phase2();
volScalarField& alpha1 = phase1;
volScalarField& alpha2 = phase2;
const volScalarField& alpha1 = phase1;
const volScalarField& alpha2 = phase2;
volVectorField& U1 = phase1.U();
surfaceScalarField& phi1 = phase1.phi();
surfaceScalarField& alphaPhi1 = phase1.alphaPhi();
surfaceScalarField& alphaRhoPhi1 = phase1.alphaRhoPhi();
volVectorField& U1 = phase1.URef();
surfaceScalarField& phi1 = phase1.phiRef();
const surfaceScalarField& alphaPhi1 = phase1.alphaPhi();
volVectorField& U2 = phase2.URef();
surfaceScalarField& phi2 = phase2.phiRef();
const surfaceScalarField& alphaPhi2 = phase2.alphaPhi();
volVectorField& U2 = phase2.U();
surfaceScalarField& phi2 = phase2.phi();
surfaceScalarField& alphaPhi2 = phase2.alphaPhi();
surfaceScalarField& alphaRhoPhi2 = phase2.alphaRhoPhi();
surfaceScalarField& phi = fluid.phi();
rhoThermo& thermo1 = phase1.thermo();
rhoThermo& thermo2 = phase2.thermo();
rhoThermo& thermo1 = phase1.thermoRef();
rhoThermo& thermo2 = phase2.thermoRef();
volScalarField& rho1 = thermo1.rho();
const volScalarField& psi1 = thermo1.psi();

View File

@ -19,7 +19,7 @@ dimensionedScalar pMin
#include "gh.H"
volScalarField& p = fluid.phase1().thermo().p();
volScalarField& p = fluid.phase1().thermoRef().p();
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh

View File

@ -1,7 +1,10 @@
surfaceScalarField alphaf1("alphaf1", fvc::interpolate(alpha1));
surfaceScalarField alphaf2("alphaf2", scalar(1) - alphaf1);
const surfaceScalarField alphaf1("alphaf1", fvc::interpolate(alpha1));
const surfaceScalarField alphaf2("alphaf2", scalar(1) - alphaf1);
volScalarField rAU1
PtrList<volScalarField> rAUs;
rAUs.append
(
new volScalarField
(
IOobject::groupName("rAU", phase1.name()),
1.0
@ -9,8 +12,11 @@ volScalarField rAU1
U1Eqn.A()
+ byDt(max(phase1.residualAlpha() - alpha1, scalar(0))*rho1)
)
)
);
volScalarField rAU2
rAUs.append
(
new volScalarField
(
IOobject::groupName("rAU", phase2.name()),
1.0
@ -18,65 +24,31 @@ volScalarField rAU2
U2Eqn.A()
+ byDt(max(phase2.residualAlpha() - alpha2, scalar(0))*rho2)
)
)
);
const volScalarField& rAU1 = rAUs[0];
const volScalarField& rAU2 = rAUs[1];
surfaceScalarField alpharAUf1
const surfaceScalarField alpharAUf1
(
fvc::interpolate(max(alpha1, phase1.residualAlpha())*rAU1)
);
surfaceScalarField alpharAUf2
const surfaceScalarField alpharAUf2
(
fvc::interpolate(max(alpha2, phase2.residualAlpha())*rAU2)
);
volScalarField Kd(fluid.Kd());
// Turbulent diffusion, particle-pressure, lift and wall-lubrication fluxes
tmp<surfaceScalarField> phiF1;
tmp<surfaceScalarField> phiF2;
{
// Turbulent-dispersion diffusivity
volScalarField D(fluid.D());
// Phase-1 turbulent dispersion and particle-pressure flux
tmp<surfaceScalarField> DbyA1
(
fvc::interpolate
(
rAU1*(D + phase1.turbulence().pPrime())
)
);
// Phase-2 turbulent dispersion and particle-pressure flux
tmp<surfaceScalarField> DbyA2
(
fvc::interpolate
(
rAU2*(D + phase2.turbulence().pPrime())
)
);
// Lift and wall-lubrication forces
volVectorField F(fluid.F());
// Phase-fraction face-gradient
surfaceScalarField snGradAlpha1(fvc::snGrad(alpha1)*mesh.magSf());
// Phase-1 dispersion, lift and wall-lubrication flux
phiF1 = DbyA1()*snGradAlpha1 + fvc::flux(rAU1*F);
// Phase-2 dispersion, lift and wall-lubrication flux
phiF2 = - DbyA2()*snGradAlpha1 - fvc::flux(rAU2*F);
// Cache the phase diffusivities for implicit treatment in the
// phase-fraction equation
if (implicitPhasePressure)
{
phase1.DbyA(DbyA1);
phase2.DbyA(DbyA2);
}
}
// Drag coefficients
const volScalarField Kd(fluid.Kd());
const volScalarField rAUKd1(rAU1*Kd);
const volScalarField rAUKd2(rAU2*Kd);
const surfaceScalarField phiKd1(fvc::interpolate(rAUKd1));
const surfaceScalarField phiKd2(fvc::interpolate(rAUKd2));
// Explicit force fluxes
PtrList<surfaceScalarField> phiFs(fluid.phiFs(rAUs));
const surfaceScalarField& phiF1 = phiFs[0];
const surfaceScalarField& phiF2 = phiFs[1];
// --- Pressure corrector loop
while (pimple.correct())
@ -90,6 +62,34 @@ while (pimple.correct())
MRF.correctBoundaryFlux(U1, phi1);
MRF.correctBoundaryFlux(U2, phi2);
// Combined buoyancy and force fluxes
const surfaceScalarField ghSnGradRho
(
"ghSnGradRho",
ghf*fvc::snGrad(rho)*mesh.magSf()
);
const surfaceScalarField phigF1
(
alpharAUf1
*(
ghSnGradRho
- alphaf2*fvc::interpolate(rho1 - rho2)*(g & mesh.Sf())
)
+ phiF1
);
const surfaceScalarField phigF2
(
alpharAUf2
*(
ghSnGradRho
- alphaf1*fvc::interpolate(rho2 - rho1)*(g & mesh.Sf())
)
+ phiF2
);
// Predicted velocities
volVectorField HbyA1
(
IOobject::groupName("HbyA", phase1.name()),
@ -116,98 +116,42 @@ while (pimple.correct())
*U2.oldTime()
);
surfaceScalarField ghSnGradRho
(
"ghSnGradRho",
ghf*fvc::snGrad(rho)*mesh.magSf()
);
// Correction force fluxes
PtrList<surfaceScalarField> ddtCorrByAs(fluid.ddtCorrByAs(rAUs));
surfaceScalarField phig1
(
alpharAUf1
*(
ghSnGradRho
- alphaf2*fvc::interpolate(rho1 - rho2)*(g & mesh.Sf())
)
);
surfaceScalarField phig2
(
alpharAUf2
*(
ghSnGradRho
- alphaf1*fvc::interpolate(rho2 - rho1)*(g & mesh.Sf())
)
);
// ddtPhiCorr filter -- only apply in pure(ish) phases
surfaceScalarField alphaf1Bar(fvc::interpolate(fvc::average(alphaf1)));
surfaceScalarField phiCorrCoeff1(pos0(alphaf1Bar - 0.99));
surfaceScalarField phiCorrCoeff2(pos0(0.01 - alphaf1Bar));
{
surfaceScalarField::Boundary& phiCorrCoeff1Bf =
phiCorrCoeff1.boundaryFieldRef();
surfaceScalarField::Boundary& phiCorrCoeff2Bf =
phiCorrCoeff2.boundaryFieldRef();
forAll(mesh.boundary(), patchi)
{
// Set ddtPhiCorr to 0 on non-coupled boundaries
if
(
!mesh.boundary()[patchi].coupled()
|| isA<cyclicAMIFvPatch>(mesh.boundary()[patchi])
)
{
phiCorrCoeff1Bf[patchi] = 0;
phiCorrCoeff2Bf[patchi] = 0;
}
}
}
// Phase-1 predicted flux
surfaceScalarField phiHbyA1
// Predicted fluxes
const surfaceScalarField phiHbyA1
(
IOobject::groupName("phiHbyA", phase1.name()),
fvc::flux(HbyA1)
+ phiCorrCoeff1
*fvc::interpolate(byDt(alpha1.oldTime()*rho1.oldTime()*rAU1))
*(MRF.absolute(phi1.oldTime()) - fvc::flux(U1.oldTime()))
- phiF1()
- phig1
fvc::flux(HbyA1) - phigF1 - ddtCorrByAs[0]
);
// Phase-2 predicted flux
surfaceScalarField phiHbyA2
const surfaceScalarField phiHbyA2
(
IOobject::groupName("phiHbyA", phase2.name()),
fvc::flux(HbyA2)
+ phiCorrCoeff2
*fvc::interpolate(byDt(alpha2.oldTime()*rho2.oldTime()*rAU2))
*(MRF.absolute(phi2.oldTime()) - fvc::flux(U2.oldTime()))
- phiF2()
- phig2
fvc::flux(HbyA2) - phigF2 - ddtCorrByAs[1]
);
// Face-drag coefficients
surfaceScalarField rAUKd1(fvc::interpolate(rAU1*Kd));
surfaceScalarField rAUKd2(fvc::interpolate(rAU2*Kd));
ddtCorrByAs.clear();
// Construct the mean predicted flux
// including explicit drag contributions based on absolute fluxes
// Drag fluxes
PtrList<surfaceScalarField> phiKdPhis(fluid.phiKdPhis(rAUs));
const surfaceScalarField& phiKdPhi1 = phiKdPhis[0];
const surfaceScalarField& phiKdPhi2 = phiKdPhis[1];
// Total predicted flux
surfaceScalarField phiHbyA
(
"phiHbyA",
alphaf1*(phiHbyA1 + rAUKd1*MRF.absolute(phi2))
+ alphaf2*(phiHbyA2 + rAUKd2*MRF.absolute(phi1))
alphaf1*(phiHbyA1 - phiKdPhi1) + alphaf2*(phiHbyA2 - phiKdPhi2)
);
MRF.makeRelative(phiHbyA);
phiKdPhis.clear();
// Construct pressure "diffusivity"
surfaceScalarField rAUf
const surfaceScalarField rAUf
(
"rAUf",
mag(alphaf1*alpharAUf1 + alphaf2*alpharAUf2)
@ -226,16 +170,13 @@ while (pimple.correct())
)/(mesh.magSf().boundaryField()*rAUf.boundaryField())
);
tmp<fvScalarMatrix> pEqnComp1;
tmp<fvScalarMatrix> pEqnComp2;
// Construct the compressibility parts of the pressure equation
tmp<fvScalarMatrix> pEqnComp1, pEqnComp2;
if (phase1.compressible())
{
if (pimple.transonic())
{
surfaceScalarField phid1
const surfaceScalarField phid1
(
IOobject::groupName("phid", phase1.name()),
fvc::interpolate(psi1)*phi1
@ -243,7 +184,7 @@ while (pimple.correct())
pEqnComp1 =
(
phase1.continuityError()
fvc::ddt(alpha1, rho1) + fvc::div(phase1.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
)/rho1
+ correction
@ -261,22 +202,17 @@ while (pimple.correct())
{
pEqnComp1 =
(
phase1.continuityError()
fvc::ddt(alpha1, rho1) + fvc::div(phase1.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
)/rho1
+ (alpha1*psi1/rho1)*correction(fvm::ddt(p_rgh));
}
}
else
{
pEqnComp1 = fvm::Su(-(fvOptions(alpha1, rho1)&rho1)/rho1, p_rgh);
}
if (phase2.compressible())
{
if (pimple.transonic())
{
surfaceScalarField phid2
const surfaceScalarField phid2
(
IOobject::groupName("phid", phase2.name()),
fvc::interpolate(psi2)*phi2
@ -284,7 +220,7 @@ while (pimple.correct())
pEqnComp2 =
(
phase2.continuityError()
fvc::ddt(alpha2, rho2) + fvc::div(phase2.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
)/rho2
+ correction
@ -302,40 +238,70 @@ while (pimple.correct())
{
pEqnComp2 =
(
phase2.continuityError()
fvc::ddt(alpha2, rho2) + fvc::div(phase2.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
)/rho2
+ (alpha2*psi2/rho2)*correction(fvm::ddt(p_rgh));
}
}
// Add option sources
{
if (fvOptions.appliesToField(rho1.name()))
{
tmp<fvScalarMatrix> optEqn1 = fvOptions(alpha1, rho1);
if (pEqnComp1.valid())
{
pEqnComp1.ref() -= (optEqn1 & rho1)/rho1;
}
else
{
pEqnComp2 = fvm::Su(-(fvOptions(alpha2, rho2)&rho2)/rho2, p_rgh);
pEqnComp1 = fvm::Su(- (optEqn1 & rho1)/rho1, p_rgh);
}
}
if (fvOptions.appliesToField(rho2.name()))
{
tmp<fvScalarMatrix> optEqn2 = fvOptions(alpha2, rho2);
if (pEqnComp2.valid())
{
pEqnComp2.ref() -= (optEqn2 & rho2)/rho2;
}
else
{
pEqnComp2 = fvm::Su(- (optEqn2 & rho2)/rho2, p_rgh);
}
}
}
if (fluid.transfersMass())
// Add mass transfer
{
PtrList<volScalarField> dmdts(fluid.dmdts());
if (dmdts.set(0))
{
if (pEqnComp1.valid())
{
pEqnComp1.ref() -= fluid.dmdt()/rho1;
pEqnComp1.ref() -= dmdts[0]/rho1;
}
else
{
pEqnComp1 = fvm::Su(-fluid.dmdt()/rho1, p_rgh);
pEqnComp1 = fvm::Su(- dmdts[0]/rho1, p_rgh);
}
}
if (dmdts.set(1))
{
if (pEqnComp2.valid())
{
pEqnComp2.ref() += fluid.dmdt()/rho2;
pEqnComp2.ref() -= dmdts[1]/rho2;
}
else
{
pEqnComp2 = fvm::Su(fluid.dmdt()/rho2, p_rgh);
pEqnComp2 = fvm::Su(- dmdts[1]/rho2, p_rgh);
}
}
}
// Cache p prior to solve for density update
volScalarField p_rgh_0(p_rgh);
const volScalarField p_rgh_0(p_rgh);
// Iterate over the pressure equation to correct for non-orthogonality
while (pimple.correctNonOrthogonal())
@ -360,11 +326,7 @@ while (pimple.correct())
pEqn += pEqnComp2();
}
solve
(
pEqn,
mesh.solver(p_rgh.select(pimple.finalInnerIter()))
);
pEqn.solve();
}
// Correct fluxes and velocities on last non-orthogonal iteration
@ -372,24 +334,28 @@ while (pimple.correct())
{
phi = phiHbyA + pEqnIncomp.flux();
surfaceScalarField mSfGradp("mSfGradp", pEqnIncomp.flux()/rAUf);
surfaceScalarField mSfGradp
(
"mSfGradp",
pEqnIncomp.flux()/rAUf
);
// Partial-elimination phase-flux corrector
{
surfaceScalarField phi1s
const surfaceScalarField phi1s
(
phiHbyA1 + alpharAUf1*mSfGradp
);
surfaceScalarField phi2s
const surfaceScalarField phi2s
(
phiHbyA2 + alpharAUf2*mSfGradp
);
surfaceScalarField phir
(
((phi1s + rAUKd1*phi2s) - (phi2s + rAUKd2*phi1s))
/(1 - rAUKd1*rAUKd2)
((phi1s + phiKd1*phi2s) - (phi2s + phiKd2*phi1s))
/(1 - phiKd1*phiKd2)
);
phi1 = phi + alphaf2*phir;
@ -413,23 +379,27 @@ while (pimple.correct())
// Partial-elimination phase-velocity corrector
{
volVectorField Us1
const volVectorField Us1
(
HbyA1
+ fvc::reconstruct(alpharAUf1*mSfGradp - phiF1() - phig1)
+ fvc::reconstruct(alpharAUf1*mSfGradp - phigF1)
);
volVectorField Us2
const volVectorField Us2
(
HbyA2
+ fvc::reconstruct(alpharAUf2*mSfGradp - phiF2() - phig2)
+ fvc::reconstruct(alpharAUf2*mSfGradp - phigF2)
);
volScalarField D1(rAU1*Kd);
volScalarField D2(rAU2*Kd);
const volVectorField U
(
alpha1*(Us1 + rAUKd1*U2) + alpha2*(Us2 + rAUKd2*U1)
);
volVectorField U(alpha1*(Us1 + D1*U2) + alpha2*(Us2 + D2*U1));
volVectorField Ur(((1 - D2)*Us1 - (1 - D1)*Us2)/(1 - D1*D2));
const volVectorField Ur
(
((1 - rAUKd2)*Us1 - (1 - rAUKd1)*Us2)/(1 - rAUKd1*rAUKd2)
);
U1 = U + alpha2*Ur;
U1.correctBoundaryConditions();

View File

@ -1,2 +0,0 @@
tddtPhi1 = fvc::ddt(phi1);
tddtPhi2 = fvc::ddt(phi2);

View File

@ -4,33 +4,22 @@ fvVectorMatrix U1Eqn(U1, rho1.dimensions()*U1.dimensions()*dimVolume/dimTime);
fvVectorMatrix U2Eqn(U2, rho2.dimensions()*U2.dimensions()*dimVolume/dimTime);
{
volScalarField Vm(fluid.Vm());
fluid.momentumTransfer(); // !!! Update coefficients shouldn't be necessary
// This should be done on demand
fvVectorMatrix UgradU1
(
fvm::div(phi1, U1) - fvm::Sp(fvc::div(phi1), U1)
+ MRF.DDt(U1)
);
autoPtr<phaseSystem::momentumTransferTable>
momentumTransferPtr(fluid.momentumTransferf());
fvVectorMatrix UgradU2
(
fvm::div(phi2, U2) - fvm::Sp(fvc::div(phi2), U2)
+ MRF.DDt(U2)
);
const volScalarField dmdt21(posPart(fluid.dmdt()));
const volScalarField dmdt12(negPart(fluid.dmdt()));
phaseSystem::momentumTransferTable&
momentumTransfer(momentumTransferPtr());
{
U1Eqn =
(
fvm::div(alphaRhoPhi1, U1) - fvm::Sp(fvc::div(alphaRhoPhi1), U1)
+ fvm::Sp(dmdt21, U1) - dmdt21*U2
+ MRF.DDt(alpha1*rho1, U1)
+ phase1.turbulence().divDevRhoReff(U1)
+ Vm*(UgradU1 - (UgradU2 & U2))
- fvOptions(alpha1, rho1, U1)
+ fvm::SuSp(fvOptions(alpha1, rho1)&rho1,U1)
phase1.UfEqn()
==
*momentumTransfer[phase1.name()]
+ fvOptions(alpha1, rho1, U1)
);
U1Eqn.relax();
fvOptions.constrain(U1Eqn);
@ -41,13 +30,10 @@ fvVectorMatrix U2Eqn(U2, rho2.dimensions()*U2.dimensions()*dimVolume/dimTime);
{
U2Eqn =
(
fvm::div(alphaRhoPhi2, U2) - fvm::Sp(fvc::div(alphaRhoPhi2), U2)
- fvm::Sp(dmdt12, U2) + dmdt12*U1
+ MRF.DDt(alpha2*rho2, U2)
+ phase2.turbulence().divDevRhoReff(U2)
+ Vm*(UgradU2 - (UgradU1 & U1))
- fvOptions(alpha2, rho2, U2)
+ fvm::SuSp(fvOptions(alpha2, rho2)&rho2,U2)
phase2.UfEqn()
==
*momentumTransfer[phase2.name()]
+ fvOptions(alpha2, rho2, U2)
);
U2Eqn.relax();
fvOptions.constrain(U2Eqn);

View File

@ -1,7 +0,0 @@
tmp<surfaceScalarField> tddtPhi1;
tmp<surfaceScalarField> tddtPhi2;
if (faceMomentum)
{
#include "pUf/DDtU.H"
}

View File

@ -22,73 +22,47 @@ surfaceScalarField alphaRhof20
);
// Drag coefficient
surfaceScalarField Kdf("Kdf", fluid.Kdf());
const surfaceScalarField Kdf("Kdf", fluid.Kdf());
// Virtual-mass coefficient
surfaceScalarField Vmf("Vmf", fluid.Vmf());
// Diagonal coefficients
PtrList<surfaceScalarField> AFfs(fluid.AFfs());
surfaceScalarField rAUf1
PtrList<surfaceScalarField> rAUfs;
rAUfs.append
(
new surfaceScalarField
(
IOobject::groupName("rAUf", phase1.name()),
1.0
/(
byDt(alphaRhof10 + Vmf)
byDt(alphaRhof10)
+ fvc::interpolate(U1Eqn.A())
+ Kdf
+ AFfs[0]
)
)
);
surfaceScalarField rAUf2
rAUfs.append
(
new surfaceScalarField
(
IOobject::groupName("rAUf", phase2.name()),
1.0
/(
byDt(alphaRhof20 + Vmf)
byDt(alphaRhof20)
+ fvc::interpolate(U2Eqn.A())
+ Kdf
+ AFfs[0]
)
)
);
const surfaceScalarField& rAUf1 = rAUfs[0];
const surfaceScalarField& rAUf2 = rAUfs[1];
AFfs.clear();
// Turbulent dispersion, particle-pressure, lift and wall-lubrication forces
tmp<surfaceScalarField> Ff1;
tmp<surfaceScalarField> Ff2;
{
// Turbulent-dispersion diffusivity
volScalarField D(fluid.D());
// Phase-1 turbulent dispersion and particle-pressure diffusivity
surfaceScalarField Df1
(
fvc::interpolate(D + phase1.turbulence().pPrime())
);
// Phase-2 turbulent dispersion and particle-pressure diffusivity
surfaceScalarField Df2
(
fvc::interpolate(D + phase2.turbulence().pPrime())
);
// Cache the phase diffusivities for implicit treatment in the
// phase-fraction equation
if (implicitPhasePressure)
{
phase1.DbyA(rAUf1*Df1);
phase2.DbyA(rAUf2*Df2);
}
// Lift and wall-lubrication forces
surfaceScalarField Ff(fluid.Ff());
// Phase-fraction face-gradient
surfaceScalarField snGradAlpha1(fvc::snGrad(alpha1)*mesh.magSf());
// Phase-1 dispersion, lift and wall-lubrication force
Ff1 = Df1*snGradAlpha1 + Ff;
// Phase-2 dispersion, lift and wall-lubrication force
Ff2 = -Df2*snGradAlpha1 - Ff;
}
// Explicit force fluxes
PtrList<surfaceScalarField> phiFfs(fluid.phiFfs(rAUfs));
const surfaceScalarField& phiFf1 = phiFfs[0];
const surfaceScalarField& phiFf2 = phiFfs[1];
while (pimple.correct())
@ -105,48 +79,47 @@ while (pimple.correct())
MRF.correctBoundaryFlux(U1, phi1);
MRF.correctBoundaryFlux(U2, phi2);
surfaceScalarField alpharAUf1
const surfaceScalarField alpharAUf1
(
IOobject::groupName("alpharAUf", phase1.name()),
max(alphaf1, phase1.residualAlpha())*rAUf1
);
surfaceScalarField alpharAUf2
const surfaceScalarField alpharAUf2
(
IOobject::groupName("alpharAUf", phase2.name()),
max(alphaf2, phase2.residualAlpha())*rAUf2
);
surfaceScalarField ghSnGradRho
// Combined buoyancy and force fluxes
const surfaceScalarField ghSnGradRho
(
"ghSnGradRho",
ghf*fvc::snGrad(rho)*mesh.magSf()
);
// Phase-1 buoyancy flux
surfaceScalarField phig1
const surfaceScalarField phigF1
(
IOobject::groupName("phig", phase1.name()),
alpharAUf1
*(
ghSnGradRho
- alphaf2*(rhof1 - rhof2)*(g & mesh.Sf())
)
+ phiFf1
);
// Phase-2 buoyancy flux
surfaceScalarField phig2
const surfaceScalarField phigF2
(
IOobject::groupName("phig", phase2.name()),
alpharAUf2
*(
ghSnGradRho
- alphaf1*(rhof2 - rhof1)*(g & mesh.Sf())
)
+ phiFf2
);
// Phase-1 predicted flux
// Predicted fluxes
surfaceScalarField phiHbyA1
(
IOobject::groupName("phiHbyA", phase1.name()),
@ -156,15 +129,11 @@ while (pimple.correct())
phiHbyA1 =
rAUf1
*(
(alphaRhof10 + Vmf)
*byDt(MRF.absolute(phi1.oldTime()))
alphaRhof10*byDt(MRF.absolute(phi1.oldTime()))
+ fvc::flux(U1Eqn.H())
+ Vmf*tddtPhi2()
+ Kdf*MRF.absolute(phi2)
- Ff1()
);
)
- phigF1;
// Phase-2 predicted flux
surfaceScalarField phiHbyA2
(
IOobject::groupName("phiHbyA", phase2.name()),
@ -174,31 +143,34 @@ while (pimple.correct())
phiHbyA2 =
rAUf2
*(
(alphaRhof20 + Vmf)
*byDt(MRF.absolute(phi2.oldTime()))
alphaRhof20*byDt(MRF.absolute(phi2.oldTime()))
+ fvc::flux(U2Eqn.H())
+ Vmf*tddtPhi1()
+ Kdf*MRF.absolute(phi1)
- Ff2()
);
)
- phigF2;
// Drag fluxes
PtrList<surfaceScalarField> phiKdPhifs(fluid.phiKdPhifs(rAUfs));
const surfaceScalarField& phiKdPhif1 = phiKdPhifs[0];
const surfaceScalarField& phiKdPhif2 = phiKdPhifs[1];
// Total predicted flux
surfaceScalarField phiHbyA
(
"phiHbyA",
alphaf1*(phiHbyA1 - phig1) + alphaf2*(phiHbyA2 - phig2)
alphaf1*(phiHbyA1 - phiKdPhif1) + alphaf2*(phiHbyA2 - phiKdPhif2)
);
MRF.makeRelative(phiHbyA);
phiHbyA1 -= phig1;
phiHbyA2 -= phig2;
phiKdPhifs.clear();
surfaceScalarField rAUf
// Construct pressure "diffusivity"
const surfaceScalarField rAUf
(
"rAUf",
mag(alphaf1*alpharAUf1 + alphaf2*alpharAUf2)
);
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
@ -212,10 +184,8 @@ while (pimple.correct())
)/(mesh.magSf().boundaryField()*rAUf.boundaryField())
);
tmp<fvScalarMatrix> pEqnComp1;
tmp<fvScalarMatrix> pEqnComp2;
// Construct the compressibility parts of the pressure equation
tmp<fvScalarMatrix> pEqnComp1, pEqnComp2;
if (phase1.compressible())
{
@ -229,7 +199,7 @@ while (pimple.correct())
pEqnComp1 =
(
phase1.continuityError()
fvc::ddt(alpha1, rho1) + fvc::div(phase1.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
)/rho1
+ correction
@ -247,16 +217,12 @@ while (pimple.correct())
{
pEqnComp1 =
(
phase1.continuityError()
fvc::ddt(alpha1, rho1) + fvc::div(phase1.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
)/rho1
+ (alpha1*psi1/rho1)*correction(fvm::ddt(p_rgh));
}
}
else
{
pEqnComp1 = fvm::Su(-(fvOptions(alpha1, rho1)&rho1)/rho1, p_rgh);
}
if (phase2.compressible())
{
@ -270,7 +236,7 @@ while (pimple.correct())
pEqnComp2 =
(
phase2.continuityError()
fvc::ddt(alpha2, rho2) + fvc::div(phase2.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
)/rho2
+ correction
@ -288,35 +254,66 @@ while (pimple.correct())
{
pEqnComp2 =
(
phase2.continuityError()
fvc::ddt(alpha2, rho2) + fvc::div(phase2.alphaRhoPhi())
- fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
)/rho2
+ (alpha2*psi2/rho2)*correction(fvm::ddt(p_rgh));
}
}
// Add option sources
{
if (fvOptions.appliesToField(rho1.name()))
{
tmp<fvScalarMatrix> optEqn1 = fvOptions(alpha1, rho1);
if (pEqnComp1.valid())
{
pEqnComp1.ref() -= (optEqn1 & rho1)/rho1;
}
else
{
pEqnComp2 = fvm::Su(-(fvOptions(alpha2, rho2)&rho2)/rho2, p_rgh);
pEqnComp1 = fvm::Su(- (optEqn1 & rho1)/rho1, p_rgh);
}
}
if (fvOptions.appliesToField(rho2.name()))
{
tmp<fvScalarMatrix> optEqn2 = fvOptions(alpha2, rho2);
if (pEqnComp2.valid())
{
pEqnComp2.ref() -= (optEqn2 & rho2)/rho2;
}
else
{
pEqnComp2 = fvm::Su(- (optEqn2 & rho2)/rho2, p_rgh);
}
}
}
if (fluid.transfersMass())
// Add mass transfer
{
PtrList<volScalarField> dmdts(fluid.dmdts());
if (dmdts.set(0))
{
if (pEqnComp1.valid())
{
pEqnComp1.ref() -= fluid.dmdt()/rho1;
pEqnComp1.ref() -= dmdts[0]/rho1;
}
else
{
pEqnComp1 = fvm::Su(-fluid.dmdt()/rho1, p_rgh);
pEqnComp1 = fvm::Su(- dmdts[0]/rho1, p_rgh);
}
}
if (dmdts.set(1))
{
if (pEqnComp2.valid())
{
pEqnComp2.ref() += fluid.dmdt()/rho2;
pEqnComp2.ref() -= dmdts[1]/rho2;
}
else
{
pEqnComp2 = fvm::Su(fluid.dmdt()/rho2, p_rgh);
pEqnComp2 = fvm::Su(- dmdts[1]/rho2, p_rgh);
}
}
}
@ -357,18 +354,14 @@ while (pimple.correct())
phi = phiHbyA + pEqnIncomp.flux();
surfaceScalarField phi1s
const surfaceScalarField phi1s
(
phiHbyA1
+ alpharAUf1*mSfGradp
- rAUf1*Kdf*MRF.absolute(phi2)
phiHbyA1 + alpharAUf1*mSfGradp
);
surfaceScalarField phi2s
const surfaceScalarField phi2s
(
phiHbyA2
+ alpharAUf2*mSfGradp
- rAUf2*Kdf*MRF.absolute(phi1)
phiHbyA2 + alpharAUf2*mSfGradp
);
surfaceScalarField phir

View File

@ -45,33 +45,6 @@ Description
#include "localEulerDdtScheme.H"
#include "fvcSmooth.H"
namespace Foam
{
tmp<volScalarField> byDt(const volScalarField& vf)
{
if (fv::localEulerDdt::enabled(vf.mesh()))
{
return fv::localEulerDdt::localRDeltaT(vf.mesh())*vf;
}
else
{
return vf/vf.mesh().time().deltaT();
}
}
tmp<surfaceScalarField> byDt(const surfaceScalarField& sf)
{
if (fv::localEulerDdt::enabled(sf.mesh()))
{
return fv::localEulerDdt::localRDeltaTf(sf.mesh())*sf;
}
else
{
return sf/sf.mesh().time().deltaT();
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -105,16 +78,7 @@ int main(int argc, char *argv[])
pimple.dict().lookupOrDefault("faceMomentum", false)
);
bool implicitPhasePressure
(
mesh.solverDict(alpha1.name()).lookupOrDefault
(
"implicitPhasePressure", false
)
);
#include "pUf/createRDeltaTf.H"
#include "pUf/createDDtU.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -159,7 +123,6 @@ int main(int argc, char *argv[])
#include "pUf/UEqns.H"
#include "EEqns.H"
#include "pUf/pEqn.H"
#include "pUf/DDtU.H"
}
else
{

View File

@ -1,657 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015-2017 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "alphatWallBoilingWallFunctionFvPatchScalarField.H"
#include "fvPatchFieldMapper.H"
#include "addToRunTimeSelectionTable.H"
#include "twoPhaseSystem.H"
#include "phaseSystem.H"
#include "ThermalPhaseChangePhaseSystem.H"
#include "MomentumTransferPhaseSystem.H"
#include "compressibleTurbulenceModel.H"
#include "ThermalDiffusivity.H"
#include "PhaseCompressibleTurbulenceModel.H"
#include "saturationModel.H"
#include "wallFvPatch.H"
#include "uniformDimensionedFields.H"
#include "mathematicalConstants.H"
using namespace Foam::constant::mathematical;
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::Enum
<
Foam::compressible::
alphatWallBoilingWallFunctionFvPatchScalarField::phaseType
>
Foam::compressible::
alphatWallBoilingWallFunctionFvPatchScalarField::phaseTypeNames_
({
{ phaseType::vaporPhase, "vapor" },
{ phaseType::liquidPhase, "liquid" },
});
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace compressible
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
alphatWallBoilingWallFunctionFvPatchScalarField::
alphatWallBoilingWallFunctionFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
alphatPhaseChangeJayatillekeWallFunctionFvPatchScalarField(p, iF),
phaseType_(liquidPhase),
relax_(0.5),
AbyV_(p.size(), 0),
alphatConv_(p.size(), 0),
dDep_(p.size(), 1e-5),
qq_(p.size(), 0),
partitioningModel_(nullptr),
nucleationSiteModel_(nullptr),
departureDiamModel_(nullptr),
departureFreqModel_(nullptr)
{
AbyV_ = this->patch().magSf();
forAll(AbyV_, facei)
{
const label faceCelli = this->patch().faceCells()[facei];
AbyV_[facei] /= iF.mesh().V()[faceCelli];
}
}
alphatWallBoilingWallFunctionFvPatchScalarField::
alphatWallBoilingWallFunctionFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
alphatPhaseChangeJayatillekeWallFunctionFvPatchScalarField(p, iF, dict),
phaseType_(phaseTypeNames_.get("phaseType", dict)),
relax_(dict.lookupOrDefault<scalar>("relax", 0.5)),
AbyV_(p.size(), 0),
alphatConv_(p.size(), 0),
dDep_(p.size(), 1e-5),
qq_(p.size(), 0),
partitioningModel_(nullptr),
nucleationSiteModel_(nullptr),
departureDiamModel_(nullptr),
departureFreqModel_(nullptr)
{
switch (phaseType_)
{
case vaporPhase:
{
partitioningModel_ =
wallBoilingModels::partitioningModel::New
(
dict.subDict("partitioningModel")
);
dmdt_ = 0;
break;
}
case liquidPhase:
{
partitioningModel_ =
wallBoilingModels::partitioningModel::New
(
dict.subDict("partitioningModel")
);
nucleationSiteModel_ =
wallBoilingModels::nucleationSiteModel::New
(
dict.subDict("nucleationSiteModel")
);
departureDiamModel_ =
wallBoilingModels::departureDiameterModel::New
(
dict.subDict("departureDiamModel")
);
departureFreqModel_ =
wallBoilingModels::departureFrequencyModel::New
(
dict.subDict("departureFreqModel")
);
if (dict.found("dDep"))
{
dDep_ = scalarField("dDep", dict, p.size());
}
if (dict.found("qQuenching"))
{
qq_ = scalarField("qQuenching", dict, p.size());
}
break;
}
}
if (dict.found("alphatConv"))
{
alphatConv_ = scalarField("alphatConv", dict, p.size());
}
AbyV_ = this->patch().magSf();
forAll(AbyV_, facei)
{
const label faceCelli = this->patch().faceCells()[facei];
AbyV_[facei] /= iF.mesh().V()[faceCelli];
}
}
alphatWallBoilingWallFunctionFvPatchScalarField::
alphatWallBoilingWallFunctionFvPatchScalarField
(
const alphatWallBoilingWallFunctionFvPatchScalarField& psf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
alphatPhaseChangeJayatillekeWallFunctionFvPatchScalarField
(
psf,
p,
iF,
mapper
),
relax_(psf.relax_),
AbyV_(psf.AbyV_),
alphatConv_(psf.alphatConv_, mapper),
dDep_(psf.dDep_, mapper),
qq_(psf.qq_, mapper),
partitioningModel_(psf.partitioningModel_),
nucleationSiteModel_(psf.nucleationSiteModel_),
departureDiamModel_(psf.departureDiamModel_),
departureFreqModel_(psf.departureFreqModel_)
{}
alphatWallBoilingWallFunctionFvPatchScalarField::
alphatWallBoilingWallFunctionFvPatchScalarField
(
const alphatWallBoilingWallFunctionFvPatchScalarField& psf
)
:
alphatPhaseChangeJayatillekeWallFunctionFvPatchScalarField(psf),
relax_(psf.relax_),
AbyV_(psf.AbyV_),
alphatConv_(psf.alphatConv_),
dDep_(psf.dDep_),
qq_(psf.qq_),
partitioningModel_(psf.partitioningModel_),
nucleationSiteModel_(psf.nucleationSiteModel_),
departureDiamModel_(psf.departureDiamModel_),
departureFreqModel_(psf.departureFreqModel_)
{}
alphatWallBoilingWallFunctionFvPatchScalarField::
alphatWallBoilingWallFunctionFvPatchScalarField
(
const alphatWallBoilingWallFunctionFvPatchScalarField& psf,
const DimensionedField<scalar, volMesh>& iF
)
:
alphatPhaseChangeJayatillekeWallFunctionFvPatchScalarField(psf, iF),
relax_(psf.relax_),
AbyV_(psf.AbyV_),
alphatConv_(psf.alphatConv_),
dDep_(psf.dDep_),
qq_(psf.qq_),
partitioningModel_(psf.partitioningModel_),
nucleationSiteModel_(psf.nucleationSiteModel_),
departureDiamModel_(psf.departureDiamModel_),
departureFreqModel_(psf.departureFreqModel_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void alphatWallBoilingWallFunctionFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
// Check that partitioningModel has been constructed
if (!partitioningModel_.valid())
{
FatalErrorInFunction
<< "partitioningModel has not been constructed!"
<< abort(FatalError);
}
// Lookup the fluid model
const ThermalPhaseChangePhaseSystem
<
MomentumTransferPhaseSystem<twoPhaseSystem>
>& fluid =
refCast
<
const ThermalPhaseChangePhaseSystem
<
MomentumTransferPhaseSystem<twoPhaseSystem>
>
>
(
db().lookupObject<phaseSystem>("phaseProperties")
);
const label patchi = patch().index();
switch (phaseType_)
{
case vaporPhase:
{
const phaseModel& vapor
(
fluid.phase1().name() == internalField().group()
? fluid.phase1()
: fluid.phase2()
);
const phaseModel& liquid(fluid.otherPhase(vapor));
// Liquid phase fraction at the wall
const scalarField liquidw(liquid.boundaryField()[patchi]);
// Vapor Liquid phase fraction at the wall
const scalarField vaporw(vapor.boundaryField()[patchi]);
const scalarField fLiquid
(
partitioningModel_->fLiquid(liquidw)
);
operator==
(
calcAlphat(*this)*(1 - fLiquid)/max(vaporw, scalar(1e-8))
);
break;
}
case liquidPhase:
{
// Check that nucleationSiteModel has been constructed
if (!nucleationSiteModel_.valid())
{
FatalErrorInFunction
<< "nucleationSiteModel has not been constructed!"
<< abort(FatalError);
}
// Check that departureDiameterModel has been constructed
if (!departureDiamModel_.valid())
{
FatalErrorInFunction
<< "departureDiameterModel has not been constructed!"
<< abort(FatalError);
}
// Check that nucleationSiteModel has been constructed
if (!departureFreqModel_.valid())
{
FatalErrorInFunction
<< "departureFrequencyModel has not been constructed!"
<< abort(FatalError);
}
const phaseModel& liquid
(
fluid.phase1().name() == internalField().group()
? fluid.phase1()
: fluid.phase2()
);
const phaseModel& vapor(fluid.otherPhase(liquid));
// Retrieve turbulence properties from model
const phaseCompressibleTurbulenceModel& turbModel =
liquid.turbulence();
const tmp<scalarField> tnutw = turbModel.nut(patchi);
const scalar Cmu25(pow025(Cmu_));
const scalarField& y = turbModel.y()[patchi];
const tmp<scalarField> tmuw = turbModel.mu(patchi);
const scalarField& muw = tmuw();
const tmp<scalarField> talphaw = liquid.thermo().alpha(patchi);
const scalarField& alphaw = talphaw();
const tmp<volScalarField> tk = turbModel.k();
const volScalarField& k = tk();
const fvPatchScalarField& kw = k.boundaryField()[patchi];
const fvPatchVectorField& Uw =
turbModel.U().boundaryField()[patchi];
const scalarField magUp(mag(Uw.patchInternalField() - Uw));
const scalarField magGradUw(mag(Uw.snGrad()));
const fvPatchScalarField& rhow =
turbModel.rho().boundaryField()[patchi];
const fvPatchScalarField& hew =
liquid.thermo().he().boundaryField()[patchi];
const fvPatchScalarField& Tw =
liquid.thermo().T().boundaryField()[patchi];
const scalarField Tc(Tw.patchInternalField());
const scalarField uTau(Cmu25*sqrt(kw));
const scalarField yPlus(uTau*y/(muw/rhow));
const scalarField Pr(muw/alphaw);
// Molecular-to-turbulent Prandtl number ratio
const scalarField Prat(Pr/Prt_);
// Thermal sublayer thickness
const scalarField P(this->Psmooth(Prat));
const scalarField yPlusTherm(this->yPlusTherm(P, Prat));
const fvPatchScalarField& rhoLiquidw =
liquid.turbulence().rho().boundaryField()[patchi];
const fvPatchScalarField& rhoVaporw =
vapor.turbulence().rho().boundaryField()[patchi];
tmp<volScalarField> tCp = liquid.thermo().Cp();
const volScalarField& Cp = tCp();
const fvPatchScalarField& Cpw = Cp.boundaryField()[patchi];
// Saturation temperature
const tmp<volScalarField> tTsat =
fluid.saturation().Tsat(liquid.thermo().p());
const volScalarField& Tsat = tTsat();
const fvPatchScalarField& Tsatw(Tsat.boundaryField()[patchi]);
const scalarField Tsatc(Tsatw.patchInternalField());
const fvPatchScalarField& pw =
liquid.thermo().p().boundaryField()[patchi];
const scalarField L
(
vapor.thermo().he(pw,Tsatc,patchi)-hew.patchInternalField()
);
// Liquid phase fraction at the wall
const scalarField liquidw(liquid.boundaryField()[patchi]);
const scalarField fLiquid(partitioningModel_->fLiquid(liquidw));
// Convective thermal diffusivity
alphatConv_ = calcAlphat(alphatConv_);
for (label i=0; i<10; i++)
{
// Liquid temperature at y+=250 is estimated from logarithmic
// thermal wall function (Koncar, Krepper & Egorov, 2005)
const scalarField Tplus_y250(Prt_*(log(E_*250)/kappa_ + P));
const scalarField Tplus(Prt_*(log(E_*yPlus)/kappa_ + P));
scalarField Tl(Tw - (Tplus_y250/Tplus)*(Tw - Tc));
Tl = max(Tc - 40, Tl);
// Nucleation site density:
const scalarField N
(
nucleationSiteModel_->N
(
liquid,
vapor,
patchi,
Tl,
Tsatw,
L
)
);
// Bubble departure diameter:
dDep_ = departureDiamModel_->dDeparture
(
liquid,
vapor,
patchi,
Tl,
Tsatw,
L
);
// Bubble departure frequency:
const scalarField fDep
(
departureFreqModel_->fDeparture
(
liquid,
vapor,
patchi,
dDep_
)
);
// Area fractions:
// Del Valle & Kenning (1985)
const scalarField Ja
(
rhoLiquidw*Cpw*(Tsatw - Tl)/(rhoVaporw*L)
);
const scalarField Al
(
fLiquid*4.8*exp( min(-Ja/80,log(VGREAT)))
);
const scalarField A2(min(pi*sqr(dDep_)*N*Al/4, scalar(1)));
const scalarField A1(max(1 - A2, scalar(1e-4)));
const scalarField A2E(min(pi*sqr(dDep_)*N*Al/4, scalar(5)));
// Volumetric mass source in the near wall cell due to the
// wall boiling
dmdt_ =
(1 - relax_)*dmdt_
+ relax_*(1.0/6.0)*A2E*dDep_*rhoVaporw*fDep*AbyV_;
// Volumetric source in the near wall cell due to the wall
// boiling
mDotL_ = dmdt_*L;
// Quenching heat transfer coefficient
const scalarField hQ
(
2*(alphaw*Cpw)*fDep*sqrt((0.8/fDep)/(pi*alphaw/rhow))
);
// Quenching heat flux
qq_ = (A2*hQ*max(Tw - Tl, scalar(0)));
// Effective thermal diffusivity that corresponds to the
// calculated convective, quenching and evaporative heat fluxes
operator==
(
(
A1*alphatConv_
+ (qq_ + qe())/max(hew.snGrad(), scalar(1e-16))
)
/max(liquidw, scalar(1e-8))
);
scalarField TsupPrev(max((Tw - Tsatw),scalar(0)));
const_cast<fvPatchScalarField&>(Tw).evaluate();
scalarField TsupNew(max((Tw - Tsatw),scalar(0)));
scalar maxErr(max(mag(TsupPrev - TsupNew)));
if (maxErr < 1e-1)
{
if (i > 0)
{
Info<< "Wall boiling wall function iterations: "
<< i + 1 << endl;
}
break;
}
if (debug)
{
const scalarField qc
(
fLiquid*A1*(alphatConv_ + alphaw)*hew.snGrad()
);
const scalarField qEff
(
liquidw*(*this + alphaw)*hew.snGrad()
);
Info<< " L: " << gMin(L) << " - " << gMax(L) << endl;
Info<< " Tl: " << gMin(Tl) << " - " << gMax(Tl) << endl;
Info<< " N: " << gMin(N) << " - " << gMax(N) << endl;
Info<< " dDep_: " << gMin(dDep_) << " - "
<< gMax(dDep_) << endl;
Info<< " fDep: " << gMin(fDep) << " - "
<< gMax(fDep) << endl;
Info<< " Al: " << gMin(Al) << " - " << gMax(Al) << endl;
Info<< " A1: " << gMin(A1) << " - " << gMax(A1) << endl;
Info<< " A2: " << gMin(A2) << " - " << gMax(A2) << endl;
Info<< " A2E: " << gMin(A2E) << " - "
<< gMax(A2E) << endl;
Info<< " dmdtW: " << gMin(dmdt_) << " - "
<< gMax(dmdt_) << endl;
Info<< " qc: " << gMin(qc) << " - " << gMax(qc) << endl;
Info<< " qq: " << gMin(fLiquid*qq()) << " - "
<< gMax(fLiquid*qq()) << endl;
Info<< " qe: " << gMin(fLiquid*qe()) << " - "
<< gMax(fLiquid*qe()) << endl;
Info<< " qEff: " << gMin(qEff) << " - "
<< gMax(qEff) << endl;
Info<< " alphat: " << gMin(*this) << " - "
<< gMax(*this) << endl;
Info<< " alphatConv: " << gMin(alphatConv_)
<< " - " << gMax(alphatConv_) << endl;
}
}
break;
}
default:
{
FatalErrorInFunction
<< "Unknown phase type. Valid types are: "
<< phaseTypeNames_ << nl << exit(FatalError);
}
}
fixedValueFvPatchScalarField::updateCoeffs();
}
void alphatWallBoilingWallFunctionFvPatchScalarField::write(Ostream& os) const
{
fvPatchField<scalar>::write(os);
os.writeEntry("phaseType", phaseTypeNames_[phaseType_]);
os.writeEntry("relax", relax_);
switch (phaseType_)
{
case vaporPhase:
{
os.beginBlock("partitioningModel");
partitioningModel_->write(os);
os.endBlock();
break;
}
case liquidPhase:
{
os.beginBlock("partitioningModel");
partitioningModel_->write(os);
os.endBlock();
os.beginBlock("nucleationSiteModel");
nucleationSiteModel_->write(os);
os.endBlock();
os.beginBlock("departureDiamModel");
departureDiamModel_->write(os);
os.endBlock();
os.beginBlock("departureFreqModel");
departureFreqModel_->write(os);
os.endBlock();
break;
}
}
dmdt_.writeEntry("dmdt", os);
dDep_.writeEntry("dDep", os);
qq_.writeEntry("qQuenching", os);
alphatConv_.writeEntry("alphatConv", os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
alphatWallBoilingWallFunctionFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace compressible
} // End namespace Foam
// ************************************************************************* //

View File

@ -12,7 +12,15 @@
)
);
MULES::explicitSolve(alpha1, phi, alphaPhi, 1, 0);
MULES::explicitSolve
(
geometricOneField(),
alpha1,
phi,
alphaPhi,
oneField(),
zeroField()
);
rhoPhi = alphaPhi*(rho1 - rho2) + phi*rho2;

View File

@ -345,12 +345,12 @@ Foam::RASModels::kineticTheoryModel::divDevRhoReff
void Foam::RASModels::kineticTheoryModel::correct()
{
// Local references
const twoPhaseSystem& fluid = refCast<const twoPhaseSystem>(phase_.fluid());
volScalarField alpha(max(alpha_, scalar(0)));
const volScalarField& rho = phase_.rho();
const surfaceScalarField& alphaRhoPhi = alphaRhoPhi_;
const volVectorField& U = U_;
const volVectorField& Uc_ =
refCast<const twoPhaseSystem>(phase_.fluid()).otherPhase(phase_).U();
const volVectorField& Uc_ = fluid.otherPhase(phase_).U();
const scalar sqrtPi = sqrt(constant::mathematical::pi);
dimensionedScalar ThetaSmall("ThetaSmall", Theta_.dimensions(), 1.0e-6);
@ -394,7 +394,11 @@ void Foam::RASModels::kineticTheoryModel::correct()
// Drag
volScalarField beta
(
refCast<const twoPhaseSystem>(phase_.fluid()).drag(phase_).K()
fluid.lookupSubModel<dragModel>
(
phase_,
fluid.otherPhase(phase_)
).K()
);
// Eq. 3.25, p. 50 Js = J1 - J2

View File

@ -270,9 +270,7 @@ Foam::BlendedInterfacialModel<modelType>::F() const
f2 = blending_.f2(pair1In2_.dispersed(), pair2In1_.dispersed());
}
tmp<GeometricField<Type, fvPatchField, volMesh>> x
(
new GeometricField<Type, fvPatchField, volMesh>
auto x = tmp<GeometricField<Type, fvPatchField, volMesh>>::New
(
IOobject
(
@ -285,7 +283,6 @@ Foam::BlendedInterfacialModel<modelType>::F() const
),
pair_.phase1().mesh(),
dimensioned<Type>(modelType::dimF, Zero)
)
);
if (model_.valid())
@ -338,9 +335,7 @@ Foam::BlendedInterfacialModel<modelType>::Ff() const
);
}
tmp<surfaceScalarField> x
(
new surfaceScalarField
auto x = tmp<surfaceScalarField>::New
(
IOobject
(
@ -353,9 +348,10 @@ Foam::BlendedInterfacialModel<modelType>::Ff() const
),
pair_.phase1().mesh(),
dimensionedScalar(modelType::dimF*dimArea, Zero)
)
);
x.ref().setOriented();
if (model_.valid())
{
x.ref() += model_->Ff()*(f1() - f2());

View File

@ -56,7 +56,7 @@ class hyperbolic
// Private data
//- Maximum fraction of phases which can be considered dispersed
HashTable<dimensionedScalar> maxDispersedAlpha_;
HashTable<dimensionedScalar, word, word::hash> maxDispersedAlpha_;
//- Width of the transition
const dimensionedScalar transitionAlphaScale_;

View File

@ -56,10 +56,12 @@ class linear
// Private data
//- Maximum fraction of phases which can be considered fully dispersed
HashTable<dimensionedScalar> maxFullyDispersedAlpha_;
HashTable<dimensionedScalar, word, word::hash>
maxFullyDispersedAlpha_;
//- Maximum fraction of phases which can be considered partly dispersed
HashTable<dimensionedScalar> maxPartlyDispersedAlpha_;
HashTable<dimensionedScalar, word, word::hash>
maxPartlyDispersedAlpha_;
public:

View File

@ -210,6 +210,18 @@ public:
return thermo_->kappa();
}
//- Thermal diffusivity for energy of mixture [kg/m/s]
tmp<volScalarField> alphahe() const
{
return thermo_->alphahe();
}
//- Thermal diffusivity for energy of mixture for patch [kg/m/s]
tmp<scalarField> alphahe(const label patchi) const
{
return thermo_->alphahe(patchi);
}
//- Return the laminar thermal conductivity
tmp<volScalarField> kappaEff
(

View File

@ -29,6 +29,15 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::phasePairKey::hash::hash()
{}
Foam::phasePairKey::phasePairKey()
{}
Foam::phasePairKey::phasePairKey
(
const word& name1,
@ -41,12 +50,10 @@ Foam::phasePairKey::phasePairKey
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
bool Foam::phasePairKey::ordered() const
{
return ordered_;
}
Foam::phasePairKey::~phasePairKey()
{}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
@ -65,8 +72,12 @@ Foam::label Foam::phasePairKey::hash::operator()
word::hash()(key.second())
);
}
return word::hash()(key.first()) + word::hash()(key.second());
else
{
return
word::hash()(key.first())
+ word::hash()(key.second());
}
}
@ -78,12 +89,13 @@ bool Foam::operator==
const phasePairKey& b
)
{
const auto cmp = Pair<word>::compare(a,b);
const auto c = Pair<word>::compare(a,b);
return
(
(a.ordered_ == b.ordered_)
&& (a.ordered_ ? (cmp == 1) : cmp)
&& (
(a.ordered_ && (c == 1))
|| (!a.ordered_ && (c != 0))
);
}
@ -119,8 +131,8 @@ Foam::Istream& Foam::operator>>(Istream& is, phasePairKey& key)
FatalErrorInFunction
<< "Phase pair type is not recognised. "
<< temp
<< "Use (phaseDispersed in phaseContinuous) for an ordered pair, "
<< "or (phase1 and phase2) for an unordered pair."
<< "Use (phaseDispersed in phaseContinuous) for an ordered"
<< "pair, or (phase1 and pase2) for an unordered pair."
<< exit(FatalError);
}

View File

@ -59,6 +59,29 @@ class phasePairKey
:
public Pair<word>
{
public:
class hash
:
public Hash<phasePairKey>
{
public:
// Constructors
// Construct null
hash();
// Member operators
// Generate a hash from a phase pair key
label operator()(const phasePairKey& key) const;
};
private:
// Private data
//- Flag to indicate whether ordering is important
@ -66,30 +89,23 @@ class phasePairKey
public:
//- Ordered or unordered hashing of word pair
struct hash
{
//- Generate a hash from a phase pair key
label operator()(const phasePairKey& key) const;
};
// Constructors
//- Construct null
phasePairKey() {} // = default
phasePairKey();
//- Construct from names and optional ordering flag
//- Construct from names and the ordering flag
phasePairKey
(
const word& name1,
const word& name2,
const bool ordered = false
const bool ordered
);
//- Destructor
virtual ~phasePairKey() = default;
virtual ~phasePairKey();
// Access

View File

@ -5,7 +5,7 @@
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2013-2017 OpenFOAM Foundation
| Copyright (C) 2013-2018 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,6 +47,7 @@ License
#include "fixedValueFvsPatchFields.H"
#include "blendingMethod.H"
#include "HashPtrTable.H"
#include "UniformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -108,21 +109,21 @@ Foam::twoPhaseSystem::twoPhaseSystem
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar(dimless/dimTime, Zero)
dimensionedScalar("dgdt", dimless/dimTime, 0)
)
{
phase2_.volScalarField::operator=(scalar(1) - phase1_);
// Blending
for (const entry& dEntry : subDict("blending"))
forAllConstIter(dictionary, subDict("blending"), iter)
{
blendingMethods_.insert
(
dEntry.dict().dictName(),
iter().dict().dictName(),
blendingMethod::New
(
dEntry.dict(),
iter().dict(),
wordList(lookup("phases"))
)
);
@ -134,7 +135,7 @@ Foam::twoPhaseSystem::twoPhaseSystem
phasePair::scalarTable sigmaTable(lookup("sigma"));
phasePair::dictTable aspectRatioTable(lookup("aspectRatio"));
pair_.reset
pair_.set
(
new phasePair
(
@ -145,7 +146,7 @@ Foam::twoPhaseSystem::twoPhaseSystem
)
);
pair1In2_.reset
pair1In2_.set
(
new orderedPhasePair
(
@ -157,7 +158,7 @@ Foam::twoPhaseSystem::twoPhaseSystem
)
);
pair2In1_.reset
pair2In1_.set
(
new orderedPhasePair
(
@ -172,100 +173,100 @@ Foam::twoPhaseSystem::twoPhaseSystem
// Models
drag_.reset
drag_.set
(
new BlendedInterfacialModel<dragModel>
(
lookup("drag"),
(
blendingMethods_.found("drag")
? *(blendingMethods_["drag"])
: *(blendingMethods_["default"])
? blendingMethods_["drag"]
: blendingMethods_["default"]
),
*pair_,
*pair1In2_,
*pair2In1_,
pair_,
pair1In2_,
pair2In1_,
false // Do not zero drag coefficient at fixed-flux BCs
)
);
virtualMass_.reset
virtualMass_.set
(
new BlendedInterfacialModel<virtualMassModel>
(
lookup("virtualMass"),
(
blendingMethods_.found("virtualMass")
? *(blendingMethods_["virtualMass"])
: *(blendingMethods_["default"])
? blendingMethods_["virtualMass"]
: blendingMethods_["default"]
),
*pair_,
*pair1In2_,
*pair2In1_
pair_,
pair1In2_,
pair2In1_
)
);
heatTransfer_.reset
heatTransfer_.set
(
new BlendedInterfacialModel<heatTransferModel>
(
lookup("heatTransfer"),
(
blendingMethods_.found("heatTransfer")
? *(blendingMethods_["heatTransfer"])
: *(blendingMethods_["default"])
? blendingMethods_["heatTransfer"]
: blendingMethods_["default"]
),
*pair_,
*pair1In2_,
*pair2In1_
pair_,
pair1In2_,
pair2In1_
)
);
lift_.reset
lift_.set
(
new BlendedInterfacialModel<liftModel>
(
lookup("lift"),
(
blendingMethods_.found("lift")
? *(blendingMethods_["lift"])
: *(blendingMethods_["default"])
? blendingMethods_["lift"]
: blendingMethods_["default"]
),
*pair_,
*pair1In2_,
*pair2In1_
pair_,
pair1In2_,
pair2In1_
)
);
wallLubrication_.reset
wallLubrication_.set
(
new BlendedInterfacialModel<wallLubricationModel>
(
lookup("wallLubrication"),
(
blendingMethods_.found("wallLubrication")
? *(blendingMethods_["wallLubrication"])
: *(blendingMethods_["default"])
? blendingMethods_["wallLubrication"]
: blendingMethods_["default"]
),
*pair_,
*pair1In2_,
*pair2In1_
pair_,
pair1In2_,
pair2In1_
)
);
turbulentDispersion_.reset
turbulentDispersion_.set
(
new BlendedInterfacialModel<turbulentDispersionModel>
(
lookup("turbulentDispersion"),
(
blendingMethods_.found("turbulentDispersion")
? *(blendingMethods_["turbulentDispersion"])
: *(blendingMethods_["default"])
? blendingMethods_["turbulentDispersion"]
: blendingMethods_["default"]
),
*pair_,
*pair1In2_,
*pair2In1_
pair_,
pair1In2_,
pair2In1_
)
);
}
@ -274,7 +275,7 @@ Foam::twoPhaseSystem::twoPhaseSystem
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::twoPhaseSystem::~twoPhaseSystem()
{} // Define here (incomplete type in header)
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
@ -362,8 +363,8 @@ void Foam::twoPhaseSystem::solve()
alpha1.name()
);
label nAlphaSubCycles(alphaControls.get<label>("nAlphaSubCycles"));
label nAlphaCorr(alphaControls.get<label>("nAlphaCorr"));
label nAlphaSubCycles(readLabel(alphaControls.lookup("nAlphaSubCycles")));
label nAlphaCorr(readLabel(alphaControls.lookup("nAlphaCorr")));
word alphaScheme("div(phi," + alpha1.name() + ')');
word alpharScheme("div(phir," + alpha1.name() + ')');
@ -401,7 +402,7 @@ void Foam::twoPhaseSystem::solve()
mesh_
),
mesh_,
dimensionedScalar(dgdt_.dimensions(), Zero)
dimensionedScalar("Sp", dgdt_.dimensions(), 0.0)
);
volScalarField::Internal Su
@ -466,8 +467,8 @@ void Foam::twoPhaseSystem::solve()
alphaPhic10,
(alphaSubCycle.index()*Sp)(),
(Su - (alphaSubCycle.index() - 1)*Sp*alpha1)(),
phase1_.alphaMax(),
0
UniformField<scalar>(phase1_.alphaMax()),
zeroField()
);
if (alphaSubCycle.index() == 1)
@ -492,8 +493,8 @@ void Foam::twoPhaseSystem::solve()
alphaPhic1,
Sp,
Su,
phase1_.alphaMax(),
0
UniformField<scalar>(phase1_.alphaMax()),
zeroField()
);
phase1_.alphaPhi() = alphaPhic1;
@ -568,19 +569,6 @@ bool Foam::twoPhaseSystem::read()
}
const Foam::dragModel& Foam::twoPhaseSystem::drag(const phaseModel& phase) const
{
return drag_->phaseModel(phase);
}
const Foam::virtualMassModel&
Foam::twoPhaseSystem::virtualMass(const phaseModel& phase) const
{
return virtualMass_->phaseModel(phase);
}
const Foam::dimensionedScalar& Foam::twoPhaseSystem::sigma() const
{
return pair_->sigma();

View File

@ -96,7 +96,7 @@ class twoPhaseSystem
autoPtr<orderedPhasePair> pair2In1_;
//- Blending methods
HashTable<autoPtr<blendingMethod>> blendingMethods_;
HashTable<autoPtr<blendingMethod>, word, word::hash> blendingMethods_;
//- Drag model
autoPtr<BlendedInterfacialModel<dragModel>> drag_;
@ -184,11 +184,17 @@ public:
// Access
//- Return the drag model for the given phase
const dragModel& drag(const phaseModel& phase) const;
//- Access a sub model between a phase pair
template<class modelType>
const modelType& lookupSubModel(const phasePair& key) const;
//- Return the virtual mass model for the given phase
const virtualMassModel& virtualMass(const phaseModel& phase) const;
//- Access a sub model between two phases
template<class modelType>
const modelType& lookupSubModel
(
const phaseModel& dispersed,
const phaseModel& continuous
) const;
//- Return the surface tension coefficient
const dimensionedScalar& sigma() const;
@ -238,6 +244,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "twoPhaseSystemTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2015-2018 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 "BlendedInterfacialModel.H"
#include "dragModel.H"
#include "virtualMassModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class modelType>
const modelType& twoPhaseSystem::lookupSubModel
(
const phasePair& key
) const
{
return
mesh().lookupObject<modelType>
(
IOobject::groupName(modelType::typeName, key.name())
);
}
template<>
inline const dragModel& twoPhaseSystem::lookupSubModel<dragModel>
(
const phaseModel& dispersed,
const phaseModel& continuous
) const
{
return drag_->phaseModel(dispersed);
}
template<>
inline const virtualMassModel& twoPhaseSystem::lookupSubModel<virtualMassModel>
(
const phaseModel& dispersed,
const phaseModel& continuous
) const
{
return virtualMass_->phaseModel(dispersed);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -109,7 +109,6 @@ structuredCoeffs
method scotch;
}
/*
constraints
{
@ -140,6 +139,7 @@ constraints
}
*/
//// Is the case distributed? Note: command-line argument -roots takes
//// precedence
//distributed yes;

View File

@ -1,55 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd |
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# | Copyright (C) 2011 OpenFOAM Foundation
#------------------------------------------------------------------------------
# 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/>.
#
# Script
# foamEbrowse
#
# Description
# Build the Ebrowse database for all the .H and .C files
#
#------------------------------------------------------------------------------
sourcesFile=${TMPDIR:-/tmp}/sourcesFile.$$
if [ $# -ne 0 ]
then
echo "Usage : ${0##*/}"
echo ""
echo "Build the Ebrowse database for all the .H and .C files"
echo ""
exit 1
fi
# Clean up on termination and on Ctrl-C
trap 'rm -f $sourcesFile 2>/dev/null; exit 0' EXIT TERM INT
cd $WM_PROJECT_DIR
mkdir .tags 2>/dev/null
cd .tags
find -H .. \( -name "*.[HC]" -o -name lnInclude -prune -o -name Doxygen -prune \) -print > $sourcesFile
ebrowse --files=$sourcesFile --output-file=ebrowse
#------------------------------------------------------------------------------

View File

@ -1,132 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd |
# \\/ M anipulation |
#------------------------------------------------------------------------------
# | Copyright (C) 2011-2012 OpenFOAM Foundation
#------------------------------------------------------------------------------
# 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/>.
#
# Script
# foamPack [OPTION]
#
# Description
# Pack and compress the OpenFOAM directory for release
#
#------------------------------------------------------------------------------
packDir=$WM_PROJECT-$WM_PROJECT_VERSION
toolsDir="${0%/*}/tools" # this script is located in the tools/ parent dir
usage() {
exec 1>&2
while [ "$#" -gt 0 ]; do echo "$1"; shift; done
cat <<USAGE
Usage: ${0##*/} [OPTION]
options:
-o, -output <dir> specify alternative output directory
-nogit bypass using 'git archive'
* Pack and compress OpenFOAM directory for release
USAGE
exit 1
}
unset outputDir nogit
# parse options
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help*)
usage
;;
-nogit)
nogit=true
shift
;;
-o | -output)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
outputDir=${2%%/}
shift 2
;;
-*)
usage "unknown option: '$*'"
;;
*)
break
;;
esac
done
# check for essential directories
[ -d $packDir ] || {
echo "Error: directory $packDir does not exist" 1>&2
exit 1
}
#------------------------------------------------------------------------------
timeStamp=$(date +%Y-%m-%d)
packExt=tgz
packBase=${packDir}_${timeStamp}
# add optional output directory
[ -d "$outputDir" ] && packBase="$outputDir/$packBase"
packFile=$packBase.$packExt
# avoid overwriting old pack file
if [ -f $packFile ]
then
echo "Error: $packFile already exists" 1>&2
exit 1
fi
# add time-stamp file before packing
echo $timeStamp 2>/dev/null > $packDir/.timeStamp
# check for git (program and .git directory)
(cd $packDir && git branch) > /dev/null 2>&1 || nogit=true
if [ "$nogit" = true ]
then
echo "pack manually" 1>&2
foamPackSource $packDir $packFile
else
if [ ! -f $packDir/.build ]
then
echo "Error: $packDir/.build does not exists" 1>&2
echo " Please update this by running e.g. 'wmakePrintBuild -update' in $packDir" 1>&2
exit 2
fi
echo "pack with git-archive" 1>&2 &&
( cd $packDir && git archive --format=tar --prefix=$packDir/ HEAD) > $packBase.tar &&
echo "add in time-stamp and lnInclude directories" 1>&2 &&
tar cf $packBase.tar2 $packDir/.timeStamp $packDir/.build $(find -H $packDir -name lnInclude -type d) &&
tar Af $packBase.tar $packBase.tar2 &&
echo "gzip tar file" 1>&2 &&
gzip -c9 $packBase.tar > $packFile &&
rm -f $packBase.tar $packBase.tar2 2>/dev/null
fi
#------------------------------------------------------------------------------

View File

@ -1,170 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd |
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# | Copyright (C) 2011-2015 OpenFOAM Foundation
#------------------------------------------------------------------------------
# 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/>.
#
# Script
# foamPackBin [OPTION] <archOptions>
#
# Description
# Pack and compress binary version of OpenFOAM for release
#
# Script
# foamPackThirdPartyBin [OPTION] <archOptions>
#
# Description
# Pack and compress binary version of OpenFOAM ThirdParty for release
#
#------------------------------------------------------------------------------
toolsDir="${0%/*}/tools" # this script is located in the tools/ parent dir
case "${0##*/}" in
*ThirdParty*)
# for ThirdParty
codeBase="OpenFOAM ThirdParty"
packDir=ThirdParty-$WM_PROJECT_VERSION
listBinDirs=$toolsDir/foamListThirdPartyBinDirs
;;
*)
# regular
codeBase="OpenFOAM"
packDir=$WM_PROJECT-$WM_PROJECT_VERSION
listBinDirs=$toolsDir/foamListBinDirs
;;
esac
usage() {
exec 1>&2
while [ "$#" -gt 0 ]; do echo "$1"; shift; done
cat <<USAGE
Usage: ${0##*/} [OPTION] <archOptions>
${0##*/} [OPTION] -current
options:
-b, -bzip2 use bzip2 instead of gzip compression
-c, -current use current value of \$WM_OPTIONS
-o, -output <dir> specify alternative output directory
* Pack and compress binary version of $codeBase for release
The value of 'archOptions' normally corresponds to \$WM_OPTIONS
The current value of \$WM_OPTIONS = $WM_OPTIONS
USAGE
exit 1
}
unset archOptions outputDir
packExt=tgz
# parse options
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help*)
usage
;;
-b | -bzip2)
packExt=tbz
shift
;;
-c | -current) # use $WM_OPTIONS - eg, 'linux64GccDPOpt'
archOptions="$WM_OPTIONS"
shift
;;
-o | -output)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
outputDir=${2%%/}
shift 2
;;
-*)
usage "unknown option: '$*'"
;;
*)
break
;;
esac
done
if [ -n "$archOptions" ]
then
[ $# -eq 0 ] || usage "Error: cannot specify both -current and architecture"
else
archOptions="$1"
[ $# -eq 1 ] || usage "Error: specify architecture"
fi
#------------------------------------------------------------------------------
timeStamp=$(date +%Y-%m-%d)
packBase=${packDir}.${archOptions}_${timeStamp}
# add optional output directory
[ -d "$outputDir" ] && packBase="$outputDir/$packBase"
packFile=$packBase.$packExt
# avoid overwriting old pack file
if [ -f $packFile ]
then
echo "Error: $packFile already exists" 1>&2
exit 1
fi
#------------------------------------------------------------------------------
# Get list of directories
dirList=$( $listBinDirs $packDir $archOptions )
if [ $? -eq 0 -a -n "$dirList" ]
then
echo "Pack into $packFile" 1>&2
echo 1>&2
else
exit 1
fi
# bzip2 or gzip compression
case "$packFile" in
*tbz)
tarOpt=cpjf
;;
*)
tarOpt=cpzf
;;
esac
# Clean up on Ctrl-C
trap 'rm -f $packFile 2>/dev/null' INT
tar $tarOpt $packFile $dirList
if [ $? -eq 0 ]
then
echo "Finished packing file $packFile" 1>&2
else
echo "Error: failure packing $packFile" 1>&2
rm -f $packFile 2>/dev/null
fi
#------------------------------------------------------------------------------

View File

@ -1,88 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd |
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# | Copyright (C) 2011 OpenFOAM Foundation
#------------------------------------------------------------------------------
# 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/>.
#
# Script
# foamPackBinAll [OPTION]
#
# Description
# Pack and compress all binary versions of OpenFOAM for release
#
# Script
# foamPackThirdPartyBinAll [OPTION]
#
# Description
# Pack and compress all binary versions of OpenFOAM ThirdParty for release
#
#------------------------------------------------------------------------------
binDir="${0%/*}" # this script is located in the bin/ dir
case "${0##*/}" in
*ThirdParty*)
# for ThirdParty
packDir=ThirdParty-$WM_PROJECT_VERSION
packBin=foamPackThirdPartyBin
;;
*)
# regular
packDir=$WM_PROJECT-$WM_PROJECT_VERSION
packBin=foamPackBin
;;
esac
[ -d $packDir ] || {
echo "Error: directory $packDir does not exist" 1>&2
exit 1
}
if [ -d $packDir/lib ]
then
# obtain archOptions types from lib/<archOptions>
for archOptions in $packDir/lib/*
do
$binDir/$packBin $@ ${archOptions##*/}
done
elif [ -d $packDir/platforms ]
then
# obtain archOptions types from platforms/<archOptions>/lib
for archOptions in $packDir/platforms/*/lib
do
archOptions=${archOptions%%/lib}
$binDir/$packBin $@ ${archOptions##*/}
done
else
echo "Error: directory $packDir does not appear packable" 1>&2
exit 1
fi
#------------------------------------------------------------------------------

View File

@ -1,149 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd |
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# | Copyright (C) 2011 OpenFOAM Foundation
#------------------------------------------------------------------------------
# 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/>.
#
# Script
# foamPackDoxygen [-prefix DIR] [-o outputDir]
#
# Description
# Pack and compress the OpenFOAM doxygen html for release
#
#------------------------------------------------------------------------------
packDir=$WM_PROJECT-$WM_PROJECT_VERSION
htmlDir=doc/Doxygen/html
usage() {
exec 1>&2
while [ "$#" -gt 0 ]; do echo "$1"; shift; done
cat <<USAGE
Usage: ${0##*/} [OPTION]
options:
-b, -bzip2 use bzip2 instead of gzip compression
-o, -output <dir> specify alternative output directory
-prefix <dir> use alternative prefix
* Pack and compress the OpenFOAM doxygen html for release
USAGE
exit 1
}
unset prefix outputDir
packExt=tgz
# parse options
while [ "$#" -gt 0 ]
do
case $1 in
-h | -help*)
usage
;;
-b | -bzip2)
packExt=tbz
shift
;;
-o | -output)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
outputDir=${2%%/}
shift 2
;;
-prefix | --prefix)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
prefix=${2%%/}
shift 2
;;
-*)
usage "unknown option: '$*'"
;;
esac
done
# if packing from within the directory, use -prefix form
if [ "${PWD##*/}" = "$packDir" ]
then
: ${prefix:=$packDir}
fi
# pack the directories directly and add prefix afterwards
if [ -n "$prefix" ]
then
packDir="$prefix"
elif [ ! -d $packDir ]
then
echo "Error: directory $packDir does not exist" 1>&2
exit 1
fi
#------------------------------------------------------------------------------
packName=${packDir}_Doxygen
# add optional output directory
[ -d "$outputDir" ] && packName="$outputDir/$packName"
packFile=$packName.$packExt
if [ -f $packFile ]
then
echo "Error: $packFile already exists" 1>&2
exit 1
fi
cat <<INFO 1>&2
-------------------------------------------------------------------------------
Packing doxygen html into $packFile
INFO
# bzip2 or gzip compression
case "$packFile" in
*tbz)
tarOpt=cpjf
;;
*)
tarOpt=cpzf
;;
esac
# Clean up on Ctrl-C
trap 'rm -f $packFile 2>/dev/null' INT
if [ -n "$prefix" ]
then
# requires GNU tar
tar $tarOpt $packFile --transform="s@^@$prefix/@" $htmlDir
else
tar $tarOpt $packFile $packDir/$htmlDir
fi
if [ $? -eq 0 ]
then
echo "Finished packing doxygen html into $packFile" 1>&2
else
echo "Error: failure packing doxygen html into $packFile" 1>&2
rm -f $packFile 2>/dev/null
fi
#------------------------------------------------------------------------------

View File

@ -1,105 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd |
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# | Copyright (C) 2011 OpenFOAM Foundation
#------------------------------------------------------------------------------
# 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/>.
#
# Script
# foamPackSource <directory> <tarFile>
#
# Description
# Pack and compress all source files from a given directory.
#
# Note
# Not normally called directly by the user
#------------------------------------------------------------------------------
tmpFile=${TMPDIR:-/tmp}/foamPackFiles.$$
toolsDir="${0%/*}/tools" # this script is located in the tools/ parent dir
[ $# -eq 2 ] || {
cat <<USAGE 1>&2
Usage : ${0##*/} directory tarFile
* Pack and compress all source files from a given directory into <tarFile>
USAGE
exit 1
}
# canonical form (no double and no trailing dashes)
packDir=$(echo "$1" | sed -e 's@//*@/@g' -e 's@/$@@')
packFile=$2
# check for essential directories
[ -d $packDir ] || {
echo "Error: directory $packDir does not exist" 1>&2
exit 1
}
# avoid overwriting old pack file
if [ -f $packFile ]
then
echo "Error: $packFile already exists" 1>&2
exit 1
fi
# Clean up on termination and on Ctrl-C
trap 'rm -f $tmpFile 2>/dev/null; exit 0' EXIT TERM INT
# get all names
$toolsDir/foamListSourceFiles $packDir > $tmpFile
# provide some feedback
cat <<INFO 1>&2
-------------------------------------------------------------------------------
Packing $packDir source files into $packFile
INFO
wc $tmpFile | awk '{print "Packing",$1,"files - this could take some time ..."}' 1>&2
# bzip2 or gzip compression
case "$packFile" in
*tbz)
tarOpt=cpjf
;;
*)
tarOpt=cpzf
;;
esac
# Clean up on Ctrl-C
trap 'rm -f $packFile $tmpFile 2>/dev/null' INT
tar $tarOpt $packFile --files-from $tmpFile
if [ $? -eq 0 ]
then
echo "Finished packing $packDir into $packFile" 1>&2
else
echo "Error: failure packing $packDir into $packFile" 1>&2
rm -f $packFile 2>/dev/null
fi
#------------------------------------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More