From 995cda665b3db16a6c3ad3da73b4fd4330289d47 Mon Sep 17 00:00:00 2001 From: Henry Weller Date: Tue, 25 Aug 2020 16:20:05 +0100 Subject: [PATCH] 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. --- .../valueMultiComponentMixture.C | 353 ++++++++++++++++++ .../valueMultiComponentMixture.H | 292 +++++++++++++++ .../psiReactionThermo/psiReactionThermos.C | 2 - .../rhoReactionThermo/rhoReactionThermos.C | 8 +- 4 files changed, 649 insertions(+), 6 deletions(-) create mode 100644 src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.C create mode 100644 src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.H diff --git a/src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.C b/src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.C new file mode 100644 index 0000000000..f4ae482489 --- /dev/null +++ b/src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.C @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#include "valueMultiComponentMixture.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::valueMultiComponentMixture::valueMultiComponentMixture +( + const dictionary& thermoDict, + const fvMesh& mesh, + const word& phaseName +) +: + multiComponentMixture + ( + thermoDict, + mesh, + phaseName + ), + thermoMixture_(this->specieThermos()), + transportMixture_(this->specieThermos()) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::scalar +Foam::valueMultiComponentMixture::thermoMixture::limit +( + const scalar T +) const +{ + return T; +} + + +template +template +Foam::scalar +Foam::valueMultiComponentMixture::thermoMixture::massWeighted +( + Method psiMethod, + const Args& ... args +) const +{ + scalar psi = 0; + + forAll(Y_, i) + { + psi += Y_[i]*(specieThermos_[i].*psiMethod)(args ...); + } + + return psi; +} + + +template +template +Foam::scalar +Foam::valueMultiComponentMixture::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 +template +Foam::scalar +Foam::valueMultiComponentMixture::transportMixture::moleWeighted +( + Method psiMethod, + const Args& ... args +) const +{ + scalar psi = 0; + + forAll(X_, i) + { + psi += X_[i]*(specieThermos_[i].*psiMethod)(args ...); + } + + return psi; +} + + +template +Foam::scalar Foam::valueMultiComponentMixture::thermoMixture::W +() const +{ + return harmonicMassWeighted(&ThermoType::W); +} + + +template +Foam::scalar Foam::valueMultiComponentMixture::thermoMixture::rho +( + scalar p, + scalar T +) const +{ + return harmonicMassWeighted(&ThermoType::rho, p, T); +} + + +template +Foam::scalar Foam::valueMultiComponentMixture::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 +Foam::scalar Foam::valueMultiComponentMixture::thermoMixture::Hf +() const +{ + return massWeighted(&ThermoType::Hf); +} + + +#define thermoMixtureFunction(Func) \ +template \ +Foam::scalar \ +Foam::valueMultiComponentMixture::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 +Foam::scalar Foam::valueMultiComponentMixture::thermoMixture::THE +( + const scalar he, + scalar p, + scalar T0 +) const +{ + return ThermoType::T + ( + *this, + he, + p, + T0, + &thermoMixture::HE, + &thermoMixture::Cpv, + &thermoMixture::limit + ); +} + + +template +Foam::scalar +Foam::valueMultiComponentMixture::transportMixture::mu +( + scalar p, + scalar T +) const +{ + return moleWeighted(&ThermoType::mu, p, T); +} + + +template +Foam::scalar +Foam::valueMultiComponentMixture::transportMixture::kappa +( + scalar p, + scalar T +) const +{ + return moleWeighted(&ThermoType::kappa, p, T); +} + + +template +Foam::scalar +Foam::valueMultiComponentMixture::transportMixture::alphah +( + scalar p, + scalar T +) const +{ + return moleWeighted(&ThermoType::alphah, p, T); +} + + +template +const typename +Foam::valueMultiComponentMixture::thermoMixtureType& +Foam::valueMultiComponentMixture::cellThermoMixture +( + const label celli +) const +{ + List& Y = thermoMixture_.Y_; + + forAll(Y, i) + { + Y[i] = this->Y()[i][celli]; + } + + return thermoMixture_; +} + + +template +const typename +Foam::valueMultiComponentMixture::thermoMixtureType& +Foam::valueMultiComponentMixture::patchFaceThermoMixture +( + const label patchi, + const label facei +) const +{ + List& Y = thermoMixture_.Y_; + + forAll(Y, i) + { + Y[i] = this->Y()[i].boundaryField()[patchi][facei]; + } + + return thermoMixture_; +} + + + +template +const typename +Foam::valueMultiComponentMixture::transportMixtureType& +Foam::valueMultiComponentMixture::cellTransportMixture +( + const label celli +) const +{ + List& 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 +const typename +Foam::valueMultiComponentMixture::transportMixtureType& +Foam::valueMultiComponentMixture::patchFaceTransportMixture +( + const label patchi, + const label facei +) const +{ + List& 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_; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.H b/src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.H new file mode 100644 index 0000000000..907cc7e633 --- /dev/null +++ b/src/thermophysicalModels/reactionThermo/mixtures/valueMultiComponentMixture/valueMultiComponentMixture.H @@ -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 . + +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 valueMultiComponentMixture +: + public multiComponentMixture +{ + +public: + + class thermoMixture + { + //- List of specie thermo + const PtrList& specieThermos_; + + //- List of mass fractions + List Y_; + + template + scalar massWeighted(Method psiMethod, const Args& ... args) const; + + template + scalar harmonicMassWeighted + ( + Method psiMethod, + const Args& ... args + ) const; + + scalar limit(const scalar T) const; + + + public: + + friend class valueMultiComponentMixture; + + thermoMixture + ( + const PtrList& 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& specieThermos_; + + //- List of mole fractions + List X_; + + template + scalar moleWeighted(Method psiMethod, const Args& ... args) const; + + + public: + + friend class valueMultiComponentMixture; + + transportMixture + ( + const PtrList& 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& + ) = 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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/reactionThermo/psiReactionThermo/psiReactionThermos.C b/src/thermophysicalModels/reactionThermo/psiReactionThermo/psiReactionThermos.C index 12d7ea279d..b4679a1b89 100644 --- a/src/thermophysicalModels/reactionThermo/psiReactionThermo/psiReactionThermos.C +++ b/src/thermophysicalModels/reactionThermo/psiReactionThermo/psiReactionThermos.C @@ -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); } diff --git a/src/thermophysicalModels/reactionThermo/rhoReactionThermo/rhoReactionThermos.C b/src/thermophysicalModels/reactionThermo/rhoReactionThermo/rhoReactionThermos.C index 454c28fb1e..0ce28b4fce 100644 --- a/src/thermophysicalModels/reactionThermo/rhoReactionThermo/rhoReactionThermos.C +++ b/src/thermophysicalModels/reactionThermo/rhoReactionThermo/rhoReactionThermos.C @@ -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); } // ************************************************************************* //