coefficientPhaseChange: Added prototype fvModel for phase change

This simple model generates a phase change between two phases calculated
from the following expression:

    \dot{m}/V = C \alpha \grad \alpha

Where:

    \dot{m}/V | mass transfer rate per unit volume
    C         | coefficient
    \alpha    | volume fraction of the source phase

Example usage:

    coefficientPhaseChange
    {
        type            coefficientPhaseChange;

        phases          (liquid vapour);

        C               [kg/m^2/s] 0.1;
    }

This model may be of use in simple situations, but it is primarily
designed to serve as a prototype for more complex and physical
mechanisms of phase changes.
This commit is contained in:
Will Bainbridge
2023-11-24 14:28:57 +00:00
parent d5df0a96f1
commit fc59bb71b8
15 changed files with 1579 additions and 7 deletions

View File

@ -32,6 +32,10 @@ derived/zeroDimensionalMassSource/zeroDimensionalMassSourceBase.C
derived/zeroDimensionalMassSource/zeroDimensionalMassSource.C
derived/massTransfer/massTransferBase.C
derived/massTransfer/coefficientMassTransfer.C
derived/phaseChange/phaseChangeBase.C
derived/phaseChange/singleComponentPhaseChangeBase.C
derived/phaseChange/multicomponentPhaseChangeBase.C
derived/phaseChange/coefficientPhaseChange.C
interRegion/interRegionModel/interRegionModel.C
interRegion/interRegionPorosityForce/interRegionPorosityForce.C

View File

@ -4,8 +4,9 @@ EXE_INC = \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/physicalProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/multicomponentThermo/lnInclude \
-I$(LIB_SRC)/MomentumTransportModels/momentumTransportModels/lnInclude \
-I$(LIB_SRC)/MomentumTransportModels/compressible/lnInclude \
-I$(LIB_SRC)/ThermophysicalTransportModels/thermophysicalTransportModel/lnInclude \

View File

