From fc59bb71b80768e24b03cfcdb65d2a0e7ef13ee0 Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Fri, 24 Nov 2023 14:28:57 +0000 Subject: [PATCH] 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. --- src/fvModels/Make/files | 4 + src/fvModels/Make/options | 3 +- .../massTransfer/coefficientMassTransfer.C | 9 +- .../derived/phaseChange/ThermoRefPair.H | 167 ++++++++++++++++ .../phaseChange/coefficientPhaseChange.C | 168 ++++++++++++++++ .../phaseChange/coefficientPhaseChange.H | 153 +++++++++++++++ .../multicomponentPhaseChangeBase.C | 183 ++++++++++++++++++ .../multicomponentPhaseChangeBase.H | 140 ++++++++++++++ .../multicomponentPhaseChangeBaseI.H | 38 ++++ .../derived/phaseChange/phaseChangeBase.C | 146 ++++++++++++++ .../derived/phaseChange/phaseChangeBase.H | 158 +++++++++++++++ .../derived/phaseChange/phaseChangeBaseI.H | 52 +++++ .../singleComponentPhaseChangeBase.C | 179 +++++++++++++++++ .../singleComponentPhaseChangeBase.H | 141 ++++++++++++++ .../singleComponentPhaseChangeBaseI.H | 45 +++++ 15 files changed, 1579 insertions(+), 7 deletions(-) create mode 100644 src/fvModels/derived/phaseChange/ThermoRefPair.H create mode 100644 src/fvModels/derived/phaseChange/coefficientPhaseChange.C create mode 100644 src/fvModels/derived/phaseChange/coefficientPhaseChange.H create mode 100644 src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.C create mode 100644 src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.H create mode 100644 src/fvModels/derived/phaseChange/multicomponentPhaseChangeBaseI.H create mode 100644 src/fvModels/derived/phaseChange/phaseChangeBase.C create mode 100644 src/fvModels/derived/phaseChange/phaseChangeBase.H create mode 100644 src/fvModels/derived/phaseChange/phaseChangeBaseI.H create mode 100644 src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.C create mode 100644 src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.H create mode 100644 src/fvModels/derived/phaseChange/singleComponentPhaseChangeBaseI.H diff --git a/src/fvModels/Make/files b/src/fvModels/Make/files index 1549002f4f..36ae5200a8 100644 --- a/src/fvModels/Make/files +++ b/src/fvModels/Make/files @@ -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 diff --git a/src/fvModels/Make/options b/src/fvModels/Make/options index 7f29dea317..5d2521c940 100644 --- a/src/fvModels/Make/options +++ b/src/fvModels/Make/options @@ -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 \ diff --git a/src/fvModels/derived/massTransfer/coefficientMassTransfer.C b/src/fvModels/derived/massTransfer/coefficientMassTransfer.C index cc18820c45..13307612c0 100644 --- a/src/fvModels/derived/massTransfer/coefficientMassTransfer.C +++ b/src/fvModels/derived/massTransfer/coefficientMassTransfer.C @@ -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(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); } } diff --git a/src/fvModels/derived/phaseChange/ThermoRefPair.H b/src/fvModels/derived/phaseChange/ThermoRefPair.H new file mode 100644 index 0000000000..cc7410cc44 --- /dev/null +++ b/src/fvModels/derived/phaseChange/ThermoRefPair.H @@ -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 . + +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 ThermoRefPair +{ + // Private Member Data + + //- Validity flags + const Pair 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& phaseNames + ) + : + valid_(true, true), + first_ + ( + db.lookupObject + ( + IOobject::groupName + ( + physicalProperties::typeName, + phaseNames.first() + ) + ) + ), + second_ + ( + db.lookupObject + ( + IOobject::groupName + ( + physicalProperties::typeName, + phaseNames.second() + ) + ) + ) + {} + + //- Construct by casting a more primitive thermo type + template + ThermoRefPair(const ThermoRefPair basicThermos) + : + valid_ + ( + isA(basicThermos.first()), + isA(basicThermos.second()) + ), + first_ + ( + valid_.first() + ? refCast(basicThermos.first()) + : NullObjectRef() + ), + second_ + ( + valid_.second() + ? refCast(basicThermos.second()) + : NullObjectRef() + ) + {} + + + // Member Functions + + //- Access the validity flags + const Pair& 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(); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/coefficientPhaseChange.C b/src/fvModels/derived/phaseChange/coefficientPhaseChange.C new file mode 100644 index 0000000000..b4d91ce99b --- /dev/null +++ b/src/fvModels/derived/phaseChange/coefficientPhaseChange.C @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#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(false, false) + ), + C_("C", dimMass/dimArea/dimTime, NaN) +{ + readCoeffs(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::tmp +Foam::fv::coefficientPhaseChange::mDot() const +{ + const volScalarField& alpha1 = + mesh().lookupObject(alphaNames().first()); + + tmp 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& eqn +) const +{ + const label i = index(alphaNames(), eqn.psi().name()); + + if (i != -1) + { + const volScalarField& alpha1 = + mesh().lookupObject(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& 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; + } +} + + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/coefficientPhaseChange.H b/src/fvModels/derived/phaseChange/coefficientPhaseChange.H new file mode 100644 index 0000000000..ae74025e21 --- /dev/null +++ b/src/fvModels/derived/phaseChange/coefficientPhaseChange.H @@ -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 . + +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> mDot() const; + + //- Override the compressible continuity equation to add + // linearisation w.r.t alpha + void addSup + ( + const volScalarField& alpha, + const volScalarField& rho, + fvMatrix& 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& eqn + ) const; + + + //- Read source dictionary + virtual bool read(const dictionary& dict); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace fv +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.C b/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.C new file mode 100644 index 0000000000..12f1bf8d4d --- /dev/null +++ b/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.C @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#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("species")) + { + FatalIOErrorInFunction(coeffs()) + << "Cannot change the species of a " << typeName << " model " + << "at run time" << exit(FatalIOError); + } + + energySemiImplicit_ = + coeffs().lookup("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("species")), + energySemiImplicit_(false) +{ + readCoeffs(); +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::tmp +Foam::fv::multicomponentPhaseChangeBase::mDot() const +{ + tmp 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& 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> 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; + } +} + + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.H b/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.H new file mode 100644 index 0000000000..5fa6cdf14a --- /dev/null +++ b/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBase.H @@ -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 . + +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> mDot + ( + const label mDoti + ) const = 0; + + //- Return the total mass transfer rate + virtual tmp> 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& eqn + ) const; + + + //- Read source dictionary + virtual bool read(const dictionary& dict); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace fv +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "multicomponentPhaseChangeBaseI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBaseI.H b/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBaseI.H new file mode 100644 index 0000000000..f1b604e590 --- /dev/null +++ b/src/fvModels/derived/phaseChange/multicomponentPhaseChangeBaseI.H @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#include "multicomponentPhaseChangeBase.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline const Foam::hashedWordList& +Foam::fv::multicomponentPhaseChangeBase::species() const +{ + return species_; +} + + +// ************************************************************************* // + diff --git a/src/fvModels/derived/phaseChange/phaseChangeBase.C b/src/fvModels/derived/phaseChange/phaseChangeBase.C new file mode 100644 index 0000000000..55bd39fb05 --- /dev/null +++ b/src/fvModels/derived/phaseChange/phaseChangeBase.C @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#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(thermos()[i])) + { + return refCast(thermos()[i]).p(); + } + } + + return mesh().lookupObject("p"); +} + + +Foam::tmp +Foam::fv::phaseChangeBase::vifToVf +( + const tmp& tvif +) +{ + tmp tvf = + volScalarField::New + ( + tvif().name(), + tvif().mesh(), + tvif().dimensions(), + extrapolatedCalculatedFvPatchField::typeName + ); + + tvf->ref() = tvif(); + tvf->correctBoundaryConditions(); + + tvif.clear(); + + return tvf; +} + + +Foam::tmp +Foam::fv::phaseChangeBase::vfToVif +( + const tmp& tvf +) +{ + tmp 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 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::fv::phaseChangeBase::Tchange() const +{ + const volScalarField::Internal mDot(this->mDot()); + + return pos0(mDot)*thermos().first().T() + neg(mDot)*thermos().second().T(); +} + + +Foam::tmp +Foam::fv::phaseChangeBase::Lfraction() const +{ + const volScalarField& kappa1 = thermos().first().kappa(); + const volScalarField& kappa2 = thermos().second().kappa(); + + return vfToVif(kappa2/(kappa1 + kappa2)); +} + + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/phaseChangeBase.H b/src/fvModels/derived/phaseChange/phaseChangeBase.H new file mode 100644 index 0000000000..53477196e5 --- /dev/null +++ b/src/fvModels/derived/phaseChange/phaseChangeBase.H @@ -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 . + +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 thermos_; + + //- The specie thermo references + const ThermoRefPair specieThermos_; + + //- Names of the energy fields + const Pair heNames_; + + +protected: + + // Protected Member Functions + + //- Access the pressure field + const volScalarField& p() const; + + //- Add a boundary field to the given internal field + static tmp vifToVf + ( + const tmp>& tvif + ); + + //- Remove the boundary field from the given geometric field + static tmp> vfToVif + ( + const tmp& 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 specieThermosRequired + ); + + + // Member Functions + + // Access + + //- Return the thermo references + inline const ThermoRefPair& thermos() const; + + //- Return the specie thermo references + inline const ThermoRefPair& + specieThermos() const; + + //- Return the names of the energy fields + inline const Pair& 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> 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> Lfraction() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace fv +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "phaseChangeBaseI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/phaseChangeBaseI.H b/src/fvModels/derived/phaseChange/phaseChangeBaseI.H new file mode 100644 index 0000000000..7be70cddd3 --- /dev/null +++ b/src/fvModels/derived/phaseChange/phaseChangeBaseI.H @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#include "phaseChangeBase.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline const Foam::ThermoRefPair& +Foam::fv::phaseChangeBase::thermos() const +{ + return thermos_; +} + + +inline const Foam::ThermoRefPair& +Foam::fv::phaseChangeBase::specieThermos() const +{ + return specieThermos_; +} + + +inline const Foam::Pair& +Foam::fv::phaseChangeBase::heNames() const +{ + return heNames_; +} + + +// ************************************************************************* // + diff --git a/src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.C b/src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.C new file mode 100644 index 0000000000..56980947f6 --- /dev/null +++ b/src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.C @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#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("specie") + ) + { + FatalIOErrorInFunction(coeffs()) + << "Cannot change the specie of a " << typeName << " model " + << "at run time" << exit(FatalIOError); + } + + energySemiImplicit_ = + coeffs().lookup("energySemiImplicit"); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::fv::singleComponentPhaseChangeBase::singleComponentPhaseChangeBase +( + const word& name, + const word& modelType, + const fvMesh& mesh, + const dictionary& dict, + const Pair specieThermosRequired +) +: + phaseChangeBase(name, modelType, mesh, dict, specieThermosRequired), + specie_ + ( + specieThermos().valid().first() || specieThermos().valid().second() + ? coeffs().lookup("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& 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> 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; + } +} + + +// ************************************************************************* // diff --git a/src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.H b/src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.H new file mode 100644 index 0000000000..ca60a04744 --- /dev/null +++ b/src/fvModels/derived/phaseChange/singleComponentPhaseChangeBase.H @@ -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 . + +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