Merge branch 'feature-liquidFilm' into 'develop'

finiteArea: new models and solvers for films

See merge request Development/openfoam!475
This commit is contained in:
Sergio Ferraris
2021-07-16 16:39:48 +00:00
205 changed files with 13189 additions and 1073 deletions

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@ -22,7 +23,9 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/pyrolysisModels/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -49,4 +52,7 @@ EXE_LIBS = \
-llagrangian \
-llagrangianIntermediate \
-llagrangianTurbulence \
-lODE
-lODE \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -8,7 +8,8 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/regionFaModels\lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -23,4 +24,5 @@ EXE_LIBS = \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-lsampling \
-latmosphericModels
-latmosphericModels \
-lregionFaModels

View File

@ -7,6 +7,7 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/regionFaModels\lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -18,4 +19,5 @@ EXE_LIBS = \
-lspecie \
-lturbulenceModels \
-lcompressibleTurbulenceModels \
-latmosphericModels
-latmosphericModels \
-lregionFaModels

View File

@ -6,7 +6,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/regionFaModels\lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -19,4 +20,5 @@ EXE_LIBS = \
-lspecie \
-lturbulenceModels \
-lcompressibleTurbulenceModels \
-latmosphericModels
-latmosphericModels \
-lregionFaModels

View File

@ -6,7 +6,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/regionFaModels\lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -19,4 +20,5 @@ EXE_LIBS = \
-lradiationModels \
-lturbulenceModels \
-lcompressibleTurbulenceModels \
-latmosphericModels
-latmosphericModels \
-lregionFaModels

View File

@ -18,7 +18,8 @@ EXE_INC = \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionFaModels\lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -36,4 +37,5 @@ EXE_LIBS = \
-lturbulenceModels \
-lcompressibleTurbulenceModels \
-lradiationModels \
-lregionModels
-lregionModels \
-lregionFaModels

View File

@ -7,7 +7,8 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels\lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -20,4 +21,5 @@ EXE_LIBS = \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-latmosphericModels
-latmosphericModels \
-lregionFaModels

View File

@ -3,6 +3,7 @@ EXE_INC = \
-I../.. \
-I../../DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -19,7 +20,9 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -39,4 +42,7 @@ EXE_LIBS = \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -2,6 +2,7 @@ EXE_INC = \
-I.. \
-I../DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -18,7 +19,9 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -38,4 +41,7 @@ EXE_LIBS = \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -2,6 +2,7 @@ EXE_INC = \
-I.. \
-I../DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -17,6 +18,8 @@ EXE_INC = \
-I$(LIB_SRC)/TurbulenceModels/phaseIncompressible/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -33,4 +36,7 @@ EXE_LIBS = \
-lDPMTurbulenceModels \
-lregionModels \
-lsurfaceFilmModels \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,6 +1,7 @@
EXE_INC = \
-I./DPMTurbulenceModels \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -14,7 +15,9 @@ EXE_INC = \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -31,4 +34,7 @@ EXE_LIBS = \
-lDPMTurbulenceModels \
-lregionModels \
-lsurfaceFilmModels \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
@ -17,6 +18,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude \
-I$(FOAM_SOLVERS)/combustion/reactingFoam \
@ -44,4 +47,7 @@ EXE_LIBS = \
-lsurfaceFilmModels \
-lODE \
-lcombustionModels \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -13,7 +14,9 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -30,4 +33,7 @@ EXE_LIBS = \
-lincompressibleTurbulenceModels \
-lincompressibleTransportModels \
-lregionModels \
-lsurfaceFilmModels
-lsurfaceFilmModels \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,6 +1,7 @@
EXE_INC = \
-I.. \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -16,7 +17,9 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -36,4 +39,7 @@ EXE_LIBS = \
-lsurfaceFilmModels \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh
-ltopoChangerFvMesh \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -0,0 +1,3 @@
kinematicParcelFoam.C
EXE = $(FOAM_APPBIN)/kinematicParcelFoam

View File

@ -0,0 +1,42 @@
EXE_INC = \
-I$(FOAM_SOLVERS)/lagrangian/reactingParcelFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-lsampling \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lincompressibleTransportModels \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-latmosphericModels \
-lregionModels \
-lsurfaceFilmModels \
-lsurfaceFilmDerivedFvPatchFields \
-llagrangian \
-llagrangianIntermediate \
-llagrangianTurbulence \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -0,0 +1,22 @@
MRF.correctBoundaryVelocity(U);
fvVectorMatrix UEqn
(
fvm::ddt(U) + fvm::div(phi, U)
+ MRF.DDt(U)
+ turbulence->divDevReff(U)
==
parcels.SU(U, true)
+ fvOptions(U)
);
UEqn.relax();
fvOptions.constrain(UEqn);
if (pimple.momentumPredictor())
{
solve(UEqn == -fvc::grad(p));
fvOptions.correct(U);
}

View File

@ -0,0 +1,16 @@
const word kinematicCloudName
(
args.getOrDefault<word>("cloud", "kinematicCloud")
);
Info<< "Constructing kinematicCloud " << kinematicCloudName << endl;
basicKinematicCloud parcels
(
kinematicCloudName,
rhoInf,
U,
muc,
g
);

View File

@ -0,0 +1 @@
regionModels::surfaceFilmModel& surfaceFilm = tsurfaceFilm();

View File

@ -0,0 +1,85 @@
#include "readGravitationalAcceleration.H"
Info<< "Reading field p\n" << endl;
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "\nReading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "createPhi.H"
singlePhaseTransportModel laminarTransport(U, phi);
dimensionedScalar rhoInfValue
(
"rhoInf",
dimDensity,
laminarTransport
);
volScalarField rhoInf
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
rhoInfValue
);
volScalarField muc
(
IOobject
(
"muc",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
rhoInf*laminarTransport.nu()
);
Info<< "Creating turbulence model\n" << endl;
autoPtr<incompressible::turbulenceModel> turbulence
(
incompressible::turbulenceModel::New(U, phi, laminarTransport)
);
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p, pimple.dict(), pRefCell, pRefValue);
mesh.setFluxRequired(p.name());
#include "createMRF.H"
#include "createClouds.H"
#include "createSurfaceFilmModel.H"
#include "createFvOptions.H"

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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
kinematicParcelFoam
Group
grpLagrangianSolvers
Description
Transient solver for incompressible, turbulent flow with kinematic,
particle cloud, and surface film modelling.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "singlePhaseTransportModel.H"
#include "turbulentTransportModel.H"
#include "surfaceFilmModel.H"
#include "basicKinematicCloud.H"
#include "fvOptions.H"
#include "pimpleControl.H"
#include "CorrectPhi.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Transient solver for incompressible, turbulent flow"
" with kinematic particle clouds"
" and surface film modelling."
);
#define CREATE_MESH createMeshesPostProcess.H
#include "postProcess.H"
#include "addCheckCaseOptions.H"
#include "setRootCaseLists.H"
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "initContinuityErrs.H"
#include "createDyMControls.H"
#include "createFields.H"
#include "createFieldRefs.H"
#include "createRegionControls.H"
#include "createUfIfPresent.H"
turbulence->validate();
#include "CourantNo.H"
#include "setInitialDeltaT.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readDyMControls.H"
#include "CourantNo.H"
#include "setMultiRegionDeltaT.H"
++runTime;
Info<< "Time = " << runTime.timeName() << nl << endl;
// Store the particle positions
parcels.storeGlobalPositions();
// Do any mesh changes
mesh.update();
if (solvePrimaryRegion && mesh.changing())
{
MRF.update();
if (correctPhi)
{
// Calculate absolute flux
// from the mapped surface velocity
phi = mesh.Sf() & Uf();
#include "../../incompressible/pimpleFoam/correctPhi.H"
// Make the fluxes relative to the mesh-motion
fvc::makeRelative(phi, U);
}
if (checkMeshCourantNo)
{
#include "meshCourantNo.H"
}
}
parcels.evolve();
surfaceFilm.evolve();
if (solvePrimaryRegion)
{
// --- PIMPLE loop
while (pimple.loop())
{
#include "UEqn.H"
// --- Pressure corrector loop
while (pimple.correct())
{
#include "pEqn.H"
}
if (pimple.turbCorr())
{
laminarTransport.correct();
turbulence->correct();
}
}
}
runTime.write();
runTime.printExecutionTime(Info);
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,62 @@
volScalarField rAU(1.0/UEqn.A());
volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p));
surfaceScalarField phiHbyA("phiHbyA", fvc::flux(HbyA));
if (pimple.ddtCorr())
{
phiHbyA += MRF.zeroFilter(fvc::interpolate(rAU)*fvc::ddtCorr(U, phi, Uf));
}
else
{
phiHbyA += MRF.zeroFilter(fvc::interpolate(rAU));
}
MRF.makeRelative(phiHbyA);
if (p.needReference())
{
fvc::makeRelative(phiHbyA, U);
adjustPhi(phiHbyA, U, p);
fvc::makeAbsolute(phiHbyA, U);
}
// Update the pressure BCs to ensure flux consistency
constrainPressure(p, U, phiHbyA, rAU, MRF);
// Non-orthogonal pressure corrector loop
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix pEqn
(
fvm::laplacian(rAU, p)
==
fvc::div(phiHbyA)
);
pEqn.setReference(pRefCell, pRefValue);
pEqn.solve(mesh.solver(p.select(pimple.finalInnerIter())));
if (pimple.finalNonOrthogonalIter())
{
phi = phiHbyA - pEqn.flux();
}
}
#include "continuityErrs.H"
p.relax();
U = HbyA - rAU*fvc::grad(p);
U.correctBoundaryConditions();
fvOptions.correct(U);
// Correct rhoUf if the mesh is moving
fvc::correctUf(Uf, U, phi);
// Make the fluxes relative to the mesh motion
fvc::makeRelative(phi, U);

View File

@ -1,6 +1,7 @@
EXE_INC = \
-I../reactingParcelFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
@ -18,6 +19,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
@ -48,4 +51,7 @@ EXE_LIBS = \
-llagrangianIntermediate \
-llagrangianTurbulence \
-lODE \
-lcombustionModels
-lcombustionModels \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -11,7 +11,11 @@ basicSpecieMixture& composition = thermo.composition();
PtrList<volScalarField>& Y = composition.Y();
const word inertSpecie(thermo.get<word>("inertSpecie"));
if (!composition.species().found(inertSpecie))
if
(
!composition.species().found(inertSpecie)
&& composition.species().size() > 0
)
{
FatalIOErrorIn(args.executable().c_str(), thermo)
<< "Inert specie " << inertSpecie << " not found in available species "

View File

@ -1,6 +1,7 @@
EXE_INC = \
-I.. \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
@ -18,6 +19,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
@ -47,4 +50,7 @@ EXE_LIBS = \
-llagrangianIntermediate \
-llagrangianTurbulence \
-lODE \
-lcombustionModels
-lcombustionModels \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@ -19,6 +20,8 @@ EXE_INC = \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude \
-I$(FOAM_SOLVERS)/combustion/reactingFoam
@ -43,4 +46,7 @@ EXE_LIBS = \
-lregionModels \
-lsurfaceFilmModels \
-lcombustionModels \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@ -20,7 +21,9 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -43,4 +46,7 @@ EXE_LIBS = \
-lsurfaceFilmModels \
-lcombustionModels \
-lsampling \
-lcoalCombustion
-lcoalCombustion \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,6 +1,7 @@
EXE_INC = \
-I../reactingParcelFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@ -20,6 +21,8 @@ EXE_INC = \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude
EXE_LIBS = \
@ -44,4 +47,7 @@ EXE_LIBS = \
-lregionModels \
-lsurfaceFilmModels \
-lcombustionModels \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -3,6 +3,7 @@ EXE_INC = \
-I.. \
-I../../reactingParcelFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@ -23,7 +24,9 @@ EXE_INC = \
-I$(LIB_SRC)/engine/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude
-I$(LIB_SRC)/combustionModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -48,4 +51,7 @@ EXE_LIBS = \
-lengine \
-lregionModels \
-lsurfaceFilmModels \
-lcombustionModels
-lcombustionModels \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,6 +1,7 @@
EXE_INC = \
-I$(FOAM_SOLVERS)/lagrangian/reactingParcelFoam/simpleReactingParcelFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@ -20,7 +21,9 @@ EXE_INC = \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude
-I$(LIB_SRC)/combustionModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -44,4 +47,7 @@ EXE_LIBS = \
-lregionModels \
-lsurfaceFilmModels \
-lcombustionModels \
-lsampling
-lsampling \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -3,6 +3,7 @@ EXE_INC = \
-I../../reactingParcelFoam \
-I../../../compressible/rhoPimpleFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@ -25,7 +26,9 @@ EXE_INC = \
-I$(LIB_SRC)/combustionModels/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -51,4 +54,7 @@ EXE_LIBS = \
-lcombustionModels \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-ldynamicMesh
-ldynamicMesh \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -11,7 +12,9 @@ EXE_INC = \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude \
EXE_LIBS = \
-lfiniteVolume \
@ -27,4 +30,7 @@ EXE_LIBS = \
-lturbulenceModels \
-lcompressibleTurbulenceModels \
-lregionModels \
-lsurfaceFilmModels
-lsurfaceFilmModels \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -1,6 +1,7 @@
EXE_INC = \
-I.. \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@ -14,7 +15,9 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -33,4 +36,7 @@ EXE_LIBS = \
-lsurfaceFilmModels \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh
-ltopoChangerFvMesh \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -2,6 +2,7 @@ EXE_INC = \
-I../VoF \
-I$(FOAM_SOLVERS)/multiphase/interFoam \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
@ -20,7 +21,9 @@ EXE_INC = \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/phaseCompressible/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
EXE_LIBS = \
-lfiniteVolume \
@ -38,3 +41,4 @@ EXE_LIBS = \
-lregionModels \
-lsurfaceFilmModels \
-lcompressibleTwoPhaseMixtureTurbulenceModels

View File

@ -83,14 +83,18 @@ wmake $targetType ODE
thermophysicalModels/Allwmake $targetType $*
TurbulenceModels/Allwmake $targetType $*
wmake $targetType combustionModels
wmakeLnInclude -u regionFaModels
wmakeLnInclude -u faOptions
regionModels/Allwmake $targetType $*
lagrangian/Allwmake $targetType $*
wmake $targetType fvOptions
wmake $targetType faOptions
wmake $targetType fvMotionSolver
wmake $targetType regionFaModels
lagrangian/Allwmake $targetType $*
wmake $targetType overset
# snappyHexMesh uses overset voxelMesh

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "limitVelocity.H"
#include "areaFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace fa
{
defineTypeNameAndDebug(limitVelocity, 0);
addToRunTimeSelectionTable
(
option,
limitVelocity,
dictionary
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fa::limitVelocity::limitVelocity
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvPatch& patch
)
:
faceSetOption(name, modelType, dict, patch),
UName_(coeffs_.getOrDefault<word>("U", "U")),
max_(coeffs_.get<scalar>("max"))
{
fieldNames_.setSize(1, UName_);
applied_.setSize(1, false);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::fa::limitVelocity::read(const dictionary& dict)
{
if (faceSetOption::read(dict))
{
coeffs_.readEntry("max", max_);
return true;
}
return false;
}
void Foam::fa::limitVelocity::correct(areaVectorField& U)
{
const scalar maxSqrU = sqr(max_);
vectorField& Uif = U.primitiveFieldRef();
for (const label facei : faces_)
{
const scalar magSqrUi = magSqr(Uif[facei]);
if (magSqrUi > maxSqrU)
{
Uif[facei] *= sqrt(maxSqrU/max(magSqrUi, SMALL));
}
}
// handle boundaries in the case of 'all'
if (selectionMode_ == smAll)
{
areaVectorField::Boundary& Ubf = U.boundaryFieldRef();
forAll(Ubf, patchi)
{
faPatchVectorField& Up = Ubf[patchi];
if (!Up.fixesValue())
{
forAll(Up, facei)
{
const scalar magSqrUi = magSqr(Up[facei]);
if (magSqrUi > maxSqrU)
{
Up[facei] *= sqrt(maxSqrU/max(magSqrUi, SMALL));
}
}
}
}
}
// We've changed internal values so give boundary conditions opportunity
// to correct.
U.correctBoundaryConditions();
}
// ************************************************************************* //

View File

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::fa::limitVelocity
Description
Limits the maximum velocity magnitude to the specified \c max value.
Usage
Minimal example by using \c constant/faOptions:
\verbatim
<faOption>
{
// Mandatory entries
type limitVelocity;
active yes;
selectionMode all;
max <maxValue>;
// Optional entries
U <UName>;
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Reqd | Deflt
type | Type name: limitVelocity | word | yes | -
max | Maximum velocity limit [m/s] | scalar | yes | -
U | Name of operand velocity field | word | no | U
\endtable
The inherited entries are elaborated in:
- \link fvOption.H \endlink
- \link faceSetOption.H \endlink
SourceFiles
limitVelocity.C
\*---------------------------------------------------------------------------*/
#ifndef limitVelocity_H
#define limitVelocity_H
#include "faceSetOption.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fa
{
/*---------------------------------------------------------------------------*\
Class limitVelocity Declaration
\*---------------------------------------------------------------------------*/
class limitVelocity
:
public faceSetOption
{
protected:
// Protected Data
//- Name of operand velocity field
word UName_;
//- Maximum velocity magnitude
scalar max_;
private:
// Private Member Functions
//- No copy construct
limitVelocity(const limitVelocity&) = delete;
//- No copy assignment
void operator=(const limitVelocity&) = delete;
public:
//- Runtime type information
TypeName("limitVelocity");
// Constructors
//- Construct from components
limitVelocity
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvPatch& patch
);
//- Destructor
virtual ~limitVelocity() = default;
// Member Functions
//- Read dictionary
virtual bool read(const dictionary& dict);
//- Correct the velocity field
virtual void correct(areaVectorField& U);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -65,6 +65,36 @@ Foam::tmp<Foam::Field<Type>> Foam::volSurfaceMapping::mapToSurface
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::volSurfaceMapping::mapToSurface
(
const Field<Type>& f
) const
{
const labelList& faceLabels = mesh_.faceLabels();
auto tresult = tmp<Field<Type>>::New(faceLabels.size(), Zero);
auto& result = tresult.ref();
const polyMesh& pMesh = mesh_();
const polyBoundaryMesh& bm = pMesh.boundaryMesh();
label patchID, faceID;
forAll(faceLabels, i)
{
if (faceLabels[i] < pMesh.nFaces())
{
patchID = bm.whichPatch(faceLabels[i]);
faceID = bm[patchID].whichFace(faceLabels[i]);
result[i] = f[faceID];
}
}
return tresult;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::volSurfaceMapping::mapInternalToSurface
(
@ -151,6 +181,19 @@ void Foam::volSurfaceMapping::mapToField
const GeometricField<Type, faPatchField, areaMesh>& af,
Field<Type>& f
) const
{
const Field<Type>& afi = af.internalField();
mapToField(afi, f);
}
template<class Type>
void Foam::volSurfaceMapping::mapToField
(
const Field<Type>& af,
Field<Type>& f
) const
{
const labelList& faceLabels = mesh_.faceLabels();
@ -158,15 +201,13 @@ void Foam::volSurfaceMapping::mapToField
const polyBoundaryMesh& bm = pMesh.boundaryMesh();
label patchID, faceID;
const Field<Type>& afi = af.internalField();
forAll(faceLabels, i)
{
if (faceLabels[i] < pMesh.nFaces())
{
patchID = bm.whichPatch(faceLabels[i]);
faceID = bm[patchID].whichFace(faceLabels[i]);
f[faceID] = afi[i];
f[faceID] = af[i];
}
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,6 +42,7 @@ SourceFiles
#define volSurfaceMapping_H
#include "faMesh.H"
#include "volMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -85,7 +86,7 @@ public:
// Member Functions
//- Map droplet cloud sources to surface
//- Map Boundary field to surface
template<class Type>
tmp<Field<Type>> mapToSurface
(
@ -93,6 +94,9 @@ public:
GeometricField<Type, fvPatchField, volMesh>::Boundary& df
) const;
//- Map vol Field to surface Field
template<class Type>
tmp<Field<Type>> mapToSurface(const Field<Type>& f) const;
//- Map patch internal field to surface
template<class Type>
@ -118,14 +122,23 @@ public:
typename GeometricField<Type, fvPatchField, volMesh>::Boundary& bf
) const;
//- Map surface field to field assumes Field
//- faces in the same order as Boundary
//- Map surface field to field
// Assumes Field faces in the same order as Boundary
template<class Type>
void mapToField
(
const GeometricField<Type, faPatchField, areaMesh>& af,
Field<Type>& f
) const;
//- Map surface field to volume field
// Assumes Field faces in the same order as Boundary
template<class Type>
void mapToField
(
const Field<Type>& af,
Field<Type>& f
) const;
};

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -92,6 +93,38 @@ movingWallVelocityFvPatchVectorField
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::vectorField>
Foam::movingWallVelocityFvPatchVectorField::Uwall() const
{
const fvMesh& mesh = internalField().mesh();
const fvPatch& p = patch();
const polyPatch& pp = p.patch();
const pointField& oldPoints = mesh.oldPoints();
vectorField oldFc(pp.size());
forAll(oldFc, i)
{
oldFc[i] = pp[i].centre(oldPoints);
}
const scalar deltaT = mesh.time().deltaTValue();
const vectorField Up((pp.faceCentres() - oldFc)/deltaT);
const auto& U = static_cast<const volVectorField&>(internalField());
tmp<scalarField> phip =
p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U));
const vectorField n(p.nf());
const scalarField& magSf = p.magSf();
tmp<scalarField> Un = phip/(magSf + VSMALL);
return (Up + n*(Un - (n & Up)));
}
void Foam::movingWallVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
@ -103,35 +136,7 @@ void Foam::movingWallVelocityFvPatchVectorField::updateCoeffs()
if (mesh.moving())
{
const fvPatch& p = patch();
const polyPatch& pp = p.patch();
const pointField& oldPoints = mesh.oldPoints();
vectorField oldFc(pp.size());
forAll(oldFc, i)
{
oldFc[i] = pp[i].centre(oldPoints);
}
const scalar deltaT = mesh.time().deltaTValue();
const vectorField Up((pp.faceCentres() - oldFc)/deltaT);
const volVectorField& U =
static_cast<const volVectorField&>(internalField());
scalarField phip
(
p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U))
);
const vectorField n(p.nf());
const scalarField& magSf = p.magSf();
tmp<scalarField> Un = phip/(magSf + VSMALL);
vectorField::operator=(Up + n*(Un - (n & Up)));
vectorField::operator=(Uwall()());
}
fixedValueFvPatchVectorField::updateCoeffs();

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015 OpenCFD Ltd.
Copyright (C) 2015-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -71,7 +71,6 @@ class movingWallVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField
{
public:
//- Runtime type information
@ -140,7 +139,10 @@ public:
}
// Member functions
// Member Functions
//- Return wall velocity field
tmp<vectorField> Uwall() const;
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
@ -9,7 +10,9 @@ EXE_INC = \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
-I$(LIB_SRC)/lagrangian/DSMC/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
LIB_LIBS = \
-lfiniteVolume \
@ -21,4 +24,8 @@ LIB_LIBS = \
-llagrangianIntermediate \
-llagrangianTurbulence \
-lregionModels \
-lsurfaceFilmModels
-lsurfaceFilmModels \
-lregionFaModels \
-lfiniteArea \
-lfaOptions

View File

@ -18,7 +18,10 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
LIB_LIBS = \
-lfiniteVolume \
@ -41,4 +44,6 @@ LIB_LIBS = \
-lregionModels \
-lsurfaceFilmModels \
-ldynamicMesh \
-ldynamicFvMesh
-ldynamicFvMesh \
-lregionFaModels \
-lfiniteArea

View File

@ -16,7 +16,10 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
LIB_LIBS = \
-lfiniteVolume \
@ -36,4 +39,6 @@ LIB_LIBS = \
-lregionModels \
-lsurfaceFilmModels \
-ldynamicMesh \
-ldynamicFvMesh
-ldynamicFvMesh \
-lregionFaModels \
-lfiniteArea

View File

@ -534,8 +534,12 @@ public:
inline const volScalarField::Internal&
UCoeff() const;
//- Return tmp momentum source term
inline tmp<fvVectorMatrix> SU(volVectorField& U) const;
//- Return tmp momentum source term (compressible)
inline tmp<fvVectorMatrix> SU
(
volVectorField& U,
bool incompressible = false
) const;
// Check

View File

@ -468,7 +468,8 @@ Foam::KinematicCloud<CloudType>::UCoeff() const
template<class CloudType>
inline Foam::tmp<Foam::fvVectorMatrix>
Foam::KinematicCloud<CloudType>::SU(volVectorField& U) const
Foam::KinematicCloud<CloudType>::SU(volVectorField& U, bool incompressible)
const
{
if (debug)
{
@ -478,18 +479,29 @@ Foam::KinematicCloud<CloudType>::SU(volVectorField& U) const
<< max(UCoeff()).value() << endl;
}
dimensionSet dim(dimForce);
if (incompressible)
{
dim.reset(dimForce/dimDensity);
}
if (solution_.coupled())
{
if (solution_.semiImplicit("U"))
{
const volScalarField::Internal
volScalarField::Internal
Vdt(mesh_.V()*this->db().time().deltaT());
if (incompressible)
{
Vdt.dimensions() *= dimDensity;
}
return UTrans()/Vdt - fvm::Sp(UCoeff()/Vdt, U) + UCoeff()/Vdt*U;
}
else
{
tmp<fvVectorMatrix> tfvm(new fvVectorMatrix(U, dimForce));
tmp<fvVectorMatrix> tfvm(new fvVectorMatrix(U, dim));
fvVectorMatrix& fvm = tfvm.ref();
fvm.source() = -UTrans()/(this->db().time().deltaT());
@ -498,7 +510,7 @@ Foam::KinematicCloud<CloudType>::SU(volVectorField& U) const
}
}
return tmp<fvVectorMatrix>::New(U, dimForce);
return tmp<fvVectorMatrix>::New(U, dim);
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,14 +32,15 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "NoSurfaceFilm.H"
#include "KinematicSurfaceFilm.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define makeParcelSurfaceFilmModels(CloudType) \
\
makeSurfaceFilmModel(CloudType); \
makeSurfaceFilmModelType(NoSurfaceFilm, CloudType);
makeSurfaceFilmModelType(NoSurfaceFilm, CloudType); \
makeSurfaceFilmModelType(KinematicSurfaceFilm, CloudType);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,6 +33,7 @@ License
#include "NoSurfaceFilm.H"
#include "ThermoSurfaceFilm.H"
#include "KinematicSurfaceFilm.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -39,7 +41,8 @@ License
\
makeSurfaceFilmModel(CloudType); \
makeSurfaceFilmModelType(NoSurfaceFilm, CloudType); \
makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType);
makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType); \
makeSurfaceFilmModelType(KinematicSurfaceFilm, CloudType);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,6 +33,7 @@ License
#include "NoSurfaceFilm.H"
#include "ThermoSurfaceFilm.H"
#include "KinematicSurfaceFilm.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -40,7 +42,8 @@ License
makeSurfaceFilmModel(CloudType); \
\
makeSurfaceFilmModelType(NoSurfaceFilm, CloudType); \
makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType);
makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType); \
makeSurfaceFilmModelType(KinematicSurfaceFilm, CloudType);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -85,11 +86,11 @@ void Foam::phaseProperties::reorder(const wordList& specieNames)
if (!found)
{
FatalErrorInFunction
WarningInFunction
<< "Could not find specie " << names0[i]
<< " in list " << names_
<< " for phase " << phaseTypeNames[phase_]
<< exit(FatalError);
<< nl;
}
}
}
@ -114,11 +115,11 @@ void Foam::phaseProperties::setCarrierIds
}
if (carrierIds_[i] == -1)
{
FatalErrorInFunction
WarningInFunction
<< "Could not find carrier specie " << names_[i]
<< " in species list" << nl
<< "Available species are: " << nl << carrierNames << nl
<< exit(FatalError);
<< nl;
}
}
}

