Files
OpenFOAM-12/applications/solvers/modules/fluid/multiphaseEuler/phaseSystems/PhaseSystems/PhaseTransferPhaseSystem/PhaseTransferPhaseSystem.C
Will Bainbridge 1df33f58c9 multiphaseEuler: Cavitation phaseTransfer model
This adds cavitation modelling to the multiphaseEuler solver module as a
phaseTransfer model. The underlying cavitation modelling is the same as
for the compressibleVoF module.

An example specification in constant/phaseProperties is shown below:

    phaseTransfer
    {
        gas_liquid
        {
            type        cavitation;

            model       Kunz;

            liquid      water;

            pSat        80000;

            UInf        5.33;
            tInf        0.028142589;
            Cc          100;
            Cv          100;
        }
    }

Based on code contributed by Petteri Peltonen, VTT.
2022-11-16 21:36:13 +00:00

482 lines
13 KiB
C++

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2018-2022 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 "PhaseTransferPhaseSystem.H"
#include "phaseTransferModel.H"
#include "fvmSup.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::dmdtfTable>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::totalDmdtfs() const
{
autoPtr<phaseSystem::dmdtfTable> totalDmdtfsPtr
(
new phaseSystem::dmdtfTable
);
phaseSystem::dmdtfTable& totalDmdtfs = totalDmdtfsPtr();
forAllConstIter
(
phaseTransferModelTable,
phaseTransferModels_,
phaseTransferModelIter
)
{
const phaseInterface& interface = phaseTransferModelIter()->interface();
totalDmdtfs.insert(interface, phaseSystem::dmdtf(interface).ptr());
if (phaseTransferModelIter()->mixture())
{
*totalDmdtfs[interface] += *dmdtfs_[interface];
}
forAllConstIter
(
HashPtrTable<volScalarField>,
*dmidtfs_[interface],
dmidtfIter
)
{
*totalDmdtfs[interface] += *dmidtfIter();
}
}
return totalDmdtfsPtr;
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class BasePhaseSystem>
void Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::addDmdtYfs
(
const phaseSystem::dmdtfTable& dmdtfs,
phaseSystem::specieTransferTable& eqns
) const
{
forAllConstIter(phaseSystem::dmdtfTable, dmdtfs, dmdtfIter)
{
const phaseInterface interface(*this, dmdtfIter.key());
const volScalarField& dmdtf = *dmdtfIter();
const volScalarField dmdtf12(negPart(dmdtf));
const volScalarField dmdtf21(posPart(dmdtf));
const phaseModel& phase1 = interface.phase1();
const phaseModel& phase2 = interface.phase2();
forAll(phase1.Y(), Yi1)
{
const volScalarField& Y1 = phase1.Y()[Yi1];
const volScalarField& Y2 = phase2.Y(Y1.member());
*eqns[Y1.name()] += dmdtf21*Y2 + fvm::Sp(dmdtf12, Y1);
*eqns[Y2.name()] -= dmdtf12*Y1 + fvm::Sp(dmdtf21, Y2);
}
}
}
template<class BasePhaseSystem>
void Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::addDmidtYf
(
const phaseSystem::dmidtfTable& dmidtfs,
phaseSystem::specieTransferTable& eqns
) const
{
forAllConstIter(phaseSystem::dmidtfTable, dmidtfs, dmidtfIter)
{
const phaseInterface interface(*this, dmidtfIter.key());
const phaseModel& phase1 = interface.phase1();
const phaseModel& phase2 = interface.phase2();
forAllConstIter(HashPtrTable<volScalarField>, *dmidtfIter(), dmidtfJter)
{
const word& member = dmidtfJter.key();
const volScalarField& dmidtf = *dmidtfJter();
if (!phase1.pure())
{
const volScalarField& Y1 = phase1.Y(member);
*eqns[Y1.name()] += dmidtf;
}
if (!phase2.pure())
{
const volScalarField& Y2 = phase2.Y(member);
*eqns[Y2.name()] -= dmidtf;
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::PhaseTransferPhaseSystem
(
const fvMesh& mesh
)
:
BasePhaseSystem(mesh)
{
this->generateInterfacialModels(phaseTransferModels_);
forAllConstIter
(
phaseTransferModelTable,
phaseTransferModels_,
phaseTransferModelIter
)
{
const phaseInterface& interface = phaseTransferModelIter()->interface();
this->template validateMassTransfer<phaseTransferModel>(interface);
if (phaseTransferModelIter()->mixture())
{
dmdtfs_.insert
(
interface,
new volScalarField
(
IOobject
(
IOobject::groupName
(
"phaseTransfer:dmdtf",
interface.name()
),
this->mesh().time().timeName(),
this->mesh()
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime, 0)
)
);
d2mdtdpfs_.insert
(
interface,
new volScalarField
(
IOobject
(
IOobject::groupName
(
"phaseTransfer:d2mdtdpf",
interface.name()
),
this->mesh().time().timeName(),
this->mesh()
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime/dimPressure, 0)
)
);
}
dmidtfs_.insert(interface, new HashPtrTable<volScalarField>());
const hashedWordList species(phaseTransferModelIter()->species());
forAllConstIter(hashedWordList, species, specieIter)
{
const word& specie = *specieIter;
dmidtfs_[interface]->insert
(
specie,
new volScalarField
(
IOobject
(
IOobject::groupName
(
IOobject::groupName
(
"phaseTransfer:dmidtf",
specie
),
interface.name()
),
this->mesh().time().timeName(),
this->mesh()
),
this->mesh(),
dimensionedScalar(dimDensity/dimTime, 0)
)
);
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::~PhaseTransferPhaseSystem()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class BasePhaseSystem>
Foam::tmp<Foam::volScalarField>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::dmdtf
(
const phaseInterfaceKey& key
) const
{
tmp<volScalarField> tDmdtf = BasePhaseSystem::dmdtf(key);
if (phaseTransferModels_.found(key))
{
if (phaseTransferModels_[key]->mixture())
{
tDmdtf.ref() += *dmdtfs_[key];
}
forAllConstIter
(
HashPtrTable<volScalarField>,
*dmidtfs_[key],
dmidtfIter
)
{
tDmdtf.ref() += *dmidtfIter();
}
}
return tDmdtf;
}
template<class BasePhaseSystem>
Foam::PtrList<Foam::volScalarField>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::dmdts() const
{
PtrList<volScalarField> dmdts(BasePhaseSystem::dmdts());
autoPtr<phaseSystem::dmdtfTable> totalDmdtfsPtr = this->totalDmdtfs();
const phaseSystem::dmdtfTable& totalDmdtfs = totalDmdtfsPtr();
forAllConstIter(phaseSystem::dmdtfTable, totalDmdtfs, totalDmdtfIter)
{
const phaseInterface interface(*this, totalDmdtfIter.key());
addField(interface.phase1(), "dmdt", *totalDmdtfIter(), dmdts);
addField(interface.phase2(), "dmdt", - *totalDmdtfIter(), dmdts);
}
return dmdts;
}
template<class BasePhaseSystem>
Foam::PtrList<Foam::volScalarField>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::d2mdtdps() const
{
PtrList<volScalarField> d2mdtdps(BasePhaseSystem::d2mdtdps());
forAllConstIter(phaseSystem::dmdtfTable, d2mdtdpfs_, d2mdtdpfIter)
{
const phaseInterface interface(*this, d2mdtdpfIter.key());
addField(interface.phase1(), "d2mdtdp", *d2mdtdpfIter(), d2mdtdps);
addField(interface.phase2(), "d2mdtdp", - *d2mdtdpfIter(), d2mdtdps);
}
return d2mdtdps;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::momentumTransferTable>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::momentumTransfer()
{
autoPtr<phaseSystem::momentumTransferTable> eqnsPtr =
BasePhaseSystem::momentumTransfer();
phaseSystem::momentumTransferTable& eqns = eqnsPtr();
this->addDmdtUfs(totalDmdtfs(), eqns);
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::momentumTransferTable>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::momentumTransferf()
{
autoPtr<phaseSystem::momentumTransferTable> eqnsPtr =
BasePhaseSystem::momentumTransferf();
phaseSystem::momentumTransferTable& eqns = eqnsPtr();
this->addDmdtUfs(totalDmdtfs(), eqns);
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::heatTransferTable>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::heatTransfer() const
{
autoPtr<phaseSystem::heatTransferTable> eqnsPtr =
BasePhaseSystem::heatTransfer();
phaseSystem::heatTransferTable& eqns = eqnsPtr();
this->addDmdtHefs(dmdtfs_, eqns);
this->addDmidtHefs(dmidtfs_, eqns);
return eqnsPtr;
}
template<class BasePhaseSystem>
Foam::autoPtr<Foam::phaseSystem::specieTransferTable>
Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::specieTransfer() const
{
autoPtr<phaseSystem::specieTransferTable> eqnsPtr
(
new phaseSystem::specieTransferTable()
);
phaseSystem::specieTransferTable& eqns = eqnsPtr();
// Create a mass transfer matrix for each species of each phase
forAll(this->phaseModels_, phasei)
{
const phaseModel& phase = this->phaseModels_[phasei];
const PtrList<volScalarField>& Yi = phase.Y();
forAll(Yi, i)
{
eqns.insert
(
Yi[i].name(),
new fvScalarMatrix(Yi[i], dimMass/dimTime)
);
}
}
this->addDmdtYfs(dmdtfs_, eqns);
this->addDmidtYf(dmidtfs_, eqns);
return eqnsPtr;
}
template<class BasePhaseSystem>
void Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::correct()
{
BasePhaseSystem::correct();
// Reset all the mass transfer rates to zero
forAllConstIter
(
phaseTransferModelTable,
phaseTransferModels_,
phaseTransferModelIter
)
{
const phaseInterface& interface = phaseTransferModelIter()->interface();
if (phaseTransferModelIter()->mixture())
{
*dmdtfs_[interface] = Zero;
*d2mdtdpfs_[interface] = Zero;
}
const hashedWordList species(phaseTransferModelIter()->species());
forAllConstIter(hashedWordList, species, specieIter)
{
const word& specie = *specieIter;
*(*dmidtfs_[interface])[specie] = Zero;
}
}
// Evaluate the models and sum the results into the mass transfer tables
forAllIter
(
phaseTransferModelTable,
phaseTransferModels_,
phaseTransferModelIter
)
{
const phaseInterface& interface = phaseTransferModelIter()->interface();
if (phaseTransferModelIter()->mixture())
{
*dmdtfs_[interface] += phaseTransferModelIter()->dmdtf();
*d2mdtdpfs_[interface] += phaseTransferModelIter()->d2mdtdpf();
}
const HashPtrTable<volScalarField> dmidtf
(
phaseTransferModelIter()->dmidtf()
);
forAllConstIter(HashPtrTable<volScalarField>, dmidtf, dmidtfIter)
{
*(*dmidtfs_[interface])[dmidtfIter.key()] += *dmidtfIter();
}
}
}
template<class BasePhaseSystem>
bool Foam::PhaseTransferPhaseSystem<BasePhaseSystem>::read()
{
if (BasePhaseSystem::read())
{
bool readOK = true;
// Models ...
return readOK;
}
else
{
return false;
}
}
// ************************************************************************* //