isothermalFilm/fvModels/filmCloudTransfer/ejectionModels: New film->cloud transfer sub-models

The filmCloudTransfer fvModel now supports an optional ejection model which
provides transfer of film to cloud by dripping from an inverted surface or
curvature separation:

Class
    Foam::filmEjectionModels::dripping

Description
    Dripping film to cloud ejection transfer model

    On an inverted surface if the film thickness is sufficient to generate a
    valid parcel the equivalent mass is removed from the film and transfered to
    the cloud as a parcel containing droplets with a diameter obtained from
    the specified parcelDistribution.

Usage
    Example usage:
    \verbatim
    filmCloudTransfer
    {
        type    filmCloudTransfer;

        libs    ("libfilmCloudTransfer.so");

        ejection
        {
            model   dripping;

            deltaStable 5e-4;

            minParticlesPerParcel 10;

            parcelDistribution
            {
                type            RosinRammler;
                Q               0;
                min             1e-3;
                max             2e-3;
                d               7.5e-05;
                n               0.5;
            }
        }
    }
    \endverbatim

Class
    Foam::filmEjectionModels::BrunDripping

Description
    Brun dripping film to cloud ejection transfer model

    If the film thickness exceeds the critical value needed to generate one or
    more drops, the equivalent mass is removed from the film.  The critical film
    thickness is calculated from the Rayleigh-Taylor stability analysis of film
    flow on an inclined plane by Brun et.al.

    Reference:
    \verbatim
        Brun, P. T., Damiano, A., Rieu, P., Balestra, G., & Gallaire, F. (2015).
        Rayleigh-Taylor instability under an inclined plane.
        Physics of Fluids (1994-present), 27(8), 084107.
    \endverbatim

    The diameter of the drops formed are obtained from the local capillary
    length multiplied by the \c dCoeff coefficient which defaults to 3.3.

    Reference:
    \verbatim
        Lefebvre, A. (1988).
        Atomisation and sprays
        (Vol. 1040, No. 2756). CRC press.
    \endverbatim

Usage
    Example usage:
    \verbatim
    filmCloudTransfer
    {
        type    filmCloudTransfer;

        libs    ("libfilmCloudTransfer.so");

        ejection
        {
            model   BrunDripping;

            deltaStable 5e-4;
        }
    }
    \endverbatim

Class
    Foam::filmEjectionModels::curvatureSeparation

Description
    Curvature induced separation film to cloud ejection transfer model

    Assesses film curvature via the mesh geometry and calculates a force
    balance of the form:

        F_sum = F_inertial + F_body + F_surface_tension

    If F_sum < 0, the film separates and is transferred to the cloud
    if F_sum >= 0 the film remains attached.

    Reference:
    \verbatim
        Owen, I., & Ryley, D. J. (1985).
        The flow of thin liquid films around corners.
        International journal of multiphase flow, 11(1), 51-62.
    \endverbatim

Usage
    Example usage:
    \verbatim
    filmCloudTransfer
    {
        type    filmCloudTransfer;

        libs    ("libfilmCloudTransfer.so");

        ejection
        {
            model   curvatureSeparation;

            deltaStable 5e-4;
        }
    }
    \endverbatim

The new tutorials/modules/multiRegion/film/cylinderDripping tutorial case
demonstrates a film dripping into the cloud.  The standard cylinder case is
turned upside-down (by changing the orientation of gravity) with an initial
0.2mm film of water over the surface which drips when the thickness is greater
than 0.5mm.  Settings for all three ejection models are provided in the
constant/film/fvModels dictionary with the standard dripping model selected.
This commit is contained in:
Henry Weller
2023-05-15 17:59:31 +01:00
parent b2d74bfdb4
commit 2cf8f66852
55 changed files with 3200 additions and 104 deletions

View File

@ -37,7 +37,6 @@ License
void Foam::solvers::isothermalFilm::correctAlpha()
{
volScalarField& alpha = alpha_;
volVectorField& U = U_;
fvVectorMatrix& UEqn = tUEqn.ref();
@ -76,7 +75,7 @@ void Foam::solvers::isothermalFilm::correctAlpha()
const surfaceScalarField phig("phig", phip + pbByAlphaGradRhof*alphaf);
phi = constrainedField(fvc::flux(HbyA) - alpharAUf*phig);
phi_ = constrainedField(fvc::flux(HbyA) - alpharAUf*phig);
const surfaceScalarField phid("phid", rhof*phi);
@ -102,7 +101,7 @@ void Foam::solvers::isothermalFilm::correctAlpha()
if (pimple.finalNonOrthogonalIter())
{
alphaRhoPhi = alphaEqn.flux();
alphaRhoPhi_ = alphaEqn.flux();
}
}
@ -111,16 +110,16 @@ void Foam::solvers::isothermalFilm::correctAlpha()
constrainedField(pbByAlphaf*fvc::snGrad(alpha)*mesh.magSf())
);
phi -= alpharAUf*phiGradAlpha;
phi_ -= alpharAUf*phiGradAlpha;
U = HbyA - rAU*fvc::reconstruct(alphaf*(phig + phiGradAlpha));
U_ = HbyA - rAU*fvc::reconstruct(alphaf*(phig + phiGradAlpha));
// Remove film-normal component of velocity
U -= nHat*(nHat & U);
U_ -= nHat*(nHat & U);
U.correctBoundaryConditions();
U_.correctBoundaryConditions();
fvConstraints().constrain(U);
fvConstraints().constrain(U_);
fvConstraints().constrain(alpha);

