Commit b240f9f9 authored by Sergio Ferraris's avatar Sergio Ferraris Committed by Andrew Heather
Browse files

ENH: Adding interfaceHeatResistance mass transfer model

1) Add interfaceHeatResistance model to icoReactingMultiphaseInterFoam
   This model uses a spread source for the continuity Eq.
   It is recommended for cases with good mesh resolution.

2) Adding iso-surface type of calculation for the interface for
   the kineticGasEvaporation model

3) Add switch for option to take into account volume change

4) Add poolEvaporation tutorial
parent da070b57
......@@ -50,6 +50,7 @@ License
#include "kineticGasEvaporation.H"
#include "Lee.H"
#include "interfaceHeatResistance.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -328,6 +329,152 @@ namespace Foam
);
// interfaceHeatResistance model definitions
// From pure phase (rho const) to phase (rho const)
makeInterfacePureType
(
interfaceHeatResistance,
heRhoThermo,
rhoThermo,
pureMixture,
constRhoHThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
constRhoHThermoPhysics
);
// From pure phase (rho const) to phase (Boussinesq)
makeInterfacePureType
(
interfaceHeatResistance,
heRhoThermo,
rhoThermo,
pureMixture,
constRhoHThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
BoussinesqFluidEThermoPhysics
);
// From pure phase (solidThermo) to phase (Boussinesq)
makeInterfacePureType
(
interfaceHeatResistance,
heSolidThermo,
solidThermo,
pureMixture,
hConstSolidThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
BoussinesqFluidEThermoPhysics
);
// From pure phase (solidThermo) to phase (rho const)
makeInterfacePureType
(
interfaceHeatResistance,
heSolidThermo,
solidThermo,
pureMixture,
hConstSolidThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
constRhoHThermoPhysics
);
// From pure phase (all-poly solidThermo) to phase (ico-rho)
makeInterfacePureType
(
interfaceHeatResistance,
heSolidThermo,
solidThermo,
pureMixture,
hPolyTranspPolyIcoSolidThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
icoPoly8HThermoPhysics
);
// From pure phase (exp-Transp, hPower solidThermo) to phase (ico-rho)
makeInterfacePureType
(
interfaceHeatResistance,
heSolidThermo,
solidThermo,
pureMixture,
hPowerSolidThermoPhysics,
heRhoThermo,
rhoThermo,
pureMixture,
icoPoly8HThermoPhysics
);
// From pure phase (const rho) to multi phase (incomp ideal gas)
makeInterfaceContSpecieMixtureType
(
interfaceHeatResistance,
heRhoThermo,
rhoThermo,
pureMixture,
constRhoHThermoPhysics,
heRhoThermo,
rhoReactionThermo,
multiComponentMixture,
constIncompressibleGasHThermoPhysics
);
// From pure phase (Boussinesq) to phase (solidThermo)
makeInterfacePureType
(
interfaceHeatResistance,
heRhoThermo,
rhoThermo,
pureMixture,
BoussinesqFluidEThermoPhysics,
heSolidThermo,
solidThermo,
pureMixture,
hConstSolidThermoPhysics
);
// From pure phase (rho const) to phase (solidThermo)
makeInterfacePureType
(
interfaceHeatResistance,
heRhoThermo,
rhoThermo,
pureMixture,
constRhoHThermoPhysics,
heSolidThermo,
solidThermo,
pureMixture,
hConstSolidThermoPhysics
);
//From pure liquid phase (ico-rho) to pure phase (exp-Transp, hPower solidThermo)
makeInterfacePureType
(
interfaceHeatResistance,
heRhoThermo,
rhoThermo,
pureMixture,
icoPoly8HThermoPhysics,
heSolidThermo,
solidThermo,
pureMixture,
hPowerSolidThermoPhysics
);
}
......
......@@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -80,6 +80,8 @@ Usage
Property | Description | Required | Default value
Tactivate | Activation temperature | yes
C | Model constant | yes
includeVolChange | Volumen change | no | yes
species | Specie name on the other phase | no | none
\endtable
SourceFiles
......@@ -143,7 +145,7 @@ public:
// Member Functions
//- Explicit mass transfer coefficient
//- Explicit total mass transfer coefficient
virtual tmp<volScalarField> Kexp
(
const volScalarField& field
......@@ -169,6 +171,7 @@ public:
//- Adds and substract alpha*div(U) as a source term
// for alpha, substituting div(U) = mDot(1/rho1 - 1/rho2)
virtual bool includeDivU();
};
......
......@@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -44,6 +44,7 @@ Foam::interfaceCompositionModel::modelVariableNames
{ modelVariable::T, "temperature" },
{ modelVariable::P, "pressure" },
{ modelVariable::Y, "massFraction" },
{ modelVariable::alpha, "alphaVolumeFraction" },
};
......@@ -64,6 +65,7 @@ Foam::interfaceCompositionModel::interfaceCompositionModel
modelVariable::T
)
),
includeVolChange_(dict.lookupOrDefault<bool>("includeVolChange", true)),
pair_(pair),
speciesName_(dict.lookupOrDefault<word>("species", "none")),
mesh_(pair_.from().mesh())
......@@ -96,4 +98,9 @@ bool Foam::interfaceCompositionModel::includeDivU()
}
bool Foam::interfaceCompositionModel::includeVolChange()
{
return includeVolChange_;
}
// ************************************************************************* //
......@@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -76,6 +76,9 @@ public:
//- Enumeration for model variables
modelVariable modelVariable_;
//- Add volume change in pEq
bool includeVolChange_;
protected:
......@@ -198,6 +201,9 @@ public:
// for alpha, substituting div(U) = mDot(1/rho1 - 1/rho2)
virtual bool includeDivU();
//- Add volume change in pEq
bool includeVolChange();
//- Returns the variable on which the model is based
const word variable() const;
};
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020 Henning Scheufler
-------------------------------------------------------------------------------
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 "interfaceHeatResistance.H"
#include "constants.H"
#include "isoCutCell.H"
#include "volPointInterpolation.H"
#include "wallPolyPatch.H"
#include "fvcSmooth.H"
using namespace Foam::constant;
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
template<class Thermo, class OtherThermo>
void Foam::meltingEvaporationModels::
interfaceHeatResistance<Thermo, OtherThermo>
::updateInterface(const volScalarField& T)
{
const fvMesh& mesh = this->mesh_;
const volScalarField& alpha = this->pair().from();
scalarField ap
(
volPointInterpolation::New(mesh).interpolate(alpha)
);
isoCutCell cutCell(mesh, ap);
forAll(interfaceArea_, celli)
{
label status = cutCell.calcSubCell(celli, isoAlpha_);
interfaceArea_[celli] = 0;
if (status == 0) // cell is cut
{
interfaceArea_[celli] =
mag(cutCell.isoFaceArea())/mesh.V()[celli];
}
}
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(pbm, patchi)
{
if (isA<wallPolyPatch>(pbm[patchi]))
{
const polyPatch& pp = pbm[patchi];
forAll(pp.faceCells(), faceI)
{
const label pCelli = pp.faceCells()[faceI];
bool interface(false);
if
(
sign(R_.value()) > 0
&& (T[pCelli] - Tactivate_.value()) > 0
)
{
interface = true;
}
if
(
sign(R_.value()) < 0
&& (T[pCelli] - Tactivate_.value()) < 0
)
{
interface = true;
}
if
(
interface
&&
(
alpha[pCelli] < 2*isoAlpha_
&& alpha[pCelli] > 0.5*isoAlpha_
)
)
{
interfaceArea_[pCelli] =
mag(pp.faceAreas()[faceI])/mesh.V()[pCelli];
}
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Thermo, class OtherThermo>
Foam::meltingEvaporationModels::interfaceHeatResistance<Thermo, OtherThermo>
::interfaceHeatResistance
(
const dictionary& dict,
const phasePair& pair
)
:
InterfaceCompositionModel<Thermo, OtherThermo>(dict, pair),
R_("R", dimPower/dimArea/dimTemperature, dict),
Tactivate_("Tactivate", dimTemperature, dict),
interfaceArea_
(
IOobject
(
"interfaceArea",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
this->mesh_,
dimensionedScalar(dimless/dimLength, Zero)
),
mDotc_
(
IOobject
(
"mDotc",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
this->mesh_,
dimensionedScalar(dimDensity/dimTime, Zero)
),
mDotcSpread_
(
IOobject
(
"mDotcSpread",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
this->mesh_,
dimensionedScalar(dimDensity/dimTime, Zero)
),
htc_
(
IOobject
(
"htc",
this->mesh_.time().timeName(),
this->mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
this->mesh_,
dimensionedScalar(dimMass/dimArea/dimTemperature/dimTime, Zero)
),
isoAlpha_(dict.lookupOrDefault<scalar>("isoAlpha", 0.5)),
spread_(dict.lookupOrDefault<scalar>("spread", 3))
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Thermo, class OtherThermo>
Foam::tmp<Foam::volScalarField>
Foam::meltingEvaporationModels::interfaceHeatResistance<Thermo, OtherThermo>
::Kexp(const volScalarField& T)
{
const fvMesh& mesh = this->mesh_;
updateInterface(T);
tmp<volScalarField> tdeltaT
(
new volScalarField
(
IOobject
(
"tdeltaT",
mesh.time().timeName(),
mesh
),
mesh,
dimensionedScalar(dimTemperature, Zero)
)
);
volScalarField& deltaT = tdeltaT.ref();
dimensionedScalar T0("T0", dimTemperature, Zero);
if (sign(R_.value()) > 0)
{
deltaT = max(T - Tactivate_, T0);
}
else
{
deltaT = max(Tactivate_ - T, T0);
}
word fullSpeciesName = this->transferSpecie();
auto tempOpen = fullSpeciesName.find('.');
const word speciesName(fullSpeciesName.substr(0, tempOpen));
tmp<volScalarField> L = this->L(speciesName, T);
htc_ = R_/L();
const volScalarField& to = this->pair().to();
const volScalarField& from = this->pair().from();
dimensionedScalar D
(
"D",
dimArea,
spread_/sqr(gAverage(this->mesh_.nonOrthDeltaCoeffs()))
);
const dimensionedScalar MdotMin("MdotMin", mDotc_.dimensions(), 1e-3);
if (max(mDotc_) > MdotMin)
{
fvc::spreadSource
(
mDotcSpread_,
mDotc_,
from,
to,
D,
1e-3
);
}
mDotc_ = interfaceArea_*htc_*deltaT;
return tmp<volScalarField>(new volScalarField(mDotc_));
}
template<class Thermo, class OtherThermo>
Foam::tmp<Foam::volScalarField>
Foam::meltingEvaporationModels::interfaceHeatResistance<Thermo, OtherThermo>
::KSp
(
label variable,
const volScalarField& refValue
)
{
if (this->modelVariable_ == variable)
{
const volScalarField coeff(htc_*interfaceArea_);
if (sign(R_.value()) > 0)
{
return(coeff*pos(refValue - Tactivate_));
}
else
{
return(coeff*pos(Tactivate_ - refValue));
}
}
else
{
return tmp<volScalarField> ();
}
}
template<class Thermo, class OtherThermo>
Foam::tmp<Foam::volScalarField>
Foam::meltingEvaporationModels::interfaceHeatResistance<Thermo, OtherThermo>
::KSu
(
label variable,
<