mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'develop' of develop.openfoam.com:Development/OpenFOAM-plus into develop
This commit is contained in:
2
Allwmake
2
Allwmake
@ -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 "========================================"
|
||||
|
||||
28
README.md
28
README.md
@ -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
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
derivedFvPatchFields/turbulentTemperatureTwoPhaseRadCoupledMixed/turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.C
|
||||
../solid/solidRegionDiffNo.C
|
||||
chtMultiRegionTwoPhaseEulerFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/chtMultiRegionTwoPhaseEulerFoam
|
||||
@ -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 \
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
|
||||
@ -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]
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
@ -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)
|
||||
);
|
||||
@ -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];
|
||||
@ -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");
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
p_rghFluid[i].storePrevIter();
|
||||
//rhoFluid[i].storePrevIter();
|
||||
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
(
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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
|
||||
(
|
||||
|
||||
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
@ -646,8 +654,8 @@ Foam::multiphaseSystem::dragCoeffs() const
|
||||
(
|
||||
max
|
||||
(
|
||||
//fvc::average(dm.phase1()*dm.phase2()),
|
||||
//fvc::average(dm.phase1())*fvc::average(dm.phase2()),
|
||||
// fvc::average(dm.phase1()*dm.phase2()),
|
||||
// fvc::average(dm.phase1())*fvc::average(dm.phase2()),
|
||||
dm.phase1()*dm.phase2(),
|
||||
dm.residualPhaseFraction()
|
||||
)
|
||||
@ -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,14 +930,16 @@ 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;
|
||||
}
|
||||
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
sizeDistribution/sizeDistribution.C
|
||||
phaseForces/phaseForces.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libreactingEulerFoamFunctionObjects
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,11 +1,9 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # Run from this directory
|
||||
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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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());
|
||||
fvScalarMatrix EEqn
|
||||
(
|
||||
phase.heEqn()
|
||||
==
|
||||
*heatTransfer[phase.name()]
|
||||
+ alpha*rho*(U&g)
|
||||
+ fvOptions(alpha, rho, phase.thermoRef().he())
|
||||
);
|
||||
|
||||
if (EEqn.valid())
|
||||
{
|
||||
EEqn =
|
||||
(
|
||||
EEqn
|
||||
==
|
||||
*heatTransfer[phase.name()]
|
||||
+ alpha*rho*(U&g)
|
||||
+ fvOptions(alpha, rho, phase.thermo().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();
|
||||
|
||||
@ -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 = \
|
||||
|
||||
@ -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]));
|
||||
fvScalarMatrix YiEqn
|
||||
(
|
||||
phase.YiEqn(Y[i])
|
||||
==
|
||||
*massTransfer[Y[i].name()]
|
||||
+ fvOptions(alpha, rho, Y[i])
|
||||
);
|
||||
|
||||
if (YiEqn.valid())
|
||||
{
|
||||
YiEqn =
|
||||
(
|
||||
YiEqn
|
||||
==
|
||||
*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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,67 +59,116 @@ 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)
|
||||
// Correct fixed-flux BCs to be consistent with the velocity BCs
|
||||
forAll(fluid.movingPhases(), movingPhasei)
|
||||
{
|
||||
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()
|
||||
);
|
||||
phaseModel& phase = fluid.movingPhases()[movingPhasei];
|
||||
MRF.correctBoundaryFlux(phase.U(), phase.phiRef());
|
||||
}
|
||||
|
||||
surfaceScalarField ghSnGradRho
|
||||
(
|
||||
"ghSnGradRho",
|
||||
ghf*fvc::snGrad(rho)*mesh.magSf()
|
||||
);
|
||||
|
||||
// Combined buoyancy and force fluxes
|
||||
PtrList<surfaceScalarField> phigFs(phases.size());
|
||||
forAll(phases, phasei)
|
||||
{
|
||||
phaseModel& phase = phases[phasei];
|
||||
|
||||
phigFs.set
|
||||
const surfaceScalarField ghSnGradRho
|
||||
(
|
||||
phasei,
|
||||
(
|
||||
alpharAUfs[phasei]
|
||||
*(
|
||||
ghSnGradRho
|
||||
- (fvc::interpolate(phase.rho() - rho))*(g & mesh.Sf())
|
||||
- fluid.surfaceTension(phase)*mesh.magSf()
|
||||
)
|
||||
).ptr()
|
||||
"ghSnGradRho",
|
||||
ghf*fvc::snGrad(rho)*mesh.magSf()
|
||||
);
|
||||
|
||||
if (phiFs.set(phasei))
|
||||
forAll(phases, phasei)
|
||||
{
|
||||
phigFs[phasei] += phiFs[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 (phiFs.set(phasei))
|
||||
{
|
||||
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())
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqnComps.set
|
||||
(
|
||||
phasei,
|
||||
fvm::Su(-(fvOptions(alpha, rho)&rho)/rho, p_rgh).ptr()
|
||||
);
|
||||
}
|
||||
|
||||
if (fluid.transfersMass(phase))
|
||||
// Add option sources
|
||||
if (fvOptions.appliesToField(rho.name()))
|
||||
{
|
||||
tmp<fvScalarMatrix> optEqn = fvOptions(alpha, rho);
|
||||
if (pEqnComps.set(phasei))
|
||||
{
|
||||
pEqnComps[phasei] -= fluid.dmdt(phase)/rho;
|
||||
pEqnComps[phasei] -= (optEqn&rho)/rho;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqnComps.set
|
||||
(
|
||||
phasei,
|
||||
fvm::Su(-fluid.dmdt(phase)/rho, p_rgh)
|
||||
fvm::Su(- (optEqn&rho)/rho, p_rgh).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Add mass transfer
|
||||
if (dmdts.set(phasei))
|
||||
{
|
||||
if (pEqnComps.set(phasei))
|
||||
{
|
||||
pEqnComps[phasei] -= dmdts[phasei]/rho;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqnComps.set
|
||||
(
|
||||
phasei,
|
||||
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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # Run from this directory
|
||||
|
||||
wclean libso twoPhaseSystem
|
||||
wclean libso twoPhaseCompressibleTurbulenceModels
|
||||
wclean
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -4,8 +4,6 @@ cd ${0%/*} || exit 1 # Run from this directory
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
wmake $targetType twoPhaseSystem
|
||||
wmake $targetType twoPhaseCompressibleTurbulenceModels
|
||||
wmake $targetType
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -8,46 +8,38 @@ for (int Ecorr=0; Ecorr<nEnergyCorrectors; Ecorr++)
|
||||
phaseSystem::heatTransferTable&
|
||||
heatTransfer = heatTransferPtr();
|
||||
|
||||
if (!phase1.isothermal())
|
||||
{
|
||||
tmp<fvScalarMatrix> E1Eqn(phase1.heEqn());
|
||||
fvScalarMatrix E1Eqn
|
||||
(
|
||||
phase1.heEqn()
|
||||
==
|
||||
*heatTransfer[phase1.name()]
|
||||
+ alpha1*rho1*(U1&g)
|
||||
+ fvOptions(alpha1, rho1, thermo1.he())
|
||||
);
|
||||
|
||||
if (E1Eqn.valid())
|
||||
{
|
||||
E1Eqn =
|
||||
(
|
||||
E1Eqn
|
||||
==
|
||||
*heatTransfer[phase1.name()]
|
||||
+ alpha1*rho1*(U1&g)
|
||||
+ fvOptions(alpha1, rho1, phase1.thermo().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());
|
||||
fvScalarMatrix E2Eqn
|
||||
(
|
||||
phase2.heEqn()
|
||||
==
|
||||
*heatTransfer[phase2.name()]
|
||||
+ alpha2*rho2*(U2&g)
|
||||
+ fvOptions(alpha2, rho2, phase2.thermoRef().he())
|
||||
);
|
||||
|
||||
if (E2Eqn.valid())
|
||||
{
|
||||
E2Eqn =
|
||||
(
|
||||
E2Eqn
|
||||
==
|
||||
*heatTransfer[phase2.name()]
|
||||
+ alpha2*rho2*(U2&g)
|
||||
+ fvOptions(alpha2, rho2, phase2.thermo().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();
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -5,46 +5,41 @@
|
||||
phaseSystem::massTransferTable&
|
||||
massTransfer(massTransferPtr());
|
||||
|
||||
PtrList<volScalarField>& Y1 = phase1.Y();
|
||||
PtrList<volScalarField>& Y2 = phase2.Y();
|
||||
|
||||
forAll(Y1, i)
|
||||
if (!phase1.pure())
|
||||
{
|
||||
tmp<fvScalarMatrix> Y1iEqn(phase1.YiEqn(Y1[i]));
|
||||
UPtrList<volScalarField>& Y1 = phase1.YActiveRef();
|
||||
|
||||
if (Y1iEqn.valid())
|
||||
forAll(Y1, i)
|
||||
{
|
||||
Y1iEqn =
|
||||
fvScalarMatrix Y1iEqn
|
||||
(
|
||||
Y1iEqn
|
||||
phase1.YiEqn(Y1[i])
|
||||
==
|
||||
*massTransfer[Y1[i].name()]
|
||||
+ fvOptions(alpha1, rho1, 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"));
|
||||
}
|
||||
}
|
||||
|
||||
forAll(Y2, i)
|
||||
if (!phase2.pure())
|
||||
{
|
||||
tmp<fvScalarMatrix> Y2iEqn(phase2.YiEqn(Y2[i]));
|
||||
UPtrList<volScalarField>& Y2 = phase2.YActiveRef();
|
||||
|
||||
if (Y2iEqn.valid())
|
||||
forAll(Y2, i)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,82 +1,54 @@
|
||||
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
|
||||
(
|
||||
IOobject::groupName("rAU", phase1.name()),
|
||||
1.0
|
||||
/(
|
||||
U1Eqn.A()
|
||||
+ byDt(max(phase1.residualAlpha() - alpha1, scalar(0))*rho1)
|
||||
new volScalarField
|
||||
(
|
||||
IOobject::groupName("rAU", phase1.name()),
|
||||
1.0
|
||||
/(
|
||||
U1Eqn.A()
|
||||
+ byDt(max(phase1.residualAlpha() - alpha1, scalar(0))*rho1)
|
||||
)
|
||||
)
|
||||
);
|
||||
volScalarField rAU2
|
||||
rAUs.append
|
||||
(
|
||||
IOobject::groupName("rAU", phase2.name()),
|
||||
1.0
|
||||
/(
|
||||
U2Eqn.A()
|
||||
+ byDt(max(phase2.residualAlpha() - alpha2, scalar(0))*rho2)
|
||||
new volScalarField
|
||||
(
|
||||
IOobject::groupName("rAU", phase2.name()),
|
||||
1.0
|
||||
/(
|
||||
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));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// Add option sources
|
||||
{
|
||||
pEqnComp2 = fvm::Su(-(fvOptions(alpha2, rho2)&rho2)/rho2, p_rgh);
|
||||
if (fvOptions.appliesToField(rho1.name()))
|
||||
{
|
||||
tmp<fvScalarMatrix> optEqn1 = fvOptions(alpha1, rho1);
|
||||
if (pEqnComp1.valid())
|
||||
{
|
||||
pEqnComp1.ref() -= (optEqn1 & rho1)/rho1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
if (pEqnComp1.valid())
|
||||
PtrList<volScalarField> dmdts(fluid.dmdts());
|
||||
if (dmdts.set(0))
|
||||
{
|
||||
pEqnComp1.ref() -= fluid.dmdt()/rho1;
|
||||
if (pEqnComp1.valid())
|
||||
{
|
||||
pEqnComp1.ref() -= dmdts[0]/rho1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqnComp1 = fvm::Su(- dmdts[0]/rho1, p_rgh);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (dmdts.set(1))
|
||||
{
|
||||
pEqnComp1 = fvm::Su(-fluid.dmdt()/rho1, p_rgh);
|
||||
}
|
||||
|
||||
if (pEqnComp2.valid())
|
||||
{
|
||||
pEqnComp2.ref() += fluid.dmdt()/rho2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqnComp2 = fvm::Su(fluid.dmdt()/rho2, p_rgh);
|
||||
if (pEqnComp2.valid())
|
||||
{
|
||||
pEqnComp2.ref() -= dmdts[1]/rho2;
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
tddtPhi1 = fvc::ddt(phi1);
|
||||
tddtPhi2 = fvc::ddt(phi2);
|
||||
@ -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);
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
tmp<surfaceScalarField> tddtPhi1;
|
||||
tmp<surfaceScalarField> tddtPhi2;
|
||||
|
||||
if (faceMomentum)
|
||||
{
|
||||
#include "pUf/DDtU.H"
|
||||
}
|
||||
@ -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
|
||||
(
|
||||
IOobject::groupName("rAUf", phase1.name()),
|
||||
1.0
|
||||
/(
|
||||
byDt(alphaRhof10 + Vmf)
|
||||
+ fvc::interpolate(U1Eqn.A())
|
||||
+ Kdf
|
||||
new surfaceScalarField
|
||||
(
|
||||
IOobject::groupName("rAUf", phase1.name()),
|
||||
1.0
|
||||
/(
|
||||
byDt(alphaRhof10)
|
||||
+ fvc::interpolate(U1Eqn.A())
|
||||
+ AFfs[0]
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
surfaceScalarField rAUf2
|
||||
rAUfs.append
|
||||
(
|
||||
IOobject::groupName("rAUf", phase2.name()),
|
||||
1.0
|
||||
/(
|
||||
byDt(alphaRhof20 + Vmf)
|
||||
+ fvc::interpolate(U2Eqn.A())
|
||||
+ Kdf
|
||||
new surfaceScalarField
|
||||
(
|
||||
IOobject::groupName("rAUf", phase2.name()),
|
||||
1.0
|
||||
/(
|
||||
byDt(alphaRhof20)
|
||||
+ fvc::interpolate(U2Eqn.A())
|
||||
+ 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));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// Add option sources
|
||||
{
|
||||
pEqnComp2 = fvm::Su(-(fvOptions(alpha2, rho2)&rho2)/rho2, p_rgh);
|
||||
if (fvOptions.appliesToField(rho1.name()))
|
||||
{
|
||||
tmp<fvScalarMatrix> optEqn1 = fvOptions(alpha1, rho1);
|
||||
if (pEqnComp1.valid())
|
||||
{
|
||||
pEqnComp1.ref() -= (optEqn1 & rho1)/rho1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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())
|
||||
{
|
||||
if (pEqnComp1.valid())
|
||||
{
|
||||
pEqnComp1.ref() -= fluid.dmdt()/rho1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqnComp1 = fvm::Su(-fluid.dmdt()/rho1, p_rgh);
|
||||
}
|
||||
|
||||
if (pEqnComp2.valid())
|
||||
// Add mass transfer
|
||||
{
|
||||
PtrList<volScalarField> dmdts(fluid.dmdts());
|
||||
if (dmdts.set(0))
|
||||
{
|
||||
pEqnComp2.ref() += fluid.dmdt()/rho2;
|
||||
if (pEqnComp1.valid())
|
||||
{
|
||||
pEqnComp1.ref() -= dmdts[0]/rho1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqnComp1 = fvm::Su(- dmdts[0]/rho1, p_rgh);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (dmdts.set(1))
|
||||
{
|
||||
pEqnComp2 = fvm::Su(fluid.dmdt()/rho2, p_rgh);
|
||||
if (pEqnComp2.valid())
|
||||
{
|
||||
pEqnComp2.ref() -= dmdts[1]/rho2;
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -270,22 +270,19 @@ Foam::BlendedInterfacialModel<modelType>::F() const
|
||||
f2 = blending_.f2(pair1In2_.dispersed(), pair2In1_.dispersed());
|
||||
}
|
||||
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>> x
|
||||
auto x = tmp<GeometricField<Type, fvPatchField, volMesh>>::New
|
||||
(
|
||||
new GeometricField<Type, fvPatchField, volMesh>
|
||||
IOobject
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
modelType::typeName + ":F",
|
||||
pair_.phase1().mesh().time().timeName(),
|
||||
pair_.phase1().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
modelType::typeName + ":F",
|
||||
pair_.phase1().mesh().time().timeName(),
|
||||
pair_.phase1().mesh(),
|
||||
dimensioned<Type>(modelType::dimF, Zero)
|
||||
)
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
pair_.phase1().mesh(),
|
||||
dimensioned<Type>(modelType::dimF, Zero)
|
||||
);
|
||||
|
||||
if (model_.valid())
|
||||
@ -338,24 +335,23 @@ Foam::BlendedInterfacialModel<modelType>::Ff() const
|
||||
);
|
||||
}
|
||||
|
||||
tmp<surfaceScalarField> x
|
||||
auto x = tmp<surfaceScalarField>::New
|
||||
(
|
||||
new surfaceScalarField
|
||||
IOobject
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
modelType::typeName + ":Ff",
|
||||
pair_.phase1().mesh().time().timeName(),
|
||||
pair_.phase1().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
modelType::typeName + ":Ff",
|
||||
pair_.phase1().mesh().time().timeName(),
|
||||
pair_.phase1().mesh(),
|
||||
dimensionedScalar(modelType::dimF*dimArea, Zero)
|
||||
)
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
pair_.phase1().mesh(),
|
||||
dimensionedScalar(modelType::dimF*dimArea, Zero)
|
||||
);
|
||||
|
||||
x.ref().setOriented();
|
||||
|
||||
if (model_.valid())
|
||||
{
|
||||
x.ref() += model_->Ff()*(f1() - f2());
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
(
|
||||
|
||||
@ -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,13 +89,14 @@ 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))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -116,11 +128,11 @@ Foam::Istream& Foam::operator>>(Istream& is, phasePairKey& key)
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -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
Reference in New Issue
Block a user