reactionThermo::valueMultiComponentMixture: New mixture type providing property value based mixing

This provides support for mixtures of species in which coefficient mixing of the
thermophysical properties is not possible/practical, e.g. tabulated data.
Thermodynamic properties are mass-fraction mixed and transport properties
mole-fraction mixed.

In the new general mixture framework it is now possible to implement more
complex mixing rules which is particularly useful for transport properties,
e.g. the Wilke model for gases.  Combinations of coefficient mixing for thermo
and complex mixing for transport is also supported.

valueMultiComponentMixture is currently instantiated on all the standard
tabulated thermo combination:

thermoType
{
    type            heRhoThermo;
    mixture         valueMultiComponentMixture;
    transport       tabulated;
    thermo          hTabulated;
    energy          sensibleEnthalpy;
    equationOfState icoTabulated;
    specie          specie;
}

but can be used for any of the current or future combinations.
This commit is contained in:
Henry Weller
2020-08-25 16:20:05 +01:00
parent 5b58603f4c
commit 995cda665b
4 changed files with 649 additions and 6 deletions

View File

@ -0,0 +1,353 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2020 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 "valueMultiComponentMixture.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class ThermoType>
Foam::valueMultiComponentMixture<ThermoType>::valueMultiComponentMixture
(
const dictionary& thermoDict,
const fvMesh& mesh,
const word& phaseName
)
:
multiComponentMixture<ThermoType>
(
thermoDict,
mesh,
phaseName
),
thermoMixture_(this->specieThermos()),
transportMixture_(this->specieThermos())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class ThermoType>
Foam::scalar
Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::limit
(
const scalar T
) const
{
return T;
}
template<class ThermoType>
template<class Method, class ... Args>
Foam::scalar
Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::massWeighted
(
Method psiMethod,
const Args& ... args
) const
{
scalar psi = 0;
forAll(Y_, i)
{
psi += Y_[i]*(specieThermos_[i].*psiMethod)(args ...);
}
return psi;
}
template<class ThermoType>
template<class Method, class ... Args>
Foam::scalar
Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::
harmonicMassWeighted
(
Method psiMethod,
const Args& ... args
) const
{
scalar rPsi = 0;
forAll(Y_, i)
{
rPsi += Y_[i]/(specieThermos_[i].*psiMethod)(args ...);
}
return 1/rPsi;
}
template<class ThermoType>
template<class Method, class ... Args>
Foam::scalar
Foam::valueMultiComponentMixture<ThermoType>::transportMixture::moleWeighted
(
Method psiMethod,
const Args& ... args
) const
{
scalar psi = 0;
forAll(X_, i)
{
psi += X_[i]*(specieThermos_[i].*psiMethod)(args ...);
}
return psi;
}
template<class ThermoType>
Foam::scalar Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::W
() const
{
return harmonicMassWeighted(&ThermoType::W);
}
template<class ThermoType>
Foam::scalar Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::rho
(
scalar p,
scalar T
) const
{
return harmonicMassWeighted(&ThermoType::rho, p, T);
}
template<class ThermoType>
Foam::scalar Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::psi
(
scalar p,
scalar T
) const
{
scalar rho = 0;
scalar psiByRho2 = 0;
forAll(Y_, i)
{
const scalar rhoi = specieThermos_[i].rho(p, T);
const scalar psii = specieThermos_[i].psi(p, T);
rho += Y_[i]*rhoi;
if (psii > 0)
{
psiByRho2 += Y_[i]*psii/sqr(rhoi);
}
}
return sqr(rho)*psiByRho2;
}
template<class ThermoType>
Foam::scalar Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::Hf
() const
{
return massWeighted(&ThermoType::Hf);
}
#define thermoMixtureFunction(Func) \
template<class ThermoType> \
Foam::scalar \
Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::Func \
( \
scalar p, \
scalar T \
) const \
{ \
return massWeighted(&ThermoType::Func, p, T); \
}
thermoMixtureFunction(Cp)
thermoMixtureFunction(Cv)
thermoMixtureFunction(Hs)
thermoMixtureFunction(Ha)
thermoMixtureFunction(Cpv)
thermoMixtureFunction(gamma)
thermoMixtureFunction(CpByCpv)
thermoMixtureFunction(HE)
template<class ThermoType>
Foam::scalar Foam::valueMultiComponentMixture<ThermoType>::thermoMixture::THE
(
const scalar he,
scalar p,
scalar T0
) const
{
return ThermoType::T
(
*this,
he,
p,
T0,
&thermoMixture::HE,
&thermoMixture::Cpv,
&thermoMixture::limit
);
}
template<class ThermoType>
Foam::scalar
Foam::valueMultiComponentMixture<ThermoType>::transportMixture::mu
(
scalar p,
scalar T
) const
{
return moleWeighted(&ThermoType::mu, p, T);
}
template<class ThermoType>
Foam::scalar
Foam::valueMultiComponentMixture<ThermoType>::transportMixture::kappa
(
scalar p,
scalar T
) const
{
return moleWeighted(&ThermoType::kappa, p, T);
}
template<class ThermoType>
Foam::scalar
Foam::valueMultiComponentMixture<ThermoType>::transportMixture::alphah
(
scalar p,
scalar T
) const
{
return moleWeighted(&ThermoType::alphah, p, T);
}
template<class ThermoType>
const typename
Foam::valueMultiComponentMixture<ThermoType>::thermoMixtureType&
Foam::valueMultiComponentMixture<ThermoType>::cellThermoMixture
(
const label celli
) const
{
List<scalar>& Y = thermoMixture_.Y_;
forAll(Y, i)
{
Y[i] = this->Y()[i][celli];
}
return thermoMixture_;
}
template<class ThermoType>
const typename
Foam::valueMultiComponentMixture<ThermoType>::thermoMixtureType&
Foam::valueMultiComponentMixture<ThermoType>::patchFaceThermoMixture
(
const label patchi,
const label facei
) const
{
List<scalar>& Y = thermoMixture_.Y_;
forAll(Y, i)
{
Y[i] = this->Y()[i].boundaryField()[patchi][facei];
}
return thermoMixture_;
}
template<class ThermoType>
const typename
Foam::valueMultiComponentMixture<ThermoType>::transportMixtureType&
Foam::valueMultiComponentMixture<ThermoType>::cellTransportMixture
(
const label celli
) const
{
List<scalar>& X = transportMixture_.X_;
scalar sumX = 0;
forAll(X, i)
{
X[i] = this->Y()[i][celli]/this->specieThermos()[i].W();
sumX += X[i];
}
forAll(X, i)
{
X[i] /= sumX;
}
return transportMixture_;
}
template<class ThermoType>
const typename
Foam::valueMultiComponentMixture<ThermoType>::transportMixtureType&
Foam::valueMultiComponentMixture<ThermoType>::patchFaceTransportMixture
(
const label patchi,
const label facei
) const
{
List<scalar>& X = transportMixture_.X_;
scalar sumX = 0;
forAll(X, i)
{
X[i] =
this->Y()[i].boundaryField()[patchi][facei]
/this->specieThermos()[i].W();
sumX += X[i];
}
forAll(X, i)
{
X[i] /= sumX;
}
return transportMixture_;
}
// ************************************************************************* //