View File

@ -1,4 +1,9 @@
filmCloudTransfer.C
ejectionModels/ejectionModel/ejectionModel.C
ejectionModels/ejectionModel/ejectionModelNew.C
ejectionModels/dripping/dripping.C
ejectionModels/BrunDripping/BrunDripping.C
ejectionModels/curvatureSeparation/curvatureSeparation.C
cloudFilmTransfer/CloudFilmTransfer/CloudFilmTransferBase.C
cloudFilmTransfer/makeThermoParcelCloudFilmTransfer.C

View File

@ -521,20 +521,29 @@ const Foam::labelList& Foam::CloudFilmTransfer<CloudType>::filmPatches() const
template<class CloudType>
void Foam::CloudFilmTransfer<CloudType>::cacheFilmFields(const label filmi)
{
// Film->Cloud transfer Not implemented yet
fv::filmCloudTransfer& filmCloudTransfer = filmTransferPtrs()[filmi];
filmCloudTransfer.resetFromCloudFields();
// Set the mass transferred from film->cloud to 0
this->massParcelPatch_.setSize
(
this->owner().mesh().boundary()[filmPatches_[filmi]].size(),
0.0
);
this->deltaFilmPatch_ = filmCloudTransfer.deltaToCloud();
// Ensure the film->cloud ejection transfer is up-to-date
filmCloudTransfer.correct();
if (filmCloudTransfer.ejecting())
{
this->massParcelPatch_ = filmCloudTransfer.ejectedMassToCloud();
this->diameterParcelPatch_ = filmCloudTransfer.ejectedDiameterToCloud();
UFilmPatch_ = filmCloudTransfer.UToCloud();
rhoFilmPatch_ = filmCloudTransfer.rhoToCloud();
TFilmPatch_ = filmCloudTransfer.TToCloud();
CpFilmPatch_ = filmCloudTransfer.CpToCloud();
}
else
{
// Set the mass transferred from film->cloud to 0
this->massParcelPatch_.setSize(0);
}
}

View File

@ -25,20 +25,22 @@ Class
Foam::CloudFilmTransfer
Description
Thermo parcel surface film model.
Thermo parcel<->film transfer model.
Responsible for:
- injecting parcels 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
References:
\verbatim
Bai, C., & Gosman, A. D. (1996).
Mathematical modelling of wall films formed by impinging sprays.
SAE transactions, 782-796.
Bai, C. X., Rusche, H., & Gosman, A. D. (2002).
Modeling of gasoline spray impingement.
Atomization and Sprays, 12(1-3).
\endverbatim
SourceFiles
CloudFilmTransfer.C

View File