View File

@ -5,8 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.

View File

@ -0,0 +1,823 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "KinematicSurfaceFilm.H"
#include "surfaceFilmRegionModel.H"
#include "liquidFilmModel.H"
#include "addToRunTimeSelectionTable.H"
#include "unitConversion.H"
#include "Pstream.H"
using namespace Foam::constant::mathematical;
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class CloudType>
Foam::wordList Foam::KinematicSurfaceFilm<CloudType>::interactionTypeNames_
{
"absorb", "bounce", "splashBai"
};
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class CloudType>
typename Foam::KinematicSurfaceFilm<CloudType>::interactionType
Foam::KinematicSurfaceFilm<CloudType>::interactionTypeEnum(const word& it) const
{
forAll(interactionTypeNames_, i)
{
if (interactionTypeNames_[i] == it)
{
return interactionType(i);
}
}
FatalErrorInFunction
<< "Unknown interaction type " << it
<< ". Valid interaction types include: " << interactionTypeNames_
<< abort(FatalError);
return interactionType(0);
}
template<class CloudType>
Foam::word Foam::KinematicSurfaceFilm<CloudType>::interactionTypeStr
(
const interactionType& it
) const
{
if (it >= interactionTypeNames_.size())
{
FatalErrorInFunction
<< "Unknown interaction type enumeration" << abort(FatalError);
}
return interactionTypeNames_[it];
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class CloudType>
Foam::vector Foam::KinematicSurfaceFilm<CloudType>::tangentVector
(
const vector& v
) const
{
vector tangent(Zero);
scalar magTangent = 0.0;
while (magTangent < SMALL)
{
const vector vTest(rndGen_.sample01<vector>());
tangent = vTest - (vTest & v)*v;
magTangent = mag(tangent);
}
return tangent/magTangent;
}
template<class CloudType>
Foam::vector Foam::KinematicSurfaceFilm<CloudType>::splashDirection
(
const vector& tanVec1,
const vector& tanVec2,
const vector& nf
) const
{
// Azimuthal angle [rad]
const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
// Ejection angle [rad]
const scalar thetaSi = degToRad(rndGen_.sample01<scalar>()*(50 - 5) + 5);
// Direction vector of new parcel
const scalar alpha = sin(thetaSi);
const scalar dcorr = cos(thetaSi);
const vector normal(alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi)));
vector dirVec(dcorr*nf);
dirVec += normal;
return dirVec/mag(dirVec);
}
template<class CloudType>
void Foam::KinematicSurfaceFilm<CloudType>::initFilmModels()
{
const fvMesh& mesh = this->owner().mesh();
// set up filmModel pointer
if (!filmModel_)
{
filmModel_ =
const_cast<regionFilm*>
(
mesh.time().objectRegistry::template findObject
<
regionFilm
>
(
"surfaceFilmProperties"
)
);
}
if (areaFilms_.size() == 0)
{
// set up areaFilms
const wordList names =
mesh.time().objectRegistry::template
sortedNames<regionModels::regionFaModel>();
forAll(names, i)
{
const regionModels::regionFaModel* regionFa =
mesh.time().objectRegistry::template findObject
<
regionModels::regionFaModel
>(names[i]);
if (regionFa && isA<areaFilm>(*regionFa))
{
areaFilm& film =
const_cast<areaFilm&>(refCast<const areaFilm>(*regionFa));
areaFilms_.append(&film);
}
}
}
}
template<class CloudType>
void Foam::KinematicSurfaceFilm<CloudType>::init(bool binitThermo)
{
if (binitThermo)
{
this->coeffDict().readEntry("pRef", pRef_);
this->coeffDict().readEntry("TRef", TRef_);
thermo_ = new liquidMixtureProperties(this->coeffDict().subDict("thermo"));
}
}
template<class CloudType>
template<class filmType>
void Foam::KinematicSurfaceFilm<CloudType>::absorbInteraction
(
filmType& film,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mass,
bool& keepParticle
)
{
if (debug)
{
Info<< "Parcel " << p.origId() << " absorbInteraction" << endl;
}
// Patch face normal
const vector& nf = pp.faceNormals()[facei];
// Patch velocity
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
// Relative parcel velocity
const vector Urel(p.U() - Up);
// Parcel normal velocity
const vector Un(nf*(Urel & nf));
// Parcel tangential velocity
const vector Ut(Urel - Un);
film.addSources
(
pp.index(),
facei,
mass, // mass
mass*Ut, // tangential momentum
mass*mag(Un), // impingement pressure
0 // energy
);
this->nParcelsTransferred()++;
this->totalMassTransferred() += mass;
keepParticle = false;
}
template<class CloudType>
void Foam::KinematicSurfaceFilm<CloudType>::bounceInteraction
(
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
) const
{
if (debug)
{
Info<< "Parcel " << p.origId() << " bounceInteraction" << endl;
}
// Patch face normal
const vector& nf = pp.faceNormals()[facei];
// Patch velocity
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
// Relative parcel velocity
const vector Urel(p.U() - Up);
// Flip parcel normal velocity component
p.U() -= 2.0*nf*(Urel & nf);
keepParticle = true;
}
template<class CloudType>
template<class filmType>
void Foam::KinematicSurfaceFilm<CloudType>::drySplashInteraction
(
filmType& filmModel,
const scalar sigma,
const scalar mu,
const parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
)
{
if (debug)
{
Info<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
}
// Patch face velocity and normal
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
const vector& nf = pp.faceNormals()[facei];
// Local pressure
//const scalar pc = thermo_.thermo().p()[p.cell()];
// Retrieve parcel properties
const scalar m = p.mass()*p.nParticle();
const scalar rho = p.rho();
const scalar d = p.d();
const vector Urel(p.U() - Up);
const vector Un(nf*(Urel & nf));
// Laplace number
const scalar La = rho*sigma*d/sqr(mu);
// Weber number
const scalar We = rho*magSqr(Un)*d/sigma;
// Critical Weber number
const scalar Wec = Adry_*pow(La, -0.183);
if (We < Wec) // Adhesion - assume absorb
{
absorbInteraction<filmType>
(filmModel, p, pp, facei, m, keepParticle);
}
else // Splash
{
// Ratio of incident mass to splashing mass
const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
splashInteraction<filmType>
(filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
}
}
template<class CloudType>
template<class filmType>
void Foam::KinematicSurfaceFilm<CloudType>::wetSplashInteraction
(
filmType& filmModel,
const scalar sigma,
const scalar mu,
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
)
{
if (debug)
{
Info<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
}
// Patch face velocity and normal
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
const vector& nf = pp.faceNormals()[facei];
// Retrieve parcel properties
const scalar m = p.mass()*p.nParticle();
const scalar rho = p.rho();
const scalar d = p.d();
vector& U = p.U();
const vector Urel(p.U() - Up);
const vector Un(nf*(Urel & nf));
const vector Ut(Urel - Un);
// Laplace number
const scalar La = rho*sigma*d/sqr(mu);
// Weber number
const scalar We = rho*magSqr(Un)*d/sigma;
// Critical Weber number
const scalar Wec = Awet_*pow(La, -0.183);
if (We < 2) // Adhesion - assume absorb
{
absorbInteraction<filmType>
(filmModel, p, pp, facei, m, keepParticle);
}
else if ((We >= 2) && (We < 20)) // Bounce
{
// Incident angle of impingement
const scalar theta = piByTwo - acos(U/mag(U) & nf);
// Restitution coefficient
const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
// Update parcel velocity
U = -epsilon*(Un) + 5.0/7.0*(Ut);
keepParticle = true;
return;
}
else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
{
absorbInteraction<filmType>
(filmModel, p, pp, facei, m, keepParticle);
}
else // Splash
{
// Ratio of incident mass to splashing mass
// splash mass can be > incident mass due to film entrainment
const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
splashInteraction<filmType>
(filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
}
}
template<class CloudType>
template<class filmType>
void Foam::KinematicSurfaceFilm<CloudType>::splashInteraction
(
filmType& filmModel,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mRatio,
const scalar We,
const scalar Wec,
const scalar sigma,
bool& keepParticle
)
{
// Patch face velocity and normal
const fvMesh& mesh = this->owner().mesh();
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
const vector& nf = pp.faceNormals()[facei];
// Determine direction vectors tangential to patch normal
const vector tanVec1(tangentVector(nf));
const vector tanVec2(nf^tanVec1);
// Retrieve parcel properties
const scalar np = p.nParticle();
const scalar m = p.mass()*np;
const scalar d = p.d();
const vector Urel(p.U() - Up);
const vector Un(nf*(Urel & nf));
const vector Ut(Urel - Un);
const vector& posC = mesh.C()[p.cell()];
const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
// Total mass of (all) splashed parcels
const scalar mSplash = m*mRatio;
// Number of splashed particles per incoming particle
const scalar Ns = 5.0*(We/Wec - 1.0);
// Average diameter of splashed particles
const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
// Cumulative diameter splash distribution
const scalar dMax = 0.9*cbrt(mRatio)*d;
const scalar dMin = 0.1*dMax;
const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
// Surface energy of secondary parcels [J]
scalar ESigmaSec = 0;
// Sample splash distribution to determine secondary parcel diameters
scalarList dNew(parcelsPerSplash_);
scalarList npNew(parcelsPerSplash_);
forAll(dNew, i)
{
const scalar y = rndGen_.sample01<scalar>();
dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
}
// Incident kinetic energy [J]
const scalar EKIn = 0.5*m*magSqr(Un);
// Incident surface energy [J]
const scalar ESigmaIn = np*sigma*p.areaS(d);
// Dissipative energy
const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
// Total energy [J]
const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
// Switch to absorb if insufficient energy for splash
if (EKs <= 0)
{
absorbInteraction<filmType>
(filmModel, p, pp, facei, m, keepParticle);
return;
}
// Helper variables to calculate magUns0
const scalar logD = log(d);
const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
scalar coeff1 = 0.0;
forAll(dNew, i)
{
coeff1 += sqr(log(dNew[i]) - logD);
}
// Magnitude of the normal velocity of the first splashed parcel
const scalar magUns0 =
sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
// Set splashed parcel properties
forAll(dNew, i)
{
const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
// Create a new parcel by copying source parcel
parcelType* pPtr = new parcelType(p);
pPtr->origId() = pPtr->getNewParticleID();
pPtr->origProc() = Pstream::myProcNo();
if (splashParcelType_ >= 0)
{
pPtr->typeId() = splashParcelType_;
}
// Perturb new parcels towards the owner cell centre
pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
pPtr->nParticle() = npNew[i];
pPtr->d() = dNew[i];
pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
// Apply correction to velocity for 2-D cases
meshTools::constrainDirection(mesh, mesh.solutionD(), pPtr->U());
// Add the new parcel
this->owner().addParticle(pPtr);
nParcelsSplashed_++;
}
// Transfer remaining part of parcel to film 0 - splashMass can be -ve
// if entraining from the film
const scalar mDash = m - mSplash;
absorbInteraction<filmType>
(filmModel, p, pp, facei, mDash, keepParticle);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class CloudType>
Foam::KinematicSurfaceFilm<CloudType>::KinematicSurfaceFilm
(
const dictionary& dict,
CloudType& owner,
const word& type,
bool initThermo
)
:
SurfaceFilmModel<CloudType>(dict, owner, type),
rndGen_(owner.rndGen()),
thermo_(nullptr),
filmModel_(nullptr),
areaFilms_(0),
interactionType_
(
interactionTypeEnum(this->coeffDict().getWord("interactionType"))
),
deltaWet_(0.0),
splashParcelType_(0),
parcelsPerSplash_(0),
Adry_(0.0),
Awet_(0.0),
Cf_(0.0),
nParcelsSplashed_(0)
{
Info<< " Applying " << interactionTypeStr(interactionType_)
<< " interaction model" << endl;
if (interactionType_ == itSplashBai)
{
this->coeffDict().readEntry("deltaWet", deltaWet_);
splashParcelType_ =
this->coeffDict().getOrDefault("splashParcelType", -1);
parcelsPerSplash_ =
this->coeffDict().getOrDefault("parcelsPerSplash", 2);
this->coeffDict().readEntry("Adry", Adry_);
this->coeffDict().readEntry("Awet", Awet_);
this->coeffDict().readEntry("Cf", Cf_);
init(initThermo);
}
}
template<class CloudType>
Foam::KinematicSurfaceFilm<CloudType>::KinematicSurfaceFilm
(
const KinematicSurfaceFilm<CloudType>& sfm,
bool initThermo
)
:
SurfaceFilmModel<CloudType>(sfm),
rndGen_(sfm.rndGen_),
thermo_(nullptr),
filmModel_(nullptr),
areaFilms_(0),
interactionType_(sfm.interactionType_),
deltaWet_(sfm.deltaWet_),
splashParcelType_(sfm.splashParcelType_),
parcelsPerSplash_(sfm.parcelsPerSplash_),
Adry_(sfm.Adry_),
Awet_(sfm.Awet_),
Cf_(sfm.Cf_),
nParcelsSplashed_(sfm.nParcelsSplashed_)
{
if (interactionType_ == itSplashBai)
{
init(initThermo);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class CloudType>
bool Foam::KinematicSurfaceFilm<CloudType>::transferParcel
(
parcelType& p,
const polyPatch& pp,
bool& keepParticle
)
{
const label patchi = pp.index();
bool bInteraction(false);
initFilmModels();
// Check the singleLayer film models
if (filmModel_)
{
if (filmModel_->isRegionPatch(patchi))
{
const label facei = pp.whichFace(p.face());
switch (interactionType_)
{
case itBounce:
{
bounceInteraction(p, pp, facei, keepParticle);
break;
}
case itAbsorb:
{
const scalar m = p.nParticle()*p.mass();
absorbInteraction<regionFilm>
(*filmModel_, p, pp, facei, m, keepParticle);
break;
}
case itSplashBai:
{
bool dry = this->deltaFilmPatch_[patchi][facei] < deltaWet_;
const scalarField X(thermo_->size(), 1);
const scalar mu = thermo_->mu(pRef_, TRef_, X);
const scalar sigma = thermo_->sigma(pRef_, TRef_, X);
if (dry)
{
drySplashInteraction<regionFilm>
(*filmModel_, sigma, mu, p, pp, facei, keepParticle);
}
else
{
wetSplashInteraction<regionFilm>
(*filmModel_, sigma, mu, p, pp, facei, keepParticle);
}
break;
}
default:
{
FatalErrorInFunction
<< "Unknown interaction type enumeration"
<< abort(FatalError);
}
}
// Transfer parcel/parcel interactions complete
bInteraction = true;
}
}
for (areaFilm& film : areaFilms_)
{
if (patchi == film.patchID())
{
const label facei = pp.whichFace(p.face());
switch (interactionType_)
{
// It only supports absorp model
case itAbsorb:
{
const scalar m = p.nParticle()*p.mass();
absorbInteraction<areaFilm>
(
film, p, pp, facei, m, keepParticle
);
break;
}
case itBounce:
{
bounceInteraction(p, pp, facei, keepParticle);
break;
}
case itSplashBai:
{
bool dry = film.h()[facei] < deltaWet_;
regionModels::areaSurfaceFilmModels::liquidFilmModel& liqFilm =
refCast
< regionModels::areaSurfaceFilmModels::liquidFilmModel
>(film);
const scalarField X(liqFilm.thermo().size(), 1);
const scalar pRef = film.pRef();
const scalar TRef = liqFilm.Tref();
const scalar mu = liqFilm.thermo().mu(pRef, TRef, X);
const scalar sigma =
liqFilm.thermo().sigma(pRef, TRef, X);
if (dry)
{
drySplashInteraction<areaFilm>
(film, sigma, mu, p, pp, facei, keepParticle);
}
else
{
wetSplashInteraction<areaFilm>
(film, sigma, mu, p, pp, facei, keepParticle);
}
break;
}
default:
{
FatalErrorInFunction
<< "Unknown interaction type enumeration"
<< abort(FatalError);
}
}
// Transfer parcel/parcel interactions complete
bInteraction = true;
}
}
// Parcel not interacting with film
return bInteraction;
}
template<class CloudType>
void Foam::KinematicSurfaceFilm<CloudType>::cacheFilmFields
(
const label filmPatchi,
const label primaryPatchi,
const regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel
)
{
SurfaceFilmModel<CloudType>::cacheFilmFields
(
filmPatchi,
primaryPatchi,
filmModel
);
}
template<class CloudType>
void Foam::KinematicSurfaceFilm<CloudType>::cacheFilmFields
(
const label filmPatchi,
const areaFilm& filmModel
)
{
SurfaceFilmModel<CloudType>::cacheFilmFields
(
filmPatchi,
filmModel
);
}
template<class CloudType>
void Foam::KinematicSurfaceFilm<CloudType>::setParcelProperties
(
parcelType& p,
const label filmFacei
) const
{
SurfaceFilmModel<CloudType>::setParcelProperties(p, filmFacei);
}
template<class CloudType>
void Foam::KinematicSurfaceFilm<CloudType>::info(Ostream& os)
{
SurfaceFilmModel<CloudType>::info(os);
label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
label nSplashTotal =
nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
os << " - new splash parcels = " << nSplashTotal << endl;
if (this->writeTime())
{
this->setModelProperty("nParcelsSplashed", nSplashTotal);
nParcelsSplashed_ = 0;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,365 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::KinematicSurfaceFilm
Group
grpLagrangianIntermediateSurfaceFilmSubModels
Description
Kinematic parcel surface film model.
Responsible for:
- injecting parcelss from the film model into the cloud, e.g. for dripping
- parcel interaction with the film, e.g absorb, bounce, splash
SourceFiles
KinematicSurfaceFilm.C
KinematicSurfaceFilmI.H
\*---------------------------------------------------------------------------*/
#ifndef KinematicSurfaceFilm_H
#define KinematicSurfaceFilm_H
#include "SurfaceFilmModel.H"
#include "UPtrList.H"
#include "liquidMixtureProperties.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//Forward declaration of classes
namespace regionModels
{
namespace surfaceFilmModels
{
class surfaceFilmRegionModel;
}
}
namespace regionModels
{
namespace areaSurfaceFilmModels
{
class liquidFilmBase;
}
}
/*---------------------------------------------------------------------------*\
Class KinematicSurfaceFilm Declaration
\*---------------------------------------------------------------------------*/
template<class CloudType>
class KinematicSurfaceFilm
:
public SurfaceFilmModel<CloudType>
{
public:
// Public Data
//- Options for the interaction types
enum interactionType
{
itAbsorb,
itBounce,
itSplashBai
};
//- Names for interactionType
static wordList interactionTypeNames_;
// Public Member Functions
//- Return interaction type enum from word
interactionType interactionTypeEnum(const word& it) const;
//- Return word from interaction type enum
word interactionTypeStr(const interactionType& it) const;
protected:
// Protected Data
//- Convenience typedef to the cloud's parcel type
typedef typename CloudType::parcelType parcelType;
typedef typename
regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm;
typedef typename
regionModels::surfaceFilmModels::surfaceFilmRegionModel regionFilm;
//- Reference to the cloud random number generator
Random& rndGen_;
// Region Film thermo
//- Region Film liquid thermo
liquidMixtureProperties* thermo_;
//- Region Film reference pressure
scalar pRef_;
//- Region Film reference temperature
scalar TRef_;
//- Pointer to filmModel
regionFilm* filmModel_;
// Area Films
//- UPointers to area films
UPtrList<areaFilm> areaFilms_;
// Interaction model data
//- Interaction type enumeration
interactionType interactionType_;
//- Film thickness beyond which patch is assumed to be wet
scalar deltaWet_;
//- Splash parcel type label - id assigned to identify parcel for
// post-processing. If not specified, defaults to originating cloud
// type
label splashParcelType_;
//- Number of new parcels resulting from splash event
label parcelsPerSplash_;
// Surface roughness coefficient typically in the range 1300 - 5200
// and decreases with increasing surface roughness
//- Dry surface roughness coefficient
// = 2630 for dry interaction (ref. Bai)
scalar Adry_;
//- Wet surface roughness coefficient
// = 1320 for wet interaction (ref. Bai)
scalar Awet_;
//- Skin friction typically in the range 0.6 < Cf < 0.8
scalar Cf_;
//- Counter for number of new splash parcels
label nParcelsSplashed_;
// Protected Member Functions
//- Return a vector tangential to input vector, v
vector tangentVector(const vector& v) const;
//- Return splashed parcel direction
vector splashDirection
(
const vector& tanVec1,
const vector& tanVec2,
const vector& nf
) const;
//- Initialise thermo
void init(bool binitThermo);
//- Initialise pointers of films
void initFilmModels();
// Injection from sheet (ejection) helper functions
//- Cache the film fields in preparation for injection
virtual void cacheFilmFields
(
const label primaryPatchi,
const areaFilm&
);
//- Cache the film fields in preparation for injection
virtual void cacheFilmFields
(
const label filmPatchi,
const label primaryPatchi,
const regionModels::surfaceFilmModels::surfaceFilmRegionModel&
);
//- Set the individual parcel properties
virtual void setParcelProperties
(
parcelType& p,
const label filmFacei
) const;
public:
//- Runtime type information
TypeName("kinematicSurfaceFilm");
// Constructors
//- Construct from components
KinematicSurfaceFilm
(
const dictionary& dict,
CloudType& owner,
const word& type = typeName,
bool initThermo = true
);
//- Construct copy
KinematicSurfaceFilm
(
const KinematicSurfaceFilm<CloudType>& sfm,
bool initThermo = true
);
//- Construct and return a clone using supplied owner cloud
virtual autoPtr<SurfaceFilmModel<CloudType>> clone() const
{
return autoPtr<SurfaceFilmModel<CloudType>>
(
new KinematicSurfaceFilm<CloudType>(*this)
);
}
//- Destructor
virtual ~KinematicSurfaceFilm() = default;
// Member Functions
// Interaction models
//- Absorb parcel into film
template<class filmType>
void absorbInteraction
(
filmType&,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mass,
bool& keepParticle
);
//- Bounce parcel (flip parcel normal velocity)
void bounceInteraction
(
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
) const;
//- Parcel interaction with dry surface
template<class filmType>
void drySplashInteraction
(
filmType&,
const scalar sigma,
const scalar mu,
const parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
);
//- Parcel interaction with wetted surface
template<class filmType>
void wetSplashInteraction
(
filmType&,
const scalar sigma,
const scalar mu,
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
);
//- Bai parcel splash interaction model
template<class filmType>
void splashInteraction
(
filmType&,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mRatio,
const scalar We,
const scalar Wec,
const scalar sigma,
bool& keepParticle
);
// Evaluation
//- Transfer parcel from cloud to surface film
// Returns true if parcel is to be transferred
virtual bool transferParcel
(
parcelType& p,
const polyPatch& pp,
bool& keepParticle
);
// I-O
//- Write surface film info to stream
virtual void info(Ostream& os);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "KinematicSurfaceFilm.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -27,8 +27,9 @@ License
\*---------------------------------------------------------------------------*/
#include "SurfaceFilmModel.H"
#include "surfaceFilmRegionModel.H"
#include "mathematicalConstants.H"
#include "surfaceFilmRegionModel.H"
#include "liquidFilmBase.H"
using namespace Foam::constant;
@ -40,13 +41,16 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel(CloudType& owner)
CloudSubModelBase<CloudType>(owner),
g_(owner.g()),
ejectedParcelType_(0),
injectionOffset_(1.1),
minDiameter_(0),
massParcelPatch_(0),
diameterParcelPatch_(0),
UFilmPatch_(0),
rhoFilmPatch_(0),
deltaFilmPatch_(0),
nParcelsTransferred_(0),
nParcelsInjected_(0)
nParcelsInjected_(0),
totalMassTransferred_(0)
{}
@ -62,7 +66,15 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel
g_(owner.g()),
ejectedParcelType_
(
this->coeffDict().getOrDefault("ejectedParcelType", -1)
this->coeffDict().template getOrDefault<label>("ejectedParcelType", -1)
),
injectionOffset_
(
this->coeffDict().template getOrDefault<scalar>("injectionOffset", 1.1)
),
minDiameter_
(
this->coeffDict().template getOrDefault<scalar>("minDiameter", -1)
),
massParcelPatch_(0),
diameterParcelPatch_(0),
@ -70,7 +82,8 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel
rhoFilmPatch_(0),
deltaFilmPatch_(owner.mesh().boundary().size()),
nParcelsTransferred_(0),
nParcelsInjected_(0)
nParcelsInjected_(0),
totalMassTransferred_()
{}
@ -83,13 +96,16 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel
CloudSubModelBase<CloudType>(sfm),
g_(sfm.g_),
ejectedParcelType_(sfm.ejectedParcelType_),
injectionOffset_(sfm.injectionOffset_),
minDiameter_(sfm.minDiameter_),
massParcelPatch_(sfm.massParcelPatch_),
diameterParcelPatch_(sfm.diameterParcelPatch_),
UFilmPatch_(sfm.UFilmPatch_),
rhoFilmPatch_(sfm.rhoFilmPatch_),
deltaFilmPatch_(sfm.deltaFilmPatch_),
nParcelsTransferred_(sfm.nParcelsTransferred_),
nParcelsInjected_(sfm.nParcelsInjected_)
nParcelsInjected_(sfm.nParcelsInjected_),
totalMassTransferred_(sfm.totalMassTransferred_)
{}
@ -102,6 +118,63 @@ Foam::SurfaceFilmModel<CloudType>::~SurfaceFilmModel()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class CloudType>
template<class CloudTrackType>
void Foam::SurfaceFilmModel<CloudType>::injectParticles
(
const label primaryPatchi,
const labelList& injectorCellsPatch,
CloudTrackType& cloud
)
{
const fvMesh& mesh = this->owner().mesh();
const vectorField& Cf = mesh.C().boundaryField()[primaryPatchi];
const vectorField& Sf = mesh.Sf().boundaryField()[primaryPatchi];
const scalarField& magSf =
mesh.magSf().boundaryField()[primaryPatchi];
forAll(injectorCellsPatch, j)
{
if (diameterParcelPatch_[j] > 0)
{
const label celli = injectorCellsPatch[j];
const scalar offset =
max
(
diameterParcelPatch_[j],
deltaFilmPatch_[primaryPatchi][j]
);
const point pos = Cf[j] - injectionOffset_*offset*Sf[j]/magSf[j];
// Create a new parcel
parcelType* pPtr =
new parcelType(this->owner().pMesh(), pos, celli);
// Check/set new parcel thermo properties
cloud.setParcelThermoProperties(*pPtr, 0.0);
setParcelProperties(*pPtr, j);
if (pPtr->nParticle() > 0.001)
{
// Check new parcel properties
cloud.checkParcelProperties(*pPtr, 0.0, false);
// Add the new parcel to the cloud
cloud.addParticle(pPtr);
nParcelsInjected_++;
}
else
{
// TODO: cache mass and re-distribute?
delete pPtr;
}
}
}
}
template<class CloudType>
template<class TrackCloudType>
void Foam::SurfaceFilmModel<CloudType>::inject(TrackCloudType& cloud)
@ -111,76 +184,77 @@ void Foam::SurfaceFilmModel<CloudType>::inject(TrackCloudType& cloud)
return;
}
const fvMesh& mesh = this->owner().mesh();
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
// Retrieve the film model from the owner database
const regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel =
this->owner().mesh().time().objectRegistry::template lookupObject
const regionModels::surfaceFilmModels::surfaceFilmRegionModel* filmModel =
mesh.time().objectRegistry::template findObject
<regionModels::surfaceFilmModels::surfaceFilmRegionModel>
(
"surfaceFilmProperties"
);
if (!filmModel.active())
// Check the singleLayer type of films
if (filmModel && filmModel->active())
{
return;
const labelList& filmPatches = filmModel->intCoupledPatchIDs();
const labelList& primaryPatches = filmModel->primaryPatchIDs();
forAll(filmPatches, i)
{
const label filmPatchi = filmPatches[i];
const label primaryPatchi = primaryPatches[i];
const labelList& injectorCellsPatch = pbm[primaryPatchi].faceCells();
cacheFilmFields(filmPatchi, primaryPatchi, *filmModel);
injectParticles(primaryPatchi, injectorCellsPatch, cloud);
}
}
const labelList& filmPatches = filmModel.intCoupledPatchIDs();
const labelList& primaryPatches = filmModel.primaryPatchIDs();
// Check finite area films
wordList names =
mesh.time().objectRegistry::template
sortedNames<regionModels::regionFaModel>();
const fvMesh& mesh = this->owner().mesh();
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(filmPatches, i)
forAll (names, i)
{
const label filmPatchi = filmPatches[i];
const label primaryPatchi = primaryPatches[i];
const regionModels::regionFaModel* regionFa =
mesh.time().objectRegistry::template cfindObject
<
regionModels::regionFaModel
>(names[i]);
const labelList& injectorCellsPatch = pbm[primaryPatchi].faceCells();
cacheFilmFields(filmPatchi, primaryPatchi, filmModel);
const vectorField& Cf = mesh.C().boundaryField()[primaryPatchi];
const vectorField& Sf = mesh.Sf().boundaryField()[primaryPatchi];
const scalarField& magSf = mesh.magSf().boundaryField()[primaryPatchi];
forAll(injectorCellsPatch, j)
// Check that it is a type areaFilm
if (regionFa && isA<areaFilm>(*regionFa) && regionFa->active())
{
if (diameterParcelPatch_[j] > 0)
areaFilm& film =
const_cast<areaFilm&>(refCast<const areaFilm>(*regionFa));
const label patchId = regionFa->patchID();
const labelList& injectorCellsPatch = pbm[patchId].faceCells();
cacheFilmFields(patchId, film);
injectParticles(patchId, injectorCellsPatch, cloud);
forAll(injectorCellsPatch, facei)
{
const label celli = injectorCellsPatch[j];
const scalar offset =
max
if (diameterParcelPatch_[facei] > 0)
{
film.addSources
(
diameterParcelPatch_[j],
deltaFilmPatch_[primaryPatchi][j]
patchId,
facei,
-massParcelPatch_[facei], // mass
Zero, // tangential momentum
Zero, // impingement
Zero // energy
);
const point pos = Cf[j] - 1.1*offset*Sf[j]/magSf[j];
// Create a new parcel
parcelType* pPtr =
new parcelType(this->owner().pMesh(), pos, celli);
// Check/set new parcel thermo properties
cloud.setParcelThermoProperties(*pPtr, 0.0);
setParcelProperties(*pPtr, j);
if (pPtr->nParticle() > 0.001)
{
// Check new parcel properties
// cloud.checkParcelProperties(*pPtr, 0.0, true);
cloud.checkParcelProperties(*pPtr, 0.0, false);
// Add the new parcel to the cloud
cloud.addParticle(pPtr);
nParcelsInjected_++;
}
else
{
// TODO: cache mass and re-distribute?
delete pPtr;
}
}
}
@ -215,6 +289,39 @@ void Foam::SurfaceFilmModel<CloudType>::cacheFilmFields
}
template<class CloudType>
void Foam::SurfaceFilmModel<CloudType>::cacheFilmFields
(
const label filmPatchi,
const regionModels::areaSurfaceFilmModels::liquidFilmBase& filmModel
)
{
const volSurfaceMapping& map = filmModel.region().vsm();
massParcelPatch_.setSize(filmModel.Uf().size(), Zero);
const scalarField& massParcelPatch =
filmModel.cloudMassTrans().boundaryField()[filmPatchi];
map.mapToField(massParcelPatch, massParcelPatch_);
const scalarField& diameterParcelPatch =
filmModel.cloudDiameterTrans().boundaryField()[filmPatchi];
diameterParcelPatch_.setSize(filmModel.Uf().size(), Zero);
map.mapToField(diameterParcelPatch, diameterParcelPatch_);
UFilmPatch_.setSize(filmModel.Uf().size(), vector::zero);
map.mapToField(filmModel.Uf(), UFilmPatch_);
rhoFilmPatch_.setSize(UFilmPatch_.size(), Zero);
map.mapToField(filmModel.rho(), rhoFilmPatch_);
deltaFilmPatch_[filmPatchi].setSize(UFilmPatch_.size(), Zero);
map.mapToField(filmModel.h(), deltaFilmPatch_[filmPatchi]);
}
template<class CloudType>
void Foam::SurfaceFilmModel<CloudType>::setParcelProperties
(
@ -230,6 +337,14 @@ void Foam::SurfaceFilmModel<CloudType>::setParcelProperties
p.nParticle() = massParcelPatch_[filmFacei]/p.rho()/vol;
if (minDiameter_ != -1)
{
if (p.d() < minDiameter_)
{
p.nParticle() = 0;
}
}
if (ejectedParcelType_ >= 0)
{
p.typeId() = ejectedParcelType_;
@ -246,22 +361,33 @@ void Foam::SurfaceFilmModel<CloudType>::info(Ostream& os)
label nInject0 =
this->template getModelProperty<label>("nParcelsInjected");
scalar massTransferred0 =
this->template getModelProperty<scalar>("massTransferred");
label nTransTotal =
nTrans0 + returnReduce(nParcelsTransferred_, sumOp<label>());
label nInjectTotal =
nInject0 + returnReduce(nParcelsInjected_, sumOp<label>());
scalar massTransferredTotal =
massTransferred0 + returnReduce(totalMassTransferred_, sumOp<scalar>());
os << " Surface film:" << nl
<< " - parcels absorbed = " << nTransTotal << nl
<< " - mass absorbed = " << massTransferredTotal << nl
<< " - parcels ejected = " << nInjectTotal << endl;
if (this->writeTime())
{
this->setModelProperty("nParcelsTransferred", nTransTotal);
this->setModelProperty("nParcelsInjected", nInjectTotal);
this->setModelProperty("massTransferred", massTransferredTotal);
nParcelsTransferred_ = 0;
nParcelsInjected_ = 0;
totalMassTransferred_ = 0;
}
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,6 +47,7 @@ SourceFiles
#include "runTimeSelectionTables.H"
#include "CloudSubModelBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -60,6 +62,15 @@ namespace regionModels
}
}
namespace regionModels
{
namespace areaSurfaceFilmModels
{
class liquidFilmBase;
}
}
/*---------------------------------------------------------------------------*\
Class SurfaceFilmModel Declaration
\*---------------------------------------------------------------------------*/
@ -76,6 +87,9 @@ protected:
//- Convenience typedef to the cloud's parcel type
typedef typename CloudType::parcelType parcelType;
typedef typename
regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm;
//- Gravitational acceleration constant
const dimensionedVector& g_;
@ -84,23 +98,29 @@ protected:
// type
label ejectedParcelType_;
//- Injection offset position
scalar injectionOffset_;
//- Minimum diameter particle injection
scalar minDiameter_;
// Cached injector fields per film patch
//- Parcel mass / patch face
scalarList massParcelPatch_;
scalarField massParcelPatch_;
//- Parcel diameter / patch face
scalarList diameterParcelPatch_;
scalarField diameterParcelPatch_;
//- Film velocity / patch face
List<vector> UFilmPatch_;
Field<vector> UFilmPatch_;
//- Film density / patch face
scalarList rhoFilmPatch_;
scalarField rhoFilmPatch_;
//- Film height of all film patches / patch face
scalarListList deltaFilmPatch_;
Field<scalarField> deltaFilmPatch_;
// Counters
@ -112,6 +132,12 @@ protected:
label nParcelsInjected_;
// Total mass info
//- Total mass transferred to the film
scalar totalMassTransferred_;
// Protected functions
//- Cache the film fields in preparation for injection
@ -122,6 +148,22 @@ protected:
const regionModels::surfaceFilmModels::surfaceFilmRegionModel&
);
//- Cache the finite area film fields in preparation for injection
virtual void cacheFilmFields
(
const label primaryPatchi,
const areaFilm&
);
//- Inject particles in cloud
template<class TrackCloudType>
void injectParticles
(
const label primaryPatchi,
const labelList& injectorCellsPatch,
TrackCloudType& cloud
);
//- Set the individual parcel properties
virtual void setParcelProperties
(
@ -204,6 +246,12 @@ public:
// the film model
inline label& nParcelsInjected();
//- Return non-const total mass transferred
inline scalar& totalMassTransferred();
//- Return consr access to mass transferred
inline scalar totalMassTransferred() const;
// Member Functions

View File

@ -63,5 +63,18 @@ Foam::label Foam::SurfaceFilmModel<CloudType>::nParcelsInjected() const
return nParcelsInjected_;
}
template<class CloudType>
Foam::scalar& Foam::SurfaceFilmModel<CloudType>::totalMassTransferred()
{
return totalMassTransferred_;
}
template<class CloudType>
Foam::scalar Foam::SurfaceFilmModel<CloudType>::totalMassTransferred() const
{
return totalMassTransferred_;
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,451 +27,6 @@ License
\*---------------------------------------------------------------------------*/
#include "ThermoSurfaceFilm.H"
#include "addToRunTimeSelectionTable.H"
#include "unitConversion.H"
#include "Pstream.H"
using namespace Foam::constant::mathematical;
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class CloudType>
Foam::wordList Foam::ThermoSurfaceFilm<CloudType>::interactionTypeNames_
{
"absorb", "bounce", "splashBai"
};
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class CloudType>
typename Foam::ThermoSurfaceFilm<CloudType>::interactionType
Foam::ThermoSurfaceFilm<CloudType>::interactionTypeEnum(const word& it) const
{
forAll(interactionTypeNames_, i)
{
if (interactionTypeNames_[i] == it)
{
return interactionType(i);
}
}
FatalErrorInFunction
<< "Unknown interaction type " << it
<< ". Valid interaction types include: " << interactionTypeNames_
<< abort(FatalError);
return interactionType(0);
}
template<class CloudType>
Foam::word Foam::ThermoSurfaceFilm<CloudType>::interactionTypeStr
(
const interactionType& it
) const
{
if (it >= interactionTypeNames_.size())
{
FatalErrorInFunction
<< "Unknown interaction type enumeration" << abort(FatalError);
}
return interactionTypeNames_[it];
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class CloudType>
Foam::vector Foam::ThermoSurfaceFilm<CloudType>::tangentVector
(
const vector& v
) const
{
vector tangent = Zero;
scalar magTangent = 0.0;
while (magTangent < SMALL)
{
vector vTest = rndGen_.sample01<vector>();
tangent = vTest - (vTest & v)*v;
magTangent = mag(tangent);
}
return tangent/magTangent;
}
template<class CloudType>
Foam::vector Foam::ThermoSurfaceFilm<CloudType>::splashDirection
(
const vector& tanVec1,
const vector& tanVec2,
const vector& nf
) const
{
// Azimuthal angle [rad]
const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
// Ejection angle [rad]
const scalar thetaSi = degToRad(rndGen_.sample01<scalar>()*(50 - 5) + 5);
// Direction vector of new parcel
const scalar alpha = sin(thetaSi);
const scalar dcorr = cos(thetaSi);
const vector normal = alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi));
vector dirVec = dcorr*nf;
dirVec += normal;
return dirVec/mag(dirVec);
}
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::absorbInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mass,
bool& keepParticle
)
{
if (debug)
{
Info<< "Parcel " << p.origId() << " absorbInteraction" << endl;
}
// Patch face normal
const vector& nf = pp.faceNormals()[facei];
// Patch velocity
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
// Relative parcel velocity
const vector Urel = p.U() - Up;
// Parcel normal velocity
const vector Un = nf*(Urel & nf);
// Parcel tangential velocity
const vector Ut = Urel - Un;
filmModel.addSources
(
pp.index(),
facei,
mass, // mass
mass*Ut, // tangential momentum
mass*mag(Un), // impingement pressure
mass*p.hs() // energy
);
this->nParcelsTransferred()++;
keepParticle = false;
}
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::bounceInteraction
(
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
) const
{
if (debug)
{
Info<< "Parcel " << p.origId() << " bounceInteraction" << endl;
}
// Patch face normal
const vector& nf = pp.faceNormals()[facei];
// Patch velocity
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
// Relative parcel velocity
const vector Urel = p.U() - Up;
// Flip parcel normal velocity component
p.U() -= 2.0*nf*(Urel & nf);
keepParticle = true;
}
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::drySplashInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
const parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
)
{
if (debug)
{
Info<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
}
const liquidProperties& liq = thermo_.liquids().properties()[0];
// Patch face velocity and normal
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
const vector& nf = pp.faceNormals()[facei];
// Local pressure
const scalar pc = thermo_.thermo().p()[p.cell()];
// Retrieve parcel properties
const scalar m = p.mass()*p.nParticle();
const scalar rho = p.rho();
const scalar d = p.d();
const scalar sigma = liq.sigma(pc, p.T());
const scalar mu = liq.mu(pc, p.T());
const vector Urel = p.U() - Up;
const vector Un = nf*(Urel & nf);
// Laplace number
const scalar La = rho*sigma*d/sqr(mu);
// Weber number
const scalar We = rho*magSqr(Un)*d/sigma;
// Critical Weber number
const scalar Wec = Adry_*pow(La, -0.183);
if (We < Wec) // Adhesion - assume absorb
{
absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
}
else // Splash
{
// Ratio of incident mass to splashing mass
const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
splashInteraction
(filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
}
}
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::wetSplashInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
)
{
if (debug)
{
Info<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
}
const liquidProperties& liq = thermo_.liquids().properties()[0];
// Patch face velocity and normal
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
const vector& nf = pp.faceNormals()[facei];
// Local pressure
const scalar pc = thermo_.thermo().p()[p.cell()];
// Retrieve parcel properties
const scalar m = p.mass()*p.nParticle();
const scalar rho = p.rho();
const scalar d = p.d();
vector& U = p.U();
const scalar sigma = liq.sigma(pc, p.T());
const scalar mu = liq.mu(pc, p.T());
const vector Urel = p.U() - Up;
const vector Un = nf*(Urel & nf);
const vector Ut = Urel - Un;
// Laplace number
const scalar La = rho*sigma*d/sqr(mu);
// Weber number
const scalar We = rho*magSqr(Un)*d/sigma;
// Critical Weber number
const scalar Wec = Awet_*pow(La, -0.183);
if (We < 2) // Adhesion - assume absorb
{
absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
}
else if ((We >= 2) && (We < 20)) // Bounce
{
// Incident angle of impingement
const scalar theta = piByTwo - acos(U/mag(U) & nf);
// Restitution coefficient
const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
// Update parcel velocity
U = -epsilon*(Un) + 5.0/7.0*(Ut);
keepParticle = true;
return;
}
else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
{
absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
}
else // Splash
{
// Ratio of incident mass to splashing mass
// splash mass can be > incident mass due to film entrainment
const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
splashInteraction
(filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
}
}
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::splashInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mRatio,
const scalar We,
const scalar Wec,
const scalar sigma,
bool& keepParticle
)
{
// Patch face velocity and normal
const fvMesh& mesh = this->owner().mesh();
const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
const vector& nf = pp.faceNormals()[facei];
// Determine direction vectors tangential to patch normal
const vector tanVec1 = tangentVector(nf);
const vector tanVec2 = nf^tanVec1;
// Retrieve parcel properties
const scalar np = p.nParticle();
const scalar m = p.mass()*np;
const scalar d = p.d();
const vector Urel = p.U() - Up;
const vector Un = nf*(Urel & nf);
const vector Ut = Urel - Un;
const vector& posC = mesh.C()[p.cell()];
const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
// Total mass of (all) splashed parcels
const scalar mSplash = m*mRatio;
// Number of splashed particles per incoming particle
const scalar Ns = 5.0*(We/Wec - 1.0);
// Average diameter of splashed particles
const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
// Cumulative diameter splash distribution
const scalar dMax = 0.9*cbrt(mRatio)*d;
const scalar dMin = 0.1*dMax;
const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
// Surface energy of secondary parcels [J]
scalar ESigmaSec = 0;
// Sample splash distribution to determine secondary parcel diameters
scalarList dNew(parcelsPerSplash_);
scalarList npNew(parcelsPerSplash_);
forAll(dNew, i)
{
const scalar y = rndGen_.sample01<scalar>();
dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
}
// Incident kinetic energy [J]
const scalar EKIn = 0.5*m*magSqr(Un);
// Incident surface energy [J]
const scalar ESigmaIn = np*sigma*p.areaS(d);
// Dissipative energy
const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
// Total energy [J]
const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
// Switch to absorb if insufficient energy for splash
if (EKs <= 0)
{
absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
return;
}
// Helper variables to calculate magUns0
const scalar logD = log(d);
const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
scalar coeff1 = 0.0;
forAll(dNew, i)
{
coeff1 += sqr(log(dNew[i]) - logD);
}
// Magnitude of the normal velocity of the first splashed parcel
const scalar magUns0 =
sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
// Set splashed parcel properties
forAll(dNew, i)
{
const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
// Create a new parcel by copying source parcel
parcelType* pPtr = new parcelType(p);
pPtr->origId() = pPtr->getNewParticleID();
pPtr->origProc() = Pstream::myProcNo();
if (splashParcelType_ >= 0)
{
pPtr->typeId() = splashParcelType_;
}
// Perturb new parcels towards the owner cell centre
pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
pPtr->nParticle() = npNew[i];
pPtr->d() = dNew[i];
pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
// Apply correction to velocity for 2-D cases
meshTools::constrainDirection(mesh, mesh.solutionD(), pPtr->U());
// Add the new parcel
this->owner().addParticle(pPtr);
nParcelsSplashed_++;
}
// Transfer remaining part of parcel to film 0 - splashMass can be -ve
// if entraining from the film
const scalar mDash = m - mSplash;
absorbInteraction(filmModel, p, pp, facei, mDash, keepParticle);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -482,41 +37,14 @@ Foam::ThermoSurfaceFilm<CloudType>::ThermoSurfaceFilm
CloudType& owner
)
:
SurfaceFilmModel<CloudType>(dict, owner, typeName),
rndGen_(owner.rndGen()),
KinematicSurfaceFilm<CloudType>(dict, owner, typeName, false),
thermo_
(
owner.db().objectRegistry::template lookupObject<SLGThermo>("SLGThermo")
),
TFilmPatch_(0),
CpFilmPatch_(0),
interactionType_
(
interactionTypeEnum(this->coeffDict().getWord("interactionType"))
),
deltaWet_(0.0),
splashParcelType_(0),
parcelsPerSplash_(0),
Adry_(0.0),
Awet_(0.0),
Cf_(0.0),
nParcelsSplashed_(0)
{
Info<< " Applying " << interactionTypeStr(interactionType_)
<< " interaction model" << endl;
if (interactionType_ == itSplashBai)
{
this->coeffDict().readEntry("deltaWet", deltaWet_);
splashParcelType_ =
this->coeffDict().getOrDefault("splashParcelType", -1);
parcelsPerSplash_ =
this->coeffDict().getOrDefault("parcelsPerSplash", 2);
this->coeffDict().readEntry("Adry", Adry_);
this->coeffDict().readEntry("Awet", Awet_);
this->coeffDict().readEntry("Cf", Cf_);
}
}
CpFilmPatch_(0)
{}
template<class CloudType>
@ -525,26 +53,10 @@ Foam::ThermoSurfaceFilm<CloudType>::ThermoSurfaceFilm
const ThermoSurfaceFilm<CloudType>& sfm
)
:
SurfaceFilmModel<CloudType>(sfm),
rndGen_(sfm.rndGen_),
KinematicSurfaceFilm<CloudType>(sfm, false),
thermo_(sfm.thermo_),
TFilmPatch_(sfm.TFilmPatch_),
CpFilmPatch_(sfm.CpFilmPatch_),
interactionType_(sfm.interactionType_),
deltaWet_(sfm.deltaWet_),
splashParcelType_(sfm.splashParcelType_),
parcelsPerSplash_(sfm.parcelsPerSplash_),
Adry_(sfm.Adry_),
Awet_(sfm.Awet_),
Cf_(sfm.Cf_),
nParcelsSplashed_(sfm.nParcelsSplashed_)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class CloudType>
Foam::ThermoSurfaceFilm<CloudType>::~ThermoSurfaceFilm()
CpFilmPatch_(sfm.CpFilmPatch_)
{}
@ -558,68 +70,134 @@ bool Foam::ThermoSurfaceFilm<CloudType>::transferParcel
bool& keepParticle
)
{
// Retrieve the film model from the owner database
regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel =
const_cast<regionModels::surfaceFilmModels::surfaceFilmRegionModel&>
(
this->owner().db().time().objectRegistry::template
lookupObject
<regionModels::surfaceFilmModels::surfaceFilmRegionModel>
(
"surfaceFilmProperties"
)
);
const label patchi = pp.index();
if (filmModel.isRegionPatch(patchi))
this->initFilmModels();
bool bInteraction(false);
// Check the singleLayer film models
if (this->filmModel_)
{
const label facei = pp.whichFace(p.face());
switch (interactionType_)
if (this->filmModel_->isRegionPatch(patchi))
{
case itBounce:
{
bounceInteraction(p, pp, facei, keepParticle);
const label facei = pp.whichFace(p.face());
break;
}
case itAbsorb:
switch (this->interactionType_)
{
const scalar m = p.nParticle()*p.mass();
absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
break;
}
case itSplashBai:
{
bool dry = this->deltaFilmPatch_[patchi][facei] < deltaWet_;
if (dry)
case KinematicSurfaceFilm<CloudType>::itBounce:
{
drySplashInteraction(filmModel, p, pp, facei, keepParticle);
}
else
{
wetSplashInteraction(filmModel, p, pp, facei, keepParticle);
}
this->bounceInteraction(p, pp, facei, keepParticle);
break;
}
default:
{
FatalErrorInFunction
<< "Unknown interaction type enumeration"
<< abort(FatalError);
break;
}
case KinematicSurfaceFilm<CloudType>::itAbsorb:
{
const scalar m = p.nParticle()*p.mass();
this->absorbInteraction //<regionFilm>
(*(this->filmModel_), p, pp, facei, m, keepParticle);
break;
}
case KinematicSurfaceFilm<CloudType>::itSplashBai:
{
// Local pressure
const scalar pc = thermo_.thermo().p()[p.cell()];
const liquidProperties& liq = thermo_.liquids().properties()[0];
const scalar sigma = liq.sigma(pc, p.T());
const scalar mu = liq.mu(pc, p.T());
bool dry = this->deltaFilmPatch_[patchi][facei] < this->deltaWet_;
if (dry)
{
this->drySplashInteraction //<CloudType, regionFilm>
(*(this->filmModel_), sigma, mu, p, pp, facei, keepParticle);
}
else
{
this->wetSplashInteraction //<regionFilm>
(*(this->filmModel_), sigma, mu, p, pp, facei, keepParticle);
}
break;
}
default:
{
FatalErrorInFunction
<< "Unknown interaction type enumeration"
<< abort(FatalError);
}
}
// Transfer parcel/parcel interactions complete
bInteraction = true;
}
}
// Transfer parcel/parcel interactions complete
return true;
for (areaFilm& film : this->areaFilms_)
{
if (patchi == film.patchID())
{
const label facei = pp.whichFace(p.face());
switch (this->interactionType_)
{
// It only supports absorp model
case KinematicSurfaceFilm<CloudType>::itAbsorb:
{
const scalar m = p.nParticle()*p.mass();
this->absorbInteraction //<areaFilm>
(
film, p, pp, facei, m, keepParticle
);
break;
}
case KinematicSurfaceFilm<CloudType>::itBounce:
{
this->bounceInteraction(p, pp, facei, keepParticle);
break;
}
case KinematicSurfaceFilm<CloudType>::itSplashBai:
{
// Local pressure
const scalar pc = thermo_.thermo().p()[p.cell()];
const liquidProperties& liq = thermo_.liquids().properties()[0];
const scalar sigma = liq.sigma(pc, p.T());
const scalar mu = liq.mu(pc, p.T());
bool dry = film.h()[facei] < this->deltaWet_;
if (dry)
{
this->drySplashInteraction //<areaFilm>
(film, sigma, mu, p, pp, facei, keepParticle);
}
else
{
this->wetSplashInteraction //<areaFilm>
(film, sigma, mu, p, pp, facei, keepParticle);
}
break;
}
default:
{
FatalErrorInFunction
<< "Unknown interaction type enumeration"
<< abort(FatalError);
}
}
// Transfer parcel/parcel interactions complete
bInteraction = true;
}
}
// Parcel not interacting with film
return false;
return bInteraction;
}
@ -631,7 +209,7 @@ void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
const regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel
)
{
SurfaceFilmModel<CloudType>::cacheFilmFields
KinematicSurfaceFilm<CloudType>::cacheFilmFields
(
filmPatchi,
primaryPatchi,
@ -646,6 +224,27 @@ void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
}
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
(
const label filmPatchi,
const areaFilm& filmModel
)
{
KinematicSurfaceFilm<CloudType>::cacheFilmFields
(
filmPatchi,
filmModel
);
const volSurfaceMapping& map = filmModel.region().vsm();
TFilmPatch_.setSize(filmModel.Tf().size(), Zero);
map.mapToField(filmModel.Tf(), TFilmPatch_);
CpFilmPatch_.setSize(filmModel.Tf().size(), Zero);
map.mapToField(filmModel.Cp(), CpFilmPatch_);
}
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::setParcelProperties
(
@ -653,7 +252,7 @@ void Foam::ThermoSurfaceFilm<CloudType>::setParcelProperties
const label filmFacei
) const
{
SurfaceFilmModel<CloudType>::setParcelProperties(p, filmFacei);
KinematicSurfaceFilm<CloudType>::setParcelProperties(p, filmFacei);
// Set parcel properties
p.T() = TFilmPatch_[filmFacei];
@ -664,19 +263,7 @@ void Foam::ThermoSurfaceFilm<CloudType>::setParcelProperties
template<class CloudType>
void Foam::ThermoSurfaceFilm<CloudType>::info(Ostream& os)
{
SurfaceFilmModel<CloudType>::info(os);
label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
label nSplashTotal =
nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
os << " - new splash parcels = " << nSplashTotal << endl;
if (this->writeTime())
{
this->setModelProperty("nParcelsSplashed", nSplashTotal);
nParcelsSplashed_ = 0;
}
KinematicSurfaceFilm<CloudType>::info(os);
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,19 +33,6 @@ Group
Description
Thermo parcel surface film model.
Responsible for:
- injecting parcelss from the film model into the cloud, e.g. for dripping
- parcel interaction with the film, e.g absorb, bounce, splash
Splash model references:
Bai and Gosman, `Mathematical modelling of wall films formed by
impinging sprays', SAE 960626, 1996
Bai et al, `Modelling of gasoline spray impingement', Atom. Sprays,
vol 12, pp 1-27, 2002
SourceFiles
ThermoSurfaceFilm.C
ThermoSurfaceFilmI.H
@ -54,7 +42,8 @@ SourceFiles
#ifndef ThermoSurfaceFilm_H
#define ThermoSurfaceFilm_H
#include "SurfaceFilmModel.H"
#include "KinematicSurfaceFilm.H"
#include "UPtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -68,42 +57,20 @@ namespace Foam
template<class CloudType>
class ThermoSurfaceFilm
:
public SurfaceFilmModel<CloudType>
public KinematicSurfaceFilm<CloudType>
{
public:
// Public data
// Interaction type enumerations
enum interactionType
{
itAbsorb,
itBounce,
itSplashBai
};
//- Word descriptions of interaction type names
static wordList interactionTypeNames_;
// Public Member Functions
// Return interaction type enum from word
interactionType interactionTypeEnum(const word& it) const;
// Return word from interaction type enum
word interactionTypeStr(const interactionType& it) const;
protected:
// Protected data
// Protected Data
//- Convenience typedef to the cloud's parcel type
typedef typename CloudType::parcelType parcelType;
//- Reference to the cloud random number generator
Random& rndGen_;
typedef typename
regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm;
typedef typename
regionModels::surfaceFilmModels::surfaceFilmRegionModel regionFilm;
//- Reference to the cloud thermo package
const SLGThermo& thermo_;
@ -112,128 +79,28 @@ protected:
// Cached injector fields per film patch
//- Film temperature / patch face
scalarList TFilmPatch_;
scalarField TFilmPatch_;
//- Film specific heat capacity / patch face
scalarList CpFilmPatch_;
// Interaction model data
//- Interaction type enumeration
interactionType interactionType_;
//- Film thickness beyond which patch is assumed to be wet
scalar deltaWet_;
//- Splash parcel type label - id assigned to identify parcel for
// post-processing. If not specified, defaults to originating cloud
// type
label splashParcelType_;
//- Number of new parcels resulting from splash event
label parcelsPerSplash_;
// Surface roughness coefficient typically in the range 1300 - 5200
// and decreases with increasing surface roughness
//- Dry surface roughness coefficient
// = 2630 for dry interaction (ref. Bai)
scalar Adry_;
//- Wet surface roughness coefficient
// = 1320 for wet interaction (ref. Bai)
scalar Awet_;
//- Skin friction typically in the range 0.6 < Cf < 0.8
scalar Cf_;
//- Counter for number of new splash parcels
label nParcelsSplashed_;
scalarField CpFilmPatch_;
// Protected Member Functions
//- Return a vector tangential to input vector, v
vector tangentVector(const vector& v) const;
//- Return splashed parcel direction
vector splashDirection
(
const vector& tanVec1,
const vector& tanVec2,
const vector& nf
) const;
// Interaction models
//- Absorb parcel into film
void absorbInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mass,
bool& keepParticle
);
//- Bounce parcel (flip parcel normal velocity)
void bounceInteraction
(
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
) const;
//- Parcel interaction with dry surface
void drySplashInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
const parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
);
//- Parcel interaction with wetted surface
void wetSplashInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
parcelType& p,
const polyPatch& pp,
const label facei,
bool& keepParticle
);
//- Bai parcel splash interaction model
void splashInteraction
(
regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
const parcelType& p,
const polyPatch& pp,
const label facei,
const scalar mRatio,
const scalar We,
const scalar Wec,
const scalar sigma,
bool& keepParticle
);
// Injection from sheet (ejection) helper functions
virtual void cacheFilmFields
(
const label primaryPatchi,
const areaFilm&
);
//- Cache the film fields in preparation for injection
virtual void cacheFilmFields
(
const label filmPatchi,
const label primaryPatchi,
const regionModels::surfaceFilmModels::surfaceFilmRegionModel&
filmModel
const regionFilm&
);
//- Set the individual parcel properties
@ -269,7 +136,7 @@ public:
//- Destructor
virtual ~ThermoSurfaceFilm();
virtual ~ThermoSurfaceFilm() = default;
// Member Functions

View File

@ -20,7 +20,10 @@ EXE_INC = \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
LIB_LIBS = \
-lfiniteVolume \
@ -44,4 +47,6 @@ LIB_LIBS = \
-lregionModels \
-lsurfaceFilmModels \
-ldynamicMesh \
-ldynamicFvMesh
-ldynamicFvMesh \
-lregionFaModels \
-lfiniteArea

View File

@ -18,7 +18,10 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/regionFaModels/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/faOptions/lnInclude
LIB_LIBS = \
-lfiniteVolume \
@ -40,4 +43,6 @@ LIB_LIBS = \
-lincompressibleTransportModels \
-lregionModels \
-lsurfaceFilmModels \
-ldynamicFvMesh
-ldynamicFvMesh \
-lregionFaModels \
-lfiniteArea

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,14 +44,15 @@ defineTypeNameAndDebug(KirchhoffShell, 0);
addToRunTimeSelectionTable(vibrationShellModel, KirchhoffShell, dictionary);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool KirchhoffShell::read(const dictionary& dict)
bool KirchhoffShell::init(const dictionary& dict)
{
this->solution().readEntry("nNonOrthCorr", nNonOrthCorr_);
return true;
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void KirchhoffShell::solveDisplacement()
{
@ -249,16 +250,11 @@ KirchhoffShell::KirchhoffShell
dimensionedScalar(inv(pow3(dimLength)), Zero)
)
{
init();
init(dict);
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void KirchhoffShell::init()
{}
void KirchhoffShell::preEvolveRegion()
{}
@ -306,11 +302,9 @@ const tmp<areaScalarField> KirchhoffShell::rho() const
);
}
void KirchhoffShell::info()
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace regionModels

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,10 +33,10 @@ Usage
\verbatim
<patchName>
{
// Mandatory/Optional (inherited) entries
// Mandatory/Optional entries
...
// Mandatory entries (unmodifiable)
// Mandatory entries
vibrationShellModel KirchhoffShell;
f0 0.04;
f1 0.0;
@ -46,7 +46,7 @@ Usage
where the entries mean:
\table
Property | Description | Type | Reqd | Dflt
Property | Description | Type | Reqd | Deflt
vibrationShellModel | Type name: KirchhoffShell | word | yes | -
f0 | Damping coefficient [1/s] | scalar | yes | -
f1 | Damping coefficient [1/s] | scalar | yes | -
@ -94,8 +94,8 @@ class KirchhoffShell
// Private Member Functions
//- Initialize KirchhoffShell
void init();
//- Initialise KirchhoffShell
bool init(const dictionary& dict);
protected:
@ -140,10 +140,6 @@ protected:
// Protected Member Functions
//- Read control parameters from dictionary
virtual bool read(const dictionary& dict);
// Equations
//- Solve energy equation

View File

@ -13,4 +13,33 @@ KirchhoffShell/KirchhoffShell.C
derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.C
derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.C
/* Sub-Model */
liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C
liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C
liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.C
liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.C
liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.C
liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModelNew.C
liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C
liquidFilm/subModels/kinematic/force/forceList/forceList.C
liquidFilm/subModels/kinematic/force/force/force.C
liquidFilm/subModels/kinematic/force/force/forceNew.C
liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.C
liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.C
liquidFilm/subModels/filmSubModelBase.C
liquidFilm/liquidFilmBase.C
liquidFilm/liquidFilmBaseNew.C
liquidFilm/liquidFilmModel/liquidFilmModel.C
liquidFilm/kinematicThinFilm/kinematicThinFilm.C
derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C
functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C
LIB = $(FOAM_LIBBIN)/libregionFaModels

View File

@ -5,7 +5,13 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/thermophysicalProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
-I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/transportModels
LIB_LIBS = \
-lfiniteVolume \
@ -13,4 +19,5 @@ LIB_LIBS = \
-lmeshTools \
-lthermophysicalProperties \
-lspecie \
-lfaOptions
-lfaOptions \
-ldistributionModels

View File

@ -0,0 +1,200 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "velocityFilmShellFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
mixedFvPatchField<vector>(p, iF),
baffle_(),
dict_(dictionary::null),
curTimeIndex_(-1),
zeroWallVelocity_(true)
{
refValue() = 0;
refGrad() = 0;
valueFraction() = 1;
}
velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
(
const velocityFilmShellFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchField<vector>
(
ptf,
p,
iF,
mapper
),
baffle_(),
dict_(ptf.dict_),
curTimeIndex_(-1),
zeroWallVelocity_(true)
{}
velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchField<vector>(p, iF),
baffle_(nullptr),
dict_(dict),
curTimeIndex_(-1),
zeroWallVelocity_(dict.getOrDefault<bool>("zeroWallVelocity", true))
{
fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
typedef regionModels::areaSurfaceFilmModels::liquidFilmBase baffle;
if (dict.found("refValue"))
{
// Full restart
refValue() = vectorField("refValue", dict, p.size());
refGrad() = vectorField("refGradient", dict, p.size());
valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume fixedValue.
refValue() = *this;
refGrad() = vector::zero;
valueFraction() = 1;
}
if (!baffle_)
{
baffle_.reset(baffle::New(p, dict).ptr());
}
}
velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
(
const velocityFilmShellFvPatchVectorField& ptf,
const DimensionedField<vector, volMesh>& iF
)
:
mixedFvPatchField<vector>(ptf, iF),
baffle_(),
dict_(ptf.dict_),
curTimeIndex_(-1),
zeroWallVelocity_(true)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void velocityFilmShellFvPatchVectorField::updateCoeffs()
{
if (this->updated())
{
return;
}
// Execute the change to the openFraction only once per time-step
if (curTimeIndex_ != this->db().time().timeIndex())
{
baffle_->evolve();
volVectorField::Boundary& vfb =
db().lookupObjectRef<volVectorField>
(
this->internalField().name()
).boundaryFieldRef();
baffle_->vsm().mapToVolume(baffle_->Us(), vfb);
refGrad() = Zero;
valueFraction() = 1;
if (zeroWallVelocity_)
{
refValue() = Zero;
}
else
{
refValue() = vfb[patch().index()];
}
curTimeIndex_ = this->db().time().timeIndex();
}
mixedFvPatchField<vector>::updateCoeffs();
}
void velocityFilmShellFvPatchVectorField::write(Ostream& os) const
{
mixedFvPatchField<vector>::write(os);
// Remove value and type already written by mixedFvPatchField
dict_.remove("value");
dict_.remove("type");
dict_.remove("refValue");
dict_.remove("refGradient");
dict_.remove("valueFraction");
dict_.write(os, false);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
velocityFilmShellFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,226 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::velocityFilmShellFvPatchVectorField
Group
grpLiquidFilmBoundaryConditions
Description
Usage
Example of the boundary condition specification:
\verbatim
<patchName>
{
type velocityFilmShell;
active true;
infoOutput true;
U U;
pRef 1e5;
T0 300;
deltaWet 1e-4;
h0 1e-8;
zeroWallVelocity true;
thermo
{
H2O;
}
turbulence laminar;
laminarCoeffs
{
friction ManningStrickler; // Wall friction model
n 0.005; // Manning number
Cf 0.9; // Gas friction
}
injectionModels
(
curvatureSeparation
);
forces ();
curvatureSeparationCoeffs
{
definedPatchRadii 0;
}
region film;
liquidFilmModel kinematicThinFilm;
value uniform (0 0 0);
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Reqd | Deflt
type | Type name: velocityFilmShell | word | yes | -
U | Name of the primary U | word | yes | -
pRef | Reference pressure for thermo | scalar | yes | -
T0 | Film initial temperature | scalar | no | READ
thermo | Flow thermo | wordRes | yes | -
zeroWallVelocity | Flag to fix zero U for primary flow <!--
--> | bool | no | true
turbulence | Type of film turbulence model | word | yes | -
injectionModels | Lagrangian injection | | no | -
forces | Film force models | wordRes | no | -
deltaWet | Wet film thickness | scalar | no | 1e-4
h0 | Numerical minimum thickness | scalar | no | 1e-7
region | Name of the 2D region | word | yes | -
liquidFilmModel | Film model | word | yes | -
\endtable
SourceFiles
velocityFilmShellFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef velocityFilmShellFvPatchVectorField_H
#define velocityFilmShellFvPatchVectorField_H
#include "autoPtr.H"
#include "liquidFilmBase.H"
#include "mixedFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class velocityFilmShellFvPatchVectorField Declaration
\*---------------------------------------------------------------------------*/
class velocityFilmShellFvPatchVectorField
:
public mixedFvPatchField<vector>
{
// Private Data
//- Thermal baffle
autoPtr<regionModels::areaSurfaceFilmModels::liquidFilmBase> baffle_;
//- Dictionary
mutable dictionary dict_;
//- Time index to evolve the film
label curTimeIndex_;
//- Zero wall velocity. Fix U to zero or to film U
bool zeroWallVelocity_;
public:
//- Runtime type information
TypeName("velocityFilmShell");
// Constructors
//- Construct from patch and internal field
velocityFilmShellFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
velocityFilmShellFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
//- velocityFilmShellFvPatchVectorField onto a new patch
velocityFilmShellFvPatchVectorField
(
const velocityFilmShellFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new velocityFilmShellFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
velocityFilmShellFvPatchVectorField
(
const velocityFilmShellFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new velocityFilmShellFvPatchVectorField(*this, iF)
);
}
// Member Functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,163 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "setTimeStepFaRegionsFunctionObject.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(setTimeStepFaRegionsFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
setTimeStepFaRegionsFunctionObject,
dictionary
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::
setTimeStepFaRegionsFunctionObject::
setTimeStepFaRegionsFunctionObject
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
timeFunctionObject(name, runTime)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::adjustTimeStep()
{
// Wanted timestep
scalar newDeltaT = regionDeltaT();
static label index = -1;
if ((time_.timeIndex() != index) && (newDeltaT < time_.deltaTValue()))
{
// Store current time so we don't get infinite recursion (since
// setDeltaT calls adjustTimeStep() again)
index = time_.timeIndex();
// Set time, allow deltaT to be adjusted for writeInterval purposes
const_cast<Time&>(time_).setDeltaT(newDeltaT, false);
return true;
}
return false;
}
bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::read
(
const dictionary& dict
)
{
if (timeFunctionObject::read(dict))
{
// Ensure that adjustTimeStep is active
if (!time_.controlDict().lookupOrDefault<bool>("adjustTimeStep", false))
{
FatalIOErrorInFunction(dict)
<< "Need to set 'adjustTimeStep' true to allow timestep control"
<< nl
<< exit(FatalIOError);
}
return true;
}
return false;
}
Foam::scalar Foam::functionObjects::setTimeStepFaRegionsFunctionObject::
regionDeltaT() const
{
const wordList names(time_.sortedNames<regionFaModel>());
scalar Co = 0.0;
forAll (names, i)
{
const auto* regionFa = time_.cfindObject<regionFaModel>(names[i]);
if (regionFa)
{
const scalar regionCo = regionFa->CourantNumber();
if (regionCo > Co)
{
Co = regionCo;
}
}
}
if (names.size() > 0)
{
const scalar regionFaMaxCo =
time_.controlDict().get<scalar>("regionFaMaxCo");
const scalar maxDeltaTFact = regionFaMaxCo/(Co + SMALL);
const scalar deltaTFact =
min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
return deltaTFact*time_.deltaTValue();
}
return time_.deltaTValue();
}
bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::execute()
{
return true;
}
bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::write()
{
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::setTimeStepFaRegionsFunctionObject
Group
grpUtilitiesFunctionObjects
Description
This function object controls the time step for classes of the type
\c regionFaModel. It reads \c regionFaMaxCo entry from \c controlDict
and evaluate the time step based on the finite area Courant Number.
Can only be used with solvers using \c adjustTimeStep control (e.g.
\c pimpleFoam). It makes no attempt to co-operate with other time step
'controllers', e.g. \c maxCo, other functionObjects. Supports \c enabled
flag but none of the other options \c timeStart, \c timeEnd, \c writeControl
etc.
Usage
Example of function object specification to manipulate the time step:
\verbatim
setTimeStep1
{
// Mandatory entries
type setTimeStepFaRegion;
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Reqd | Deflt
type | Type name: setTimeStepFaRegion | word | yes | -
enabled | On/off switch | bool | no | yes
\endtable
The inherited entries are elaborated in:
- \link timeFunctionObject.H \endlink
- \link regionFaModel.H \endlink
SourceFiles
setTimeStepFaRegionsFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_setTimeStepFaRegionsFunctionObject_H
#define functionObjects_setTimeStepFaRegionsFunctionObject_H
#include "timeFunctionObject.H"
#include "regionFaModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam::regionModels;
namespace Foam
{
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class setTimeStepFaRegionsFunctionObject Declaration
\*---------------------------------------------------------------------------*/
class setTimeStepFaRegionsFunctionObject
:
public functionObjects::timeFunctionObject
{
// Private Member Functions
//- No copy construct
setTimeStepFaRegionsFunctionObject
(
const setTimeStepFaRegionsFunctionObject&
) = delete;
//- No copy assignment
void operator=(const setTimeStepFaRegionsFunctionObject&) = delete;
//- Return minimum deltaT from fa regions
scalar regionDeltaT() const;
public:
//- Runtime type information
TypeName("setTimeStepFaRegion");
// Constructors
//- Construct from components
setTimeStepFaRegionsFunctionObject
(
const word& name,
const Time& runTime,
const dictionary& dict
);
// Destructor
virtual ~setTimeStepFaRegionsFunctionObject() = default;
// Member Functions
//- Called at the end of Time::adjustDeltaT() if adjustTime is true
virtual bool adjustTimeStep();
//- Read and set the function object if its data have changed
virtual bool read(const dictionary& dict);
//- Execute does nothing
virtual bool execute();
//- Write does nothing
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,190 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "kinematicThinFilm.H"
#include "addToRunTimeSelectionTable.H"
#include "uniformDimensionedFields.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(kinematicThinFilm, 0);
addToRunTimeSelectionTable(liquidFilmBase, kinematicThinFilm, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
kinematicThinFilm::kinematicThinFilm
(
const word& modelType,
const fvPatch& patch,
const dictionary& dict
)
:
liquidFilmModel(modelType, patch, dict)
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void kinematicThinFilm::preEvolveRegion()
{
rhoSp_.storePrevIter();
USp_.storePrevIter();
pnSp_.storePrevIter();
// Update mass exchange sources
liquidFilmModel::preEvolveRegion();
// gas pressure map from primary region
ppf_ = pg();
}
void kinematicThinFilm::evolveRegion()
{
if (debug)
{
InfoInFunction << endl;
}
const areaVectorField& ns = regionMesh().faceAreaNormals();
const areaVectorField gs(g_ - ns*(ns & g_));
phi2s_ = fac::interpolate(h_)*phif_;
for (int oCorr=1; oCorr<=nOuterCorr_; oCorr++)
{
pf_.storePrevIter();
faVectorMatrix UsEqn
(
fam::ddt(h_, Uf_)
+ fam::div(phi2s_, Uf_)
==
gs*h_
+ turbulence_->Su(Uf_)
+ faOptions()(h_, Uf_, sqr(dimVelocity))
+ forces_.correct(Uf_)
+ USp_
);
UsEqn.relax();
faOptions().constrain(UsEqn);
if (momentumPredictor_)
{
solve(UsEqn == - fac::grad(pf_*h_)/rho_ + pf_*fac::grad(h_)/rho_);
}
for (int corr=1; corr<=nCorr_; corr++)
{
areaScalarField UsA(UsEqn.A());
Uf_ = UsEqn.H()/UsA;
Uf_.correctBoundaryConditions();
faOptions().correct(Uf_);
phif_ =
(fac::interpolate(Uf_) & regionMesh().Le())
- fac::interpolate(1.0/(rho_*UsA))
* fac::lnGrad(pf_*h_)*regionMesh().magLe()
+ fac::interpolate(pf_/(rho_*UsA))
* fac::lnGrad(h_)*regionMesh().magLe();
for (int nFilm=1; nFilm<=nFilmCorr_; nFilm++)
{
faScalarMatrix hEqn
(
fam::ddt(h_)
+ fam::div(phif_, h_)
==
faOptions()(rho_, h_, dimVelocity)
+ rhoSp_
);
hEqn.relax();
faOptions().constrain(hEqn);
hEqn.solve();
faOptions().correct(h_);
if (nFilm == nFilmCorr_)
{
phi2s_ = hEqn.flux();
}
}
// Bound h_
h_ = max(h_, h0_);
pf_ = rho_*gn_*h_ - sigma_*fac::laplacian(h_) + pnSp_ + ppf_;
pf_.correctBoundaryConditions();
pf_.relax();
Uf_ -= (1.0/(rho_*UsA))*fac::grad(pf_*h_)
- (pf_/(rho_*UsA))*fac::grad(h_);
Uf_.correctBoundaryConditions();
faOptions().correct(Uf_);
}
}
Info<< "Film h min/max = " << min(h_).value() << ", "
<< max(h_).value() << endl;
Info<< "Film U min/max = " << max(mag(Uf_)).value() << endl;
}
void kinematicThinFilm::postEvolveRegion()
{
// Reset sources
liquidFilmModel::postEvolveRegion();
// Correct thermo
correctThermoFields();
// Correct turbulence
turbulence_->correct();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionFaModels::kinematicThinFilm
Description
Thin film model.
SourceFiles
kinematicThinFilm.C
kinematicThinFilmI.H
\*---------------------------------------------------------------------------*/
#ifndef kinematicThinFilm_H
#define kinematicThinFilm_H
#include "volFieldsFwd.H"
#include "liquidFilmModel.H"
#include "faMesh.H"
#include "filmTurbulenceModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class kinematicThinFilm Declaration
\*---------------------------------------------------------------------------*/
class kinematicThinFilm
:
public liquidFilmModel
{
public:
//- Runtime type information
TypeName("kinematicThinFilm");
// Constructors
//- Construct from components and dict
kinematicThinFilm
(
const word& modelType,
const fvPatch& patch,
const dictionary& dict
);
//- No copy construct
kinematicThinFilm(const kinematicThinFilm&) = delete;
//- No copy assignment
void operator=(const kinematicThinFilm&) = delete;
//- Destructor
virtual ~kinematicThinFilm() = default;
// Member Functions
// Evolution
//- Pre-evolve film
virtual void preEvolveRegion();
//- Evolve the film
virtual void evolveRegion();
//- Post-evolve film
virtual void postEvolveRegion();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,560 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "liquidFilmBase.H"
#include "faMesh.H"
#include "gravityMeshObject.H"
#include "movingWallVelocityFvPatchVectorField.H"
#include "turbulentFluidThermoModel.H"
#include "turbulentTransportModel.H"
#include "calculatedFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(liquidFilmBase, 0);
defineRunTimeSelectionTable(liquidFilmBase, dictionary);
const Foam::word liquidFilmName("liquidFilm");
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
liquidFilmBase::liquidFilmBase
(
const word& modelType,
const fvPatch& p,
const dictionary& dict
)
:
regionFaModel(p, liquidFilmName, modelType, dict, true),
momentumPredictor_
(
this->solution().subDict("PIMPLE").get<bool>("momentumPredictor")
),
nOuterCorr_
(
this->solution().subDict("PIMPLE").get<label>("nOuterCorr")
),
nCorr_(this->solution().subDict("PIMPLE").get<label>("nCorr")),
nFilmCorr_
(
this->solution().subDict("PIMPLE").get<label>("nFilmCorr")
),
h0_("h0", dimLength, 1e-7, dict),
deltaWet_("deltaWet", dimLength, 1e-4, dict),
UName_(dict.get<word>("U")),
pName_(dict.lookupOrDefault<word>("p", word::null)),
pRef_(dict.get<scalar>("pRef")),
h_
(
IOobject
(
"hf_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
regionMesh()
),
Uf_
(
IOobject
(
"Uf_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
regionMesh()
),
pf_
(
IOobject
(
"pf_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
regionMesh(),
dimensionedScalar(dimPressure, Zero)
),
ppf_
(
IOobject
(
"ppf_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
regionMesh(),
dimensionedScalar(dimPressure, Zero)
),
phif_
(
IOobject
(
"phif_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fac::interpolate(Uf_) & regionMesh().Le()
),
phi2s_
(
IOobject
(
"phi2s_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fac::interpolate(h_*Uf_) & regionMesh().Le()
),
gn_
(
IOobject
(
"gn",
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
regionMesh(),
dimensionedScalar(dimAcceleration, Zero)
),
g_(meshObjects::gravity::New(primaryMesh().time())),
massSource_
(
IOobject
(
"massSource",
primaryMesh().time().timeName(),
primaryMesh()
),
primaryMesh(),
dimensionedScalar(dimMass, Zero),
calculatedFvPatchField<scalar>::typeName
),
momentumSource_
(
IOobject
(
"momentumSource",
primaryMesh().time().timeName(),
primaryMesh()
),
primaryMesh(),
dimensionedVector(dimPressure, Zero),
calculatedFvPatchField<vector>::typeName
),
pnSource_
(
IOobject
(
"pnSource",
primaryMesh().time().timeName(),
primaryMesh()
),
primaryMesh(),
dimensionedScalar(dimPressure, Zero),
calculatedFvPatchField<scalar>::typeName
),
energySource_
(
IOobject
(
"energySource",
primaryMesh().time().timeName(),
primaryMesh()
),
primaryMesh(),
dimensionedScalar(dimEnergy, Zero),
calculatedFvPatchField<scalar>::typeName
),
addedMassTotal_(0),
faOptions_(Foam::fa::options::New(p))
{
const areaVectorField& ns = regionMesh().faceAreaNormals();
gn_ = g_ & ns;
if (!faOptions_.optionList::size())
{
Info << "No finite area options present" << endl;
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
liquidFilmBase::~liquidFilmBase()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
scalar liquidFilmBase::CourantNumber() const
{
scalar CoNum = 0.0;
scalar velMag = 0.0;
edgeScalarField SfUfbyDelta
(
regionMesh().edgeInterpolation::deltaCoeffs()*mag(phif_)
);
CoNum =
max(SfUfbyDelta/regionMesh().magLe()).value()*time().deltaT().value();
velMag = max(mag(phif_)/regionMesh().magLe()).value();
reduce(CoNum, maxOp<scalar>());
reduce(velMag, maxOp<scalar>());
Info<< "Max film Courant Number: " << CoNum
<< " Film velocity magnitude: " << velMag << endl;
return CoNum;
}
Foam::tmp<Foam::areaVectorField> liquidFilmBase::Uw() const
{
tmp<areaVectorField> tUw
(
new areaVectorField
(
IOobject
(
"tUw",
primaryMesh().time().timeName(),
primaryMesh()
),
regionMesh(),
dimensionedVector(dimVelocity, Zero)
)
);
areaVectorField& Uw = tUw.ref();
const polyPatch& pp = primaryMesh().boundaryMesh()[patch_.index()];
if
(
primaryMesh().moving()
&& isA<movingWallVelocityFvPatchVectorField>(pp)
)
{
const movingWallVelocityFvPatchVectorField& wpp =
refCast<const movingWallVelocityFvPatchVectorField>(pp);
tmp<vectorField> tUwall = wpp.Uwall();
// Map Up to area
tmp<vectorField> UsWall = vsmPtr_->mapToSurface(tUwall());
const vectorField& nHat =
regionMesh().faceAreaNormals().internalField();
Uw.primitiveFieldRef() = UsWall() - nHat*(UsWall() & nHat);
}
return tUw;
}
Foam::tmp<Foam::areaVectorField> liquidFilmBase::Us() const
{
tmp<areaVectorField> tUs
(
new areaVectorField
(
IOobject
(
"tUs",
primaryMesh().time().timeName(),
primaryMesh()
),
regionMesh(),
dimensionedVector(dimVelocity, Zero)
)
);
// Uf quadratic profile
tUs.ref() = Foam::sqrt(2.0)*Uf_;
return tUs;
}
Foam::tmp<Foam::areaVectorField> liquidFilmBase::Up() const
{
const label patchi = patch_.index();
const volVectorField& Uprimary =
primaryMesh().lookupObject<volVectorField>(UName_);
const fvPatchVectorField& Uw = Uprimary.boundaryField()[patchi];
tmp<areaVectorField> tUp
(
new areaVectorField
(
IOobject
(
"tUp",
primaryMesh().time().timeName(),
primaryMesh()
),
regionMesh(),
dimensionedVector(dimVelocity, Zero)
)
);
areaVectorField& Up = tUp.ref();
scalarField hp(patch_.size(), Zero);
// map areas h to hp on primary
vsmPtr_->mapToField(h_, hp);
const vectorField& nHat = regionMesh().faceAreaNormals().internalField();
// U tangential on primary
const vectorField Ust(-Uw.snGrad()*hp);
// Map U tang to surface
Up.primitiveFieldRef() = vsmPtr_->mapToSurface(Ust);
// U tangent on surface
Up.primitiveFieldRef() -= nHat*(Up.primitiveField() & nHat);
return tUp;
}
tmp<areaScalarField> liquidFilmBase::pg() const
{
tmp<areaScalarField> tpg
(
new areaScalarField
(
IOobject
(
"tpg",
primaryMesh().time().timeName(),
primaryMesh()
),
regionMesh(),
dimensionedScalar(dimPressure, Zero)
)
);
areaScalarField& pfg = tpg.ref();
if (pName_ != word::null)
{
const volScalarField& pp =
primaryMesh().lookupObject<volScalarField>(pName_);
volScalarField::Boundary& pw =
const_cast<volScalarField::Boundary&>(pp.boundaryField());
//pw -= pRef_;
pfg.primitiveFieldRef() = vsmPtr_->mapInternalToSurface<scalar>(pw)();
}
return tpg;
}
tmp<areaScalarField> liquidFilmBase::alpha() const
{
tmp<areaScalarField> talpha
(
new areaScalarField
(
IOobject
(
"talpha",
primaryMesh().time().timeName(),
primaryMesh()
),
regionMesh(),
dimensionedScalar(dimless, Zero)
)
);
areaScalarField& alpha = talpha.ref();
alpha = pos0(h_ - deltaWet_);
return talpha;
}
void liquidFilmBase::addSources
(
const label patchi,
const label facei,
const scalar massSource,
const vector& momentumSource,
const scalar pressureSource,
const scalar energySource
)
{
massSource_.boundaryFieldRef()[patchi][facei] += massSource;
pnSource_.boundaryFieldRef()[patchi][facei] += pressureSource;
momentumSource_.boundaryFieldRef()[patchi][facei] += momentumSource;
}
void liquidFilmBase::preEvolveRegion()
{
regionFaModel::preEvolveRegion();
}
void liquidFilmBase::postEvolveRegion()
{
if (debug && primaryMesh().time().writeTime())
{
massSource_.write();
pnSource_.write();
momentumSource_.write();
}
massSource_.boundaryFieldRef() = Zero;
pnSource_.boundaryFieldRef() = Zero;
momentumSource_.boundaryFieldRef() = Zero;
regionFaModel::postEvolveRegion();
}
Foam::fa::options& liquidFilmBase::faOptions()
{
return faOptions_;
}
const areaVectorField& liquidFilmBase::Uf() const
{
return Uf_;
}
const areaScalarField& liquidFilmBase::gn() const
{
return gn_;
}
const uniformDimensionedVectorField& liquidFilmBase::g() const
{
return g_;
}
const areaScalarField& liquidFilmBase::h() const
{
return h_;
}
const edgeScalarField& liquidFilmBase::phif() const
{
return phif_;
}
const edgeScalarField& liquidFilmBase::phi2s() const
{
return phi2s_;
}
const dimensionedScalar& liquidFilmBase::h0() const
{
return h0_;
}
const regionFaModel& liquidFilmBase::region() const
{
return *this;
}
scalar liquidFilmBase::pRef()
{
return pRef_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,331 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::liquidFilmBase
Description
Base class for thermal 2D shells
SourceFiles
liquidFilmBase.C
\*---------------------------------------------------------------------------*/
#ifndef liquidFilmBase_H
#define liquidFilmBase_H
#include "runTimeSelectionTables.H"
#include "autoPtr.H"
#include "faCFD.H"
#include "volFieldsFwd.H"
#include "uniformDimensionedFields.H"
#include "regionFaModel.H"
#include "faOptions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class liquidFilmBase Declaration
\*---------------------------------------------------------------------------*/
class liquidFilmBase
:
public regionFaModel
{
protected:
// Protected Data
// Solution parameters
//- Momentum predictor
Switch momentumPredictor_;
//- Number of outer correctors
label nOuterCorr_;
//- Number of PISO-like correctors
label nCorr_;
//- Number of film thickness correctors
label nFilmCorr_;
//- Cumulative continuity error
scalar cumulativeContErr_;
//- Smallest numerical thickness
dimensionedScalar h0_;
//- Delta wet for sub-models
dimensionedScalar deltaWet_;
//- Name of the velocity field
word UName_;
//- Name of the pressure field
word pName_;
//- Reference absolute pressure
scalar pRef_;
// Fields
//- Film hight
areaScalarField h_;
//- Film velocity
areaVectorField Uf_;
//- Film pressure
areaScalarField pf_;
//- Primary region pressure
areaScalarField ppf_;
//- Film momentum flux
edgeScalarField phif_;
//- Film height flux
edgeScalarField phi2s_;
//- Normal gravity field
areaScalarField gn_;
//- Gravity
uniformDimensionedVectorField g_;
// Mass exchanage fields from the primary region (lagragian)
//- Mass
volScalarField massSource_;
//- Momentum
volVectorField momentumSource_;
//- Normal pressure by particles
volScalarField pnSource_;
//- Energy
volScalarField energySource_;
//- Total mass added
scalar addedMassTotal_;
//- faOptions
Foam::fa::options& faOptions_;
public:
//- Runtime type information
TypeName("liquidFilmBase");
// Declare runtime constructor selection tables
declareRunTimeSelectionTable
(
autoPtr,
liquidFilmBase,
dictionary,
(
const word& modelType,
const fvPatch& patch,
const dictionary& dict
),
(modelType, patch, dict)
);
// Constructors
//- Construct from type name and mesh and dict
liquidFilmBase
(
const word& modelType,
const fvPatch& patch,
const dictionary& dict
);
//- No copy construct
liquidFilmBase(const liquidFilmBase&) = delete;
//- No copy assignment
void operator=(const liquidFilmBase&) = delete;
// Selectors
//- Return a reference to the selected model using dictionary
static autoPtr<liquidFilmBase> New
(
const fvPatch& patch,
const dictionary& dict
);
//- Destructor
virtual ~liquidFilmBase();
// Member Functions
//- Courant number evaluation
virtual scalar CourantNumber() const;
// Helper functions
//- Wall velocity
tmp<areaVectorField> Uw() const;
//- Film surface film velocity
tmp<areaVectorField> Us() const;
//- Primary region velocity at film hight. Assume the film to be
// in the viscous sub-layer
tmp<areaVectorField> Up() const;
//- Map primary static pressure
tmp<areaScalarField> pg() const;
//- Wet indicator using h0
tmp<areaScalarField> alpha() const;
// Access functions
//- Return faOptions
Foam::fa::options& faOptions();
//- Access const reference Uf
const areaVectorField& Uf() const;
//- Access const reference gn
const areaScalarField& gn() const;
//- Gravity
const uniformDimensionedVectorField& g() const;
//- Access const reference h
const areaScalarField& h() const;
//- Access to momentum flux
const edgeScalarField& phif() const;
//- Access continuity flux
const edgeScalarField& phi2s() const;
//- Return h0
const dimensionedScalar& h0() const;
//- Access to this region
const regionFaModel& region() const;
//- Access to pRef
scalar pRef();
// Transfer fields - to the primary region (lagragian injection)
//- Return mass transfer source - Eulerian phase only
//virtual tmp<volScalarField> primaryMassTrans() const = 0;
//- Return the film mass available for transfer to cloud
virtual const volScalarField& cloudMassTrans() const = 0;
//- Return the parcel diameters originating from film to cloud
virtual const volScalarField& cloudDiameterTrans() const = 0;
// Evolution
//- Pre-evolve film
virtual void preEvolveRegion();
//- Post-evolve film
virtual void postEvolveRegion();
// Thermo variables
//- Access const reference mu
virtual const areaScalarField& mu() const = 0;
//- Access const reference rho
virtual const areaScalarField& rho() const = 0;
//- Access const reference sigma
virtual const areaScalarField& sigma() const = 0;
//- Access const reference Tf
virtual const areaScalarField& Tf() const = 0;
//- Access const reference Cp
virtual const areaScalarField& Cp() const = 0;
// External hook to add sources and mass exchange variables
//- Add sources
virtual void addSources
(
const label patchi, // patchi on primary region
const label facei, // facei of patchi
const scalar massSource, // [kg]
const vector& momentumSource, // [kg.m/s] (tang'l momentum)
const scalar pressureSource, // [kg.m/s] (normal momentum)
const scalar energySource = 0 // [J]
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "liquidFilmBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
autoPtr<liquidFilmBase> liquidFilmBase::New
(
const fvPatch& p,
const dictionary& dict
)
{
word modelType = dict.get<word>("liquidFilmModel");
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalErrorInFunction
<< "Unknown liquidFilmBase type "
<< modelType << nl << nl
<< "Valid liquidFilmBase types :" << nl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<liquidFilmBase>(cstrIter()(modelType, p, dict));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,381 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "liquidFilmModel.H"
#include "addToRunTimeSelectionTable.H"
#include "uniformDimensionedFields.H"
#include "gravityMeshObject.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(liquidFilmModel, 0);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void liquidFilmModel::correctThermoFields()
{
scalarField X(thermo_.size(), 1);
forAll (rho_, faceI)
{
rho_[faceI] = thermo_.rho(pRef_, Tf_[faceI], X);
mu_[faceI] = thermo_.mu(pRef_, Tf_[faceI], X);
sigma_[faceI] = thermo_.sigma(pRef_, Tf_[faceI], X);
Cp_[faceI] = thermo_.Cp(pRef_, Tf_[faceI], X);
}
forAll (regionMesh().boundary(), patchI)
{
const scalarField& patchTf = Tf_.boundaryFieldRef()[patchI];
scalarField& patchRho = rho_.boundaryFieldRef()[patchI];
scalarField& patchmu = mu_.boundaryFieldRef()[patchI];
scalarField& patchsigma = sigma_.boundaryFieldRef()[patchI];
scalarField& patchCp = Cp_.boundaryFieldRef()[patchI];
forAll(patchRho, edgeI)
{
patchRho[edgeI] = thermo_.rho(pRef_, patchTf[edgeI], X);
patchmu[edgeI] = thermo_.mu(pRef_, patchTf[edgeI], X);
patchsigma[edgeI] = thermo_.sigma(pRef_, patchTf[edgeI], X);
patchCp[edgeI] = thermo_.Cp(pRef_, patchTf[edgeI], X);
}
}
//Initialize pf_
pf_ = rho_*gn_*h_ - sigma_*fac::laplacian(h_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
liquidFilmModel::liquidFilmModel
(
const word& modelType,
const fvPatch& patch,
const dictionary& dict
)
:
liquidFilmBase(modelType, patch, dict),
thermo_(dict.subDict("thermo")),
rho_
(
IOobject
(
"rhof",
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
regionMesh(),
dimensionedScalar(dimDensity, Zero)
),
mu_
(
IOobject
(
"muf",
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
regionMesh(),
dimensionedScalar(dimViscosity, Zero)
),
Tf_
(
IOobject
(
"Tf_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
regionMesh(),
dimensionedScalar(dimTemperature, Zero)
),
Cp_
(
IOobject
(
"Cp_" + regionName_,
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
regionMesh(),
dimensionedScalar(dimEnergy/dimTemperature, Zero)
),
sigma_
(
IOobject
(
"sigmaf",
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
regionMesh(),
dimensionedScalar(dimMass/sqr(dimTime), Zero)
),
hRho_
(
IOobject
(
h_.name() + "*" + rho_.name(),
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
regionMesh(),
dimensionedScalar(h_.dimensions()*rho_.dimensions(), Zero)
),
rhoSp_
(
IOobject
(
"rhoSp",
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
regionMesh(),
dimensionedScalar(dimVelocity, Zero)
),
USp_
(
IOobject
(
"USp",
primaryMesh().time().timeName(),
primaryMesh()
),
regionMesh(),
dimensionedVector(sqr(dimVelocity), Zero)
),
pnSp_
(
IOobject
(
"pnSp",
primaryMesh().time().timeName(),
primaryMesh()
),
regionMesh(),
dimensionedScalar(dimPressure, Zero)
),
cloudMassTrans_
(
IOobject
(
"cloudMassTrans",
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
primaryMesh(),
dimensionedScalar(dimMass, Zero),
calculatedFvPatchField<scalar>::typeName
),
cloudDiameterTrans_
(
IOobject
(
"cloudDiameterTrans",
primaryMesh().time().timeName(),
primaryMesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
primaryMesh(),
dimensionedScalar(dimLength, Zero),
calculatedFvPatchField<scalar>::typeName
),
turbulence_(filmTurbulenceModel::New(*this, dict)),
availableMass_(regionMesh().faces().size(), Zero),
injection_(*this, dict),
forces_(*this, dict)
{
if (dict.found("T0"))
{
Tref_ = dict.get<scalar>("T0");
Tf_ = dimensionedScalar("T0", dimTemperature, dict);
}
correctThermoFields();
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
const areaScalarField& liquidFilmModel::mu() const
{
return mu_;
}
const areaScalarField& liquidFilmModel::rho() const
{
return rho_;
}
const areaScalarField& liquidFilmModel::sigma() const
{
return sigma_;
}
const areaScalarField& liquidFilmModel::Tf() const
{
return Tf_;
}
const areaScalarField& liquidFilmModel::Cp() const
{
return Cp_;
}
const liquidMixtureProperties& liquidFilmModel::thermo() const
{
return thermo_;
}
scalar liquidFilmModel::Tref() const
{
return Tref_;
}
const volScalarField& liquidFilmModel::cloudMassTrans() const
{
return cloudMassTrans_;
}
const volScalarField& liquidFilmModel::cloudDiameterTrans() const
{
return cloudDiameterTrans_;
}
void liquidFilmModel::preEvolveRegion()
{
liquidFilmBase::preEvolveRegion();
cloudMassTrans_ == dimensionedScalar(dimMass, Zero);
cloudDiameterTrans_ == dimensionedScalar(dimLength, Zero);
const scalar deltaT = primaryMesh().time().deltaTValue();
const scalarField rAreaDeltaT(scalar(1)/deltaT/regionMesh().S().field());
// Map the total mass, mom and pnSource from particles
rhoSp_.primitiveFieldRef() =
vsm().mapToSurface(massSource_.boundaryField()[patchID()]);
// [kg.m/s]
USp_.primitiveFieldRef() =
vsm().mapToSurface(momentumSource_.boundaryField()[patchID()]);
pnSp_.primitiveFieldRef() =
vsm().mapToSurface(pnSource_.boundaryField()[patchID()]);
// Calculate rate per area
rhoSp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
USp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
pnSp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
rhoSp_.relax();
pnSp_.relax();
USp_.relax();
}
void liquidFilmModel::postEvolveRegion()
{
availableMass_ = (h() - h0_)*rho()*regionMesh().S();
injection_.correct(availableMass_, cloudMassTrans_, cloudDiameterTrans_);
liquidFilmBase::postEvolveRegion();
}
void liquidFilmModel::info()
{
Info<< "\nSurface film: " << type() << " on patch: " << patchID() << endl;
const DimensionedField<scalar, areaMesh>& sf = regionMesh().S();
Info<< indent << "min/max(mag(Uf)) = "
<< gMin(mag(Uf_.field())) << ", "
<< gMax(mag(Uf_.field())) << nl
<< indent << "min/max(delta) = "
<< gMin(h_.field()) << ", " << gMax(h_.field()) << nl
<< indent << "coverage = "
<< gSum(alpha()().field()*mag(sf.field()))/gSum(mag(sf.field())) << nl
<< indent << "total mass = "
<< gSum(availableMass_) << nl;
injection_.info(Info);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,237 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionFaModels::liquidFilmModel
Description
Thin Model Film model.
SourceFiles
liquidFilmModel.C
kinematicThinFilmI.H
\*---------------------------------------------------------------------------*/
#ifndef liquidFilmModel_H
#define liquidFilmModel_H
#include "volFieldsFwd.H"
#include "liquidFilmBase.H"
#include "faMesh.H"
#include "filmTurbulenceModel.H"
#include "liquidMixtureProperties.H"
#include "injectionModelList.H"
#include "faCFD.H"
#include "forceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class liquidFilmModel Declaration
\*---------------------------------------------------------------------------*/
class liquidFilmModel
:
public liquidFilmBase
{
protected:
// Thermo properties
//- Liquid thermo
liquidMixtureProperties thermo_;
//- Reference tempararure
scalar Tref_;
// Fields
//- Density [kg/m3]
areaScalarField rho_;
//- Dynamic viscosity [Pa.s]
areaScalarField mu_;
//- Film temperature
areaScalarField Tf_;
//- Film Heat capacity
areaScalarField Cp_;
//- Surface tension [m/s2]
areaScalarField sigma_;
//- Film rho*height
areaScalarField hRho_;
// Mass exchange sources
//- Mass source
areaScalarField rhoSp_;
//- Momentum source
areaVectorField USp_;
//- Normal pressure by particles
areaScalarField pnSp_;
// Transfer fields
//- Film mass for transfer to cloud
volScalarField cloudMassTrans_;
//- Parcel diameters originating from film to cloud
volScalarField cloudDiameterTrans_;
// General properties
//- Turbulence model
autoPtr<filmTurbulenceModel> turbulence_;
// Sub-models
//- Available mass for transfer via sub-models
scalarField availableMass_;
//- Cloud injection
injectionModelList injection_;
//- Transfer with the continuous phase
//transferModelList transfer_;
//- List of film forces
forceList forces_;
public:
//- Runtime type information
TypeName("liquidFilmModel");
// Constructors
//- Construct from components and dict
liquidFilmModel
(
const word& modelType,
const fvPatch& patch,
const dictionary& dict
);
//- No copy construct
liquidFilmModel(const liquidFilmModel&) = delete;
//- No copy assignment
void operator=(const liquidFilmModel&) = delete;
//- Destructor
virtual ~liquidFilmModel() = default;
// Member Functions
// Helpers
//- Correct thermo
void correctThermoFields();
// Access
//- Access const reference mu
const areaScalarField& mu() const;
//- Access const reference rho
const areaScalarField& rho() const;
//- Access const reference sigma
const areaScalarField& sigma() const;
//- Access const reference Tf
const areaScalarField& Tf() const;
//- Access const reference Cp
const areaScalarField& Cp() const;
//- Access to thermo
const liquidMixtureProperties& thermo() const;
//- Access to reference temperature
scalar Tref() const;
// Transfer fields - to the primary region (lagragian injection)
//- Return the film mass available for transfer to cloud
virtual const volScalarField& cloudMassTrans() const;
//- Return the parcel diameters originating from film to cloud
virtual const volScalarField& cloudDiameterTrans() const;
// Evolution
//- Pre-evolve film
virtual void preEvolveRegion();
//- Post-evolve film
virtual void postEvolveRegion();
// I-O
//- Provide some feedback
virtual void info();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "filmSubModelBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
filmSubModelBase::filmSubModelBase(liquidFilmBase& film)
:
subModelBase(film.outputProperties()),
filmModel_(film)
{}
filmSubModelBase::filmSubModelBase
(
liquidFilmBase& film,
const dictionary& dict,
const word& baseName,
const word& modelType,
const word& dictExt
)
:
subModelBase
(
film.outputProperties(),
dict,
baseName,
modelType,
dictExt
),
filmModel_(film)
{}
filmSubModelBase::filmSubModelBase
(
const word& modelName,
liquidFilmBase& film,
const dictionary& dict,
const word& baseName,
const word& modelType
)
:
subModelBase
(
modelName,
film.outputProperties(),
dict,
baseName,
modelType
),
filmModel_(film)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
filmSubModelBase::~filmSubModelBase()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool filmSubModelBase::writeTime() const
{
return active() && filmModel_.time().writeTime();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::surfaceFilmModels::filmSubModelBase
Description
Base class for surface film sub-models
SourceFiles
filmSubModelBaseI.H
filmSubModelBase.C
\*---------------------------------------------------------------------------*/
#ifndef filmSubModelBase_H
#define filmSubModelBase_H
#include "liquidFilmBase.H"
#include "subModelBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class filmSubModelBase Declaration
\*---------------------------------------------------------------------------*/
class filmSubModelBase
:
public subModelBase
{
protected:
// Protected Data
//- Reference to the film surface film model
liquidFilmBase& filmModel_;
public:
// Constructors
//- Construct null
filmSubModelBase(liquidFilmBase& film);
//- Construct from film film without name
filmSubModelBase
(
liquidFilmBase& film,
const dictionary& dict,
const word& baseName,
const word& modelType,
const word& dictExt = "Coeffs"
);
//- Construct from film film with name
filmSubModelBase
(
const word& modelName,
liquidFilmBase& film,
const dictionary& dict,
const word& baseName,
const word& modelType
);
//- Destructor
virtual ~filmSubModelBase();
// Member Functions
// Access
//- Flag to indicate when to write a property
virtual bool writeTime() const;
//- Return const access to the film surface film model
inline const liquidFilmBase& film() const;
//- Return the reference to the film surface film model
inline liquidFilmBase& film();
template<class FilmType>
inline const FilmType& filmType() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "filmSubModelBaseI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "filmSubModelBaseTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline const liquidFilmBase& filmSubModelBase::film() const
{
return filmModel_;
}
inline liquidFilmBase& filmSubModelBase::film()
{
return filmModel_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class FilmType>
const FilmType& filmSubModelBase::filmType() const
{
if (!isA<FilmType>(filmModel_))
{
FatalErrorInFunction
<< "Model " << this->modelType() << " requested film type "
<< FilmType::typeName << " but film is type " << filmModel_.type()
<< abort(FatalError);
}
return refCast<const FilmType>(filmModel_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,170 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "filmTurbulenceModel.H"
#include "gravityMeshObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(filmTurbulenceModel, 0);
defineRunTimeSelectionTable(filmTurbulenceModel, dictionary);
const Enum
<
filmTurbulenceModel::frictionMethodType
>
filmTurbulenceModel::frictionMethodTypeNames_
{
{ frictionMethodType::mquadraticProfile, "quadraticProfile" },
{ frictionMethodType::mlinearProfile, "linearProfile" },
{ frictionMethodType::mDarcyWeisbach, "DarcyWeisbach" },
{ frictionMethodType::mManningStrickler, "ManningStrickler" }
};
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
filmTurbulenceModel::filmTurbulenceModel
(
const word& modelType,
liquidFilmBase& film,
const dictionary& dict
)
:
film_(film),
dict_(dict.subDict(modelType + "Coeffs")),
method_(frictionMethodTypeNames_.get("friction", dict_))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
filmTurbulenceModel::~filmTurbulenceModel()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
const liquidFilmBase& filmTurbulenceModel::film() const
{
return film_;
}
tmp<areaScalarField> filmTurbulenceModel::Cw() const
{
auto tCw =
tmp<areaScalarField>::New
(
IOobject
(
"tCw",
film_.primaryMesh().time().timeName(),
film_.primaryMesh()
),
film_.regionMesh(),
dimensionedScalar(dimVelocity)
);
auto& Cw = tCw.ref();
switch (method_)
{
case mquadraticProfile:
{
const scalarField& mu = film_.mu().primitiveField();
const scalarField& h = film_.h().primitiveField();
const scalar h0 = film_.h0().value();
Cw.primitiveFieldRef() = 3*mu/(h + h0);
Cw.min(5000.0);
break;
}
case mlinearProfile:
{
const scalarField& mu = film_.mu().primitiveField();
const scalarField& h = film_.h().primitiveField();
const scalar h0 = film_.h0().value();
Cw.primitiveFieldRef() = 2*mu/(h + h0);
break;
}
case mDarcyWeisbach:
{
const uniformDimensionedVectorField& g =
meshObjects::gravity::New(film_.primaryMesh().time());
const vectorField& Uf = film_.Uf().primitiveField();
scalar Cf = dict_.get<scalar>("Cf");
Cw.primitiveFieldRef() = Cf*mag(g.value())*mag(Uf);
break;
}
case mManningStrickler:
{
const uniformDimensionedVectorField& g =
meshObjects::gravity::New(film_.primaryMesh().time());
const scalar n = dict_.get<scalar>("n");
const vectorField& Uf = film_.Uf().primitiveField();
const scalarField& h = film_.h().primitiveField();
const scalar h0 = film_.h0().value();
Cw.primitiveFieldRef() =
sqr(n)*mag(g.value())*mag(Uf)/cbrt(h+h0);
break;
}
default:
{
FatalErrorInFunction
<< "Unimplemented method "
<< frictionMethodTypeNames_[method_] << nl
<< "Please set 'frictionMethod' to one of "
<< flatOutput(frictionMethodTypeNames_.sortedToc()) << nl
<< exit(FatalError);
break;
}
}
return tCw;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,183 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::areaSurfaceFilmModels::filmTurbulenceModel
Description
Base class for film turbulence models
SourceFiles
filmTurbulenceModel.C
filmTurbulenceModelNew.C
\*---------------------------------------------------------------------------*/
#ifndef regionFaModels_filmTurbulenceModel_H
#define regionFaModels_filmTurbulenceModel_H
#include "areaFieldsFwd.H"
#include "runTimeSelectionTables.H"
#include "faMatrices.H"
#include "liquidFilmBase.H"
#include "fvMesh.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class filmTurbulenceModel Declaration
\*---------------------------------------------------------------------------*/
class filmTurbulenceModel
{
// Private Member Functions
//- No copy construct
filmTurbulenceModel(const filmTurbulenceModel&) = delete;
//- No copy assignment
void operator=(const filmTurbulenceModel&) = delete;
public:
// Public Enumerations
//- Options for the friction models
enum frictionMethodType
{
mquadraticProfile,
mlinearProfile,
mDarcyWeisbach,
mManningStrickler
};
protected:
// Protected Data
//- Reference to liquidFilmBase
const liquidFilmBase& film_;
//- Names for friction models
static const Enum<frictionMethodType> frictionMethodTypeNames_;
//- Model dictionary
const dictionary dict_;
//- Method used
const frictionMethodType method_;
public:
//- Runtime type information
TypeName("filmTurbulenceModel");
// Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
filmTurbulenceModel,
dictionary,
(
liquidFilmBase& film,
const dictionary& dict
),
(film, dict)
);
// Constructors
//- Construct from type name, dictionary and surface film model
filmTurbulenceModel
(
const word& modelType,
liquidFilmBase& film,
const dictionary& dict
);
// Selectors
//- Return a reference to the selected injection model
static autoPtr<filmTurbulenceModel> New
(
liquidFilmBase& film,
const dictionary& dict
);
//- Destructor
virtual ~filmTurbulenceModel();
// Member Functions
// Access
//- Return film
const liquidFilmBase& film() const;
// Evolution
//- Return the wall film surface friction
virtual tmp<areaScalarField> Cw() const;
//- Return the film turbulence viscosity
virtual tmp<areaScalarField> mut() const = 0;
//- Correct/update the model
virtual void correct() = 0;
//- Return the source for the film momentum equation
virtual tmp<faVectorMatrix> Su(areaVectorField& U) const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "filmTurbulenceModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
autoPtr<filmTurbulenceModel> filmTurbulenceModel::New
(
liquidFilmBase& model,
const dictionary& dict
)
{
const word modelType(dict.get<word>("turbulence"));
Info<< " Selecting filmTurbulenceModel " << modelType << endl;
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalIOErrorInLookup
(
dict,
"filmTurbulenceModel",
modelType,
*dictionaryConstructorTablePtr_
) << exit(FatalIOError);
}
return autoPtr<filmTurbulenceModel>(cstrIter()(model, dict));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,117 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "laminar.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(laminar, 0);
addToRunTimeSelectionTable(filmTurbulenceModel, laminar, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
laminar::laminar
(
liquidFilmBase& film,
const dictionary& dict
)
:
filmTurbulenceModel(type(), film, dict),
Cf_(dict_.get<scalar>("Cf"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
laminar::~laminar()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
tmp<areaScalarField> laminar::mut() const
{
auto tmut =
tmp<areaScalarField>::New
(
IOobject
(
"mut",
film().primaryMesh().time().timeName(),
film().primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
film().regionMesh(),
dimensionedScalar(dimMass/dimLength/dimTime)
);
return tmut;
}
void laminar::correct()
{}
tmp<faVectorMatrix> laminar::Su(areaVectorField& U) const
{
// local references to film fields
tmp<areaVectorField> Uw = film_.Uw();
tmp<areaVectorField> Up = film_.Up();
// employ simple coeff-based model
const dimensionedScalar Cf("Cf", dimVelocity, Cf_);
tmp<areaScalarField> wf = Cw();
return
(
- fam::Sp(Cf, U) + Cf*Up() // surface contribution
- fam::Sp(wf(), U) + wf()*Uw() // wall contribution
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::areaSurfaceFilmModels::laminar
Description
Film laminar turbulence model.
SourceFiles
laminar.C
\*---------------------------------------------------------------------------*/
#ifndef regionFaModels_surfaceFilmModels_laminar_H
#define regionFaModels_surfaceFilmModels_laminar_H
#include "liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H"
#include "faCFD.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class laminar Declaration
\*---------------------------------------------------------------------------*/
class laminar
:
public filmTurbulenceModel
{
// Private Data
//- Surface roughness coefficient
scalar Cf_;
// Private Member Functions
//- No copy construct
laminar(const laminar&) = delete;
//- No copy assignment
void operator=(const laminar&) = delete;
public:
//- Runtime type information
TypeName("laminar");
// Constructors
//- Construct from surface film model
laminar(liquidFilmBase& film, const dictionary& dict);
//- Destructor
virtual ~laminar();
// Member Functions
// Evolution
//- Return the film turbulence viscosity
virtual tmp<areaScalarField> mut() const;
//- Correct/update the model
virtual void correct();
//- Return the source for the film momentum equation
virtual tmp<faVectorMatrix> Su(areaVectorField& U) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,195 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "contactAngleForce.H"
#include "addToRunTimeSelectionTable.H"
#include "faCFD.H"
#include "unitConversion.H"
#include "meshWavePatchDistMethod.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(contactAngleForce, 0);
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void contactAngleForce::initialise()
{
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
contactAngleForce::contactAngleForce
(
const word& typeName,
liquidFilmBase& film,
const dictionary& dict
)
:
force(typeName, film, dict),
Ccf_(coeffDict_.get<scalar>("Ccf")),
mask_
(
IOobject
(
typeName + ":fContactForceMask",
film.primaryMesh().time().timeName(),
film.primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
film.regionMesh(),
dimensionedScalar("mask", dimless, 1.0)
)
{
initialise();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
contactAngleForce::~contactAngleForce()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
tmp<faVectorMatrix> contactAngleForce::correct(areaVectorField& U)
{
tmp<areaVectorField> tForce
(
new areaVectorField
(
IOobject
(
typeName + ":contactForce",
film().primaryMesh().time().timeName(),
film().primaryMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
film().regionMesh(),
dimensionedVector(dimForce/dimDensity/dimArea, Zero)
)
);
vectorField& force = tForce.ref().primitiveFieldRef();
const labelUList& own = film().regionMesh().owner();
const labelUList& nbr = film().regionMesh().neighbour();
const DimensionedField<scalar, areaMesh>& magSf = film().regionMesh().S();
tmp<areaScalarField> talpha = film().alpha();
const areaScalarField& sigma = film().sigma();
const areaScalarField& rhof = film().rho();
tmp<areaScalarField> ttheta = theta();
const areaScalarField& theta = ttheta();
const areaVectorField gradAlpha(fac::grad(talpha()));
forAll(nbr, edgei)
{
const label faceO = own[edgei];
const label faceN = nbr[edgei];
label facei = -1;
if ((talpha()[faceO] > 0.5) && (talpha()[faceN] < 0.5))
{
facei = faceO;
}
else if ((talpha()[faceO] < 0.5) && (talpha()[faceN] > 0.5))
{
facei = faceN;
}
if (facei != -1 && mask_[facei] > 0.5)
{
const scalar invDx = film().regionMesh().deltaCoeffs()[edgei];
const vector n
(
gradAlpha[facei]/(mag(gradAlpha[facei]) + ROOTVSMALL)
);
const scalar cosTheta = cos(degToRad(theta[facei]));
force[facei] +=
Ccf_*n*sigma[facei]*(1 - cosTheta)/invDx/rhof[facei];
}
}
forAll(sigma.boundaryField(), patchi)
{
const faPatchField<scalar>& alphaPf = sigma.boundaryField()[patchi];
const faPatchField<scalar>& sigmaPf = sigma.boundaryField()[patchi];
const labelUList& faces = alphaPf.patch().edgeFaces();
forAll(sigmaPf, edgei)
{
label face0 = faces[edgei];
force[face0] = vector::zero;
}
}
force /= magSf.field();
if (film().regionMesh().time().writeTime())
{
tForce().write();
gradAlpha.write();
}
tmp<faVectorMatrix> tfvm
(
new faVectorMatrix(U, dimForce/dimDensity)
);
tfvm.ref() += tForce;
return tfvm;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,127 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::areaSurfaceFilmModels::contactAngleForce
Description
Base-class for film contact angle force models.
The effect of the contact angle force can be ignored over a specified
distance from patches.
SourceFiles
contactAngleForce.C
\*---------------------------------------------------------------------------*/
#ifndef contactAngleForce_H
#define contactAngleForce_H
#include "force.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class contactAngleForce Declaration
\*---------------------------------------------------------------------------*/
class contactAngleForce
:
public force
{
// Private Data
//- Coefficient applied to the contact angle force
scalar Ccf_;
//- Mask over which force is applied
areaScalarField mask_;
// Private Member Functions
//- Initialise
void initialise();
//- No copy construct
contactAngleForce(const contactAngleForce&) = delete;
//- No copy assignment
void operator=(const contactAngleForce&) = delete;
protected:
//- Return the contact angle field
virtual tmp<areaScalarField> theta() const = 0;
public:
//- Runtime type information
TypeName("contactAngle");
// Constructors
//- Construct from surface film model
contactAngleForce
(
const word& typeName,
liquidFilmBase& film,
const dictionary& dict
);
//- Destructor
virtual ~contactAngleForce();
// Member Functions
//- Correct
virtual tmp<faVectorMatrix> correct(areaVectorField& U);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,124 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "perturbedTemperatureDependentContactAngleForce.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(perturbedTemperatureDependentContactAngleForce, 0);
addToRunTimeSelectionTable
(
force,
perturbedTemperatureDependentContactAngleForce,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
perturbedTemperatureDependentContactAngleForce::
perturbedTemperatureDependentContactAngleForce
(
liquidFilmBase& film,
const dictionary& dict
)
:
contactAngleForce(typeName, film, dict),
thetaPtr_(Function1<scalar>::New("theta", coeffDict_)),
rndGen_(label(0)),
distribution_
(
distributionModel::New
(
coeffDict_.subDict("distribution"),
rndGen_
)
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
perturbedTemperatureDependentContactAngleForce::
~perturbedTemperatureDependentContactAngleForce()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
tmp<areaScalarField> perturbedTemperatureDependentContactAngleForce::
theta() const
{
tmp<areaScalarField> ttheta
(
new areaScalarField
(
IOobject
(
typeName + ":theta",
film().primaryMesh().time().timeName(),
film().primaryMesh()
),
film().regionMesh(),
dimensionedScalar(dimless, Zero)
)
);
areaScalarField& theta = ttheta.ref();
scalarField& thetai = theta.ref();
const areaScalarField& T = film().Tf();
// Initialize with the function of temperature
thetai = thetaPtr_->value(T());
// Add the stochastic perturbation
forAll(thetai, facei)
{
thetai[facei] += distribution_->sample();
}
return ttheta;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::areaSurfaceFilmModels::
perturbedTemperatureDependentContactAngleForce
Description
Temperature dependent contact angle force with a stochastic perturbation.
The contact angle in degrees is specified as a \c Foam::Function1 type,
to enable the use of, e.g. \c constant, \c polynomial, \c table values
and the stochastic perturbation obtained from a
\c Foam::distributionModels::distributionModel.
See also
- Foam::regionModels::areaSurfaceFilmModels::contactAngleForce
- areaSurfaceFilmModels::temperatureDependentContactAngleForce
- Foam::regionModels::areaSurfaceFilmModels::distributionContactAngleForce
- Foam::Function1Types
- Foam::distributionModel
SourceFiles
perturbedTemperatureDependentContactAngleForce.C
\*---------------------------------------------------------------------------*/
#ifndef perturbedTemperatureDependentContactAngleForce_H
#define perturbedTemperatureDependentContactAngleForce_H
#include "contactAngleForce.H"
#include "Function1.H"
#include "distributionModel.H"
#include "Random.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class perturbedTemperatureDependentContactAngleForce Declaration
\*---------------------------------------------------------------------------*/
class perturbedTemperatureDependentContactAngleForce
:
public contactAngleForce
{
// Private Data
//- Contact angle function
autoPtr<Function1<scalar>> thetaPtr_;
//- Random number generator
Random rndGen_;
//- Parcel size PDF model
const autoPtr<distributionModel> distribution_;
// Private Member Functions
//- No copy construct
perturbedTemperatureDependentContactAngleForce
(
const perturbedTemperatureDependentContactAngleForce&
) = delete;
//- No copy assignment
void operator=
(
const perturbedTemperatureDependentContactAngleForce&
) = delete;
protected:
//- Return the contact angle field
virtual tmp<areaScalarField> theta() const;
public:
//- Runtime type information
TypeName("perturbedTemperatureDependentContactAngle");
// Constructors
//- Construct from surface film model
perturbedTemperatureDependentContactAngleForce
(
liquidFilmBase& film,
const dictionary& dict
);
//- Destructor
virtual ~perturbedTemperatureDependentContactAngleForce();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "force.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(force, 0);
defineRunTimeSelectionTable(force, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
force::force(liquidFilmBase& film)
:
filmSubModelBase(film)
{}
force::force
(
const word& modelType,
liquidFilmBase& film,
const dictionary& dict
)
:
filmSubModelBase(film, dict, typeName, modelType)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
force::~force()
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,138 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::areaSurfaceFilmModels::force
Description
Base class for film (stress-based) force models
SourceFiles
force.C
forceNew.C
\*---------------------------------------------------------------------------*/
#ifndef force_H
#define force_H
#include "filmSubModelBase.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class force Declaration
\*---------------------------------------------------------------------------*/
class force
:
public filmSubModelBase
{
// Private Member Functions
//- No copy construct
force(const force&) = delete;
//- No copy assignment
void operator=(const force&) = delete;
public:
//- Runtime type information
TypeName("force");
// Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
force,
dictionary,
(
liquidFilmBase& film,
const dictionary& dict
),
(film, dict)
);
// Constructors
//- Construct null
force(liquidFilmBase& film);
//- Construct from type name, dictionary and surface film model
force
(
const word& modelType,
liquidFilmBase& film,
const dictionary& dict
);
// Selectors
//- Return a reference to the selected force model
static autoPtr<force> New
(
liquidFilmBase& film,
const dictionary& dict,
const word& modelType
);
//- Destructor
virtual ~force();
// Member Functions
// Evolution
//- Correct
virtual tmp<faVectorMatrix> correct(areaVectorField& U) = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "force.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
autoPtr<force> force::New
(
liquidFilmBase& model,
const dictionary& dict,
const word& modelType
)
{
Info<< " " << modelType << endl;
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalIOErrorInLookup
(
dict,
"force",
modelType,
*dictionaryConstructorTablePtr_
) << exit(FatalIOError);
}
return autoPtr<force>(cstrIter()(model, dict));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "forceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
forceList::forceList(liquidFilmBase& film)
:
PtrList<force>()
{}
forceList::forceList
(
liquidFilmBase& film,
const dictionary& dict
)
:
PtrList<force>()
{
const wordList models(dict.lookup("forces"));
Info<< " Selecting film force models" << endl;
if (models.size() > 0)
{
this->setSize(models.size());
forAll(models, i)
{
set(i, force::New(film, dict, models[i]));
}
}
else
{
Info<< " none" << endl;
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
forceList::~forceList()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
tmp<faVectorMatrix> forceList::correct(areaVectorField& U)
{
tmp<faVectorMatrix> tResult
(
new faVectorMatrix(U, dimForce/dimDensity)
);
faVectorMatrix& result = tResult.ref();
forAll(*this, i)
{
result += this->operator[](i).correct(U);
}
return tResult;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::surfaceFilmModels::forceList
Description
List container for film sources
SourceFiles
forceList.C
\*---------------------------------------------------------------------------*/
#ifndef forceList_H
#define forceList_H
#include "PtrList.H"
#include "force.H"
#include "faCFD.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class forceList Declaration
\*---------------------------------------------------------------------------*/
class forceList
:
public PtrList<force>
{
public:
// Constructors
//- Construct null
forceList(liquidFilmBase& film);
//- Construct from type name, dictionary and surface film model
forceList
(
liquidFilmBase& film,
const dictionary& dict
);
//- Destructor
virtual ~forceList();
// Member Functions
//- Return (net) force system
tmp<faVectorMatrix> correct(areaVectorField& U);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,324 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "curvatureSeparation.H"
#include "addToRunTimeSelectionTable.H"
#include "Time.H"
#include "stringListOps.H"
#include "cyclicPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(curvatureSeparation, 0);
addToRunTimeSelectionTable
(
injectionModel,
curvatureSeparation,
dictionary
);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
tmp<areaScalarField> curvatureSeparation::calcInvR1
(
const areaVectorField& U,
const scalarField& calcCosAngle
) const
{
const dimensionedScalar smallU(dimVelocity, ROOTVSMALL);
const areaVectorField UHat(U/(mag(U) + smallU));
tmp<areaScalarField> tinvR1
(
new areaScalarField("invR1", UHat & (UHat & -gradNHat_))
);
scalarField& invR1 = tinvR1.ref().primitiveFieldRef();
// apply defined patch radii
const scalar rMin = 1e-6;
const scalar definedInvR1 = 1.0/max(rMin, definedPatchRadii_);
if (definedPatchRadii_ > 0)
{
invR1 = definedInvR1;
}
// filter out large radii
const scalar rMax = 1e6;
forAll(invR1, i)
{
if ((mag(invR1[i]) < 1/rMax))
{
invR1[i] = -1.0;
}
}
return tinvR1;
}
tmp<scalarField> curvatureSeparation::calcCosAngle
(
const edgeScalarField& phi
) const
{
const areaVectorField& U = film().Uf();
const dimensionedScalar smallU(dimVelocity, ROOTVSMALL);
const areaVectorField UHat(U/(mag(U) + smallU));
const faMesh& mesh = film().regionMesh();
const labelUList& own = mesh.edgeOwner();
const labelUList& nbr = mesh.edgeNeighbour();
scalarField phiMax(mesh.nFaces(), -GREAT);
scalarField cosAngle(UHat.size(), Zero);
const scalarField invR1(calcInvR1(U, cosAngle));
forAll(nbr, edgei)
{
const label cellO = own[edgei];
const label cellN = nbr[edgei];
if (phi[edgei] > phiMax[cellO])
{
phiMax[cellO] = phi[edgei];
cosAngle[cellO] = -gHat_ & UHat[cellN];
}
if (-phi[edgei] > phiMax[cellN])
{
phiMax[cellN] = -phi[edgei];
cosAngle[cellN] = -gHat_ & UHat[cellO];
}
}
cosAngle *= pos(invR1);
// checks
if (debug && mesh.time().writeTime())
{
areaScalarField volCosAngle
(
IOobject
(
"cosAngle",
film().primaryMesh().time().timeName(),
film().primaryMesh(),
IOobject::NO_READ
),
film().regionMesh(),
dimensionedScalar(dimless, Zero)
);
volCosAngle.primitiveFieldRef() = cosAngle;
volCosAngle.correctBoundaryConditions();
volCosAngle.write();
}
return max(min(cosAngle, scalar(1)), scalar(-1));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
curvatureSeparation::curvatureSeparation
(
liquidFilmBase& film,
const dictionary& dict
)
:
injectionModel(type(), film, dict),
gradNHat_(fac::grad(film.regionMesh().faceAreaNormals())),
deltaByR1Min_(coeffDict_.getOrDefault<scalar>("deltaByR1Min", 0)),
definedPatchRadii_
(
coeffDict_.getOrDefault<scalar>("definedPatchRadii", 0)
),
magG_(mag(film.g().value())),
gHat_(Zero),
fThreshold_
(
coeffDict_.getOrDefault<scalar>("fThreshold", 1e-8)
),
minInvR1_
(
coeffDict_.getOrDefault<scalar>("minInvR1", 5)
)
{
if (magG_ < ROOTVSMALL)
{
FatalErrorInFunction
<< "Acceleration due to gravity must be non-zero"
<< exit(FatalError);
}
gHat_ = film.g().value()/magG_;
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void curvatureSeparation::correct
(
scalarField& availableMass,
scalarField& massToInject,
scalarField& diameterToInject
)
{
const faMesh& mesh = film().regionMesh();
const areaScalarField& delta = film().h();
const areaVectorField& U = film().Uf();
const edgeScalarField& phi = film().phi2s();
const areaScalarField& rho = film().rho();
const scalarField magSqrU(magSqr(film().Uf()));
const areaScalarField& sigma = film().sigma();
const scalarField cosAngle(calcCosAngle(phi));
const scalarField invR1(calcInvR1(U, cosAngle));
// calculate force balance
scalarField Fnet(mesh.nFaces(), Zero);
scalarField separated(mesh.nFaces(), Zero);
forAll(invR1, i)
{
if ((invR1[i] > minInvR1_) && (delta[i]*invR1[i] > deltaByR1Min_))
{
const scalar R1 = 1.0/(invR1[i] + ROOTVSMALL);
const scalar R2 = R1 + delta[i];
// inertial force
const scalar Fi = -delta[i]*rho[i]*magSqrU[i]*72.0/60.0*invR1[i];
// body force
const scalar Fb =
- 0.5*rho[i]*magG_*invR1[i]*(sqr(R1) - sqr(R2))*cosAngle[i];
// surface force
const scalar Fs = sigma[i]/R2;
Fnet[i] = Fi + Fb + Fs;
if (Fnet[i] + fThreshold_ < 0)
{
separated[i] = 1.0;
}
}
}
// inject all available mass
massToInject = separated*availableMass;
diameterToInject = separated*delta;
availableMass -= separated*availableMass;
addToInjectedMass(sum(massToInject));
if (debug && mesh.time().writeTime())
{
areaScalarField volFnet
(
IOobject
(
"Fnet",
film().primaryMesh().time().timeName(),
film().primaryMesh(),
IOobject::NO_READ
),
mesh,
dimensionedScalar(dimForce, Zero)
);
volFnet.primitiveFieldRef() = Fnet;
volFnet.write();
areaScalarField areaSeparated
(
IOobject
(
"separated",
film().primaryMesh().time().timeName(),
film().primaryMesh(),
IOobject::NO_READ
),
mesh,
dimensionedScalar(dimMass, Zero)
);
areaSeparated.primitiveFieldRef() = separated;
areaSeparated.write();
areaScalarField areaMassToInject
(
IOobject
(
"massToInject",
film().primaryMesh().time().timeName(),
film().primaryMesh(),
IOobject::NO_READ
),
mesh,
dimensionedScalar(dimMass, Zero)
);
areaMassToInject.primitiveFieldRef() = massToInject;
areaMassToInject.write();
areaScalarField areaInvR1
(
IOobject
(
"InvR1",
film().primaryMesh().time().timeName(),
film().primaryMesh(),
IOobject::NO_READ
),
mesh,
dimensionedScalar(inv(dimLength), Zero)
);
areaInvR1.primitiveFieldRef() = invR1;
areaInvR1.write();
}
injectionModel::correct();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::areaSurfaceFilmModels::curvatureSeparation
Description
Curvature film separation model
Assesses film curvature via the mesh geometry and calculates a force
balance of the form:
F_sum = F_inertial + F_body + F_surface
If F_sum < 0, the film separates. Similarly, if F_sum > 0 the film will
remain attached.
Based on description given by
Owen and D. J. Ryley. The flow of thin liquid films around corners.
International Journal of Multiphase Flow, 11(1):51-62, 1985.
SourceFiles
curvatureSeparation.C
\*---------------------------------------------------------------------------*/
#ifndef curvatureSeparation_H
#define curvatureSeparation_H
#include "injectionModel.H"
#include "faCFD.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class curvatureSeparation Declaration
\*---------------------------------------------------------------------------*/
class curvatureSeparation
:
public injectionModel
{
// Private Member Functions
//- No copy construct
curvatureSeparation(const curvatureSeparation&) = delete;
//- No copy assignment
void operator=(const curvatureSeparation&) = delete;
protected:
// Protected Data
//- Gradient of surface normals
areaTensorField gradNHat_;
//- Minimum gravity driven film thickness (non-dimensionalised delta/R1)
scalar deltaByR1Min_;
//- List of radii for patches - if patch not defined, radius
//- calculated based on mesh geometry
scalar definedPatchRadii_;
//- Magnitude of gravity vector
scalar magG_;
//- Direction of gravity vector
vector gHat_;
//- Threshold force for separation
scalar fThreshold_;
//- Minimum inv R1 for separation
scalar minInvR1_;
// Protected Member Functions
//- Calculate local (inverse) radius of curvature
tmp<areaScalarField> calcInvR1
(
const areaVectorField& U,
const scalarField& calcCosAngle
) const;
//- Calculate the cosine of the angle between gravity vector and
//- cell out flow direction
tmp<scalarField> calcCosAngle(const edgeScalarField& phi) const;
public:
//- Runtime type information
TypeName("curvatureSeparation");
// Constructors
//- Construct from surface film model
curvatureSeparation
(
liquidFilmBase& film,
const dictionary& dict
);
//- Destructor
virtual ~curvatureSeparation() = default;
// Member Functions
// Evolution
//- Correct
virtual void correct
(
scalarField& availableMass,
scalarField& massToInject,
scalarField& diameterToInject
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "injectionModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(injectionModel, 0);
defineRunTimeSelectionTable(injectionModel, dictionary);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void injectionModel::addToInjectedMass(const scalar dMass)
{
injectedMass_ += dMass;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
injectionModel::injectionModel(liquidFilmBase& film)
:
filmSubModelBase(film),
injectedMass_(0.0)
{}
injectionModel::injectionModel
(
const word& modelType,
liquidFilmBase& film,
const dictionary& dict
)
:
filmSubModelBase(film, dict, typeName, modelType),
injectedMass_(0.0)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
injectionModel::~injectionModel()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void injectionModel::correct()
{
if (writeTime())
{
scalar injectedMass0 = getModelProperty<scalar>("injectedMass");
injectedMass0 += returnReduce(injectedMass_, sumOp<scalar>());
setModelProperty<scalar>("injectedMass", injectedMass0);
injectedMass_ = 0.0;
}
}
scalar injectionModel::injectedMassTotal() const
{
const scalar injectedMass0 = getModelProperty<scalar>("injectedMass");
return injectedMass0 + returnReduce(injectedMass_, sumOp<scalar>());
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,169 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::areaSurfaceFilmModels::injectionModel
Description
Base class for film injection models, handling mass transfer from the
film.
SourceFiles
injectionModel.C
injectionModelNew.C
\*---------------------------------------------------------------------------*/
#ifndef injectionModel_H
#define injectionModel_H
#include "filmSubModelBase.H"
#include "runTimeSelectionTables.H"
#include "scalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class injectionModel Declaration
\*---------------------------------------------------------------------------*/
class injectionModel
:
public filmSubModelBase
{
// Private Data
//- Injected mass
scalar injectedMass_;
// Private Member Functions
//- No copy construct
injectionModel(const injectionModel&) = delete;
//- No copy assignment
void operator=(const injectionModel&) = delete;
protected:
// Protected Member Functions
//- Add to injected mass
void addToInjectedMass(const scalar dMass);
//- Correct
void correct();
public:
//- Runtime type information
TypeName("injectionModel");
// Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
injectionModel,
dictionary,
(
liquidFilmBase& film,
const dictionary& dict
),
(film, dict)
);
// Constructors
//- Construct null
injectionModel(liquidFilmBase& film);
//- Construct from type name, dictionary and surface film model
injectionModel
(
const word& modelType,
liquidFilmBase& film,
const dictionary& dict
);
// Selectors
//- Return a reference to the selected injection model
static autoPtr<injectionModel> New
(
liquidFilmBase& film,
const dictionary& dict,
const word& mdoelType
);
//- Destructor
virtual ~injectionModel();
// Member Functions
//- Correct
virtual void correct
(
scalarField& availableMass,
scalarField& massToInject,
scalarField& diameterToInject
) = 0;
//- Return the total mass injected
virtual scalar injectedMassTotal() const;
//- Accumulate the total mass injected for the patches into the
//- scalarField provided
virtual void patchInjectedMassTotals(scalar& patchMasses) const
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "injectionModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
autoPtr<injectionModel> injectionModel::New
(
liquidFilmBase& model,
const dictionary& dict,
const word& modelType
)
{
Info<< " " << modelType << endl;
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalIOErrorInLookup
(
dict,
"injectionModel",
modelType,
*dictionaryConstructorTablePtr_
) << exit(FatalIOError);
}
return autoPtr<injectionModel>(cstrIter()(model, dict));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,169 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "injectionModelList.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
injectionModelList::injectionModelList(liquidFilmBase& film)
:
PtrList<injectionModel>(),
filmSubModelBase(film)
{}
injectionModelList::injectionModelList
(
liquidFilmBase& film,
const dictionary& dict
)
:
PtrList<injectionModel>(),
filmSubModelBase
(
"injectionModelList",
film,
dict,
"injectionModelList",
"injectionModelList"
),
massInjected_(Zero)
{
const wordList activeModels(dict.lookup("injectionModels"));
wordHashSet models(activeModels);
Info<< " Selecting film injection models" << endl;
if (models.size())
{
this->setSize(models.size());
label i = 0;
for (const word& model : models)
{
set(i, injectionModel::New(film, dict, model));
i++;
}
}
else
{
Info<< " none" << endl;
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
injectionModelList::~injectionModelList()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void injectionModelList::correct
(
scalarField& availableMass,
volScalarField& massToInject,
volScalarField& diameterToInject
)
{
const label patchi = film().patchID();
// Correct models that accumulate mass and diameter transfers
forAll(*this, i)
{
injectionModel& im = operator[](i);
im.correct
(
availableMass,
massToInject.boundaryFieldRef()[patchi],
diameterToInject.boundaryFieldRef()[patchi]
);
}
massInjected_ += gSum(massToInject.boundaryField()[patchi]);
}
void injectionModelList::info(Ostream& os)
{
const polyBoundaryMesh& pbm = film().primaryMesh().boundaryMesh();
scalar injectedMass = 0;
scalar patchInjectedMasses = 0;
forAll(*this, i)
{
const injectionModel& im = operator[](i);
injectedMass += im.injectedMassTotal();
im.patchInjectedMassTotals(patchInjectedMasses);
}
os << indent << "injected mass = " << injectedMass << nl;
const label patchi = film().patchID();
if (mag(patchInjectedMasses) > VSMALL)
{
os << indent << indent << "from patch " << pbm[patchi].name()
<< " = " << patchInjectedMasses << nl;
}
scalar mass0(Zero);
this->getBaseProperty("massInjected", mass0);
scalar mass(massInjected_);
mass += mass0;
Info<< indent << " - patch: " << pbm[patchi].name() << " "
<< mass << endl;
if (film().primaryMesh().time().writeTime())
{
setBaseProperty("massInjected", mass);
massInjected_ = 0.0;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,127 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::regionModels::surfaceFilmModels::injectionModelList
Description
List container for film injection models
SourceFiles
injectionModelList.C
\*---------------------------------------------------------------------------*/
#ifndef injectionModelList_H
#define injectionModelList_H
#include "PtrList.H"
#include "injectionModel.H"
#include "filmSubModelBase.H"
#include "scalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace regionModels
{
namespace areaSurfaceFilmModels
{
/*---------------------------------------------------------------------------*\
Class injectionModelList Declaration
\*---------------------------------------------------------------------------*/
class injectionModelList
:
public PtrList<injectionModel>,
public filmSubModelBase
{
// Private Data
//- List of mass injected per patch
scalar massInjected_;
// Private Member Functions
//- No copy construct
injectionModelList(const injectionModelList&) = delete;
//- No copy assignment
void operator=(const injectionModelList&) = delete;
public:
// Constructors
//- Construct null
injectionModelList(liquidFilmBase& film);
//- Construct from type name, dictionary and surface film model
injectionModelList
(
liquidFilmBase& film,
const dictionary& dict
);
//- Destructor
virtual ~injectionModelList();
// Member Functions
// Evolution
//- Correct
virtual void correct
(
scalarField& availableMass,
volScalarField& massToInject,
volScalarField& diameterToInject
);
// I-O
//- Provide some info
virtual void info(Ostream& os);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace areaSurfaceFilmModels
} // End namespace regionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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