View File

@ -0,0 +1,292 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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::valueMultiComponentMixture
Description
Foam::valueMultiComponentMixture
SourceFiles
valueMultiComponentMixture.C
\*---------------------------------------------------------------------------*/
#ifndef valueMultiComponentMixture_H
#define valueMultiComponentMixture_H
#include "multiComponentMixture.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class valueMultiComponentMixture Declaration
\*---------------------------------------------------------------------------*/
template<class ThermoType>
class valueMultiComponentMixture
:
public multiComponentMixture<ThermoType>
{
public:
class thermoMixture
{
//- List of specie thermo
const PtrList<ThermoType>& specieThermos_;
//- List of mass fractions
List<scalar> Y_;
template<class Method, class ... Args>
scalar massWeighted(Method psiMethod, const Args& ... args) const;
template<class Method, class ... Args>
scalar harmonicMassWeighted
(
Method psiMethod,
const Args& ... args
) const;
scalar limit(const scalar T) const;
public:
friend class valueMultiComponentMixture;
thermoMixture
(
const PtrList<ThermoType>& specieThermos
)
:
specieThermos_(specieThermos),
Y_(specieThermos.size())
{}
// Fundamental properties
//- Molecular weight [kg/kmol]
scalar W() const;
//- Return density [kg/m^3]
scalar rho(scalar p, scalar T) const;
//- Return compressibility [s^2/m^2]
scalar psi(scalar p, scalar T) const;
// Heat capacity at constant pressure [J/kg/K]
scalar Cp(const scalar p, const scalar T) const;
// Heat capacity at constant volume [J/kg/K]
scalar Cv(const scalar p, const scalar T) const;
// Sensible enthalpy [J/kg]
scalar Hs(const scalar p, const scalar T) const;
// Absolute enthalpy [J/kg]
scalar Ha(const scalar p, const scalar T) const;
// Enthalpy of formation [J/kg]
scalar Hf() const;
// Mass specific derived properties
//- Heat capacity at constant pressure/volume [J/kg/K]
scalar Cpv(const scalar p, const scalar T) const;
//- Gamma = Cp/Cv []
scalar gamma(const scalar p, const scalar T) const;
//- Ratio of heat capacity at constant pressure to that at
// constant pressure/volume []
scalar CpByCpv(const scalar p, const scalar T) const;
//- Enthalpy/Internal energy [J/kg]
scalar HE(const scalar p, const scalar T) const;
// Energy->temperature inversion functions
//- Temperature from enthalpy or internal energy
// given an initial temperature T0
scalar THE
(
const scalar he,
const scalar p,
const scalar T0
) const;
};
class transportMixture
{
//- List of specie thermo
const PtrList<ThermoType>& specieThermos_;
//- List of mole fractions
List<scalar> X_;
template<class Method, class ... Args>
scalar moleWeighted(Method psiMethod, const Args& ... args) const;
public:
friend class valueMultiComponentMixture;
transportMixture
(
const PtrList<ThermoType>& specieThermos
)
:
specieThermos_(specieThermos),
X_(specieThermos.size())
{}
// Transport properties
//- Dynamic viscosity [kg/m/s]
scalar mu(const scalar p, const scalar T) const;
//- Thermal conductivity [W/m/K]
scalar kappa(const scalar p, const scalar T) const;
//- Thermal diffusivity of enthalpy [kg/m/s]
scalar alphah(const scalar p, const scalar T) const;
};
//- Mixing type for thermodynamic properties
typedef thermoMixture thermoMixtureType;
//- Mixing type for transport properties
typedef transportMixture transportMixtureType;
private:
// Private Data
//- Mutable storage for the cell/face mixture thermo data
mutable thermoMixtureType thermoMixture_;
//- Mutable storage for the cell/face mixture thermo data
mutable transportMixtureType transportMixture_;
public:
// Constructors
//- Construct from dictionary, mesh and phase name
valueMultiComponentMixture
(
const dictionary&,
const fvMesh&,
const word&
);
//- Disallow default bitwise copy construction
valueMultiComponentMixture
(
const valueMultiComponentMixture<ThermoType>&
) = delete;
//- Destructor
virtual ~valueMultiComponentMixture()
{}
// Member Functions
//- Return the instantiated type name
static word typeName()
{
return
"valueMultiComponentMixture<" + ThermoType::typeName() + '>';
}
const thermoMixtureType& cellThermoMixture(const label celli) const;
const thermoMixtureType& patchFaceThermoMixture
(
const label patchi,
const label facei
) const;
const transportMixtureType& cellTransportMixture
(
const label celli
) const;
const transportMixtureType& patchFaceTransportMixture
(
const label patchi,
const label facei
) const;
const transportMixtureType& cellTransportMixture
(
const label celli,
const thermoMixtureType& thermoMixture
) const
{
return cellTransportMixture(celli);
}
const transportMixtureType& patchFaceTransportMixture
(
const label patchi,
const label facei,
const thermoMixtureType& thermoMixture
) const
{
return patchFaceTransportMixture(patchi, facei);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "valueMultiComponentMixture.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "coefficientMultiComponentMixture.H"
// #include "complexMultiComponentMixture.H"
#include "singleComponentMixture.H"
#include "psiThermo.H"
@ -60,7 +59,6 @@ License
namespace Foam
{
forGases(makePsiReactionThermos, coefficientMultiComponentMixture);
// forGases(makePsiReactionThermos, complexMultiComponentMixture);
forGases(makePsiReactionThermo, singleComponentMixture);
}

View File

@ -24,7 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "coefficientMultiComponentMixture.H"
// #include "complexMultiComponentMixture.H"
#include "valueMultiComponentMixture.H"
#include "singleComponentMixture.H"
#include "rhoThermo.H"
@ -34,6 +34,7 @@ License
#include "forGases.H"
#include "forLiquids.H"
#include "forPolynomials.H"
#include "forTabulated.H"
#include "makeReactionThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -62,16 +63,15 @@ License
namespace Foam
{
forGases(makeRhoReactionThermos, coefficientMultiComponentMixture);
// forGases(makeRhoReactionThermos, complexMultiComponentMixture);
forGases(makeRhoReactionThermo, singleComponentMixture);
forLiquids(makeRhoReactionThermos, coefficientMultiComponentMixture);
// forLiquids(makeRhoReactionThermos, complexMultiComponentMixture);
forLiquids(makeRhoReactionThermo, singleComponentMixture);
forPolynomials(makeRhoReactionThermos, coefficientMultiComponentMixture);
// forPolynomials(makeRhoReactionThermos, complexMultiComponentMixture);
forPolynomials(makeRhoReactionThermo, singleComponentMixture);
forTabulated(makeRhoReactionThermos, valueMultiComponentMixture);
}
// ************************************************************************* //