INT: Org integration of VOF, Euler phase solvers and models.

Integration of VOF MULES new interfaces. Update of VOF solvers and all instances
of MULES in the code.
Integration of reactingTwoPhaseEuler and reactingMultiphaseEuler solvers and sub-models
Updating reactingEuler tutorials accordingly (most of them tested)

New eRefConst thermo used in tutorials. Some modifications at thermo specie level
affecting mostly eThermo. hThermo mostly unaffected

New chtMultiRegionTwoPhaseEulerFoam solver for quenching and tutorial.

Phases sub-models for reactingTwoPhaseEuler and reactingMultiphaseEuler were moved
to src/phaseSystemModels/reactingEulerFoam in order to be used by BC for
chtMultiRegionTwoPhaseEulerFoam.

Update of interCondensatingEvaporatingFoam solver.
This commit is contained in:
Sergio Ferraris
2019-06-07 09:38:35 +01:00
committed by Andrew Heather
parent 0628bfb017
commit 8170f2ad92
914 changed files with 68142 additions and 8336 deletions

View File

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

View File

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

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
chtMultiRegionTwoPhaseEulerFoam
Group
grpHeatTransferSolvers
Description
Transient solver for buoyant, turbulent fluid flow and solid heat
conduction with conjugate heat transfer between solid and fluid regions.
It solves a two-phase Euler approach on the fluid region.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "turbulentFluidThermoModel.H"
#include "twoPhaseSystem.H"
#include "phaseCompressibleTurbulenceModel.H"
#include "pimpleControl.H"
#include "fixedGradientFvPatchFields.H"
#include "regionProperties.H"
#include "solidRegionDiffNo.H"
#include "solidThermo.H"
#include "radiationModel.H"
#include "fvOptions.H"
#include "coordinateSystem.H"
#include "loopControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Transient solver for buoyant, turbulent two phase fluid flow and"
"solid heat conduction with conjugate heat transfer "
"between solid and fluid regions."
);
#define NO_CONTROL
#define CREATE_MESH createMeshesPostProcess.H
#include "postProcess.H"
#include "setRootCase.H"
#include "createTime.H"
#include "createMeshes.H"
#include "createFields.H"
#include "initContinuityErrs.H"
#include "createTimeControls.H"
#include "readSolidTimeControls.H"
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setInitialMultiRegionDeltaT.H"
while (runTime.run())
{
#include "readTimeControls.H"
#include "readSolidTimeControls.H"
#include "readPIMPLEControls.H"
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setMultiRegionDeltaT.H"
++runTime;
Info<< "Time = " << runTime.timeName() << nl << endl;
if (nOuterCorr != 1)
{
forAll(fluidRegions, i)
{
#include "storeOldFluidFields.H"
}
}
// --- PIMPLE loop
for (int oCorr=0; oCorr<nOuterCorr; ++oCorr)
{
const bool finalIter = (oCorr == nOuterCorr-1);
forAll(fluidRegions, i)
{
Info<< "\nSolving for fluid region "
<< fluidRegions[i].name() << endl;
#include "setRegionFluidFields.H"
#include "readFluidMultiRegionPIMPLEControls.H"
#include "solveFluid.H"
}
forAll(solidRegions, i)
{
Info<< "\nSolving for solid region "
<< solidRegions[i].name() << endl;
#include "setRegionSolidFields.H"
#include "readSolidMultiRegionPIMPLEControls.H"
#include "solveSolid.H"
}
// Additional loops for energy solution only
if (!oCorr && nOuterCorr > 1)
{
loopControl looping(runTime, pimple, "energyCoupling");
while (looping.loop())
{
Info<< nl << looping << nl;
forAll(fluidRegions, i)
{
Info<< "\nSolving for fluid region "
<< fluidRegions[i].name() << endl;
#include "setRegionFluidFields.H"
#include "readFluidMultiRegionPIMPLEControls.H"
frozenFlow = true;
#include "solveFluid.H"
}
forAll(solidRegions, i)
{
Info<< "\nSolving for solid region "
<< solidRegions[i].name() << endl;
#include "setRegionSolidFields.H"
#include "readSolidMultiRegionPIMPLEControls.H"
#include "solveSolid.H"
}
}
}
}
runTime.write();
runTime.printExecutionTime(Info);
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,252 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::compressible::
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
Description
Mixed boundary condition for temperature and radiation heat transfer
to be used for in multiregion cases with two phase Euler system
Usage
\table
Property | Description | Required | Default value
Tnbr | name of the field | no | T
qrNbr | name of the radiative flux in the nbr region | no | none
qr | name of the radiative flux in this region | no | none
region | region to which this BC belongs | yes
otherPhase | name of the vapour phase in the fluid region | yes
kappaMethod | inherited from temperatureCoupledBase | inherited |
kappa | inherited from temperatureCoupledBase | inherited |
\endtable
Example of the boundary condition specification on the fluid region:
\verbatim
<patchName>
{
type compressible::turbulentTemperatureTwoPhaseRadCoupledMixed;
Tnbr T;
qrNbr none;
qr none;
kappaMethod phaseSystem;
region fluid;
otherPhase gas;
value uniform 300;
}
\endverbatim
Example of the boundary condition specification on the solid region:
\verbatim
<patchName>
{
type compressible::turbulentTemperatureTwoPhaseRadCoupledMixed;
Tnbr T.liquid;
qrNbr none;
qr none;
kappaMethod solidThermo;
region solid;
otherPhase gas;
value uniform 300;
}
\endverbatim
Needs to be on underlying mapped(Wall)FvPatch.
SourceFiles
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField_H
#define turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField_H
#include "mixedFvPatchFields.H"
#include "scalarList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace compressible
{
/*---------------------------------------------------------------------------*\
Class turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField Declaration
\*---------------------------------------------------------------------------*/
class turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
:
public mixedFvPatchScalarField
{
public:
// Public enumerations
//- Type of supplied Kappa
enum KMethodType
{
mtSolidThermo,
mtLookup,
mtPhaseSystem
};
// Data types
//- Enumeration listing the region
enum regionType
{
solid,
fluid
};
private:
// Private data
//- Heat source type names
static const Enum<regionType> regionTypeNames_;
//- Kappa method types
static const Enum<KMethodType> KMethodTypeNames_;
//- Heat source type
regionType regionType_;
//- How to get K
const KMethodType method_;
//- Name of thermal conductivity field (if looked up from database)
const word kappaName_;
//- name of the other phase (vapor/liquid phase)
word otherPhaseName_;
//- Name of field on the neighbour region
const word TnbrName_;
//- Name of the radiative heat flux in the neighbour region
const word qrNbrName_;
//- Name of the radiative heat flux in local region
const word qrName_;
// Private members
//- Given patch temperature calculate corresponding K field
tmp<scalarField> kappa(const scalarField& Tp) const;
public:
//- Runtime type information
TypeName("compressible::turbulentTemperatureTwoPhaseRadCoupledMixed");
// Constructors
//- Construct from patch and internal field
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// turbulentTemperatureCoupledBaffleMixedFvPatchScalarField onto a
// new patch
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
*this
)
);
}
//- Construct as copy setting internal field reference
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
(
*this,
iF
)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace compressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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