/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2015-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 "MovingPhaseModel.H"
#include "phaseSystem.H"
#include "fixedValueFvPatchFields.H"
#include "slipFvPatchFields.H"
#include "partialSlipFvPatchFields.H"
#include "fvmDdt.H"
#include "fvmDiv.H"
#include "fvmSup.H"
#include "fvcDdt.H"
#include "fvcDiv.H"
#include "fvcFlux.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template
Foam::tmp
Foam::MovingPhaseModel::phi(const volVectorField& U) const
{
word phiName(IOobject::groupName("phi", this->name()));
typeIOobject phiHeader
(
phiName,
U.mesh().time().name(),
U.mesh(),
IOobject::NO_READ
);
if (phiHeader.headerOk())
{
Info<< "Reading face flux field " << phiName << endl;
return tmp
(
new surfaceScalarField
(
IOobject
(
phiName,
U.mesh().time().name(),
U.mesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
U.mesh()
)
);
}
else
{
Info<< "Calculating face flux field " << phiName << endl;
wordList phiTypes
(
U.boundaryField().size(),
calculatedFvPatchScalarField::typeName
);
forAll(U.boundaryField(), patchi)
{
if (!U.boundaryField()[patchi].assignable())
{
phiTypes[patchi] = fixedValueFvPatchScalarField::typeName;
}
}
return tmp
(
new surfaceScalarField
(
IOobject
(
phiName,
U.mesh().time().name(),
U.mesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
fvc::flux(U),
phiTypes
)
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template
Foam::MovingPhaseModel::MovingPhaseModel
(
const phaseSystem& fluid,
const word& phaseName,
const bool referencePhase,
const label index
)
:
BasePhaseModel(fluid, phaseName, referencePhase, index),
U_
(
IOobject
(
IOobject::groupName("U", this->name()),
fluid.mesh().time().name(),
fluid.mesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluid.mesh()
),
phi_(phi(U_)),
alphaPhi_
(
IOobject
(
IOobject::groupName("alphaPhi", this->name()),
fluid.mesh().time().name(),
fluid.mesh(),
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
fluid.mesh(),
dimensionedScalar(dimensionSet(0, 3, -1, 0, 0), 0)
),
alphaRhoPhi_
(
IOobject
(
IOobject::groupName("alphaRhoPhi", this->name()),
fluid.mesh().time().name(),
fluid.mesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fluid.mesh(),
dimensionedScalar(dimensionSet(1, 0, -1, 0, 0), 0)
),
Uf_(nullptr),
DUDt_(nullptr),
DUDtf_(nullptr),
divU_(nullptr),
momentumTransport_
(
phaseCompressible::momentumTransportModel::New
(
*this,
this->rho(),
U_,
alphaRhoPhi_,
phi_,
*this
)
),
thermophysicalTransport_
(
PhaseThermophysicalTransportModel
<
phaseCompressible::momentumTransportModel,
transportThermoModel
>::New(momentumTransport_, this->thermo_)
),
continuityError_
(
IOobject
(
IOobject::groupName("continuityError", this->name()),
fluid.mesh().time().name(),
fluid.mesh()
),
fluid.mesh(),
dimensionedScalar(dimDensity/dimTime, 0)
),
K_(nullptr)
{
phi_.writeOpt() = IOobject::AUTO_WRITE;
if (fluid.mesh().dynamic() || this->fluid().MRF().size())
{
Uf_ = new surfaceVectorField
(
IOobject
(
IOobject::groupName("Uf", this->name()),
fluid.mesh().time().name(),
fluid.mesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fvc::interpolate(U_)
);
}
correctKinematics();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template
Foam::MovingPhaseModel::~MovingPhaseModel()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template
void Foam::MovingPhaseModel::correctContinuityError
(
const volScalarField& source
)
{
volScalarField& rho = this->rho();
continuityError_ = fvc::ddt(*this, rho) + fvc::div(alphaRhoPhi_) - source;
}
template
void Foam::MovingPhaseModel::correct()
{
BasePhaseModel::correct();
}
template
void Foam::MovingPhaseModel::correctKinematics()
{
BasePhaseModel::correctKinematics();
if (DUDt_.valid())
{
DUDt_.clear();
DUDt();
}
if (DUDtf_.valid())
{
DUDtf_.clear();
DUDtf();
}
if (K_.valid())
{
K_.ref() = 0.5*magSqr(this->U());
}
}
template
void Foam::MovingPhaseModel::predictMomentumTransport()
{
BasePhaseModel::predictMomentumTransport();
momentumTransport_->predict();
}
template
void Foam::MovingPhaseModel::predictThermophysicalTransport()
{
BasePhaseModel::predictThermophysicalTransport();
thermophysicalTransport_->predict();
}
template
void Foam::MovingPhaseModel::correctMomentumTransport()
{
BasePhaseModel::correctMomentumTransport();
momentumTransport_->correct();
}
template
void Foam::MovingPhaseModel::correctThermophysicalTransport()
{
BasePhaseModel::correctThermophysicalTransport();
thermophysicalTransport_->correct();
}
template
void Foam::MovingPhaseModel::correctUf()
{
const fvMesh& mesh = this->fluid().mesh();
if (Uf_.valid())
{
Uf_() = fvc::interpolate(U_);
surfaceVectorField n(mesh.Sf()/mesh.magSf());
Uf_() +=
n*(
this->fluid().MRF().absolute(fvc::absolute(phi_, U_))
/mesh.magSf()
- (n & Uf_())
);
}
}
template
bool Foam::MovingPhaseModel::stationary() const
{
return false;
}
template
Foam::tmp
Foam::MovingPhaseModel::UEqn()
{
const volScalarField& alpha = *this;
const volScalarField& rho = this->rho();
return
(
fvm::ddt(alpha, rho, U_)
+ fvm::div(alphaRhoPhi_, U_)
+ fvm::SuSp(-this->continuityError(), U_)
+ this->fluid().MRF().DDt(alpha*rho, U_)
+ momentumTransport_->divDevTau(U_)
);
}
template
Foam::tmp
Foam::MovingPhaseModel::UfEqn()
{
// As the "normal" U-eqn but without the ddt terms
const volScalarField& alpha = *this;
const volScalarField& rho = this->rho();
return
(
fvm::div(alphaRhoPhi_, U_)
+ fvm::SuSp(fvc::ddt(*this, rho) - this->continuityError(), U_)
+ this->fluid().MRF().DDt(alpha*rho, U_)
+ momentumTransport_->divDevTau(U_)
);
}
template
Foam::tmp
Foam::MovingPhaseModel::U() const
{
return U_;
}
template
Foam::volVectorField&
Foam::MovingPhaseModel::URef()
{
return U_;
}
template
const Foam::volVectorField&
Foam::MovingPhaseModel::URef() const
{
return U_;
}
template
Foam::tmp
Foam::MovingPhaseModel::phi() const
{
return phi_;
}
template
Foam::surfaceScalarField&
Foam::MovingPhaseModel::phiRef()
{
return phi_;
}
template
const Foam::surfaceScalarField&
Foam::MovingPhaseModel::phiRef() const
{
return phi_;
}
template
const Foam::autoPtr&
Foam::MovingPhaseModel::Uf() const
{
return Uf_;
}
template
Foam::surfaceVectorField&
Foam::MovingPhaseModel::UfRef()
{
if (Uf_.valid())
{
return Uf_();
}
else
{
FatalErrorInFunction
<< "Uf has not been allocated."
<< exit(FatalError);
return const_cast(surfaceVectorField::null());
}
}
template
const Foam::surfaceVectorField&
Foam::MovingPhaseModel::UfRef() const
{
if (Uf_.valid())
{
return Uf_();
}
else
{
FatalErrorInFunction
<< "Uf has not been allocated."
<< exit(FatalError);
return const_cast(surfaceVectorField::null());
}
}
template
Foam::tmp
Foam::MovingPhaseModel::alphaPhi() const
{
return alphaPhi_;
}
template
Foam::surfaceScalarField&
Foam::MovingPhaseModel::alphaPhiRef()
{
return alphaPhi_;
}
template
const Foam::surfaceScalarField&
Foam::MovingPhaseModel::alphaPhiRef() const
{
return alphaPhi_;
}
template
Foam::tmp
Foam::MovingPhaseModel::alphaRhoPhi() const
{
return alphaRhoPhi_;
}
template
Foam::surfaceScalarField&
Foam::MovingPhaseModel::alphaRhoPhiRef()
{
return alphaRhoPhi_;
}
template
const Foam::surfaceScalarField&
Foam::MovingPhaseModel::alphaRhoPhiRef() const
{
return alphaRhoPhi_;
}
template
Foam::tmp
Foam::MovingPhaseModel::DUDt() const
{
if (!DUDt_.valid())
{
const tmp taphi(fvc::absolute(phi_, U_));
const surfaceScalarField& aphi(taphi());
DUDt_ =
new volVectorField
(
IOobject::groupName("DUDt", this->name()),
fvc::ddt(U_) + fvc::div(aphi, U_) - fvc::div(aphi)*U_
);
}
return tmp(DUDt_());
}
template
Foam::tmp
Foam::MovingPhaseModel::DUDtf() const
{
if (!DUDtf_.valid())
{
DUDtf_ =
new surfaceScalarField
(
IOobject::groupName("DUDtf", this->name()),
byDt(phi_ - phi_.oldTime())
);
}
return tmp(DUDtf_());
}
template
Foam::tmp
Foam::MovingPhaseModel::continuityError() const
{
return continuityError_;
}
template
Foam::tmp
Foam::MovingPhaseModel::K() const
{
if (!K_.valid())
{
K_ =
new volScalarField
(
IOobject::groupName("K", this->name()),
0.5*magSqr(this->U())
);
}
return tmp(K_());
}
template
const Foam::autoPtr&
Foam::MovingPhaseModel::divU() const
{
return divU_;
}
template
void Foam::MovingPhaseModel::divU(tmp divU)
{
if (!divU_.valid())
{
divU_ = divU.ptr();
divU_().rename(IOobject::groupName("divU", this->name()));
divU_().checkIn();
}
else
{
divU_() = divU;
}
}
template
Foam::tmp
Foam::MovingPhaseModel::k() const
{
return momentumTransport_->k();
}
template
Foam::tmp
Foam::MovingPhaseModel::pPrime() const
{
return momentumTransport_->pPrime();
}
template
Foam::tmp
Foam::MovingPhaseModel::kappaEff(const label patchi) const
{
return thermophysicalTransport_->kappaEff(patchi);
}
template
Foam::tmp
Foam::MovingPhaseModel::divq(volScalarField& he) const
{
return thermophysicalTransport_->divq(he);
}
template
Foam::tmp
Foam::MovingPhaseModel::divj(volScalarField& Yi) const
{
return thermophysicalTransport_->divj(Yi);
}
// ************************************************************************* //