From be479bf9309306341c4cfcb9fa686352d0c71e69 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 18 Apr 2018 10:10:03 +0200 Subject: [PATCH 1/2] [freeflow] Add base volVars class --- dumux/freeflow/volumevariables.hh | 244 ++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 dumux/freeflow/volumevariables.hh diff --git a/dumux/freeflow/volumevariables.hh b/dumux/freeflow/volumevariables.hh new file mode 100644 index 0000000000..7b944f7440 --- /dev/null +++ b/dumux/freeflow/volumevariables.hh @@ -0,0 +1,244 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program 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 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup FreeflowModels + * + * \copydoc Dumux::FreeFlowVolumeVariables + */ +#ifndef DUMUX_FREEFLOW_VOLUME_VARIABLES_HH +#define DUMUX_FREEFLOW_VOLUME_VARIABLES_HH + +#include +#include + +namespace Dumux { + +// forward declaration +template +class FreeFlowVolumeVariablesImplementation; + +/*! + * \ingroup FreeflowModels + * \brief Volume variables for free-flow models. + * The class is specialized for isothermal and non-isothermal models. + */ +template +using FreeFlowVolumeVariables = FreeFlowVolumeVariablesImplementation; + +/*! + * \ingroup FreeflowModels + * \brief Volume variables for isothermal free-flow models. + */ +template +class FreeFlowVolumeVariablesImplementation +{ + using Scalar = typename Traits::PrimaryVariables::value_type; + +public: + //! export the type used for the primary variables + using PrimaryVariables = typename Traits::PrimaryVariables; + //! export the type encapsulating primary variable indices + using Indices = typename Traits::ModelTraits::Indices; + + //! return number of phases considered by the model + static constexpr int numPhases() { return Traits::ModelTraits::numPhases(); } + //! return number of components considered by the model + static constexpr int numComponents() { return Traits::ModelTraits::numComponents(); } + + + /*! + * \brief Update all quantities for a given control volume + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template + void update(const ElementSolution &elemSol, + const Problem &problem, + const Element &element, + const SubControlVolume& scv) + { + priVars_ = extractDofPriVars(elemSol, scv); + extrusionFactor_ = problem.extrusionFactor(element, scv, elemSol); + } + + /*! + * \brief Returns the primary variables at the dof associated with a given scv. + */ + template + static const auto& extractDofPriVars(const ElementSolution& elemSol, + const SubControlVolume& scv) + { return elemSol[0]; } + + /*! + * \brief Return how much the sub-control volume is extruded. + * + * This means the factor by which a lower-dimensional (1D or 2D) + * entity needs to be expanded to get a full dimensional cell. The + * default is 1.0 which means that 1D problems are actually + * thought as pipes with a cross section of 1 m^2 and 2D problems + * are assumed to extend 1 m to the back. + */ + Scalar extrusionFactor() const + { return extrusionFactor_; } + + /*! + * \brief Return a component of primary variable vector + * + * \param pvIdx The index of the primary variable of interest + */ + Scalar priVar(const int pvIdx) const + { return priVars_[pvIdx]; } + + //! The temperature is obtained from the problem as a constant for isothermal models + template + static Scalar temperature(const ElementSolution &elemSol, + const Problem& problem, + const Element &element, + const SubControlVolume &scv) + { + return problem.temperatureAtPos(scv.dofPosition()); + } + + //! The phase enthalpy is zero for isothermal models + //! This is needed for completing the fluid state + template + static Scalar enthalpy(const FluidState& fluidState, + const ParameterCache& paramCache) + { + return 0; + } + +protected: + PrimaryVariables priVars_; + Scalar extrusionFactor_; +}; + +/*! + * \ingroup FreeflowModels + * \brief Volume variables for the non-isothermal free-flow models. + */ +template +class FreeFlowVolumeVariablesImplementation +: public FreeFlowVolumeVariablesImplementation +{ + using ParentType = FreeFlowVolumeVariablesImplementation; + using Scalar = typename Traits::PrimaryVariables::value_type; + static constexpr int phaseIdx = Traits::phaseIndex(); + +public: + //! export the type used for the primary variables + using PrimaryVariables = typename Traits::PrimaryVariables; + //! export the underlying fluid system + using FluidSystem = typename Traits::FluidSystem; + //! export the type encapsulating primary variable indices + using Indices = typename Traits::ModelTraits::Indices; + + + /*! + * \brief Update all quantities for a given control volume + * + * \param priVars A vector containing the primary variables for the control volume + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param fvGeometry The finite volume geometry for the element + * \param scvIdx Local index of the sub control volume which is inside the element + */ + template + void update(const ElemSol &elemSol, + const Problem &problem, + const Element &element, + const Scv &scv) + { + ParentType::update(elemSol, problem, element, scv); + } + + /*! + * \brief Returns the total internal energy of a phase in the + * sub-control volume. + * + * \param phaseIdx The phase index + */ + Scalar internalEnergy() const + { return asImp_().fluidState().internalEnergy(phaseIdx); } + + /*! + * \brief Returns the total enthalpy of a phase in the sub-control + * volume. + * + * \param phaseIdx The phase index + */ + Scalar enthalpy() const + { return asImp_().fluidState().enthalpy(phaseIdx); } + + /*! + * \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ + * of the fluid phase in the sub-control volume. + */ + Scalar thermalConductivity() const + { return FluidSystem::thermalConductivity(asImp_().fluidState(), phaseIdx); } + + /*! + * \brief Returns the effective thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ + * of the fluid-flow in the sub-control volume. + */ + Scalar effectiveThermalConductivity() const + { + return thermalConductivity(); + } + + /*! + * \brief Return the specific isobaric heat capacity \f$\mathrm{[J/(kg*K)]}\f$ + * in the sub-control volume. + */ + Scalar heatCapacity() const + { return FluidSystem::heatCapacity(asImp_().fluidState(), phaseIdx); } + + //! The temperature is a primary variable for non-isothermal models + template + static Scalar temperature(const ElemSol &elemSol, + const Problem& problem, + const Element &element, + const Scv &scv) + { + return ParentType::extractDofPriVars(elemSol, scv)[Indices::temperatureIdx]; + } + + //! The phase enthalpy is zero for isothermal models + //! This is needed for completing the fluid state + template + static Scalar enthalpy(const FluidState& fluidState, + const ParameterCache& paramCache) + { + return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); + } + +protected: + const Impl &asImp_() const { return *static_cast(this); } + Impl &asImp_() { return *static_cast(this); } + +}; +} + +#endif // DUMUX_FREEFLOW_VOLUME_VARIABLES_HH -- GitLab From dfa302b1357470e3cdcac497df5dc1593dd18951 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Fri, 20 Apr 2018 11:46:12 +0200 Subject: [PATCH 2/2] [freeflow] Free volVars of TypeTag --- dumux/common/properties.hh | 1 - .../staggered/freeflow/maxwellstefanslaw.hh | 1 - dumux/freeflow/navierstokes/indices.hh | 3 + dumux/freeflow/navierstokes/model.hh | 40 ++- .../freeflow/navierstokes/volumevariables.hh | 267 +++--------------- dumux/freeflow/navierstokesnc/indices.hh | 9 +- dumux/freeflow/navierstokesnc/model.hh | 35 ++- .../navierstokesnc/volumevariables.hh | 147 ++++++---- dumux/freeflow/rans/model.hh | 13 +- dumux/freeflow/rans/volumevariables.hh | 130 ++++----- dumux/freeflow/rans/zeroeq/model.hh | 33 ++- dumux/freeflow/rans/zeroeq/volumevariables.hh | 188 ++++-------- dumux/freeflow/ransnc/model.hh | 70 ++--- dumux/freeflow/ransnc/volumevariables.hh | 46 +-- dumux/freeflow/volumevariables.hh | 16 +- 15 files changed, 412 insertions(+), 587 deletions(-) diff --git a/dumux/common/properties.hh b/dumux/common/properties.hh index b6a57311eb..4d058fc124 100644 --- a/dumux/common/properties.hh +++ b/dumux/common/properties.hh @@ -189,7 +189,6 @@ NEW_PROP_TAG(SherwoodFormulation); NEW_PROP_TAG(EnableInertiaTerms); //!< Returns whether to include inertia terms in the momentum balance eq or not (Stokes / Navier-Stokes) NEW_PROP_TAG(NormalizePressure); //!< Returns whether to normalize the pressure term in the momentum balance or not -NEW_PROP_TAG(SinglePhaseVolumeVariables); //!< Returns the single-phase, momentum-based volume variables implementation (needed for the RANS models) } // end namespace Properties } // end namespace Dumux diff --git a/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh b/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh index a826694421..a8f2d1ac45 100644 --- a/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh +++ b/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh @@ -74,7 +74,6 @@ class MaxwellStefansLawImplementation pressureIdx = Indices::pressureIdx, conti0EqIdx = Indices::conti0EqIdx, replaceCompEqIdx = Indices::replaceCompEqIdx, - phaseIdx = Indices::phaseIdx }; public: diff --git a/dumux/freeflow/navierstokes/indices.hh b/dumux/freeflow/navierstokes/indices.hh index 13cd017e69..f775628766 100644 --- a/dumux/freeflow/navierstokes/indices.hh +++ b/dumux/freeflow/navierstokes/indices.hh @@ -61,6 +61,9 @@ struct NavierStokesIndices { return dirIdx; } + + //! The index of the fluid phase in the fluid system (for compatibility reasons) + static constexpr int fluidSystemPhaseIdx = 0; }; } // end namespace Dumux diff --git a/dumux/freeflow/navierstokes/model.hh b/dumux/freeflow/navierstokes/model.hh index 9af47cb146..ae26d70ea3 100644 --- a/dumux/freeflow/navierstokes/model.hh +++ b/dumux/freeflow/navierstokes/model.hh @@ -100,6 +100,27 @@ struct NavierStokesModelTraits using Indices = NavierStokesIndices; }; +/*! + * \ingroup NavierStokesModel + * \brief Traits class for the volume variables of the Navier-Stokes model. + * + * \tparam PV The type used for primary variables + * \tparam FSY The fluid system type + * \tparam FST The fluid state type + * \tparam MT The model traits + */ +template +struct NavierStokesVolumeVariablesTraits +{ + using PrimaryVariables = PV; + using FluidSystem = FSY; + using FluidState = FST; + using ModelTraits = MT; +}; + // \{ /////////////////////////////////////////////////////////////////////////// // properties for the single-phase Navier-Stokes model @@ -150,8 +171,23 @@ public: //! The local residual SET_TYPE_PROP(NavierStokes, LocalResidual, NavierStokesResidual); -//! The volume variables -SET_TYPE_PROP(NavierStokes, VolumeVariables, NavierStokesVolumeVariables); +//! Set the volume variables property +SET_PROP(NavierStokes, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + static_assert(MT::numPhases() == 1 && MT::numComponents() == 1 && + FSY::numPhases == 1 && FSY::numComponents == 1, + "The Navier-Stokes model only works with a single-phase fluid system."); + + using Traits = NavierStokesVolumeVariablesTraits; +public: + using type = NavierStokesVolumeVariables; +}; //! The flux variables SET_TYPE_PROP(NavierStokes, FluxVariables, NavierStokesFluxVariables); diff --git a/dumux/freeflow/navierstokes/volumevariables.hh b/dumux/freeflow/navierstokes/volumevariables.hh index cf39b841b4..87e1c41612 100644 --- a/dumux/freeflow/navierstokes/volumevariables.hh +++ b/dumux/freeflow/navierstokes/volumevariables.hh @@ -25,40 +25,30 @@ #ifndef DUMUX_NAVIERSTOKES_VOLUME_VARIABLES_HH #define DUMUX_NAVIERSTOKES_VOLUME_VARIABLES_HH -#include -#include +#include namespace Dumux { -// forward declaration -template -class NavierStokesVolumeVariablesImplementation; - /*! * \ingroup NavierStokesModel * \brief Volume variables for the single-phase Navier-Stokes model. - * The class is specialized for isothermal and non-isothermal models. */ -template -using NavierStokesVolumeVariables = NavierStokesVolumeVariablesImplementation; - -/*! - * \ingroup NavierStokesModel - * \brief Volume variables for the isothermal single-phase Navier-Stokes model. - */ -template -class NavierStokesVolumeVariablesImplementation +template +class NavierStokesVolumeVariables : public FreeFlowVolumeVariables< Traits, NavierStokesVolumeVariables > { - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using ThisType = NavierStokesVolumeVariables; + using ParentType = FreeFlowVolumeVariables; + + using Scalar = typename Traits::PrimaryVariables::value_type; + using Indices = typename Traits::ModelTraits::Indices; - static const int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); + static constexpr int fluidSystemPhaseIdx = Indices::fluidSystemPhaseIdx; public: - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); + //! export the underlying fluid system + using FluidSystem = typename Traits::FluidSystem; + //! export the fluid state type + using FluidState = typename Traits::FluidState; /*! * \brief Update all quantities for a given control volume @@ -70,24 +60,15 @@ public: * \param scv The sub-control volume */ template - void update(const ElementSolution &elemSol, - const Problem &problem, - const Element &element, + void update(const ElementSolution& elemSol, + const Problem& problem, + const Element& element, const SubControlVolume& scv) { - extrusionFactor_ = problem.extrusionFactor(element, scv, elemSol); - + ParentType::update(elemSol, problem, element, scv); completeFluidState(elemSol, problem, element, scv, fluidState_); } - /*! - * \brief Returns the primary variables at the dof associated with a given scv. - */ - template - static const auto& extractDofPriVars(const ElementSolution& elemSol, - const SubControlVolume& scv) - { return elemSol[0]; } - /*! * \brief Update the fluid state */ @@ -98,37 +79,43 @@ public: const SubControlVolume& scv, FluidState& fluidState) { - const Scalar t = problem.temperatureAtPos(scv.dofPosition()); + const Scalar t = ParentType::temperature(elemSol, problem, element, scv); fluidState.setTemperature(t); - fluidState.setPressure(phaseIdx, elemSol[0][Indices::pressureIdx]); + fluidState.setPressure(fluidSystemPhaseIdx, elemSol[0][Indices::pressureIdx]); // saturation in a single phase is always 1 and thus redundant // to set. But since we use the fluid state shared by the // immiscible multi-phase models, so we have to set it here... - fluidState.setSaturation(phaseIdx, 1.0); + fluidState.setSaturation(fluidSystemPhaseIdx, 1.0); typename FluidSystem::ParameterCache paramCache; - paramCache.updatePhase(fluidState, phaseIdx); + paramCache.updatePhase(fluidState, fluidSystemPhaseIdx); + + Scalar value = FluidSystem::density(fluidState, paramCache, fluidSystemPhaseIdx); + fluidState.setDensity(fluidSystemPhaseIdx, value); - Scalar value = FluidSystem::density(fluidState, paramCache, phaseIdx); - fluidState.setDensity(phaseIdx, value); + value = FluidSystem::viscosity(fluidState, paramCache, fluidSystemPhaseIdx); + fluidState.setViscosity(fluidSystemPhaseIdx, value); - value = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); - fluidState.setViscosity(phaseIdx, value); + // compute and set the enthalpy + value = ParentType::enthalpy(fluidState, paramCache); + fluidState.setEnthalpy(fluidSystemPhaseIdx, value); } /*! - * \brief Return how much the sub-control volume is extruded. - * - * This means the factor by which a lower-dimensional (1D or 2D) - * entity needs to be expanded to get a full dimensional cell. The - * default is 1.0 which means that 1D problems are actually - * thought as pipes with a cross section of 1 m^2 and 2D problems - * are assumed to extend 1 m to the back. + * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within + * the control volume. */ - Scalar extrusionFactor() const - { return extrusionFactor_; } + Scalar pressure() const + { return fluidState_.pressure(fluidSystemPhaseIdx); } + + /*! + * \brief Return the mass density \f$\mathrm{[kg/m^3]}\f$ of a given phase within the + * control volume. + */ + Scalar density() const + { return fluidState_.density(fluidSystemPhaseIdx); } /*! * \brief Return temperature \f$\mathrm{[K]}\f$ inside the sub-control volume. @@ -140,27 +127,13 @@ public: Scalar temperature() const { return fluidState_.temperature(); } - /*! - * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within - * the control volume. - */ - Scalar pressure() const - { return fluidState_.pressure(phaseIdx); } - - /*! - * \brief Return the mass density \f$\mathrm{[kg/m^3]}\f$ of a given phase within the - * control volume. - */ - Scalar density() const - { return fluidState_.density(phaseIdx); } - /*! * \brief Returns the mass density of a given phase within the * control volume. */ Scalar molarDensity() const { - return fluidState_.molarDensity(phaseIdx); + return fluidState_.molarDensity(fluidSystemPhaseIdx); } /*! @@ -169,7 +142,7 @@ public: */ Scalar molarMass() const { - return fluidState_.averageMolarMass(phaseIdx); + return fluidState_.averageMolarMass(fluidSystemPhaseIdx); } /*! @@ -177,7 +150,7 @@ public: * control volume. */ Scalar viscosity() const - { return fluidState_.viscosity(phaseIdx); } + { return fluidState_.viscosity(fluidSystemPhaseIdx); } /*! * \brief Return the effective dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the @@ -189,161 +162,13 @@ public: /*! * \brief Return the fluid state of the control volume. */ - const FluidState &fluidState() const + const FluidState& fluidState() const { return fluidState_; } - //! The temperature is obtained from the problem as a constant for isothermal models - template - static Scalar temperature(const ElementSolution &elemSol, - const Problem& problem, - const Element &element, - const SubControlVolume &scv) - { - return problem.temperatureAtPos(scv.dofPosition()); - } - - //! The phase enthalpy is zero for isothermal models - //! This is needed for completing the fluid state - template - static Scalar enthalpy(const FluidState& fluidState, - const ParameterCache& paramCache) - { - return 0; - } - protected: FluidState fluidState_; - Scalar extrusionFactor_; }; -/*! - * \ingroup NavierStokesModel - * \brief Volume variables for the non-isothermal single-phase Navier-Stokes model. - */ -template -class NavierStokesVolumeVariablesImplementation -: virtual public NavierStokesVolumeVariablesImplementation -{ - using ParentType = NavierStokesVolumeVariablesImplementation; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - - static const int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); - static const int temperatureIdx = Indices::temperatureIdx; - -public: - using PrimaryVariables = typename ParentType::PrimaryVariables; - using FluidSystem = typename ParentType::FluidSystem; - using FluidState = typename ParentType::FluidState; - - /*! - * \brief Update all quantities for a given control volume - * - * \param elemSol A vector containing all primary variables connected to the element - * \param problem The object specifying the problem which ought to - * be simulated - * \param element An element which contains part of the control volume - * \param scv The sub-control volume - */ - template - void update(const ElementSolution &elemSol, - const Problem &problem, - const Element &element, - const SubControlVolume &scv) - { - this->extrusionFactor_ = problem.extrusionFactor(element, scv, elemSol); - - completeFluidState(elemSol, problem, element, scv, this->fluidState_); - } - - /*! - * \brief Update the fluid state - */ - template - static void completeFluidState(const ElementSolution& elemSol, - const Problem& problem, - const Element& element, - const SubControlVolume& scv, - FluidState& fluidState) - { - fluidState.setTemperature(elemSol[0][Indices::temperatureIdx]); - fluidState.setPressure(phaseIdx, elemSol[0][Indices::pressureIdx]); - - // saturation in a single phase is always 1 and thus redundant - // to set. But since we use the fluid state shared by the - // immiscible multi-phase models, so we have to set it here... - fluidState.setSaturation(phaseIdx, 1.0); - - typename FluidSystem::ParameterCache paramCache; - paramCache.updatePhase(fluidState, phaseIdx); - - Scalar value = FluidSystem::density(fluidState, paramCache, phaseIdx); - fluidState.setDensity(phaseIdx, value); - - value = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); - fluidState.setViscosity(phaseIdx, value); - - // compute and set the enthalpy - value = FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); - fluidState.setEnthalpy(phaseIdx, value); - } - - /*! - * \brief Returns the total internal energy of the fluid phase in the - * sub-control volume. - */ - Scalar internalEnergy() const - { return this->fluidState_.internalEnergy(phaseIdx); } - - /*! - * \brief Returns the total enthalpy of the fluid phase in the sub-control - * volume. - */ - Scalar enthalpy() const - { return this->fluidState_.enthalpy(phaseIdx); } - - /*! - * \brief Return the specific isobaric heat capacity \f$\mathrm{[J/(kg*K)]}\f$ - * in the sub-control volume. - */ - Scalar heatCapacity() const - { return FluidSystem::heatCapacity(this->fluidState_, phaseIdx); } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ - * of the fluid phase in the sub-control volume. - */ - Scalar thermalConductivity() const - { return FluidSystem::thermalConductivity(this->fluidState_, phaseIdx); } - - /*! - * \brief Returns the effective thermal conductivity \f$\mathrm{[W/(m*K)]}\f$. - */ - Scalar effectiveThermalConductivity() const - { return thermalConductivity(); } - - //! The temperature is a primary variable for non-isothermal models - using ParentType::temperature; - template - static Scalar temperature(const ElementSolution &elemSol, - const Problem& problem, - const Element &element, - const SubControlVolume &scv) - { - return ParentType::extractDofPriVars(elemSol, scv)[temperatureIdx]; - } - - //! The phase enthalpy is zero for isothermal models - //! This is needed for completing the fluid state - template - static Scalar enthalpy(const FluidState& fluidState, - const ParameterCache& paramCache) - { - return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); - } - -}; -} +} // end namespace Dumux -#endif +#endif // DUMUX_NAVIERSTOKES_VOLUME_VARIABLES_HH diff --git a/dumux/freeflow/navierstokesnc/indices.hh b/dumux/freeflow/navierstokesnc/indices.hh index dfaa510336..ec95316b17 100644 --- a/dumux/freeflow/navierstokesnc/indices.hh +++ b/dumux/freeflow/navierstokesnc/indices.hh @@ -33,12 +33,15 @@ namespace Dumux { * \brief The common indices for the isothermal multi-component Navier-Stokes model. */ template + int phaseIdx, int theReplaceCompEqIdx> struct NavierStokesNCIndices : public NavierStokesIndices { public: - static constexpr int phaseIdx = thePhaseIdx; //!< The phase index - static constexpr int mainCompIdx = phaseIdx; //!< The index of the main component + //! The index of the fluid phase in the fluid system + static constexpr int fluidSystemPhaseIdx = phaseIdx; + + //! The index of the main component + static constexpr int mainCompIdx = fluidSystemPhaseIdx; //! The index of the component whose mass balance will be replaced by the total one static constexpr int replaceCompEqIdx = theReplaceCompEqIdx; diff --git a/dumux/freeflow/navierstokesnc/model.hh b/dumux/freeflow/navierstokesnc/model.hh index 1251ca193e..200ee12881 100644 --- a/dumux/freeflow/navierstokesnc/model.hh +++ b/dumux/freeflow/navierstokesnc/model.hh @@ -74,7 +74,7 @@ namespace Dumux { * \ingroup NavierStokesModel * \brief Traits for the Navier-Stokes multi-component model */ -template +template struct NavierStokesNCModelTraits { //! The dimension of the model @@ -90,6 +90,9 @@ struct NavierStokesNCModelTraits //! The number of components static constexpr int numComponents() { return nComp; } + //! Use moles or not + static constexpr bool useMoles() { return useM; } + //! Enable advection static constexpr bool enableAdvection() { return true; } @@ -113,7 +116,7 @@ namespace Properties { ////////////////////////////////////////////////////////////////// //! The type tag for the single-phase, multi-component isothermal Navier-Stokes model -NEW_TYPE_TAG(NavierStokesNC, INHERITS_FROM(NavierStokes)); +NEW_TYPE_TAG(NavierStokesNC, INHERITS_FROM(FreeFlow)); //! The type tag for the single-phase, multi-component non-isothermal Navier-Stokes model NEW_TYPE_TAG(NavierStokesNCNI, INHERITS_FROM(NavierStokesNC)); @@ -132,23 +135,42 @@ private: static constexpr int numComponents = FluidSystem::numComponents; static constexpr int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); static constexpr int replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx); + static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); public: - using type = NavierStokesNCModelTraits; + using type = NavierStokesNCModelTraits; }; SET_INT_PROP(NavierStokesNC, PhaseIdx, 0); //!< Defines the phaseIdx SET_BOOL_PROP(NavierStokesNC, UseMoles, false); //!< Defines whether molar (true) or mass (false) density is used SET_INT_PROP(NavierStokesNC, ReplaceCompEqIdx, 0); //); -//! The volume variables -SET_TYPE_PROP(NavierStokesNC, VolumeVariables, NavierStokesNCVolumeVariables); +//! Set the volume variables property +SET_PROP(NavierStokesNC, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + using Traits = NavierStokesVolumeVariablesTraits; +public: + using type = NavierStokesNCVolumeVariables; +}; + //! The flux variables SET_TYPE_PROP(NavierStokesNC, FluxVariables, NavierStokesNCFluxVariables); +//! The flux variables cache class, by default the one for free flow +SET_TYPE_PROP(NavierStokesNC, FluxVariablesCache, FreeFlowFluxVariablesCache); + //! The specific vtk output fields SET_PROP(NavierStokesNC, VtkOutputFields) { @@ -192,7 +214,8 @@ private: static constexpr int numComponents = FluidSystem::numComponents; static constexpr int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); static constexpr int replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx); - using IsothermalModelTraits = NavierStokesNCModelTraits; + static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); + using IsothermalModelTraits = NavierStokesNCModelTraits; public: using type = NavierStokesNIModelTraits; }; diff --git a/dumux/freeflow/navierstokesnc/volumevariables.hh b/dumux/freeflow/navierstokesnc/volumevariables.hh index a40cc720ac..85c0c094e1 100644 --- a/dumux/freeflow/navierstokesnc/volumevariables.hh +++ b/dumux/freeflow/navierstokesnc/volumevariables.hh @@ -26,10 +26,8 @@ #define DUMUX_NAVIER_STOKES_NC_VOLUMEVARIABLES_HH #include -#include -#include -#include +#include namespace Dumux { @@ -37,31 +35,25 @@ namespace Dumux { * \ingroup NavierStokesNCModel * \brief Volume variables for the single-phase, multi-component Navier-Stokes model. */ -template -class NavierStokesNCVolumeVariables : virtual public NavierStokesVolumeVariables +template +class NavierStokesNCVolumeVariables : public FreeFlowVolumeVariables< Traits, NavierStokesNCVolumeVariables > { - using ParentType = NavierStokesVolumeVariables; - using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using SubControlVolume = typename FVElementGeometry::SubControlVolume; - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; - - enum { numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents(), - numPhases = GET_PROP_TYPE(TypeTag, ModelTraits)::numPhases(), - mainCompIdx = Indices::mainCompIdx, - pressureIdx = Indices::pressureIdx - }; - - static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); - static constexpr auto phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); + using ThisType = NavierStokesNCVolumeVariables; + using ParentType = FreeFlowVolumeVariables; + + using Scalar = typename Traits::PrimaryVariables::value_type; + using Indices = typename Traits::ModelTraits::Indices; + + static constexpr int fluidSystemPhaseIdx = Indices::fluidSystemPhaseIdx; + static constexpr int numComponents = Traits::ModelTraits::numComponents(); + + static constexpr bool useMoles = Traits::ModelTraits::useMoles(); public: - using FluidSystem = typename ParentType::FluidSystem; - using FluidState = typename ParentType::FluidState; + //! export the underlying fluid system + using FluidSystem = typename Traits::FluidSystem; + //! export the fluid state type + using FluidState = typename Traits::FluidState; /*! * \brief Update all quantities for a given control volume @@ -72,18 +64,18 @@ public: * \param element An element which contains part of the control volume * \param scv The sub-control volume */ - template + template void update(const ElementSolution &elemSol, const Problem &problem, const Element &element, const SubControlVolume& scv) { - this->extrusionFactor_ = problem.extrusionFactor(element, scv, elemSol); + ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, this->fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_); typename FluidSystem::ParameterCache paramCache; - paramCache.updateAll(this->fluidState_); + paramCache.updateAll(fluidState_); for (unsigned int compIIdx = 0; compIIdx < numComponents; ++compIIdx) { for (unsigned int compJIdx = 0; compJIdx < numComponents; ++compJIdx) @@ -92,9 +84,9 @@ public: if(compIIdx != compJIdx) { diffCoefficient_[compIIdx][compJIdx] - = FluidSystem::binaryDiffusionCoefficient(this->fluidState_, + = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, - phaseIdx, + fluidSystemPhaseIdx, compIIdx, compJIdx); } @@ -105,7 +97,7 @@ public: /*! * \brief Update the fluid state */ - template + template static void completeFluidState(const ElementSolution& elemSol, const Problem& problem, const Element& element, @@ -113,51 +105,88 @@ public: FluidState& fluidState) { fluidState.setTemperature(ParentType::temperature(elemSol, problem, element, scv)); - fluidState.setPressure(phaseIdx, elemSol[0][Indices::pressureIdx]); + fluidState.setPressure(fluidSystemPhaseIdx, elemSol[0][Indices::pressureIdx]); // saturation in a single phase is always 1 and thus redundant // to set. But since we use the fluid state shared by the // immiscible multi-phase models, so we have to set it here... - fluidState.setSaturation(phaseIdx, 1.0); + fluidState.setSaturation(fluidSystemPhaseIdx, 1.0); Scalar sumFracMinorComp = 0.0; for(int compIdx = 0; compIdx < numComponents; ++compIdx) { - if(compIdx == mainCompIdx) + if(compIdx == Indices::mainCompIdx) continue; - int offset = mainCompIdx != 0 ? 1 : 0; + int offset = Indices::mainCompIdx != 0 ? 1 : 0; // temporary add 1.0 to remove spurious differences in mole fractions // which are below the numerical accuracy Scalar moleOrMassFraction = elemSol[0][Indices::conti0EqIdx+compIdx+offset] + 1.0; moleOrMassFraction = moleOrMassFraction - 1.0; if(useMoles) - fluidState.setMoleFraction(phaseIdx, compIdx, moleOrMassFraction); + fluidState.setMoleFraction(fluidSystemPhaseIdx, compIdx, moleOrMassFraction); else - fluidState.setMassFraction(phaseIdx, compIdx, moleOrMassFraction); + fluidState.setMassFraction(fluidSystemPhaseIdx, compIdx, moleOrMassFraction); sumFracMinorComp += moleOrMassFraction; } if(useMoles) - fluidState.setMoleFraction(phaseIdx, mainCompIdx, 1.0 - sumFracMinorComp); + fluidState.setMoleFraction(fluidSystemPhaseIdx, Indices::mainCompIdx, 1.0 - sumFracMinorComp); else - fluidState.setMassFraction(phaseIdx, mainCompIdx, 1.0 - sumFracMinorComp); + fluidState.setMassFraction(fluidSystemPhaseIdx, Indices::mainCompIdx, 1.0 - sumFracMinorComp); typename FluidSystem::ParameterCache paramCache; - paramCache.updatePhase(fluidState, phaseIdx); + paramCache.updatePhase(fluidState, fluidSystemPhaseIdx); - Scalar value = FluidSystem::density(fluidState, paramCache, phaseIdx); - fluidState.setDensity(phaseIdx, value); + Scalar value = FluidSystem::density(fluidState, paramCache, fluidSystemPhaseIdx); + fluidState.setDensity(fluidSystemPhaseIdx, value); - value = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); - fluidState.setViscosity(phaseIdx, value); + value = FluidSystem::viscosity(fluidState, paramCache, fluidSystemPhaseIdx); + fluidState.setViscosity(fluidSystemPhaseIdx, value); // compute and set the enthalpy const Scalar h = ParentType::enthalpy(fluidState, paramCache); - fluidState.setEnthalpy(phaseIdx, h); + fluidState.setEnthalpy(fluidSystemPhaseIdx, h); } + /*! + * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within + * the control volume. + */ + Scalar pressure() const + { return fluidState_.pressure(fluidSystemPhaseIdx); } + + /*! + * \brief Return the mass density \f$\mathrm{[kg/m^3]}\f$ of a given phase within the + * control volume. + */ + Scalar density() const + { return fluidState_.density(fluidSystemPhaseIdx); } + + /*! + * \brief Return temperature \f$\mathrm{[K]}\f$ inside the sub-control volume. + * + * Note that we assume thermodynamic equilibrium, i.e. the + * temperatures of the rock matrix and of all fluid phases are + * identical. + */ + Scalar temperature() const + { return fluidState_.temperature(); } + + /*! + * \brief Return the effective dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the + * control volume. + */ + Scalar effectiveViscosity() const + { return viscosity(); } + + /*! + * \brief Return the dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the + * control volume. + */ + Scalar viscosity() const + { return fluidState_.viscosity(fluidSystemPhaseIdx); } /*! * \brief Returns the mass fraction of a component in the phase \f$\mathrm{[-]}\f$ @@ -166,7 +195,7 @@ public: */ Scalar massFraction(int compIdx) const { - return this->fluidState_.massFraction(phaseIdx, compIdx); + return fluidState_.massFraction(fluidSystemPhaseIdx, compIdx); } /*! @@ -176,7 +205,7 @@ public: */ Scalar moleFraction(int compIdx) const { - return this->fluidState_.moleFraction(phaseIdx, compIdx); + return fluidState_.moleFraction(fluidSystemPhaseIdx, compIdx); } /*! @@ -184,7 +213,7 @@ public: */ Scalar molarDensity() const { - return this->fluidState_.molarDensity(phaseIdx); + return fluidState_.molarDensity(fluidSystemPhaseIdx); } /*! @@ -193,10 +222,10 @@ public: * \param compIIdx the index of the component which diffusive * \param compJIdx the index of the component with respect to which compIIdx diffuses */ - Scalar diffusionCoefficient(int compIIdx, int compJIdx = phaseIdx) const + Scalar diffusionCoefficient(int compIIdx, int compJIdx = fluidSystemPhaseIdx) const { if (compIIdx == compJIdx) - DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient called for phaseIdx = compIdx"); + DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient called for fluidSystemPhaseIdx = compIdx"); return diffCoefficient_[compIIdx][compJIdx]; } @@ -206,19 +235,19 @@ public: * \param compIIdx the index of the component which diffusive * \param compJIdx the index of the component with respect to which compIIdx diffuses */ - Scalar effectiveDiffusivity(int compIIdx, int compJIdx = phaseIdx) const + Scalar effectiveDiffusivity(int compIIdx, int compJIdx = fluidSystemPhaseIdx) const { return diffusionCoefficient(compIIdx, compJIdx); } -protected: - - Implementation &asImp_() - { return *static_cast(this); } - - const Implementation &asImp_() const - { return *static_cast(this); } + /*! + * \brief Return the fluid state of the control volume. + */ + const FluidState& fluidState() const + { return fluidState_; } +protected: + FluidState fluidState_; std::array, numComponents> diffCoefficient_; }; diff --git a/dumux/freeflow/rans/model.hh b/dumux/freeflow/rans/model.hh index 297709f5de..a0830144df 100644 --- a/dumux/freeflow/rans/model.hh +++ b/dumux/freeflow/rans/model.hh @@ -38,15 +38,9 @@ #define DUMUX_RANS_MODEL_HH #include -#include -#include #include -#include -#include #include -#include -#include "volumevariables.hh" #include "vtkoutputfields.hh" namespace Dumux { @@ -69,9 +63,6 @@ NEW_TYPE_TAG(RANS, INHERITS_FROM(NavierStokes)); /////////////////////////////////////////////////////////////////////////// SET_BOOL_PROP(RANS, EnableInertiaTerms, true); //!< Explicitly force the consideration of inertia terms by default -//! The volume variables -SET_TYPE_PROP(RANS, VolumeVariables, RANSVolumeVariables); - //! The specific vtk output fields SET_PROP(RANS, VtkOutputFields) { @@ -94,6 +85,10 @@ SET_PROP(RANSNI, ModelTraits) private: using GridView = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::GridView; static constexpr int dim = GridView::dimension; + static constexpr bool enableInertiaTerms = GET_PROP_VALUE(TypeTag, EnableInertiaTerms); + + static_assert(enableInertiaTerms, "The RANS model only works with intertia terms enabled!"); + using IsothermalTraits = NavierStokesModelTraits; public: using type = NavierStokesNIModelTraits; diff --git a/dumux/freeflow/rans/volumevariables.hh b/dumux/freeflow/rans/volumevariables.hh index e35379383e..dcf1bfcca5 100644 --- a/dumux/freeflow/rans/volumevariables.hh +++ b/dumux/freeflow/rans/volumevariables.hh @@ -28,16 +28,13 @@ #include #include -#include #include -#include -#include namespace Dumux { // forward declaration -template +template class RANSVolumeVariablesImplementation; /*! @@ -45,34 +42,23 @@ class RANSVolumeVariablesImplementation; * \brief Volume variables for the single-phase Reynolds-Averaged Navier-Stokes models. * The class is specialized for isothermal and non-isothermal models. */ -template -using RANSVolumeVariables = RANSVolumeVariablesImplementation; +template +using RANSVolumeVariables = RANSVolumeVariablesImplementation; /*! * \ingroup RANSModel * \brief Volume variables for the isothermal single-phase Reynolds-Averaged Navier-Stokes models. */ -template -class RANSVolumeVariablesImplementation -: virtual public NavierStokesVolumeVariablesImplementation +template +class RANSVolumeVariablesImplementation { - using ParentType = NavierStokesVolumeVariablesImplementation; - using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using SubControlVolume = typename FVElementGeometry::SubControlVolume; - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; - - enum { dimWorld = GridView::dimensionworld }; + using Scalar = typename Traits::PrimaryVariables::value_type; + + enum { dimWorld = Traits::ModelTraits::dim() }; using DimVector = Dune::FieldVector; using DimMatrix = Dune::FieldMatrix; public: - using FluidSystem = typename ParentType::FluidSystem; - using FluidState = typename ParentType::FluidState; /*! * \brief Update all turbulent quantities for a given control volume @@ -85,7 +71,7 @@ public: * \param element An element which contains part of the control volume * \param scv The sub-control volume */ - template + template void updateRANSProperties(const ElementSolution &elemSol, const Problem &problem, const Element &element, @@ -102,14 +88,16 @@ public: velocity_ = problem.velocity_[elementID_]; velocityMaximum_ = problem.velocityMaximum_[wallElementID_]; velocityGradients_ = problem.velocityGradients_[elementID_]; - unsigned int flowNormalAxis = problem.flowNormalAxis_[elementID_]; - unsigned int wallNormalAxis = problem.wallNormalAxis_[elementID_]; + const auto flowNormalAxis = problem.flowNormalAxis_[elementID_]; + const auto wallNormalAxis = problem.wallNormalAxis_[elementID_]; uStar_ = sqrt(problem.kinematicViscosity_[wallElementID_] * abs(problem.velocityGradients_[wallElementID_][flowNormalAxis][wallNormalAxis])); uStar_ = max(uStar_, 1e-10); // zero values lead to numerical problems in some turbulence models yPlus_ = wallDistance_ * uStar_ / kinematicViscosity(); uPlus_ = velocity_[flowNormalAxis] / uStar_; - dynamicEddyViscosity_ = 0.0; // will be set by the specific RANS implementation + + // get the dynamic eddy viscosity from the specific RANS implementation + dynamicEddyViscosity_ = asImp_().calculateEddyViscosity(elemSol, problem, element, scv); } /*! @@ -167,84 +155,84 @@ public: Scalar dynamicEddyViscosity() const { return dynamicEddyViscosity_; } - /*! - * \brief Return the dynamic eddy viscosity \f$\mathrm{[Pa s]}\f$ of the flow within the - * control volume. - */ - void setDynamicEddyViscosity(Scalar value) - { - dynamicEddyViscosity_ = value; - } - - /*! - * \brief Return the effective dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the - * control volume. - */ - Scalar effectiveViscosity() const - { return ParentType::viscosity() + dynamicEddyViscosity(); } - /*! * \brief Return the kinematic viscosity \f$\mathrm{[m^2/s]}\f$ of the fluid within the * control volume. */ Scalar kinematicViscosity() const - { return ParentType::viscosity() / ParentType::density(); } + { return asImp_().viscosity() / asImp_().density(); } /*! * \brief Return the kinematic eddy viscosity \f$\mathrm{[Pa s]}\f$ of the flow within the * control volume. */ Scalar kinematicEddyViscosity() const - { return dynamicEddyViscosity() / ParentType::density(); } + { return dynamicEddyViscosity() / asImp_().density(); } protected: DimVector velocity_; DimVector velocityMaximum_; DimMatrix velocityGradients_; Scalar dynamicEddyViscosity_; - unsigned int elementID_; - unsigned int wallElementID_; + std::size_t elementID_; + std::size_t wallElementID_; Scalar wallDistance_; Scalar uStar_; Scalar yPlus_; Scalar uPlus_; + + const Impl &asImp_() const { return *static_cast(this); } + Impl &asImp_() { return *static_cast(this); } }; /*! * \ingroup RANSModel * \brief Volume variables for the non-isothermal single-phase Reynolds-Averaged Navier-Stokes models. */ -template -class RANSVolumeVariablesImplementation -: virtual public NavierStokesVolumeVariablesImplementation, - virtual public RANSVolumeVariablesImplementation +template +class RANSVolumeVariablesImplementation +: public RANSVolumeVariablesImplementation { - using ParentTypeNonIsothermal = NavierStokesVolumeVariablesImplementation; - using ParentTypeIsothermal = RANSVolumeVariablesImplementation; - using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using SubControlVolume = typename FVElementGeometry::SubControlVolume; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; + using ParentType = RANSVolumeVariablesImplementation; + using Scalar = typename Traits::PrimaryVariables::value_type; public: - using FluidSystem = typename ParentTypeIsothermal::FluidSystem; - using FluidState = typename ParentTypeIsothermal::FluidState; + + /*! + * \brief Update all turbulent quantities for a given control volume + * + * Wall related quantities are stored and the calculateEddyViscosity(...) + * function of the turbulence model implementation is called. + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template + void updateRANSProperties(const ElementSolution &elemSol, + const Problem &problem, + const Element &element, + const SubControlVolume& scv) + { + ParentType::updateRANSProperties(elemSol, problem, element, scv); + calculateEddyThermalConductivity(problem); + } /*! * \brief Calculates the eddy thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ based * on the kinematic eddy viscosity and the turbulent prandtl number */ - void calculateEddyThermalConductivity() + template + void calculateEddyThermalConductivity(const Problem& problem) { static const auto turbulentPrandtlNumber - = getParamFromGroup(GET_PROP_VALUE(TypeTag, ModelParameterGroup), + = getParamFromGroup(problem.paramGroup(), "RANS.TurbulentPrandtlNumber", 1.0); - eddyThermalConductivity_ = ParentTypeIsothermal::kinematicEddyViscosity() - * ParentTypeIsothermal::density() - * ParentTypeNonIsothermal::heatCapacity() + + eddyThermalConductivity_ = ParentType::kinematicEddyViscosity() + * ParentType::asImp_().density() + * ParentType::asImp_().heatCapacity() / turbulentPrandtlNumber; } @@ -255,16 +243,6 @@ public: Scalar eddyThermalConductivity() const { return eddyThermalConductivity_; } - /*! - * \brief Returns the effective thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ - * of the fluid-flow in the sub-control volume. - */ - Scalar effectiveThermalConductivity() const - { - return ParentTypeNonIsothermal::thermalConductivity() - + eddyThermalConductivity(); - } - protected: Scalar eddyThermalConductivity_; }; diff --git a/dumux/freeflow/rans/zeroeq/model.hh b/dumux/freeflow/rans/zeroeq/model.hh index 2de4b348fe..07b55e954a 100644 --- a/dumux/freeflow/rans/zeroeq/model.hh +++ b/dumux/freeflow/rans/zeroeq/model.hh @@ -36,6 +36,7 @@ #include #include #include +#include #include "volumevariables.hh" @@ -49,8 +50,20 @@ namespace Properties { //! The type tag for the single-phase, isothermal Reynolds-Averaged Navier-Stokes 0-Eq. model NEW_TYPE_TAG(ZeroEq, INHERITS_FROM(RANS)); -//! The volume variables -SET_TYPE_PROP(ZeroEq, VolumeVariables, ZeroEqVolumeVariables); +//! Set the volume variables property +SET_PROP(ZeroEq, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + using Traits = NavierStokesVolumeVariablesTraits; + using NSVolVars = NavierStokesVolumeVariables; +public: + using type = ZeroEqVolumeVariables; +}; ////////////////////////////////////////////////////////////////// // default property values for the non-isothermal RANS 0-Eq. model @@ -59,8 +72,20 @@ SET_TYPE_PROP(ZeroEq, VolumeVariables, ZeroEqVolumeVariables); //! The type tag for the single-phase, isothermal Reynolds-Averaged Navier-Stokes model NEW_TYPE_TAG(ZeroEqNI, INHERITS_FROM(RANSNI)); -//! The volume variables -SET_TYPE_PROP(ZeroEqNI, VolumeVariables, ZeroEqVolumeVariables); +//! Set the volume variables property +SET_PROP(ZeroEqNI, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + using Traits = NavierStokesVolumeVariablesTraits; + using NSVolVars = NavierStokesVolumeVariables; +public: + using type = ZeroEqVolumeVariables; +}; // \} } diff --git a/dumux/freeflow/rans/zeroeq/volumevariables.hh b/dumux/freeflow/rans/zeroeq/volumevariables.hh index 5a5ec53840..7b77ed089a 100644 --- a/dumux/freeflow/rans/zeroeq/volumevariables.hh +++ b/dumux/freeflow/rans/zeroeq/volumevariables.hh @@ -25,51 +25,38 @@ #ifndef DUMUX_ZEROEQ_VOLUME_VARIABLES_HH #define DUMUX_ZEROEQ_VOLUME_VARIABLES_HH -#include -#include -#include +#include #include - #include "models.hh" namespace Dumux { -// forward declaration -template -class ZeroEqVolumeVariablesImplementation; - /*! * \ingroup ZeroEqModel * \brief Volume variables for the single-phase 0-Eq. model. - * The class is specialized for isothermal and non-isothermal models. - */ -template -using ZeroEqVolumeVariables = ZeroEqVolumeVariablesImplementation; - -/*! - * \ingroup ZeroEqModel - * \brief Volume variables for the isothermal single-phase 0-Eq. model. */ -template -class ZeroEqVolumeVariablesImplementation -: virtual public RANSVolumeVariablesImplementation +template +class ZeroEqVolumeVariables +: public RANSVolumeVariables< Traits, ZeroEqVolumeVariables > +, public NSVolumeVariables { - using ParentType = RANSVolumeVariablesImplementation; - using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using SubControlVolume = typename FVElementGeometry::SubControlVolume; - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; - - static const int defaultPhaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); + using ThisType = ZeroEqVolumeVariables; + using RANSParentType = RANSVolumeVariables; + using NavierStokesParentType = NSVolumeVariables; + + using Scalar = typename Traits::PrimaryVariables::value_type; + using Indices = typename Traits::ModelTraits::Indices; + + static constexpr bool enableEnergyBalance = Traits::ModelTraits::enableEnergyBalance(); + + public: - using FluidSystem = typename ParentType::FluidSystem; - using FluidState = typename ParentType::FluidState; + //! export the underlying fluid system + using FluidSystem = typename Traits::FluidSystem; + //! export the fluid state type + using FluidState = typename Traits::FluidState; /*! * \brief Update all quantities for a given control volume @@ -80,36 +67,35 @@ public: * \param element An element which contains part of the control volume * \param scv The sub-control volume */ - template + template void update(const ElementSolution &elemSol, const Problem &problem, const Element &element, const SubControlVolume& scv) { - ParentType::update(elemSol, problem, element, scv); - updateRANSProperties(elemSol, problem, element, scv); + NavierStokesParentType::update(elemSol, problem, element, scv); + RANSParentType::updateRANSProperties(elemSol, problem, element, scv); } /*! - * \brief Update all turbulent quantities for a given control volume - * - * Wall and roughness related quantities are stored. Eddy viscosity is set. - * - * \param elemSol A vector containing all primary variables connected to the element - * \param problem The object specifying the problem which ought to be simulated - * \param element An element which contains part of the control volume - * \param scv The sub-control volume + * \brief Return the effective dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the + * control volume. + */ + Scalar effectiveViscosity() const + { + return NavierStokesParentType::viscosity() + + RANSParentType::dynamicEddyViscosity(); + } + + /*! + * \brief Returns the effective thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ + * of the fluid-flow in the sub-control volume. */ - template - void updateRANSProperties(const ElementSolution &elemSol, - const Problem &problem, - const Element &element, - const SubControlVolume& scv) + template = 0> + Scalar effectiveThermalConductivity() const { - ParentType::updateRANSProperties(elemSol, problem, element, scv); - additionalRoughnessLength_ = problem.additionalRoughnessLength_[ParentType::elementID()]; - yPlusRough_ = wallDistanceRough() * ParentType::uStar() / ParentType::kinematicViscosity(); - calculateEddyViscosity(elemSol, problem, element, scv); + return NavierStokesParentType::thermalConductivity() + + RANSParentType::eddyThermalConductivity(); } /*! @@ -120,19 +106,22 @@ public: * \param element An element which contains part of the control volume * \param scv The sub-control volume */ - template - void calculateEddyViscosity(const ElementSolution &elemSol, - const Problem &problem, - const Element &element, - const SubControlVolume& scv) + template + Scalar calculateEddyViscosity(const ElementSolution &elemSol, + const Problem &problem, + const Element &element, + const SubControlVolume& scv) { + additionalRoughnessLength_ = problem.additionalRoughnessLength_[RANSParentType::elementID()]; + yPlusRough_ = wallDistanceRough() * RANSParentType::uStar() / RANSParentType::kinematicViscosity(); + using std::abs; using std::exp; using std::sqrt; Scalar kinematicEddyViscosity = 0.0; - unsigned int flowNormalAxis = problem.flowNormalAxis_[ParentType::elementID()]; - unsigned int wallNormalAxis = problem.wallNormalAxis_[ParentType::elementID()]; - Scalar velGrad = abs(ParentType::velocityGradients()[flowNormalAxis][wallNormalAxis]); + unsigned int flowNormalAxis = problem.flowNormalAxis_[RANSParentType::elementID()]; + unsigned int wallNormalAxis = problem.wallNormalAxis_[RANSParentType::elementID()]; + Scalar velGrad = abs(RANSParentType::velocityGradients()[flowNormalAxis][wallNormalAxis]); if (problem.eddyViscosityModel_ == EddyViscosityModels::none) { @@ -152,21 +141,22 @@ public: } else if (problem.eddyViscosityModel_ == EddyViscosityModels::baldwinLomax) { - kinematicEddyViscosity = problem.kinematicEddyViscosity_[ParentType::elementID()]; + kinematicEddyViscosity = problem.kinematicEddyViscosity_[RANSParentType::elementID()]; } else { DUNE_THROW(Dune::NotImplemented, "This eddy viscosity model is not implemented: " << problem.eddyViscosityModel_); } - ParentType::setDynamicEddyViscosity(kinematicEddyViscosity * ParentType::density()); + + return kinematicEddyViscosity * NavierStokesParentType::density(); } /*! * \brief Return the wall distance \f$\mathrm{[m]}\f$ including an additional roughness length */ Scalar wallDistanceRough() const - { return ParentType::wallDistance() + additionalRoughnessLength_; } + { return RANSParentType::wallDistance() + additionalRoughnessLength_; } /*! * \brief Return the dimensionless wall distance \f$\mathrm{[-]}\f$ including an additional roughness length @@ -174,72 +164,18 @@ public: Scalar yPlusRough() const { return yPlusRough_; } + /*! + * \brief Return the fluid state of the control volume. + */ + const FluidState& fluidState() const + { return NavierStokesParentType::fluidState_; } + protected: + Scalar additionalRoughnessLength_; Scalar yPlusRough_; }; -/*! - * \ingroup ZeroEqModel - * \brief Volume variables for the non-isothermal single-phase 0-Eq. model. - */ -template -class ZeroEqVolumeVariablesImplementation -: virtual public ZeroEqVolumeVariablesImplementation, - virtual public RANSVolumeVariablesImplementation -{ - using ParentTypeNonIsothermal = RANSVolumeVariablesImplementation; - using ParentTypeIsothermal = ZeroEqVolumeVariablesImplementation; - using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using SubControlVolume = typename FVElementGeometry::SubControlVolume; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; - -public: - using FluidSystem = typename ParentTypeIsothermal::FluidSystem; - using FluidState = typename ParentTypeIsothermal::FluidState; - - /*! - * \brief Update all quantities for a given control volume - * - * \param elemSol A vector containing all primary variables connected to the element - * \param problem The object specifying the problem which ought to be simulated - * \param element An element which contains part of the control volume - * \param scv The sub-control volume - */ - template - void update(const ElementSolution &elemSol, - const Problem &problem, - const Element &element, - const SubControlVolume &scv) - { - ParentTypeNonIsothermal::update(elemSol, problem, element, scv); - updateRANSProperties(elemSol, problem, element, scv); - } - - /*! - * \brief Update all turbulent quantities for a given control volume - * - * Wall and roughness related quantities are stored. Eddy viscosity is set. - * - * \param elemSol A vector containing all primary variables connected to the element - * \param problem The object specifying the problem which ought to be simulated - * \param element An element which contains part of the control volume - * \param scv The sub-control volume - */ - template - void updateRANSProperties(const ElementSolution &elemSol, - const Problem &problem, - const Element &element, - const SubControlVolume& scv) - { - ParentTypeIsothermal::updateRANSProperties(elemSol, problem, element, scv); - ParentTypeNonIsothermal::calculateEddyThermalConductivity(); - } -}; -} +} // end namespace Dumux -#endif +#endif // DUMUX_ZEROEQ_VOLUME_VARIABLES_HH diff --git a/dumux/freeflow/ransnc/model.hh b/dumux/freeflow/ransnc/model.hh index e07821d7ca..0da3400607 100644 --- a/dumux/freeflow/ransnc/model.hh +++ b/dumux/freeflow/ransnc/model.hh @@ -53,13 +53,7 @@ #define DUMUX_RANS_NC_MODEL_HH #include - -#include -#include #include -#include -#include -#include #include "indices.hh" #include "volumevariables.hh" @@ -67,19 +61,6 @@ namespace Dumux { -/*! - * \ingroup RANSModel - * \brief Traits for the RANS multi-component model - */ -template -struct RANSNCModelTraits : NavierStokesNCModelTraits -{ -private: - using ParentType = NavierStokesNCModelTraits; -public: - using Indices = RANSNCIndices; -}; - /////////////////////////////////////////////////////////////////////////// // properties for the single-phase, multi-component RANS model /////////////////////////////////////////////////////////////////////////// @@ -90,16 +71,28 @@ namespace Properties { ////////////////////////////////////////////////////////////////// //! The type tags for the single-phase, multi-component isothermal RANS model -NEW_TYPE_TAG(RANSNC, INHERITS_FROM(RANS, NavierStokesNC)); -NEW_TYPE_TAG(ZeroEqNC, INHERITS_FROM(ZeroEq, RANSNC)); +NEW_TYPE_TAG(RANSNC, INHERITS_FROM(NavierStokesNC)); +NEW_TYPE_TAG(ZeroEqNC, INHERITS_FROM(RANSNC)); /////////////////////////////////////////////////////////////////////////// // default property values /////////////////////////////////////////////////////////////////////////// -//! The volume variables -SET_TYPE_PROP(RANSNC, VolumeVariables, RANSNCVolumeVariables); -SET_TYPE_PROP(ZeroEqNC, SinglePhaseVolumeVariables, ZeroEqVolumeVariables); +//! Set the volume variables property +SET_PROP(ZeroEqNC, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + using Traits = NavierStokesVolumeVariablesTraits; + using NSVolVars = NavierStokesNCVolumeVariables; + using RANSVolVars = ZeroEqVolumeVariables; +public: + using type = RANSNCVolumeVariables; +}; //! The specific vtk output fields SET_PROP(ZeroEqNC, VtkOutputFields) @@ -118,26 +111,23 @@ public: ////////////////////////////////////////////////////////////////////////// //! The type tags for the single-phase, multi-component non-isothermal RANS models -NEW_TYPE_TAG(RANSNCNI, INHERITS_FROM(RANSNI, NavierStokesNC)); -NEW_TYPE_TAG(ZeroEqNCNI, INHERITS_FROM(ZeroEqNI, RANSNCNI)); - -//! The volume variables -SET_TYPE_PROP(RANSNCNI, VolumeVariables, RANSNCVolumeVariables); -SET_TYPE_PROP(ZeroEqNCNI, SinglePhaseVolumeVariables, ZeroEqVolumeVariables); +NEW_TYPE_TAG(RANSNCNI, INHERITS_FROM(NavierStokesNCNI)); +NEW_TYPE_TAG(ZeroEqNCNI, INHERITS_FROM(RANSNCNI)); -//! The model traits of the non-isothermal model -SET_PROP(RANSNCNI, ModelTraits) +//! Set the volume variables property +SET_PROP(ZeroEqNCNI, VolumeVariables) { private: - using GridView = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::GridView; - static constexpr int dim = GridView::dimension; - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - static constexpr int numComponents = FluidSystem::numComponents; - static constexpr int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); - static constexpr int replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx); - using IsothermalModelTraits = NavierStokesNCModelTraits; + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + using Traits = NavierStokesVolumeVariablesTraits; + using NSVolVars = NavierStokesNCVolumeVariables; + using RANSVolVars = ZeroEqVolumeVariables; public: - using type = NavierStokesNIModelTraits; + using type = RANSNCVolumeVariables; }; //! The specific vtk output fields diff --git a/dumux/freeflow/ransnc/volumevariables.hh b/dumux/freeflow/ransnc/volumevariables.hh index cae342af6d..f6d7987927 100644 --- a/dumux/freeflow/ransnc/volumevariables.hh +++ b/dumux/freeflow/ransnc/volumevariables.hh @@ -25,37 +25,21 @@ #ifndef DUMUX_RANS_NC_VOLUMEVARIABLES_HH #define DUMUX_RANS_NC_VOLUMEVARIABLES_HH -#include - -#include -#include - namespace Dumux { /*! * \ingroup RANSNCModel * \brief Volume variables for the single-phase, multi-component Reynolds-averaged Navier-Stokes model. */ -template -class RANSNCVolumeVariables - : virtual public GET_PROP_TYPE(TypeTag, SinglePhaseVolumeVariables), - virtual public NavierStokesNCVolumeVariables +template +class RANSNCVolumeVariables : public RANSVolVars { - using ParentTypeSinglePhase = typename GET_PROP_TYPE(TypeTag, SinglePhaseVolumeVariables); - using ParentTypeCompositional = NavierStokesNCVolumeVariables; - using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using SubControlVolume = typename FVElementGeometry::SubControlVolume; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; + using ParentType = RANSVolVars; + using Scalar = typename Traits::PrimaryVariables::value_type; - static constexpr auto phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); + static constexpr int fluidSystemPhaseIdx = Traits::ModelTraits::Indices::fluidSystemPhaseIdx; public: - using FluidSystem = typename ParentTypeCompositional::FluidSystem; - using FluidState = typename ParentTypeCompositional::FluidState; /*! * \brief Update all quantities for a given control volume @@ -66,27 +50,27 @@ public: * \param element An element which contains part of the control volume * \param scv The sub-control volume */ - template + template void update(const ElementSolution &elemSol, const Problem &problem, const Element &element, const SubControlVolume& scv) { - ParentTypeCompositional::update(elemSol, problem, element, scv); - ParentTypeSinglePhase::updateRANSProperties(elemSol, problem, element, scv); - calculateEddyDiffusivity(); + ParentType::update(elemSol, problem, element, scv); + calculateEddyDiffusivity(problem); } /*! * \brief Calculates the eddy diffusivity \f$\mathrm{[m^2/s]}\f$ based * on the kinematic eddy viscosity and the turbulent schmidt number */ - void calculateEddyDiffusivity() + template + void calculateEddyDiffusivity(const Problem& problem) { static const auto turbulentSchmidtNumber - = getParamFromGroup(GET_PROP_VALUE(TypeTag, ModelParameterGroup), + = getParamFromGroup(problem.paramGroup(), "RANS.TurbulentSchmidtNumber", 1.0); - eddyDiffusivity_ = ParentTypeSinglePhase::kinematicEddyViscosity() + eddyDiffusivity_ = ParentType::kinematicEddyViscosity() / turbulentSchmidtNumber; } @@ -104,13 +88,13 @@ public: * \param compIIdx the index of the component which diffusive * \param compJIdx the index of the component with respect to which compIIdx diffuses */ - Scalar effectiveDiffusivity(int compIIdx, int compJIdx = phaseIdx) const + Scalar effectiveDiffusivity(int compIIdx, int compJIdx = fluidSystemPhaseIdx) const { - return ParentTypeCompositional::diffusionCoefficient(compIIdx, compJIdx) + return ParentType::diffusionCoefficient(compIIdx, fluidSystemPhaseIdx) + eddyDiffusivity(); } -protected: +private: Scalar eddyDiffusivity_; }; diff --git a/dumux/freeflow/volumevariables.hh b/dumux/freeflow/volumevariables.hh index 7b944f7440..fbde620483 100644 --- a/dumux/freeflow/volumevariables.hh +++ b/dumux/freeflow/volumevariables.hh @@ -144,7 +144,7 @@ class FreeFlowVolumeVariablesImplementation { using ParentType = FreeFlowVolumeVariablesImplementation; using Scalar = typename Traits::PrimaryVariables::value_type; - static constexpr int phaseIdx = Traits::phaseIndex(); + static constexpr int fluidSystemPhaseIdx = Traits::ModelTraits::Indices::fluidSystemPhaseIdx; public: //! export the type used for the primary variables @@ -178,26 +178,26 @@ public: * \brief Returns the total internal energy of a phase in the * sub-control volume. * - * \param phaseIdx The phase index + * \param fluidSystemPhaseIdx The phase index */ Scalar internalEnergy() const - { return asImp_().fluidState().internalEnergy(phaseIdx); } + { return asImp_().fluidState().internalEnergy(fluidSystemPhaseIdx); } /*! * \brief Returns the total enthalpy of a phase in the sub-control * volume. * - * \param phaseIdx The phase index + * \param fluidSystemPhaseIdx The phase index */ Scalar enthalpy() const - { return asImp_().fluidState().enthalpy(phaseIdx); } + { return asImp_().fluidState().enthalpy(fluidSystemPhaseIdx); } /*! * \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ * of the fluid phase in the sub-control volume. */ Scalar thermalConductivity() const - { return FluidSystem::thermalConductivity(asImp_().fluidState(), phaseIdx); } + { return FluidSystem::thermalConductivity(asImp_().fluidState(), fluidSystemPhaseIdx); } /*! * \brief Returns the effective thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ @@ -213,7 +213,7 @@ public: * in the sub-control volume. */ Scalar heatCapacity() const - { return FluidSystem::heatCapacity(asImp_().fluidState(), phaseIdx); } + { return FluidSystem::heatCapacity(asImp_().fluidState(), fluidSystemPhaseIdx); } //! The temperature is a primary variable for non-isothermal models template @@ -231,7 +231,7 @@ public: static Scalar enthalpy(const FluidState& fluidState, const ParameterCache& paramCache) { - return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); + return FluidSystem::enthalpy(fluidState, paramCache, fluidSystemPhaseIdx); } protected: -- GitLab