Commit 985e5cf2 authored by Timo Koch's avatar Timo Koch
Browse files

Merge branch 'feature/improve-freeflow-inheritance' into 'master'

Revise FreeFlow VolVars

See merge request !915
parents 01564121 dfa302b1
......@@ -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
......
......@@ -74,7 +74,6 @@ class MaxwellStefansLawImplementation<TypeTag, DiscretizationMethod::staggered >
pressureIdx = Indices::pressureIdx,
conti0EqIdx = Indices::conti0EqIdx,
replaceCompEqIdx = Indices::replaceCompEqIdx,
phaseIdx = Indices::phaseIdx
};
public:
......
......@@ -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
......
......@@ -100,6 +100,27 @@ struct NavierStokesModelTraits
using Indices = NavierStokesIndices<dim()>;
};
/*!
* \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<class PV,
class FSY,
class FST,
class MT>
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<TypeTag>);
//! The volume variables
SET_TYPE_PROP(NavierStokes, VolumeVariables, NavierStokesVolumeVariables<TypeTag>);
//! 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<PV, FSY, FST, MT>;
public:
using type = NavierStokesVolumeVariables<Traits>;
};
//! The flux variables
SET_TYPE_PROP(NavierStokes, FluxVariables, NavierStokesFluxVariables<TypeTag>);
......
......@@ -25,40 +25,30 @@
#ifndef DUMUX_NAVIERSTOKES_VOLUME_VARIABLES_HH
#define DUMUX_NAVIERSTOKES_VOLUME_VARIABLES_HH
#include <dumux/common/properties.hh>
#include <dumux/material/fluidstates/immiscible.hh>
#include <dumux/freeflow/volumevariables.hh>
namespace Dumux {
// forward declaration
template <class TypeTag, bool enableEnergyBalance>
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 <class TypeTag>
using NavierStokesVolumeVariables = NavierStokesVolumeVariablesImplementation<TypeTag, GET_PROP_TYPE(TypeTag, ModelTraits)::enableEnergyBalance()>;
/*!
* \ingroup NavierStokesModel
* \brief Volume variables for the isothermal single-phase Navier-Stokes model.
*/
template <class TypeTag>
class NavierStokesVolumeVariablesImplementation<TypeTag, false>
template <class Traits>
class NavierStokesVolumeVariables : public FreeFlowVolumeVariables< Traits, NavierStokesVolumeVariables<Traits> >
{
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<Traits>;
using ParentType = FreeFlowVolumeVariables<Traits, ThisType>;
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<class ElementSolution, class Problem, class Element, class SubControlVolume>
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<class ElementSolution, class SubControlVolume>
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<class ElementSolution, class Problem, class Element, class SubControlVolume>
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<class ParameterCache>
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 TypeTag>
class NavierStokesVolumeVariablesImplementation<TypeTag, true>
: virtual public NavierStokesVolumeVariablesImplementation<TypeTag, false>
{
using ParentType = NavierStokesVolumeVariablesImplementation<TypeTag, false>;
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<class ElementSolution, class Problem, class Element, class SubControlVolume>
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<class ElementSolution, class Problem, class Element, class SubControlVolume>
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<class ElementSolution, class Problem, class Element, class SubControlVolume>
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<class FluidState, class ParameterCache>
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
......@@ -33,12 +33,15 @@ namespace Dumux {
* \brief The common indices for the isothermal multi-component Navier-Stokes model.
*/
template <int dimension, int numEquations,
int thePhaseIdx, int theReplaceCompEqIdx>
int phaseIdx, int theReplaceCompEqIdx>
struct NavierStokesNCIndices : public NavierStokesIndices<dimension>
{
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;
......
......@@ -74,7 +74,7 @@ namespace Dumux {
* \ingroup NavierStokesModel
* \brief Traits for the Navier-Stokes multi-component model
*/
template<int dimension, int nComp, int phaseIdx, int replaceCompEqIdx>
template<int dimension, int nComp, int phaseIdx, int replaceCompEqIdx, bool useM>
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<dim, numComponents, phaseIdx, replaceCompEqIdx>;
using type = NavierStokesNCModelTraits<dim, numComponents, phaseIdx, replaceCompEqIdx, useMoles>;
};
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); //<! Set the ReplaceCompEqIdx to 0 by default
SET_BOOL_PROP(NavierStokesNC, EnableInertiaTerms, true); //!< Consider inertia terms by default
SET_BOOL_PROP(NavierStokesNC, NormalizePressure, true); //!< Normalize the pressure term in the momentum balance by default
//! The local residual
SET_TYPE_PROP(NavierStokesNC, LocalResidual, NavierStokesNCResidual<TypeTag>);
//! The volume variables
SET_TYPE_PROP(NavierStokesNC, VolumeVariables, NavierStokesNCVolumeVariables<TypeTag>);
//! 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<PV, FSY, FST, MT>;
public:
using type = NavierStokesNCVolumeVariables<Traits>;
};
//! The flux variables
SET_TYPE_PROP(NavierStokesNC, FluxVariables, NavierStokesNCFluxVariables<TypeTag>);
//! The flux variables cache class, by default the one for free flow
SET_TYPE_PROP(NavierStokesNC, FluxVariablesCache, FreeFlowFluxVariablesCache<TypeTag>);
//! 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<dim, numComponents, phaseIdx, replaceCompEqIdx>;
static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
using IsothermalModelTraits = NavierStokesNCModelTraits<dim, numComponents, phaseIdx, replaceCompEqIdx, useMoles>;
public:
using type = NavierStokesNIModelTraits<IsothermalModelTraits>;
};
......
......@@ -26,10 +26,8 @@
#define DUMUX_NAVIER_STOKES_NC_VOLUMEVARIABLES_HH
#include <dune/common/exceptions.hh>
#include <dumux/common/properties.hh>
#include <dumux/freeflow/navierstokes/volumevariables.hh>
#include <dumux/material/fluidstates/immiscible.hh>
#include <dumux/freeflow/volumevariables.hh>
namespace Dumux {
......@@ -37,31 +35,25 @@ namespace Dumux {
* \ingroup NavierStokesNCModel
* \brief Volume variables for the single-phase, multi-component Navier-Stokes model.
*/
template <class TypeTag>
class NavierStokesNCVolumeVariables : virtual public NavierStokesVolumeVariables<TypeTag>
template <class Traits>
class NavierStokesNCVolumeVariables : public FreeFlowVolumeVariables< Traits, NavierStokesNCVolumeVariables<Traits> >
{
using ParentType = NavierStokesVolumeVariables<TypeTag>;
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<Traits>;
using ParentType = FreeFlowVolumeVariables<Traits, ThisType>;
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;