@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2016-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "BrunDripping.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace filmEjectionModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(BrunDripping, 0);
addToRunTimeSelectionTable(ejectionModel, BrunDripping, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
BrunDripping::BrunDripping
(
const dictionary& dict,
const solvers::isothermalFilm& film
)
:
ejectionModel(dict, film),
ubarStar_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookupOrDefault("ubarStar", 1.62208)
),
dCoeff_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookupOrDefault("dCoeff", 3.3)
),
deltaStable_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookupOrDefault("deltaStable", scalar(0))
),
minParticlesPerParcel_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookupOrDefault("minParticlesPerParcel", 1)
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
BrunDripping::~BrunDripping()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void BrunDripping::correct()
{
const scalar piBy6 = constant::mathematical::pi/6;
const scalarField& magSf = film_.magSf;
const vectorField& nHat = film_.nHat;
const scalarField& delta = film_.delta;
const scalarField& rho = film_.rho;
const tmp<volScalarField> tsigma = film_.sigma();
const volScalarField::Internal& sigma = tsigma();
const scalar magg = mag(film_.g.value());
const vector gHat = -film_.g.value()/magg;
const scalar deltaT = film_.mesh.time().deltaTValue();
forAll(delta, celli)
{
rate_[celli] = 0;
diameter_[celli] = 0;
const scalar sinAlpha = nHat[celli] & gHat;
if (sinAlpha > small && delta[celli] > deltaStable_)
{
const scalar lc = sqrt(sigma[celli]/(rho[celli]*magg));
const scalar deltaStable = max
(
3*lc*sqrt(1 - sqr(sinAlpha))
/(ubarStar_*sqrt(sinAlpha)*sinAlpha),
deltaStable_
);
if (delta[celli] > deltaStable)
{
const scalar ddelta = delta[celli] - deltaStable;
const scalar massDrip = ddelta*rho[celli]*magSf[celli];
// Calculate dripped droplet diameter
diameter_[celli] = dCoeff_*lc;
// Calculate the minimum mass of a droplet parcel
const scalar minMass =
minParticlesPerParcel_
*rho[celli]*piBy6*pow3(diameter_[celli]);
if (massDrip > minMass)
{
// Calculate rate of dripping
rate_[celli] = ddelta/(deltaT*delta[celli]);
}
}
}
}
ejectionModel::correct();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace filmEjectionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2016-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::filmEjectionModels::BrunDripping
Description
Brun dripping film to cloud ejection transfer model
If the film thickness exceeds the critical value needed to generate one or
more drops, the equivalent mass is removed from the film. The critical film
thickness is calculated from the Rayleigh-Taylor stability analysis of film
flow on an inclined plane by Brun et.al.
Reference:
\verbatim
Brun, P. T., Damiano, A., Rieu, P., Balestra, G., & Gallaire, F. (2015).
Rayleigh-Taylor instability under an inclined plane.
Physics of Fluids (1994-present), 27(8), 084107.
\endverbatim
The diameter of the drops formed are obtained from the local capillary
length multiplied by the \c dCoeff coefficient which defaults to 3.3.
Reference:
\verbatim
Lefebvre, A. (1988).
Atomisation and sprays
(Vol. 1040, No. 2756). CRC press.
\endverbatim
Usage
Example usage:
\verbatim
filmCloudTransfer
{
type filmCloudTransfer;
libs ("libfilmCloudTransfer.so");
ejection
{
model BrunDripping;
deltaStable 5e-4;
}
}
\endverbatim
SourceFiles
BrunDripping.C
\*---------------------------------------------------------------------------*/
#ifndef BrunDripping_H
#define BrunDripping_H
#include "ejectionModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace filmEjectionModels
{
/*---------------------------------------------------------------------------*\
Class BrunDripping Declaration
\*---------------------------------------------------------------------------*/
class BrunDripping
:
public ejectionModel
{
// Private Member Data
//- Critical non-dimensional interface velocity
// Coefficient in the film angle stability function.
// Defaults to 1.62208
scalar ubarStar_;
//- Coefficient relating the diameter of the drops formed to
// the capillary length.
// Defaults to 3.3
scalar dCoeff_;
//- Stable film thickness - drips only formed if thickness
// exceeds this threshold value
scalar deltaStable_;
//- Minimum number of droplets per parcel
scalar minParticlesPerParcel_;
public:
//- Runtime type information
TypeName("BrunDripping");
// Constructors
//- Construct from dictionary and film model
BrunDripping
(
const dictionary& dict,
const solvers::isothermalFilm& film
);
//- Disallow default bitwise copy construction
BrunDripping(const BrunDripping&) = delete;
//- Destructor
virtual ~BrunDripping();
// Member Functions
//- Correct
virtual void correct();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const BrunDripping&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace filmEjectionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,309 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "curvatureSeparation.H"
#include "fvcGrad.H"
#include "zeroGradientFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace filmEjectionModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(curvatureSeparation, 0);
addToRunTimeSelectionTable
(
ejectionModel,
curvatureSeparation,
dictionary
);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
tmp<scalarField> curvatureSeparation::calcInvR1
(
const volVectorField& U
) const
{
const vectorField UHat(U.field()/(mag(U.field()) + rootVSmall));
tmp<scalarField> tinvR1(-(UHat & (UHat & gradNHat_)));
scalarField& invR1 = tinvR1.ref();
const scalar rMin = 1e-6;
const fvMesh& mesh = film_.mesh;
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(patchRadii_, i)
{
const label patchi = patchRadii_[i].first();
const scalar definedInvR1 = 1/max(rMin, patchRadii_[i].second());
UIndirectList<scalar>(invR1, pbm[patchi].faceCells()) = definedInvR1;
}
// Filter out large radii
const scalar rMax = 1e6;
forAll(invR1, i)
{
if (mag(invR1[i]) < 1/rMax)
{
invR1[i] = -1;
}
}
return tinvR1;
}
tmp<scalarField> curvatureSeparation::calcCosAngle
(
const surfaceScalarField& alphaRhoPhi
) const
{
const fvMesh& mesh = film_.mesh;
const scalar magg(mag(film_.g.value()));
const vector gHat(film_.g.value()/magg);
const vectorField nf(mesh.Sf()/mesh.magSf());
const labelUList& own = mesh.owner();
const labelUList& nbr = mesh.neighbour();
scalarField alphaRhoPhiMax(mesh.nCells(), -great);
tmp<scalarField> tcosAngle
(
new scalarField(mesh.nCells(), 0)
);
scalarField& cosAngle = tcosAngle.ref();
forAll(nbr, facei)
{
const label cellO = own[facei];
const label cellN = nbr[facei];
if (alphaRhoPhi[facei] > alphaRhoPhiMax[cellO])
{
alphaRhoPhiMax[cellO] = alphaRhoPhi[facei];
cosAngle[cellO] = -gHat & nf[facei];
}
if (-alphaRhoPhi[facei] > alphaRhoPhiMax[cellN])
{
alphaRhoPhiMax[cellN] = -alphaRhoPhi[facei];
cosAngle[cellN] = -gHat & -nf[facei];
}
}
forAll(alphaRhoPhi.boundaryField(), patchi)
{
const fvsPatchScalarField& alphaRhoPhip =
alphaRhoPhi.boundaryField()[patchi];
const fvPatch& pp = alphaRhoPhip.patch();
if (pp.coupled())
{
const labelList& faceCells = pp.faceCells();
const vectorField nf(pp.nf());
forAll(alphaRhoPhip, i)
{
const label celli = faceCells[i];
if (alphaRhoPhip[i] > alphaRhoPhiMax[celli])
{
alphaRhoPhiMax[celli] = alphaRhoPhip[i];
cosAngle[celli] = -gHat & nf[i];
}
}
}
}
return tcosAngle;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
curvatureSeparation::curvatureSeparation
(
const dictionary& dict,
const solvers::isothermalFilm& film
)
:
ejectionModel(dict, film),
gradNHat_(fvc::grad(film_.nHat)),
deltaByR1Min_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookupOrDefault<scalar>("deltaByR1Min", scalar(0))
),
deltaStable_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookupOrDefault("deltaStable", scalar(0))
)
{
const List<Tuple2<word, scalar>> prIn
(
dict.lookupOrDefault("patchRadii", List<Tuple2<word, scalar>>::null())
);
const wordList& allPatchNames = film_.mesh.boundaryMesh().names();
DynamicList<Tuple2<label, scalar>> prData(allPatchNames.size());
labelHashSet uniquePatchIDs;
forAllReverse(prIn, i)
{
labelList patchIDs = findStrings(prIn[i].first(), allPatchNames);
forAll(patchIDs, j)
{
const label patchi = patchIDs[j];
if (!uniquePatchIDs.found(patchi))
{
const scalar radius = prIn[i].second();
prData.append(Tuple2<label, scalar>(patchi, radius));
uniquePatchIDs.insert(patchi);
}
}
}
patchRadii_.transfer(prData);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
curvatureSeparation::~curvatureSeparation()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void curvatureSeparation::correct()
{
const scalarField& delta = film_.delta();
const scalarField& rho = film_.rho();
const vectorField& U = film_.U();
const tmp<volScalarField> tsigma = film_.sigma();
const volScalarField::Internal& sigma = tsigma();
const scalarField invR1(calcInvR1(film_.U));
const scalarField cosAngle(calcCosAngle(film_.alphaRhoPhi));
const scalar magg(mag(film_.g.value()));
const scalar deltaT = film_.mesh.time().deltaTValue();
// Calculate force balance
const scalar Fthreshold = 1e-10;
forAll(delta, celli)
{
rate_[celli] = 0;
diameter_[celli] = 0;
if
(
delta[celli] > deltaStable_
&& invR1[celli] > 0
&& delta[celli]*invR1[celli] > deltaByR1Min_
)
{
const scalar R1 = 1/(invR1[celli] + rootVSmall);
const scalar R2 = R1 + delta[celli];
// Inertial force
const scalar Fi =
-delta[celli]*rho[celli]
*magSqr(U[celli])*72/60*invR1[celli];
// Body force
const scalar Fb =
-0.5*rho[celli]*magg
*invR1[celli]*(sqr(R1) - sqr(R2))*cosAngle[celli];
// Surface tension force
const scalar Fs = sigma[celli]/R2;
if (Fi + Fb + Fs + Fthreshold < 0)
{
// Calculate rate of separation
rate_[celli] =
(delta[celli] - deltaStable_)/(deltaT*delta[celli]);
// Set the separated droplet diameter to the film thickness
diameter_[celli] = delta[celli];
}
}
}
}
void curvatureSeparation::topoChange(const polyTopoChangeMap& map)
{
ejectionModel::topoChange(map);
gradNHat_ = fvc::grad(film_.nHat);
}
void curvatureSeparation::mapMesh(const polyMeshMap& map)
{
ejectionModel::mapMesh(map);
gradNHat_ = fvc::grad(film_.nHat);
}
void curvatureSeparation::distribute(const polyDistributionMap& map)
{
ejectionModel::distribute(map);
gradNHat_ = fvc::grad(film_.nHat);
}
bool curvatureSeparation::movePoints()
{
ejectionModel::movePoints();
gradNHat_ = fvc::grad(film_.nHat);
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace filmEjectionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,175 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::filmEjectionModels::curvatureSeparation
Description
Curvature induced separation film to cloud ejection transfer model
Assesses film curvature via the mesh geometry and calculates a force
balance of the form:
F_sum = F_inertial + F_body + F_surface_tension
If F_sum < 0, the film separates and is transferred to the cloud
if F_sum >= 0 the film remains attached.
Reference:
\verbatim
Owen, I., & Ryley, D. J. (1985).
The flow of thin liquid films around corners.
International journal of multiphase flow, 11(1), 51-62.
\endverbatim
Usage
Example usage:
\verbatim
filmCloudTransfer
{
type filmCloudTransfer;
libs ("libfilmCloudTransfer.so");
ejection
{
model curvatureSeparation;
deltaStable 5e-4;
}
}
\endverbatim
SourceFiles
curvatureSeparation.C
\*---------------------------------------------------------------------------*/
#ifndef curvatureSeparation_H
#define curvatureSeparation_H
#include "ejectionModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace filmEjectionModels
{
/*---------------------------------------------------------------------------*\
Class curvatureSeparation Declaration
\*---------------------------------------------------------------------------*/
class curvatureSeparation
:
public ejectionModel
{
// Private Member Data
//- Gradient of film wall normals
tensorField gradNHat_;
//- Minimum gravity driven film thickness (non-dimensionalised delta/R1)
scalar deltaByR1Min_;
//- Stable film thickness - drips only formed if thickness
// exceeds this threshold value
scalar deltaStable_;
//- List of radii for patches
// if patch not listed the radius is calculated from the face normals
List<Tuple2<label, scalar>> patchRadii_;
// Protected Member Functions
//- Calculate local (inverse) radius of curvature
tmp<scalarField> calcInvR1(const volVectorField& U) const;
//- Calculate the cosine of the angle between gravity vector and
// cell out flow direction
tmp<scalarField> calcCosAngle(const surfaceScalarField& phi) const;
public:
//- Runtime type information
TypeName("curvatureSeparation");
// Constructors
//- Construct from dictionary and film model
curvatureSeparation
(
const dictionary& dict,
const solvers::isothermalFilm& film
);
//- Disallow default bitwise copy construction
curvatureSeparation(const curvatureSeparation&) = delete;
//- Destructor
virtual ~curvatureSeparation();
// Member Functions
//- Correct
virtual void correct();
// Mesh changes
//- Update topology using the given map
virtual void topoChange(const polyTopoChangeMap&);
//- Update from another mesh using the given map
virtual void mapMesh(const polyMeshMap&);
//- Redistribute or update using the given distribution map
virtual void distribute(const polyDistributionMap&);
//- Update for mesh motion
virtual bool movePoints();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const curvatureSeparation&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace filmEjectionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "dripping.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace filmEjectionModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(dripping, 0);
addToRunTimeSelectionTable(ejectionModel, dripping, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
dripping::dripping
(
const dictionary& dict,
const solvers::isothermalFilm& film
)
:
ejectionModel(dict, film),
deltaStable_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookup<scalar>("deltaStable")
),
minParticlesPerParcel_
(
dict.optionalSubDict(typeName + "Coeffs")
.lookupOrDefault("minParticlesPerParcel", 1)
),
rndGen_(label(0)),
parcelDistribution_
(
distribution::New
(
dict.optionalSubDict(typeName + "Coeffs")
.subDict("parcelDistribution"),
rndGen_,
0
)
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
dripping::~dripping()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void dripping::correct()
{
const scalar piBy6 = constant::mathematical::pi/6;
const scalarField gnHat(film_.nHat() & (-film_.g));
const scalarField& magSf = film_.magSf;
const scalarField& delta = film_.delta;
const scalarField& rho = film_.rho;
const scalar deltaT = film_.mesh.time().deltaTValue();
forAll(delta, celli)
{
rate_[celli] = 0;
diameter_[celli] = 0;
// Calculate available dripping mass
if (gnHat[celli] > small && delta[celli] > deltaStable_)
{
const scalar ddelta = delta[celli] - deltaStable_;
const scalar massDrip = ddelta*rho[celli]*magSf[celli];
// Sample dripped droplet diameter
diameter_[celli] = parcelDistribution_->sample();
// Calculate the minimum mass of a parcel
const scalar minMass =
minParticlesPerParcel_
*rho[celli]*piBy6*pow3(diameter_[celli]);
if (massDrip > minMass)
{
// Calculate rate of dripping
rate_[celli] = ddelta/(deltaT*delta[celli]);
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace filmEjectionModels
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::filmEjectionModels::dripping
Description
Dripping film to cloud ejection transfer model
On an inverted surface if the film thickness is sufficient to generate a
valid parcel the equivalent mass is removed from the film and transfered to
the cloud as a parcel containing droplets with a diameter obtained from
the specified parcelDistribution.
Usage
Example usage:
\verbatim
filmCloudTransfer
{
type filmCloudTransfer;
libs ("libfilmCloudTransfer.so");
ejection
{
model dripping;
deltaStable 5e-4;
minParticlesPerParcel 10;
parcelDistribution
{
type RosinRammler;
Q 0;
min 1e-3;
max 2e-3;
d 7.5e-05;
n 0.5;
}
}
}
\endverbatim
SourceFiles
dripping.C
\*---------------------------------------------------------------------------*/
#ifndef dripping_H
#define dripping_H
#include "ejectionModel.H"
#include "distribution.H"
#include "Random.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace filmEjectionModels
{
/*---------------------------------------------------------------------------*\
Class dripping Declaration
\*---------------------------------------------------------------------------*/
class dripping
:
public ejectionModel
{
// Private Member Data
//- Stable film thickness - drips only formed if thickness
// exceeds this threshold value
scalar deltaStable_;
//- Minimum number of droplets per parcel
scalar minParticlesPerParcel_;
//- Random number generator
Random rndGen_;
//- Parcel size PDF model
const autoPtr<distribution> parcelDistribution_;
public:
//- Runtime type information
TypeName("dripping");
// Constructors
//- Construct from dictionary and film model
dripping
(
const dictionary& dict,
const solvers::isothermalFilm& film
);
//- Disallow default bitwise copy construction
dripping(const dripping&) = delete;
//- Destructor
virtual ~dripping();
// Member Functions
// Evolution
//- Correct
virtual void correct();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const dripping&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace filmEjectionModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "ejectionModel.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ejectionModel, 0);
defineRunTimeSelectionTable(ejectionModel, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ejectionModel::ejectionModel
(
const dictionary& dict,
const solvers::isothermalFilm& film
)
:
film_(film),
rate_
(
volScalarField::Internal::New
(
"ejectionRate",
film.mesh,
dimensionedScalar(dimless/dimTime, 0)
)
),
diameter_
(
volScalarField::Internal::New
(
"ejectionDiameter",
film.mesh,
dimensionedScalar(dimLength, 0)
)
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ejectionModel::~ejectionModel()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ejectionModel::topoChange(const polyTopoChangeMap&)
{
// Resize in case of mesh change
rate_.setSize(film_.mesh.nCells());
diameter_.setSize(film_.mesh.nCells());
}
void Foam::ejectionModel::mapMesh(const polyMeshMap&)
{
// Resize in case of mesh change
rate_.setSize(film_.mesh.nCells());
diameter_.setSize(film_.mesh.nCells());
}
void Foam::ejectionModel::distribute(const polyDistributionMap&)
{
// Resize in case of mesh change
rate_.setSize(film_.mesh.nCells());
diameter_.setSize(film_.mesh.nCells());
}
bool Foam::ejectionModel::movePoints()
{
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::filmEjectionModels::ejectionModel
Description
Abstract base class for film to cloud ejection transfer models
SourceFiles
ejectionModel.C
ejectionModelNew.C
\*---------------------------------------------------------------------------*/
#ifndef ejectionModel_H
#define ejectionModel_H
#include "isothermalFilm.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ejectionModel Declaration
\*---------------------------------------------------------------------------*/
class ejectionModel
{
protected:
// Protected Member Data
//- Reference to the film
const solvers::isothermalFilm& film_;
//- Cached ejection rate (transfer to cloud)
volScalarField::Internal rate_;
//- Cached diameter of ejected droplets
volScalarField::Internal diameter_;
public:
//- Runtime type information
TypeName("ejectionModel");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
ejectionModel,
dictionary,
(
const dictionary& dict,
const solvers::isothermalFilm& film
),
(dict, film)
);
// Constructors
//- Construct from dictionary and film model
ejectionModel
(
const dictionary& dict,
const solvers::isothermalFilm& film
);
//- Disallow default bitwise copy construction
ejectionModel(const ejectionModel&) = delete;
// Selector
static autoPtr<ejectionModel> New
(
const dictionary& dict,
const solvers::isothermalFilm& film
);
//- Destructor
virtual ~ejectionModel();
// Member Functions
//- Return ejection rate (transfer to cloud)
const volScalarField::Internal& rate() const
{
return rate_;
}
//- Return diameter of ejected droplets
const volScalarField::Internal& diameter() const
{
return diameter_;
}
//- Correct
virtual void correct() = 0;
// Mesh changes
//- Update topology using the given map
virtual void topoChange(const polyTopoChangeMap&);
//- Update from another mesh using the given map
virtual void mapMesh(const polyMeshMap&);
//- Redistribute or update using the given distribution map
virtual void distribute(const polyDistributionMap&);
//- Update for mesh motion
virtual bool movePoints();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const ejectionModel&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "ejectionModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::ejectionModel> Foam::ejectionModel::New
(
const dictionary& dict,
const solvers::isothermalFilm& film
)
{
const word modelType(dict.lookup("model"));
Info<< "Selecting film ejection model " << modelType << endl;
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(modelType);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorInFunction
<< "Unknown film ejection model "
<< modelType << nl << nl
<< "Valid film ejection models are:" << nl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<ejectionModel>
(
cstrIter()(dict.optionalSubDict(modelType + "Coeffs"), film)
);
}
// ************************************************************************* //

View File

@ -58,7 +58,13 @@ Foam::fv::filmCloudTransfer::filmCloudTransfer
:
fvModel(sourceName, modelType, mesh, dict),
film_(mesh.lookupObject<solvers::isothermalFilm>(solver::typeName)),
curTimeIndex_(-1)
curTimeIndex_(-1),
ejection_
(
dict.found("ejection")
? ejectionModel::New(dict.subDict("ejection"), film_)
: autoPtr<ejectionModel>(nullptr)
)
{}
@ -84,6 +90,11 @@ void Foam::fv::filmCloudTransfer::correct()
}
curTimeIndex_ = mesh().time().timeIndex();
if (ejection_.valid())
{
ejection_->correct();
}
}
@ -172,6 +183,11 @@ void Foam::fv::filmCloudTransfer::addSup
if (fieldName == film_.alpha.name())
{
eqn += CloudToFilmTransferRate<scalar>(massFromCloud_, dimMass);
if (ejection_.valid())
{
eqn -= fvm::Sp(ejection_->rate()*rho(), eqn.psi());
}
}
else
{
@ -198,6 +214,11 @@ void Foam::fv::filmCloudTransfer::addSup
if (fieldName == film_.thermo.he().name())
{
eqn += CloudToFilmTransferRate<scalar>(energyFromCloud_, dimEnergy);
if (ejection_.valid())
{
eqn -= fvm::Sp(alpha()*rho()*ejection_->rate(), eqn.psi());
}
}
else
{
@ -222,6 +243,11 @@ void Foam::fv::filmCloudTransfer::addSup
}
eqn += CloudToFilmTransferRate<vector>(momentumFromCloud_, dimMomentum);
if (ejection_.valid())
{
eqn -= fvm::Sp(alpha()*rho()*ejection_->rate(), eqn.psi());
}
}
@ -267,7 +293,7 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
inline Foam::fv::filmCloudTransfer::filmToCloudTransfer
(
const VolField<Type>& prop
const VolInternalField<Type>& prop
) const
{
return film_.surfacePatchMap().toNeighbour
@ -277,27 +303,102 @@ inline Foam::fv::filmCloudTransfer::filmToCloudTransfer
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::fv::filmCloudTransfer::deltaToCloud() const
bool Foam::fv::filmCloudTransfer::ejecting() const
{
return filmToCloudTransfer(film_.delta);
return ejection_.valid();
}
void Foam::fv::filmCloudTransfer::topoChange(const polyTopoChangeMap&)
{}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::fv::filmCloudTransfer::ejectedMassToCloud() const
{
return filmToCloudTransfer<scalar>
(
(
mesh().V()
*mesh().time().deltaTValue()
*film_.alpha()*film_.rho()*ejection_->rate()
)()
);
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::fv::filmCloudTransfer::ejectedDiameterToCloud() const
{
return filmToCloudTransfer<scalar>(ejection_->diameter());
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::fv::filmCloudTransfer::deltaToCloud() const
{
return filmToCloudTransfer<scalar>(film_.delta);
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::fv::filmCloudTransfer::UToCloud() const
{
return filmToCloudTransfer<vector>(film_.U);
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::fv::filmCloudTransfer::rhoToCloud() const
{
return filmToCloudTransfer<scalar>(film_.rho);
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::fv::filmCloudTransfer::TToCloud() const
{
return filmToCloudTransfer<scalar>(film_.thermo.T());
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::fv::filmCloudTransfer::CpToCloud() const
{
return filmToCloudTransfer<scalar>(film_.thermo.Cp());
}
void Foam::fv::filmCloudTransfer::topoChange(const polyTopoChangeMap& map)
{
if (ejection_.valid())
{
ejection_->topoChange(map);
}
}
void Foam::fv::filmCloudTransfer::mapMesh(const polyMeshMap& map)
{}
{
if (ejection_.valid())
{
ejection_->mapMesh(map);
}
}
void Foam::fv::filmCloudTransfer::distribute(const polyDistributionMap&)
{}
void Foam::fv::filmCloudTransfer::distribute(const polyDistributionMap& map)
{
if (ejection_.valid())
{
ejection_->distribute(map);
}
}
bool Foam::fv::filmCloudTransfer::movePoints()
{
if (ejection_.valid())
{
ejection_->movePoints();
}
return true;
}

View File

@ -48,6 +48,7 @@ SourceFiles
#include "fvModel.H"
#include "isothermalFilm.H"
#include "ejectionModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -72,10 +73,15 @@ class filmCloudTransfer
//- Current time index (used for updating)
mutable label curTimeIndex_;
scalarField massFromCloud_;
vectorField momentumFromCloud_;
scalarField pressureFromCloud_;
scalarField energyFromCloud_;
// Transfers from cloud
scalarField massFromCloud_;
vectorField momentumFromCloud_;
scalarField pressureFromCloud_;
scalarField energyFromCloud_;
//- Pointer to the ejection model
autoPtr<ejectionModel> ejection_;
// Private Member Functions
@ -94,7 +100,7 @@ class filmCloudTransfer
tmp<Field<Type>>
inline filmToCloudTransfer
(
const VolField<Type>& prop
const VolInternalField<Type>& prop
) const;
@ -192,9 +198,30 @@ public:
// Transfer to cloud
//- Return true if the film is ejecting to the cloud
bool ejecting() const;
//- Transfer the ejected mass to the cloud
tmp<Field<scalar>> ejectedMassToCloud() const;
//- Transfer the ejected droplet diameter to the cloud
tmp<Field<scalar>> ejectedDiameterToCloud() const;
//- Transfer the film delta field to the cloud
tmp<Field<scalar>> deltaToCloud() const;
//- Transfer the film velocity field to the cloud
tmp<Field<vector>> UToCloud() const;
//- Transfer the film density field to the cloud
tmp<Field<scalar>> rhoToCloud() const;
//- Transfer the film temperature field to the cloud
tmp<Field<scalar>> TToCloud() const;
//- Transfer the film heat capacity field to the cloud
tmp<Field<scalar>> CpToCloud() const;
// Mesh changes

View File

@ -189,13 +189,13 @@ bool Foam::solvers::isothermalFilm::initFilmMesh()
const polyPatch& wallp = bm[patchi];
const labelList& fCells = wallp.faceCells();
UIndirectList<vector>(nHat, fCells) = wallp.faceNormals();
UIndirectList<scalar>(magSf, fCells) = wallp.magFaceAreas();
UIndirectList<vector>(nHat_, fCells) = wallp.faceNormals();
UIndirectList<scalar>(magSf_, fCells) = wallp.magFaceAreas();
}
nHat.correctBoundaryConditions();
nHat_.correctBoundaryConditions();
VbyA_.primitiveFieldRef() = mesh.V()/magSf;
VbyA_.primitiveFieldRef() = mesh.V()/magSf_;
VbyA_.correctBoundaryConditions();
return true;
@ -246,7 +246,7 @@ Foam::solvers::isothermalFilm::isothermalFilm
p(thermo_.p()),
nHat
nHat_
(
IOobject
(
@ -259,7 +259,7 @@ Foam::solvers::isothermalFilm::isothermalFilm
zeroGradientFvPatchField<vector>::typeName
),
magSf
magSf_
(
IOobject
(
@ -315,18 +315,6 @@ Foam::solvers::isothermalFilm::isothermalFilm
deltaWet("deltaWet", dimLength, thermo_.properties()),
g
(
IOobject
(
"g",
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
U_
(
IOobject
@ -340,7 +328,7 @@ Foam::solvers::isothermalFilm::isothermalFilm
mesh
),
alphaRhoPhi
alphaRhoPhi_
(
IOobject
(
@ -353,7 +341,7 @@ Foam::solvers::isothermalFilm::isothermalFilm
fvc::flux(alpha_*thermo_.rho()*U_)
),
phi
phi_
(
IOobject
(
@ -376,18 +364,34 @@ Foam::solvers::isothermalFilm::isothermalFilm
alpha_,
thermo_.rho(),
U_,
alphaRhoPhi,
phi,
alphaRhoPhi_,
phi_,
thermo_
)
),
g
(
IOobject
(
"g",
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
nHat(nHat_),
magSf(magSf_),
VbyA(VbyA_),
delta(delta_),
alpha(alpha_),
thermo(thermo_),
rho(thermo_.rho()),
U(U_)
U(U_),
alphaRhoPhi(alphaRhoPhi_),
phi(phi_)
{
// Read the controls
readControls();

View File

@ -112,10 +112,10 @@ protected:
label surfacePatchID;
//- Film wall normal
volVectorField nHat;
volVectorField nHat_;
//- Film cell cross-sectional area magnitude
volScalarField::Internal magSf;
volScalarField::Internal magSf_;
//- Film cell volume/wall face area
volScalarField VbyA_;
@ -133,22 +133,16 @@ protected:
dimensionedScalar deltaWet;
// Buoyancy
//- Acceleration due to gravity
uniformDimensionedVectorField g;
// Kinematic properties
//- Film velocity field
volVectorField U_;
//- Film mass-flux field
surfaceScalarField alphaRhoPhi;
surfaceScalarField alphaRhoPhi_;
//- Film volumetric-flux field
surfaceScalarField phi;
surfaceScalarField phi_;
// Interface properties
@ -263,6 +257,15 @@ public:
// Public Data
//- Acceleration due to gravity
const uniformDimensionedVectorField g;
//- Film wall normal
const volVectorField& nHat;
//- Film cell cross-sectional area magnitude
const volScalarField::Internal& magSf;
//- Film cell volume/wall face area
const volScalarField& VbyA;
@ -275,12 +278,18 @@ public:
//- Reference to the fluid thermophysical properties
const fluidThermo& thermo;
//- The thermodynamic density field
//- Reference to the thermodynamic density field
const volScalarField& rho;
//- Film velocity field
//- Reference to the film velocity field
const volVectorField& U;
//- Reference to the film mass-flux field
const surfaceScalarField& alphaRhoPhi;
//- Reference to the film volumetric-flux field
const surfaceScalarField& phi;
public:
@ -312,6 +321,9 @@ public:
//- Return the film surface patch region-region map
const mappedPatchBase& surfacePatchMap() const;
//- Return the film surface tension coefficient field
tmp<volScalarField> sigma() const;
//- Return the current maximum time-step for stable solution
virtual scalar maxDeltaT() const;

View File

@ -32,6 +32,13 @@ License
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::solvers::isothermalFilm::sigma() const
{
return constrainedField(surfaceTension->sigma());
}
Foam::tmp<Foam::surfaceScalarField>
Foam::solvers::isothermalFilm::pbByAlphaRhof() const
{
@ -81,7 +88,7 @@ void Foam::solvers::isothermalFilm::momentumPredictor()
volVectorField& U = U_;
// Calculate the surface tension coefficient
const volScalarField sigma(constrainedField(surfaceTension->sigma()));
const volScalarField sigma(this->sigma());
tUEqn =
(