@ -104,7 +104,7 @@ void Foam::fv::coefficientMassTransfer::addSup
}
else
{
massTransferBase::addSupType(alpha, eqn);
massTransferBase::addSup(alpha, eqn);
}
}
@ -123,10 +123,7 @@ void Foam::fv::coefficientMassTransfer::addSup
const volScalarField& alpha1 =
mesh().lookupObject<volScalarField>(alphaNames().first());
const volScalarField::Internal SByAlpha1
(
C_*mag(fvc::grad(alpha1))
);
const volScalarField::Internal SByAlpha1(C_*mag(fvc::grad(alpha1)));
if (i == 0)
{
@ -139,7 +136,7 @@ void Foam::fv::coefficientMassTransfer::addSup
}
else
{
massTransferBase::addSupType(alpha, rho, eqn);
massTransferBase::addSup(alpha, rho, eqn);
}
}

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::ThermoRefPair
Description
Class containing a pair of thermo references. Handles down-casting to more
specific thermo types by constructing one pair from another (e.g.,
constructing a multicomponentThermo reference pair from a basicThermo
pair). Tracks validity of the references.
\*---------------------------------------------------------------------------*/
#ifndef ThermoRefPair_H
#define ThermoRefPair_H
#include "physicalProperties.H"
#include "objectRegistry.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ThermoRefPair Declaration
\*---------------------------------------------------------------------------*/
template<class ThermoType>
class ThermoRefPair
{
// Private Member Data
//- Validity flags
const Pair<bool> valid_;
//- The first thermo
const ThermoType& first_;
//- The second thermo
const ThermoType& second_;
public:
// Constructors
//- Construct from a database and phase names
ThermoRefPair
(
const objectRegistry& db,
const Pair<word>& phaseNames
)
:
valid_(true, true),
first_
(
db.lookupObject<ThermoType>
(
IOobject::groupName
(
physicalProperties::typeName,
phaseNames.first()
)
)
),
second_
(
db.lookupObject<ThermoType>
(
IOobject::groupName
(
physicalProperties::typeName,
phaseNames.second()
)
)
)
{}
//- Construct by casting a more primitive thermo type
template<class BasicThermoType>
ThermoRefPair(const ThermoRefPair<BasicThermoType> basicThermos)
:
valid_
(
isA<ThermoType>(basicThermos.first()),
isA<ThermoType>(basicThermos.second())
),
first_
(
valid_.first()
? refCast<const ThermoType>(basicThermos.first())
: NullObjectRef<ThermoType>()
),
second_
(
valid_.second()
? refCast<const ThermoType>(basicThermos.second())
: NullObjectRef<ThermoType>()
)
{}
// Member Functions
//- Access the validity flags
const Pair<bool>& valid() const
{
return valid_;
}
//- Access the first thermo
const ThermoType& first() const
{
return first_;
}
//- Access the second thermo
const ThermoType& second() const
{
return second_;
}
// Member Operators
//- Access a thermo by index
const ThermoType& operator[](const label i) const
{
return
i == 0 ? first()
: i == 1 ? second()
: NullObjectRef<ThermoType>();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,168 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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 "coefficientPhaseChange.H"
#include "fvcGrad.H"
#include "multicomponentThermo.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(coefficientPhaseChange, 0);
addToRunTimeSelectionTable(fvModel, coefficientPhaseChange, dictionary);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fv::coefficientPhaseChange::readCoeffs()
{
C_.read(coeffs());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::coefficientPhaseChange::coefficientPhaseChange
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict
)
:
singleComponentPhaseChangeBase
(
name,
modelType,
mesh,
dict,
Pair<bool>(false, false)
),
C_("C", dimMass/dimArea/dimTime, NaN)
{
readCoeffs();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField::Internal>
Foam::fv::coefficientPhaseChange::mDot() const
{
const volScalarField& alpha1 =
mesh().lookupObject<volScalarField>(alphaNames().first());
tmp<volScalarField::Internal> tmDot =
C_*alpha1()*mag(fvc::grad(alpha1))()();
if (specieis().first() != -1)
{
tmDot.ref() *= specieThermos().first().Y()[specieis().first()];
}
return tmDot;
}
void Foam::fv::coefficientPhaseChange::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<scalar>& eqn
) const
{
const label i = index(alphaNames(), eqn.psi().name());
if (i != -1)
{
const volScalarField& alpha1 =
mesh().lookupObject<volScalarField>(alphaNames().first());
volScalarField::Internal mDotByAlpha1(C_*mag(fvc::grad(alpha1)));
if (specieis().first() != -1)
{
mDotByAlpha1 *= specieThermos().first().Y()[specieis().first()];
}
if (i == 0)
{
eqn -= fvm::Sp(mDotByAlpha1, eqn.psi());
}
else
{
eqn +=
mDotByAlpha1*alpha1
- correction(fvm::Sp(mDotByAlpha1, eqn.psi()));
}
}
else
{
phaseChangeBase::addSup(alpha, rho, eqn);
}
}
void Foam::fv::coefficientPhaseChange::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
const volScalarField& Yi,
fvMatrix<scalar>& eqn
) const
{
const label i = index(alphaNames(), eqn.psi().name());
if (i == 0 && specieis().first() != -1 && Yi.member() == specie())
{
eqn -= fvm::Sp(C_*alpha()*mag(fvc::grad(alpha))()(), Yi);
}
else
{
singleComponentPhaseChangeBase::addSup(alpha, rho, Yi, eqn);
}
}
bool Foam::fv::coefficientPhaseChange::read(const dictionary& dict)
{
if (singleComponentPhaseChangeBase::read(dict))
{
readCoeffs();
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,153 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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::fv::coefficientPhaseChange
Description
This simple model generates a phase change between two phases calculated
from the following expression:
\f[
\dot{m}/V = C \alpha \grad \alpha
\f]
\vartable
\dot{m}/V | mass transfer rate per unit volume
C | coefficient
\alpha | volume fraction of the source phase
\endvartable
Usage
Example usage:
\verbatim
coefficientPhaseChange
{
type coefficientPhaseChange;
phases (liquid vapour);
C [kg/m^2/s] 0.1;
}
\endverbatim
SourceFiles
coefficientPhaseChange.C
\*---------------------------------------------------------------------------*/
#ifndef coefficientPhaseChange_H
#define coefficientPhaseChange_H
#include "singleComponentPhaseChangeBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class coefficientPhaseChange Declaration
\*---------------------------------------------------------------------------*/
class coefficientPhaseChange
:
public singleComponentPhaseChangeBase
{
private:
// Private Data
//- Phase change coefficient. Multiplies the estimated interfacial
// area density return the phase change rate. Units of [kg/m^2/s].
dimensionedScalar C_;
// Private Member Functions
//- Non-virtual read
void readCoeffs();
public:
//- Runtime type information
TypeName("coefficientPhaseChange");
// Constructors
//- Construct from explicit source name and mesh
coefficientPhaseChange
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict
);
// Member Functions
// Sources
//- Return the phase change rate
virtual tmp<DimensionedField<scalar, volMesh>> mDot() const;
//- Override the compressible continuity equation to add
// linearisation w.r.t alpha
void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<scalar>& eqn
) const;
//- Override the compressible mass fraction equation to add
// linearisation w.r.t the mass fraction
void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
const volScalarField& Yi,
fvMatrix<scalar>& eqn
) const;
//- Read source dictionary
virtual bool read(const dictionary& dict);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,183 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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 "multicomponentPhaseChangeBase.H"
#include "basicThermo.H"
#include "multicomponentThermo.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(multicomponentPhaseChangeBase, 0);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fv::multicomponentPhaseChangeBase::readCoeffs()
{
if (species_ != coeffs().lookup<wordList>("species"))
{
FatalIOErrorInFunction(coeffs())
<< "Cannot change the species of a " << typeName << " model "
<< "at run time" << exit(FatalIOError);
}
energySemiImplicit_ =
coeffs().lookup<bool>("energySemiImplicit");
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::multicomponentPhaseChangeBase::multicomponentPhaseChangeBase
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict
)
:
phaseChangeBase(name, modelType, mesh, dict, {true, true}),
species_(coeffs().lookup<wordList>("species")),
energySemiImplicit_(false)
{
readCoeffs();
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField::Internal>
Foam::fv::multicomponentPhaseChangeBase::mDot() const
{
tmp<volScalarField::Internal> tmDot =
volScalarField::Internal::New
(
"mDot",
mesh(),
dimensionedScalar(dimDensity/dimTime, Zero)
);
forAll(species(), mDoti)
{
tmDot.ref() += mDot(mDoti);
}
return tmDot;
}
void Foam::fv::multicomponentPhaseChangeBase::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
const volScalarField& heOrYi,
fvMatrix<scalar>& eqn
) const
{
const label i = index(phaseNames(), alpha.group());
const label s = sign(phaseNames(), alpha.group());
// Energy equation
if (index(heNames(), heOrYi.name()) != -1)
{
const volScalarField& p = this->p();
const volScalarField Tchange(vifToVf(this->Tchange()));
forAll(species(), mDoti)
{
const label speciei =
specieThermos()[i].species()[species()[mDoti]];
const volScalarField::Internal mDotIn(s*mDot(mDoti));
// Absolute enthalpies at the interface
Pair<tmp<volScalarField::Internal>> has;
for (label j = 0; j < 2; ++ j)
{
has[j] = vfToVif(specieThermos()[j].hai(speciei, p, Tchange));
}
// Direct transfer of energy due to mass transfer
if (energySemiImplicit_)
{
eqn += -fvm::SuSp(-mDotIn, heOrYi) + mDotIn*(has[i]() - heOrYi);
}
else
{
eqn += mDotIn*has[i]();
}
// Latent heat of phase change
eqn +=
(i == 0 ? Lfraction() - 1 : Lfraction())
*mDotIn*(has.second() - has.first());
}
}
// Mass fraction equation
else if
(
specieThermos().valid()[i]
&& specieThermos()[i].containsSpecie(heOrYi.member())
)
{
// A transferring specie
if (species().found(heOrYi.member()))
{
eqn += s*mDot(species()[heOrYi.member()]);
}
// A non-transferring specie. Do nothing.
else
{}
}
// Something else. Fall back.
else
{
phaseChangeBase::addSup(alpha, rho, eqn);
}
}
bool Foam::fv::multicomponentPhaseChangeBase::read(const dictionary& dict)
{
if (phaseChangeBase::read(dict))
{
readCoeffs();
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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::fv::multicomponentPhaseChangeBase
Description
Base class for phase change models in which multiple components may change
phase. This can only be applied between multicomponent phases.
SourceFiles
multicomponentPhaseChangeBase.C
\*---------------------------------------------------------------------------*/
#ifndef multicomponentPhaseChangeBase_H
#define multicomponentPhaseChangeBase_H
#include "phaseChangeBase.H"
#include "hashedWordList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class multicomponentPhaseChangeBase Declaration
\*---------------------------------------------------------------------------*/
class multicomponentPhaseChangeBase
:
public phaseChangeBase
{
private:
// Private Data
//- The names of the changing species
const hashedWordList species_;
//- Whether or not to linearise the energy source
bool energySemiImplicit_;
// Private Member Functions
//- Non-virtual read
void readCoeffs();
public:
//- Runtime type information
TypeName("multicomponentPhaseChangeBase");
// Constructors
//- Construct from explicit source name and mesh
multicomponentPhaseChangeBase
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict
);
// Member Functions
// Access
//- Return the names of the changing species
inline const hashedWordList& species() const;
// Sources
//- Return the mass transfer rates of each specie
virtual tmp<DimensionedField<scalar, volMesh>> mDot
(
const label mDoti
) const = 0;
//- Return the total mass transfer rate
virtual tmp<DimensionedField<scalar, volMesh>> mDot() const;
//- Override the energy equation to add the phase change heat, or
// the species equations to add the relevant mass sources
void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
const volScalarField& heOrYi,
fvMatrix<scalar>& eqn
) const;
//- Read source dictionary
virtual bool read(const dictionary& dict);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "multicomponentPhaseChangeBaseI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,38 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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 "multicomponentPhaseChangeBase.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::hashedWordList&
Foam::fv::multicomponentPhaseChangeBase::species() const
{
return species_;
}
// ************************************************************************* //

View File

@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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 "phaseChangeBase.H"
#include "fluidThermo.H"
#include "multicomponentThermo.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(phaseChangeBase, 0);
}
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
const Foam::volScalarField& Foam::fv::phaseChangeBase::p() const
{
for (label i = 0; i < 2; ++ i)
{
if (isA<fluidThermo>(thermos()[i]))
{
return refCast<const fluidThermo>(thermos()[i]).p();
}
}
return mesh().lookupObject<volScalarField>("p");
}
Foam::tmp<Foam::volScalarField>
Foam::fv::phaseChangeBase::vifToVf
(
const tmp<volScalarField::Internal>& tvif
)
{
tmp<volScalarField> tvf =
volScalarField::New
(
tvif().name(),
tvif().mesh(),
tvif().dimensions(),
extrapolatedCalculatedFvPatchField<scalar>::typeName
);
tvf->ref() = tvif();
tvf->correctBoundaryConditions();
tvif.clear();
return tvf;
}
Foam::tmp<Foam::volScalarField::Internal>
Foam::fv::phaseChangeBase::vfToVif
(
const tmp<volScalarField>& tvf
)
{
tmp<volScalarField::Internal> tvif(tvf.ptr());
tvf.clear();
return tvif;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::phaseChangeBase::phaseChangeBase
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict,
const Pair<bool> specieThermosRequired
)
:
massTransferBase(name, modelType, mesh, dict),
thermos_(mesh, phaseNames()),
specieThermos_(thermos_),
heNames_(thermos_.first().he().name(), thermos_.second().he().name())
{
forAll(specieThermos_.valid(), i)
{
if (!specieThermos_.valid()[i] && specieThermosRequired[i])
{
FatalErrorInFunction
<< "Model " << name << " of type " << modelType
<< " requires a multicomponent thermo for phase "
<< phaseNames()[i] << exit(FatalError);
}
}
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField::Internal>
Foam::fv::phaseChangeBase::Tchange() const
{
const volScalarField::Internal mDot(this->mDot());
return pos0(mDot)*thermos().first().T() + neg(mDot)*thermos().second().T();
}
Foam::tmp<Foam::volScalarField::Internal>
Foam::fv::phaseChangeBase::Lfraction() const
{
const volScalarField& kappa1 = thermos().first().kappa();
const volScalarField& kappa2 = thermos().second().kappa();
return vfToVif(kappa2/(kappa1 + kappa2));
}
// ************************************************************************* //

View File

@ -0,0 +1,158 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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::fv::phaseChangeBase
Description
Base class for phase change models
SourceFiles
phaseChangeBase.C
\*---------------------------------------------------------------------------*/
#ifndef phaseChangeBase_H
#define phaseChangeBase_H
#include "massTransferBase.H"
#include "ThermoRefPair.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class basicThermo;
class multicomponentThermo;
namespace fv
{
/*---------------------------------------------------------------------------*\
Class phaseChangeBase Declaration
\*---------------------------------------------------------------------------*/
class phaseChangeBase
:
public massTransferBase
{
private:
// Private Data
//- The thermo references
const ThermoRefPair<basicThermo> thermos_;
//- The specie thermo references
const ThermoRefPair<multicomponentThermo> specieThermos_;
//- Names of the energy fields
const Pair<word> heNames_;
protected:
// Protected Member Functions
//- Access the pressure field
const volScalarField& p() const;
//- Add a boundary field to the given internal field
static tmp<volScalarField> vifToVf
(
const tmp<DimensionedField<scalar, volMesh>>& tvif
);
//- Remove the boundary field from the given geometric field
static tmp<DimensionedField<scalar, volMesh>> vfToVif
(
const tmp<volScalarField>& tvf
);
public:
//- Runtime type information
TypeName("phaseChangeBase");
// Constructors
//- Construct from explicit source name and mesh
phaseChangeBase
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict,
const Pair<bool> specieThermosRequired
);
// Member Functions
// Access
//- Return the thermo references
inline const ThermoRefPair<basicThermo>& thermos() const;
//- Return the specie thermo references
inline const ThermoRefPair<multicomponentThermo>&
specieThermos() const;
//- Return the names of the energy fields
inline const Pair<word>& heNames() const;
// Evaluation
//- Return the temperature at which the phases are considered to be
// changing. By default this is considered to be the temperature
// of the "source" phase (i.e., the phase for which mDot is
// negative), but this can be overridden to account for heat
// transfer modelling or similar.
virtual tmp<DimensionedField<scalar, volMesh>> Tchange() const;
//- Return the fraction of the latent heat that is transferred into
// the second phase. By default this is weighted by the phase
// thermal conductivities, but this can be overridden to account
// for heat transfer modelling or similar.
virtual tmp<DimensionedField<scalar, volMesh>> Lfraction() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "phaseChangeBaseI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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 "phaseChangeBase.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::ThermoRefPair<Foam::basicThermo>&
Foam::fv::phaseChangeBase::thermos() const
{
return thermos_;
}
inline const Foam::ThermoRefPair<Foam::multicomponentThermo>&
Foam::fv::phaseChangeBase::specieThermos() const
{
return specieThermos_;
}
inline const Foam::Pair<Foam::word>&
Foam::fv::phaseChangeBase::heNames() const
{
return heNames_;
}
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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 "singleComponentPhaseChangeBase.H"
#include "basicThermo.H"
#include "multicomponentThermo.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(singleComponentPhaseChangeBase, 0);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fv::singleComponentPhaseChangeBase::readCoeffs()
{
if
(
(specieThermos().valid().first() || specieThermos().valid().second())
&& specie_ != coeffs().lookup<word>("specie")
)
{
FatalIOErrorInFunction(coeffs())
<< "Cannot change the specie of a " << typeName << " model "
<< "at run time" << exit(FatalIOError);
}
energySemiImplicit_ =
coeffs().lookup<bool>("energySemiImplicit");
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::singleComponentPhaseChangeBase::singleComponentPhaseChangeBase
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict,
const Pair<bool> specieThermosRequired
)
:
phaseChangeBase(name, modelType, mesh, dict, specieThermosRequired),
specie_
(
specieThermos().valid().first() || specieThermos().valid().second()
? coeffs().lookup<word>("specie")
: word::null
),
specieis_
(
specieThermos().valid().first()
? specieThermos().first().species()[specie_]
: -1,
specieThermos().valid().second()
? specieThermos().second().species()[specie_]
: -1
),
energySemiImplicit_(false)
{
readCoeffs();
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::fv::singleComponentPhaseChangeBase::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
const volScalarField& heOrYi,
fvMatrix<scalar>& eqn
) const
{
const label i = index(phaseNames(), alpha.group());
const label s = sign(phaseNames(), alpha.group());
// Energy equation
if (index(heNames(), heOrYi.name()) != -1)
{
const volScalarField& p = this->p();
const volScalarField Tchange(vifToVf(this->Tchange()));
const volScalarField::Internal mDotIn(s*mDot());
// Absolute enthalpies at the interface
Pair<tmp<volScalarField::Internal>> has;
for (label j = 0; j < 2; ++ j)
{
has[j] =
specieThermos().valid()[j]
? vfToVif(specieThermos()[j].hai(specieis_[j], p, Tchange))
: vfToVif(thermos()[j].ha(p, Tchange));
}
// Direct transfer of energy due to mass transfer
if (energySemiImplicit_)
{
eqn += -fvm::SuSp(-mDotIn, heOrYi) + mDotIn*(has[i]() - heOrYi);
}
else
{
eqn += mDotIn*has[i]();
}
// Latent heat of phase change
eqn +=
(i == 0 ? Lfraction() - 1 : Lfraction())
*mDotIn*(has.second() - has.first());
}
// Mass fraction equation
else if
(
specieThermos().valid()[i]
&& specieThermos()[i].containsSpecie(heOrYi.member())
)
{
// The transferring specie
if (heOrYi.member() == specie())
{
eqn += s*mDot();
}
// A non-transferring specie. Do nothing.
else
{}
}
// Something else. Fall back.
else
{
massTransferBase::addSup(alpha, rho, heOrYi, eqn);
}
}
bool Foam::fv::singleComponentPhaseChangeBase::read(const dictionary& dict)
{
if (phaseChangeBase::read(dict))
{
readCoeffs();
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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::fv::singleComponentPhaseChangeBase
Description
Base class for phase change models in which only a single component changes
phase. Can be applied to any combination of pure and multicomponent phases.
If either phase is multicomponent, then a single specie must be identified
as the one that changes phase.
SourceFiles
singleComponentPhaseChangeBase.C
\*---------------------------------------------------------------------------*/
#ifndef singleComponentPhaseChangeBase_H
#define singleComponentPhaseChangeBase_H
#include "phaseChangeBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class singleComponentPhaseChangeBase Declaration
\*---------------------------------------------------------------------------*/
class singleComponentPhaseChangeBase
:
public phaseChangeBase
{
private:
// Private Data
//- The name of the changing specie, or word::null if neither thermo
// is multicomponent
const word specie_;
//- The indices of the changing species in the phases, or -1 if the
// phases are not multicomponent
const Pair<label> specieis_;
//- Whether or not to linearise the energy source
bool energySemiImplicit_;
// Private Member Functions
//- Non-virtual read
void readCoeffs();
public:
//- Runtime type information
TypeName("singleComponentPhaseChangeBase");
// Constructors
//- Construct from explicit source name and mesh
singleComponentPhaseChangeBase
(
const word& name,
const word& modelType,
const fvMesh& mesh,
const dictionary& dict,
const Pair<bool> specieThermosRequired
);
// Member Functions
// Access
//- Return the name of the changing specie
inline const word& specie() const;
//- Return the indices of the changing species in the phases
inline const Pair<label>& specieis() const;
// Sources
//- Override the energy equation to add the phase change heat, or
// the species equations to add the relevant mass sources
void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
const volScalarField& heOrYi,
fvMatrix<scalar>& eqn
) const;
//- Read source dictionary
virtual bool read(const dictionary& dict);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "singleComponentPhaseChangeBaseI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-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 "singleComponentPhaseChangeBase.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::word&
Foam::fv::singleComponentPhaseChangeBase::specie() const
{
return specie_;
}
inline const Foam::Pair<Foam::label>&
Foam::fv::singleComponentPhaseChangeBase::specieis() const
{
return specieis_;
}
// ************************************************************************* //