mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-12-28 03:37:59 +00:00
ENH: centralize more libraries in src/phaseSystemModels
- prelude to code refactoring
NOTE
no source code change in this commit, only relocation,
renaming and adjustment of Make/{files,options}
This commit is contained in:
committed by
Sergio Ferraris
parent
42ce617b43
commit
03526e2097
@ -0,0 +1,415 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "MultiComponentPhaseModel.H"
|
||||
|
||||
#include "phaseSystem.H"
|
||||
#include "multiphaseSystem.H"
|
||||
#include "fvmDdt.H"
|
||||
#include "fvmDiv.H"
|
||||
#include "fvmSup.H"
|
||||
#include "fvmLaplacian.H"
|
||||
#include "fvcDdt.H"
|
||||
#include "fvcDiv.H"
|
||||
#include "fvcDDt.H"
|
||||
#include "fvMatrix.H"
|
||||
#include "fvcFlux.H"
|
||||
#include "CMULES.H"
|
||||
#include "subCycle.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::
|
||||
MultiComponentPhaseModel
|
||||
(
|
||||
const phaseSystem& fluid,
|
||||
const word& phaseName
|
||||
)
|
||||
:
|
||||
BasePhaseModel(fluid, phaseName),
|
||||
species_(),
|
||||
inertIndex_(-1)
|
||||
{
|
||||
thermoPtr_.set
|
||||
(
|
||||
phaseThermo::New
|
||||
(
|
||||
fluid.mesh(),
|
||||
phaseName,
|
||||
basicThermo::phasePropertyName(basicThermo::dictName, phaseName)
|
||||
).ptr()
|
||||
);
|
||||
|
||||
if (thermoPtr_->composition().species().empty())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< " The selected thermo is pure. Use a multicomponent thermo."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
species_ = thermoPtr_->composition().species();
|
||||
|
||||
inertIndex_ = species_[thermoPtr_().template get<word>("inertSpecie")];
|
||||
|
||||
X_.setSize(thermoPtr_->composition().species().size());
|
||||
|
||||
// Initiate X's using Y's to set BC's
|
||||
forAll(species_, i)
|
||||
{
|
||||
X_.set
|
||||
(
|
||||
i,
|
||||
new volScalarField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
IOobject::groupName("X" + species_[i], phaseName),
|
||||
fluid.mesh().time().timeName(),
|
||||
fluid.mesh()
|
||||
),
|
||||
Y()[i]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Init vol fractions from mass fractions
|
||||
calculateVolumeFractions();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>
|
||||
::calculateVolumeFractions()
|
||||
{
|
||||
volScalarField Xtotal(0.0*X_[0]);
|
||||
const volScalarField W(thermo().W());
|
||||
|
||||
forAll(X_, i)
|
||||
{
|
||||
const dimensionedScalar Wi
|
||||
(
|
||||
"W",
|
||||
dimMass/dimMoles,
|
||||
thermo().composition().W(i)
|
||||
);
|
||||
|
||||
if (i != inertIndex_)
|
||||
{
|
||||
X_[i] = W*Y()[i]/Wi;
|
||||
Xtotal += X_[i];
|
||||
X_[i].correctBoundaryConditions();
|
||||
}
|
||||
}
|
||||
X_[inertIndex_] = 1.0 - Xtotal;
|
||||
X_[inertIndex_].correctBoundaryConditions();
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::
|
||||
calculateMassFractions()
|
||||
{
|
||||
volScalarField W(X_[0]*thermo().composition().W(0));
|
||||
for(label i=1; i< species_.size(); i++)
|
||||
{
|
||||
W += X_[i]*thermo().composition().W(i);
|
||||
}
|
||||
|
||||
forAll(Y(), i)
|
||||
{
|
||||
Y()[i] = X_[i]*thermo().composition().W(i)/W;
|
||||
|
||||
Info<< Y()[i].name() << " mass fraction = "
|
||||
<< " Min(Y) = " << min(Y()[i]).value()
|
||||
<< " Max(Y) = " << max(Y()[i]).value()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
const phaseThermo&
|
||||
Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::thermo() const
|
||||
{
|
||||
return thermoPtr_();
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
phaseThermo&
|
||||
Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::thermo()
|
||||
{
|
||||
return thermoPtr_();
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::correct()
|
||||
{
|
||||
return thermo().correct();
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
void Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::solveYi
|
||||
(
|
||||
PtrList<volScalarField::Internal>& Su,
|
||||
PtrList<volScalarField::Internal>& Sp
|
||||
)
|
||||
{
|
||||
const volScalarField& alpha1 = *this;
|
||||
|
||||
const fvMesh& mesh = alpha1.mesh();
|
||||
|
||||
const dictionary& MULEScontrols = mesh.solverDict(alpha1.name());
|
||||
|
||||
scalar cAlpha(MULEScontrols.get<scalar>("cYi"));
|
||||
|
||||
PtrList<surfaceScalarField> phiYiCorrs(species_.size());
|
||||
const surfaceScalarField& phi = this->fluid().phi();
|
||||
|
||||
surfaceScalarField phic(mag((phi)/mesh.magSf()));
|
||||
|
||||
phic = min(cAlpha*phic, max(phic));
|
||||
|
||||
surfaceScalarField phir(0.0*phi);
|
||||
|
||||
forAllConstIter(phaseSystem::phaseModelTable,this->fluid().phases(),iter2)
|
||||
{
|
||||
const volScalarField& alpha2 = iter2()();
|
||||
if (&alpha2 == &alpha1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
phir += phic*this->fluid().nHatf(alpha1, alpha2);
|
||||
}
|
||||
|
||||
// Do not compress interface at non-coupled boundary faces
|
||||
// (inlets, outlets etc.)
|
||||
surfaceScalarField::Boundary& phirBf = phir.boundaryFieldRef();
|
||||
forAll(phir.boundaryField(), patchi)
|
||||
{
|
||||
fvsPatchScalarField& phirp = phirBf[patchi];
|
||||
|
||||
if (!phirp.coupled())
|
||||
{
|
||||
phirp == 0;
|
||||
}
|
||||
}
|
||||
|
||||
word phirScheme("div(Yiphir," + alpha1.name() + ')');
|
||||
|
||||
forAll(X_, i)
|
||||
{
|
||||
if (inertIndex_ != i)
|
||||
{
|
||||
volScalarField& Yi = X_[i];
|
||||
|
||||
phiYiCorrs.set
|
||||
(
|
||||
i,
|
||||
new surfaceScalarField
|
||||
(
|
||||
"phi" + Yi.name() + "Corr",
|
||||
fvc::flux
|
||||
(
|
||||
phi,
|
||||
Yi,
|
||||
"div(phi," + Yi.name() + ')'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
surfaceScalarField& phiYiCorr = phiYiCorrs[i];
|
||||
|
||||
forAllConstIter
|
||||
(
|
||||
phaseSystem::phaseModelTable, this->fluid().phases(), iter2
|
||||
)
|
||||
{
|
||||
//const volScalarField& alpha2 = iter2()().oldTime();
|
||||
const volScalarField& alpha2 = iter2()();
|
||||
|
||||
if (&alpha2 == &alpha1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
phiYiCorr += fvc::flux
|
||||
(
|
||||
-fvc::flux(-phir, alpha2, phirScheme),
|
||||
Yi,
|
||||
phirScheme
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure that the flux at inflow BCs is preserved
|
||||
forAll(phiYiCorr.boundaryField(), patchi)
|
||||
{
|
||||
fvsPatchScalarField& phiYiCorrp =
|
||||
phiYiCorr.boundaryFieldRef()[patchi];
|
||||
|
||||
if (!phiYiCorrp.coupled())
|
||||
{
|
||||
const scalarField& phi1p = phi.boundaryField()[patchi];
|
||||
const scalarField& Yip = Yi.boundaryField()[patchi];
|
||||
|
||||
forAll(phiYiCorrp, facei)
|
||||
{
|
||||
if (phi1p[facei] < 0)
|
||||
{
|
||||
phiYiCorrp[facei] = Yip[facei]*phi1p[facei];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MULES::limit
|
||||
(
|
||||
1.0/mesh.time().deltaT().value(),
|
||||
geometricOneField(),
|
||||
Yi,
|
||||
phi,
|
||||
phiYiCorr,
|
||||
Sp[i],
|
||||
Su[i],
|
||||
oneField(),
|
||||
zeroField(),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
volScalarField Yt(0.0*X_[0]);
|
||||
|
||||
scalar nYiSubCycles
|
||||
(
|
||||
MULEScontrols.getOrDefault<scalar>("nYiSubCycles", 1)
|
||||
);
|
||||
|
||||
forAll(X_, i)
|
||||
{
|
||||
if (inertIndex_ != i)
|
||||
{
|
||||
volScalarField& Yi = X_[i];
|
||||
|
||||
fvScalarMatrix YiEqn
|
||||
(
|
||||
fv::EulerDdtScheme<scalar>(mesh).fvmDdt(Yi)
|
||||
+ fv::gaussConvectionScheme<scalar>
|
||||
(
|
||||
mesh,
|
||||
phi,
|
||||
upwind<scalar>(mesh, phi)
|
||||
).fvmDiv(phi, Yi)
|
||||
==
|
||||
Su[i] + fvm::Sp(Sp[i], Yi)
|
||||
);
|
||||
|
||||
YiEqn.solve();
|
||||
|
||||
surfaceScalarField& phiYiCorr = phiYiCorrs[i];
|
||||
|
||||
// Add a bounded upwind U-mean flux
|
||||
phiYiCorr += YiEqn.flux();
|
||||
|
||||
if (nYiSubCycles > 1)
|
||||
{
|
||||
for
|
||||
(
|
||||
subCycle<volScalarField> YiSubCycle(Yi, nYiSubCycles);
|
||||
!(++YiSubCycle).end();
|
||||
)
|
||||
{
|
||||
MULES::explicitSolve
|
||||
(
|
||||
geometricOneField(),
|
||||
Yi,
|
||||
phi,
|
||||
phiYiCorr,
|
||||
Sp[i],
|
||||
Su[i],
|
||||
oneField(),
|
||||
zeroField()
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MULES::explicitSolve
|
||||
(
|
||||
geometricOneField(),
|
||||
Yi,
|
||||
phi,
|
||||
phiYiCorr,
|
||||
Sp[i],
|
||||
Su[i],
|
||||
oneField(),
|
||||
zeroField()
|
||||
);
|
||||
}
|
||||
Yt += Yi;
|
||||
}
|
||||
}
|
||||
|
||||
X_[inertIndex_] = scalar(1) - Yt;
|
||||
X_[inertIndex_].max(0.0);
|
||||
|
||||
calculateMassFractions();
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
const Foam::PtrList<Foam::volScalarField>&
|
||||
Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::Y() const
|
||||
{
|
||||
return thermoPtr_->composition().Y();
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
Foam::PtrList<Foam::volScalarField>&
|
||||
Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::Y()
|
||||
{
|
||||
return thermoPtr_->composition().Y();
|
||||
}
|
||||
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
Foam::label
|
||||
Foam::MultiComponentPhaseModel<BasePhaseModel, phaseThermo>::inertIndex() const
|
||||
{
|
||||
return inertIndex_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,155 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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::MultiComponentPhaseModel
|
||||
|
||||
Description
|
||||
Class which represents a phase with multiple species. Returns the species'
|
||||
mass fractions, and their governing equations.
|
||||
|
||||
SourceFiles
|
||||
MultiComponentPhaseModel.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MultiComponentPhaseModel_H
|
||||
#define MultiComponentPhaseModel_H
|
||||
|
||||
#include "phaseModel.H"
|
||||
#include "hashedWordList.H"
|
||||
#include "rhoReactionThermo.H"
|
||||
#include "basicThermo.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class phaseModel Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class BasePhaseModel, class phaseThermo>
|
||||
class MultiComponentPhaseModel
|
||||
:
|
||||
public BasePhaseModel
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Species table
|
||||
hashedWordList species_;
|
||||
|
||||
//- Inert species index
|
||||
label inertIndex_;
|
||||
|
||||
//- Thermophysical model
|
||||
autoPtr<phaseThermo> thermoPtr_;
|
||||
|
||||
//- Ptr list of volumetric fractions for species
|
||||
PtrList<volScalarField> X_;
|
||||
|
||||
|
||||
// Protected functions
|
||||
|
||||
//- Transfor volume fraction into mass fractions
|
||||
void calculateMassFractions();
|
||||
|
||||
//- Transfor mass fraction into volume fractions
|
||||
void calculateVolumeFractions();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
MultiComponentPhaseModel
|
||||
(
|
||||
const phaseSystem& fluid,
|
||||
const word& phaseName
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~MultiComponentPhaseModel() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Species table
|
||||
const hashedWordList& species() const
|
||||
{
|
||||
return species_;
|
||||
}
|
||||
|
||||
|
||||
// Thermo
|
||||
|
||||
//- Access to thermo
|
||||
virtual const phaseThermo& thermo() const;
|
||||
|
||||
//- Access non-const thermo
|
||||
virtual phaseThermo& thermo();
|
||||
|
||||
//- Correct phase thermo
|
||||
virtual void correct();
|
||||
|
||||
//- Solve species fraction equation
|
||||
virtual void solveYi
|
||||
(
|
||||
PtrList<volScalarField::Internal>&,
|
||||
PtrList<volScalarField::Internal>&
|
||||
);
|
||||
|
||||
//- Constant access the species mass fractions
|
||||
virtual const PtrList<volScalarField>& Y() const;
|
||||
|
||||
//- Access the species mass fractions
|
||||
virtual PtrList<volScalarField>& Y();
|
||||
|
||||
//- Return inert species index
|
||||
label inertIndex() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "MultiComponentPhaseModel.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user