From 812027d4982024cbe143c6cc1a257e7dc1f1ea84 Mon Sep 17 00:00:00 2001
From: Timo Koch <timo.koch@iws.uni-stuttgart.de>
Date: Tue, 3 Apr 2018 19:18:25 +0200
Subject: [PATCH] [disc][cc] Free grid/element volvars from TypeTag

---
 dumux/discretization/box/elementsolution.hh   |  4 +-
 .../cellcentered/elementsolution.hh           | 45 +++++------
 .../cellcentered/gridvolumevariables.hh       | 67 ++++++++--------
 .../mpfa/elementvolumevariables.hh            | 80 +++++++++----------
 .../cellcentered/mpfa/gridvolumevariables.hh  | 64 +++++++++++++++
 .../cellcentered/mpfa/properties.hh           | 33 ++++----
 .../tpfa/elementvolumevariables.hh            | 79 ++++++++----------
 .../cellcentered/tpfa/gridvolumevariables.hh  | 64 +++++++++++++++
 .../cellcentered/tpfa/properties.hh           | 31 ++++---
 dumux/discretization/evalgradients.hh         | 16 ++--
 dumux/discretization/evalsolution.hh          | 50 +++++-------
 .../porousmediumflow/1pnc/volumevariables.hh  | 25 +-----
 .../2p/incompressiblelocalresidual.hh         |  6 +-
 .../porousmediumflow/2pnc/volumevariables.hh  |  6 +-
 dumux/porousmediumflow/volumevariables.hh     |  3 +-
 15 files changed, 334 insertions(+), 239 deletions(-)
 create mode 100644 dumux/discretization/cellcentered/mpfa/gridvolumevariables.hh
 create mode 100644 dumux/discretization/cellcentered/tpfa/gridvolumevariables.hh

diff --git a/dumux/discretization/box/elementsolution.hh b/dumux/discretization/box/elementsolution.hh
index dbd82c316f..e3bb73557f 100644
--- a/dumux/discretization/box/elementsolution.hh
+++ b/dumux/discretization/box/elementsolution.hh
@@ -124,8 +124,8 @@ auto elementSolution(const Element& element, const SolutionVector& sol, const FV
 template<class Element, class ElementVolumeVariables, class FVElementGeometry>
 auto elementSolution(const Element& element, const ElementVolumeVariables& elemVolVars, const FVElementGeometry& gg)
 -> std::enable_if_t<FVElementGeometry::FVGridGeometry::discMethod == DiscretizationMethod::box,
-                    BoxElementSolution<typename FVElementGeometry::FVGridGeometry,
-                                       typename ElementVolumeVariables::SolutionVector>>
+                    BoxElementSolution<FVElementGeometry,
+                                       typename ElementVolumeVariables::VolumeVariables::PrimaryVariables>>
 {
     return BoxElementSolution<typename FVElementGeometry::FVGridGeometry,
                               typename ElementVolumeVariables::SolutionVector>(element, elemVolVars, gg);
diff --git a/dumux/discretization/cellcentered/elementsolution.hh b/dumux/discretization/cellcentered/elementsolution.hh
index d629536271..e69991f8d3 100644
--- a/dumux/discretization/cellcentered/elementsolution.hh
+++ b/dumux/discretization/cellcentered/elementsolution.hh
@@ -35,37 +35,33 @@ namespace Dumux {
  * \ingroup CCDiscretization
  * \brief The element solution vector
  */
-template<class FVGridGeometry, class SolutionVector>
+template<class FVElementGeometry, class PV>
 class CCElementSolution
 {
+    using FVGridGeometry = typename FVElementGeometry::FVGridGeometry;
     using GridView = typename FVGridGeometry::GridView;
     using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename FVGridGeometry::LocalView;
 
 public:
-    using PrimaryVariables = std::decay_t<decltype(std::declval<SolutionVector>()[0])>;
+    //! export the primary variables type
+    using PrimaryVariables = PV;
 
     //! default constructor
     CCElementSolution() = default;
 
-    //! Constructor with element and solution
+    //! Constructor with element, solution vector and grid geometry
+    template<class SolutionVector>
     CCElementSolution(const Element& element, const SolutionVector& sol,
                       const FVGridGeometry& fvGridGeometry)
     : CCElementSolution(sol[fvGridGeometry.elementMapper().index(element)])
     {}
 
-    //! Constructor with element and solution and element geometry
-    CCElementSolution(const Element& element, const SolutionVector& sol,
-                      const FVElementGeometry& fvGeometry)
-    : CCElementSolution(sol[fvGeometry.fvGridGeometry().elementMapper().index(element)])
-    {}
-
-    //! Constructor with element and elemVolVars and fvGeometry
+    //! Constructor with element, element volume variables and fv element geometry
     template<class ElementVolumeVariables>
     CCElementSolution(const Element& element, const ElementVolumeVariables& elemVolVars,
                       const FVElementGeometry& fvGeometry)
     {
-        for(const auto& scv : scvs(fvGeometry))
+        for (const auto& scv : scvs(fvGeometry))
             priVars_ = elemVolVars[scv].priVars();
     }
 
@@ -78,6 +74,7 @@ public:
     : priVars_(priVars) {}
 
     //! extract the element solution from the solution vector using a mapper
+    template<class SolutionVector>
     void update(const Element& element, const SolutionVector& sol,
                 const FVGridGeometry& fvGridGeometry)
     {
@@ -112,9 +109,12 @@ template<class Element, class SolutionVector, class FVGridGeometry>
 auto elementSolution(const Element& element, const SolutionVector& sol, const FVGridGeometry& gg)
 -> std::enable_if_t<FVGridGeometry::discMethod == DiscretizationMethod::cctpfa ||
                     FVGridGeometry::discMethod == DiscretizationMethod::ccmpfa,
-                    CCElementSolution<FVGridGeometry, SolutionVector>>
+                    CCElementSolution<typename FVGridGeometry::LocalView,
+                                      std::decay_t<decltype(std::declval<SolutionVector>()[0])>>
+                    >
 {
-    return CCElementSolution<FVGridGeometry, SolutionVector>(element, sol, gg);
+    using PrimaryVariables = std::decay_t<decltype(std::declval<SolutionVector>()[0])>;
+    return CCElementSolution<typename FVGridGeometry::LocalView, PrimaryVariables>(element, sol, gg);
 }
 
 /*!
@@ -125,11 +125,10 @@ template<class Element, class ElementVolumeVariables, class FVElementGeometry>
 auto elementSolution(const Element& element, const ElementVolumeVariables& elemVolVars, const FVElementGeometry& gg)
 -> std::enable_if_t<FVElementGeometry::FVGridGeometry::discMethod == DiscretizationMethod::cctpfa ||
                     FVElementGeometry::FVGridGeometry::discMethod == DiscretizationMethod::ccmpfa,
-                    CCElementSolution<typename FVElementGeometry::FVGridGeometry,
-                                       typename ElementVolumeVariables::SolutionVector>>
+                    CCElementSolution<FVElementGeometry, typename ElementVolumeVariables::VolumeVariables::PrimaryVariables>>
 {
-    return CCElementSolution<typename FVElementGeometry::FVGridGeometry,
-                             typename ElementVolumeVariables::SolutionVector>(element, elemVolVars, gg);
+    using PrimaryVariables = typename ElementVolumeVariables::VolumeVariables::PrimaryVariables;
+    return CCElementSolution<FVElementGeometry, PrimaryVariables>(element, elemVolVars, gg);
 }
 
 /*!
@@ -137,13 +136,13 @@ auto elementSolution(const Element& element, const ElementVolumeVariables& elemV
  * \brief  Make an element solution for cell-centered schemes
  * \note This is e.g. used to contruct an element solution at Dirichlet boundaries
  */
-template<class SolutionVector, class FVGridGeometry, class PrimaryVariables>
+template<class FVElementGeometry, class PrimaryVariables>
 auto elementSolution(PrimaryVariables&& priVars)
--> std::enable_if_t<FVGridGeometry::discMethod == DiscretizationMethod::cctpfa ||
-                    FVGridGeometry::discMethod == DiscretizationMethod::ccmpfa,
-                    CCElementSolution<FVGridGeometry, SolutionVector>>
+-> std::enable_if_t<FVElementGeometry::FVGridGeometry::discMethod == DiscretizationMethod::cctpfa ||
+                    FVElementGeometry::FVGridGeometry::discMethod == DiscretizationMethod::ccmpfa,
+                    CCElementSolution<FVElementGeometry, PrimaryVariables>>
 {
-    return CCElementSolution<FVGridGeometry, SolutionVector>(std::move(priVars));
+    return CCElementSolution<FVElementGeometry, PrimaryVariables>(std::move(priVars));
 }
 
 } // end namespace Dumux
diff --git a/dumux/discretization/cellcentered/gridvolumevariables.hh b/dumux/discretization/cellcentered/gridvolumevariables.hh
index d71e6b89eb..be85257c75 100644
--- a/dumux/discretization/cellcentered/gridvolumevariables.hh
+++ b/dumux/discretization/cellcentered/gridvolumevariables.hh
@@ -24,7 +24,7 @@
 #ifndef DUMUX_DISCRETIZATION_CC_GRID_VOLUMEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_CC_GRID_VOLUMEVARIABLES_HH
 
-#include <dumux/common/properties.hh>
+#include <type_traits>
 
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
@@ -36,38 +36,32 @@ namespace Dumux {
  * \ingroup CCDiscretization
  * \brief Base class for the grid volume variables
  * \note This class has a cached version and a non-cached version
- * \tparam TypeTag the TypeTag
- * \tparam enableGridVolVarsCache if the cache is enabled
+ * \tparam Traits the traits class injecting the problem, volVar and elemVolVars type
+ * \tparam cachingEnabled if the cache is enabled
  */
-template<class TypeTag, bool enableGridVolVarsCache>
-class CCGridVolumeVariables
-{};
+template<class Traits, bool cachingEnabled = false>
+class CCGridVolumeVariables {};
 
 //! specialization in case of storing the volume variables
-template<class TypeTag>
-class CCGridVolumeVariables<TypeTag, /*enableGridVolVarsCache*/true>
+template<class Traits>
+class CCGridVolumeVariables<Traits, /*cachingEnabled*/true>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolume = typename FVElementGeometry::SubControlVolume;
-    using IndexType = typename GridView::IndexSet::IndexType;
-
-    static const int dim = GridView::dimension;
-    using Element = typename GridView::template Codim<0>::Entity;
+    using ThisType = CCGridVolumeVariables<Traits, true>;
+    using Problem = typename Traits::Problem;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    //! export the volume variables type
+    using VolumeVariables = typename Traits::VolumeVariables;
 
     //! make it possible to query if caching is enabled
     static constexpr bool cachingEnabled = true;
 
+    //! export the type of the local view
+    using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
+
     CCGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
 
+    template<class FVGridGeometry, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol)
     {
         const auto numScv = fvGridGeometry.numScv();
@@ -98,7 +92,7 @@ public:
                 {
                     const auto insideScvIdx = scvf.insideScvIdx();
                     const auto& insideScv = fvGeometry.scv(insideScvIdx);
-                    const auto dirichletPriVars = elementSolution<SolutionVector, FVGridGeometry>(problem().dirichlet(element, scvf));
+                    const auto dirichletPriVars = elementSolution<typename FVGridGeometry::LocalView>(problem().dirichlet(element, scvf));
 
                     volumeVariables_[scvf.outsideScvIdx()].update(dirichletPriVars,
                                                                   problem(),
@@ -109,24 +103,26 @@ public:
         }
     }
 
-    const VolumeVariables& volVars(const IndexType scvIdx) const
+    const VolumeVariables& volVars(const std::size_t scvIdx) const
     { return volumeVariables_[scvIdx]; }
 
-    VolumeVariables& volVars(const IndexType scvIdx)
+    VolumeVariables& volVars(const std::size_t scvIdx)
     { return volumeVariables_[scvIdx]; }
 
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     const VolumeVariables& volVars(const SubControlVolume scv) const
     { return volumeVariables_[scv.dofIndex()]; }
 
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     VolumeVariables& volVars(const SubControlVolume scv)
     { return volumeVariables_[scv.dofIndex()]; }
 
     // required for compatibility with the box method
-    const VolumeVariables& volVars(const IndexType scvIdx, const IndexType localIdx) const
+    const VolumeVariables& volVars(const std::size_t scvIdx, const std::size_t localIdx) const
     { return volumeVariables_[scvIdx]; }
 
     // required for compatibility with the box method
-    VolumeVariables& volVars(const IndexType scvIdx, const IndexType localIdx)
+    VolumeVariables& volVars(const std::size_t scvIdx, const std::size_t localIdx)
     { return volumeVariables_[scvIdx]; }
 
     //! The problem we are solving
@@ -140,22 +136,25 @@ private:
 
 
 //! Specialization when the current volume variables are not stored globally
-template<class TypeTag>
-class CCGridVolumeVariables<TypeTag, /*enableGridVolVarsCache*/false>
+template<class Traits>
+class CCGridVolumeVariables<Traits, /*cachingEnabled*/false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using ThisType = CCGridVolumeVariables<Traits, false>;
+    using Problem = typename Traits::Problem;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    //! export the volume variables type
+    using VolumeVariables = typename Traits::VolumeVariables;
 
     //! make it possible to query if caching is enabled
     static constexpr bool cachingEnabled = false;
 
+    //! export the type of the local view
+    using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
+
     CCGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
 
+    template<class FVGridGeometry, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol) {}
 
     //! The problem we are solving
@@ -166,6 +165,6 @@ private:
     const Problem* problemPtr_;
 };
 
-} // end namespace
+} // end namespace Dumux
 
 #endif
diff --git a/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh b/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh
index 2bf3471453..4e8a7e37c0 100644
--- a/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh
+++ b/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh
@@ -25,7 +25,8 @@
 #define DUMUX_DISCRETIZATION_CCMPFA_ELEMENT_VOLUMEVARIABLES_HH
 
 #include <utility>
-#include <dumux/common/properties.hh>
+#include <type_traits>
+
 #include <dumux/discretization/cellcentered/elementsolution.hh>
 
 namespace Dumux {
@@ -34,8 +35,10 @@ namespace Dumux {
  * \ingroup CCMpfaDiscretization
  * \brief The local (stencil) volume variables class for cell centered mpfa models
  * \note The class is specilized for versions with and without caching
+ * \tparam GVV the grid volume variables type
+ * \tparam cachingEnabled if the cache is enabled
  */
-template<class TypeTag, bool enableGridVolVarsCache>
+template<class GVV, bool cachingEnabled>
 class CCMpfaElementVolumeVariables;
 
 /*!
@@ -43,42 +46,39 @@ class CCMpfaElementVolumeVariables;
  * \brief The local (stencil) volume variables class for cell centered mpfa models with caching
  * \note the volume variables are stored for the whole grid view in the corresponding GridVolumeVariables class
  */
-template<class TypeTag>
-class CCMpfaElementVolumeVariables<TypeTag, /*enableGridVolVarsCache*/true>
+template<class GVV>
+class CCMpfaElementVolumeVariables<GVV, /*cachingEnabled*/true>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using SubControlVolume = typename FVElementGeometry::SubControlVolume;
-    using GridIndexType = typename GridView::IndexSet::IndexType;
-
 public:
-    //! Export type of the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    //! export type of the grid volume variables
+    using GridVolumeVariables = GVV;
+
+    //! export type of the volume variables
+    using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
 
     //! Constructor
     CCMpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars)
     : gridVolVarsPtr_(&gridVolVars) {}
 
     //! operator for the access with an scv
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     const VolumeVariables& operator [](const SubControlVolume& scv) const
     { return gridVolVars().volVars(scv.dofIndex()); }
 
     //! operator for the access with an index
-    const VolumeVariables& operator [](const GridIndexType scvIdx) const
+    const VolumeVariables& operator [](const std::size_t scvIdx) const
     { return gridVolVars().volVars(scvIdx); }
 
     //! precompute all volume variables in a stencil of an element - do nothing volVars: are cached
-    void bind(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const SolutionVector& sol)
     {}
 
     //! precompute the volume variables of an element - do nothing: volVars are cached
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const SolutionVector& sol)
     {}
@@ -96,29 +96,23 @@ private:
  * \ingroup CCMpfaDiscretization
  * \brief The local (stencil) volume variables class for cell centered tpfa models with caching
  */
-template<class TypeTag>
-class CCMpfaElementVolumeVariables<TypeTag, /*enableGridVolVarsCache*/false>
+template<class GVV>
+class CCMpfaElementVolumeVariables<GVV, /*cachingEnabled*/false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename FVGridGeometry::LocalView;
-    using SubControlVolume = typename FVElementGeometry::SubControlVolume;
-    using GridIndexType = typename GridView::IndexSet::IndexType;
-
 public:
-    //! Export type of the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    //! export type of the grid volume variables
+    using GridVolumeVariables = GVV;
+
+    //! export type of the volume variables
+    using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
 
     //! Constructor
     CCMpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars)
     : gridVolVarsPtr_(&gridVolVars) {}
 
     //! Prepares the volume variables within the element stencil
-    void bind(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const SolutionVector& sol)
     {
@@ -182,8 +176,7 @@ public:
                 {
                     // boundary volume variables
                     VolumeVariables dirichletVolVars;
-                    dirichletVolVars.update(elementSolution<SolutionVector, FVGridGeometry>
-                                                (problem.dirichlet(element, scvf)),
+                    dirichletVolVars.update(elementSolution<FVElementGeometry>(problem.dirichlet(element, scvf)),
                                             problem,
                                             element,
                                             scvI);
@@ -238,7 +231,8 @@ public:
     }
 
     //! Prepares the volume variables of an element
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const SolutionVector& sol)
     {
@@ -259,19 +253,21 @@ public:
     }
 
     //! access operator with scv
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     const VolumeVariables& operator [](const SubControlVolume& scv) const
     { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
 
     //! access operator with scv
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     VolumeVariables& operator [](const SubControlVolume& scv)
     { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
 
     //! access operator with scv index
-    const VolumeVariables& operator [](GridIndexType scvIdx) const
+    const VolumeVariables& operator [](std::size_t scvIdx) const
     { return volumeVariables_[getLocalIdx_(scvIdx)]; }
 
     //! access operator with scv index
-    VolumeVariables& operator [](GridIndexType scvIdx)
+    VolumeVariables& operator [](std::size_t scvIdx)
     { return volumeVariables_[getLocalIdx_(scvIdx)]; }
 
     //! The global volume variables object we are a restriction of
@@ -293,6 +289,7 @@ private:
     // needed number of volume variables. However, memory is not an issue for the global
     // caching being deactivated and we want to make sure we reserve enough memory here.
     // TODO: What about non-symmetric schemes? Is there a better way for estimating this?
+    template<class FVElementGeometry>
     std::size_t maxNumBoundaryVolVars_(const FVElementGeometry& fvGeometry)
     {
         const auto& fvGridGeometry = fvGeometry.fvGridGeometry();
@@ -311,7 +308,7 @@ private:
     }
 
     //! adds the volume variables from a given nodal index set to the local containers
-    template<class NodalIndexSet>
+    template<class Problem, class FVElementGeometry, class NodalIndexSet>
     void addBoundaryVolVars_(const Problem& problem, const FVElementGeometry& fvGeometry, const NodalIndexSet& nodalIndexSet)
     {
         // check each scvf in the index set for boundary presence
@@ -333,8 +330,7 @@ private:
             {
                 VolumeVariables dirichletVolVars;
                 const auto& ivScv = fvGeometry.scv(insideScvIdx);
-                dirichletVolVars.update(elementSolution<SolutionVector, FVGridGeometry>
-                                            (problem.dirichlet(insideElement, ivScvf)),
+                dirichletVolVars.update(elementSolution<FVElementGeometry>(problem.dirichlet(insideElement, ivScvf)),
                                         problem,
                                         insideElement,
                                         ivScv);
@@ -353,7 +349,7 @@ private:
         return std::distance(volVarIndices_.begin(), it);
     }
 
-    std::vector<GridIndexType> volVarIndices_;
+    std::vector<std::size_t> volVarIndices_;
     std::vector<VolumeVariables> volumeVariables_;
 };
 
diff --git a/dumux/discretization/cellcentered/mpfa/gridvolumevariables.hh b/dumux/discretization/cellcentered/mpfa/gridvolumevariables.hh
new file mode 100644
index 0000000000..cff206c0ba
--- /dev/null
+++ b/dumux/discretization/cellcentered/mpfa/gridvolumevariables.hh
@@ -0,0 +1,64 @@
+// -*- 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 <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup CCMpfaDiscretization
+ * \brief The grid volume variables class for cell centered mpfa models
+ */
+#ifndef DUMUX_DISCRETIZATION_CC_MPFA_GRID_VOLUMEVARIABLES_HH
+#define DUMUX_DISCRETIZATION_CC_MPFA_GRID_VOLUMEVARIABLES_HH
+
+#include <dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh>
+#include <dumux/discretization/cellcentered/gridvolumevariables.hh>
+
+namespace Dumux {
+
+template<class P, class VV>
+struct CCMpfaDefaultGridVolumeVariablesTraits
+{
+    using Problem = P;
+    using VolumeVariables = VV;
+
+    template<class GridVolumeVariables, bool cachingEnabled>
+    using LocalView = CCMpfaElementVolumeVariables<GridVolumeVariables, cachingEnabled>;
+};
+
+/*!
+ * \ingroup CCMpfaDiscretization
+ * \brief Base class for the grid volume variables
+ * \note This class has a cached version and a non-cached version
+ * \tparam Problem the type of problem we are solving
+ * \tparam VolumeVariables the type of volume variables we are using for the model
+ * \tparam Traits the traits class injecting the problem, volVar and elemVolVars type
+ * \tparam cachingEnabled if the cache is enabled
+ */
+template<class Problem,
+         class VolumeVariables,
+         bool cachingEnabled = false,
+         class Traits = CCMpfaDefaultGridVolumeVariablesTraits<Problem, VolumeVariables> >
+class CCMpfaGridVolumeVariables : public CCGridVolumeVariables<Traits, cachingEnabled>
+{
+public:
+    using ParentType = CCGridVolumeVariables<Traits, cachingEnabled>;
+    using ParentType::ParentType;
+};
+
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/discretization/cellcentered/mpfa/properties.hh b/dumux/discretization/cellcentered/mpfa/properties.hh
index 44e093eea6..b2ea8f4290 100644
--- a/dumux/discretization/cellcentered/mpfa/properties.hh
+++ b/dumux/discretization/cellcentered/mpfa/properties.hh
@@ -34,24 +34,22 @@
 
 #include <dumux/discretization/fvproperties.hh>
 
-#include <dumux/discretization/cellcentered/gridvolumevariables.hh>
 #include <dumux/discretization/cellcentered/elementsolution.hh>
 #include <dumux/discretization/cellcentered/elementboundarytypes.hh>
 
 #include <dumux/discretization/cellcentered/mpfa/methods.hh>
 #include <dumux/discretization/cellcentered/mpfa/fvgridgeometrytraits.hh>
 #include <dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh>
+#include <dumux/discretization/cellcentered/mpfa/gridvolumevariables.hh>
 #include <dumux/discretization/cellcentered/mpfa/gridfluxvariablescache.hh>
-#include <dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh>
 #include <dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh>
 #include <dumux/discretization/cellcentered/mpfa/dualgridindexset.hh>
 
 #include <dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh>
 
-namespace Dumux
-{
-namespace Properties
-{
+namespace Dumux {
+namespace Properties {
+
 //! Type tag for the cell-centered mpfa scheme.
 NEW_TYPE_TAG(CCMpfaModel, INHERITS_FROM(FiniteVolumeModel));
 
@@ -99,6 +97,20 @@ public:
     using type = CCMpfaFVGridGeometry<GridView, Traits, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>;
 };
 
+//! The grid volume variables vector class
+SET_PROP(CCMpfaModel, GridVolumeVariables)
+{
+private:
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+public:
+    using type = CCMpfaGridVolumeVariables<Problem, VolumeVariables, enableCache>;
+};
+
+//! The element volume variables vector class
+SET_TYPE_PROP(CCMpfaModel, ElementVolumeVariables, typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView);
+
 //! The global flux variables cache vector class
 SET_TYPE_PROP(CCMpfaModel,
               GridFluxVariablesCache,
@@ -109,15 +121,6 @@ SET_TYPE_PROP(CCMpfaModel,
               ElementFluxVariablesCache,
               CCMpfaElementFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
 
-
-//! The global previous volume variables vector class
-SET_TYPE_PROP(CCMpfaModel,
-              ElementVolumeVariables,
-              CCMpfaElementVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
-
-//! The global current volume variables vector class
-SET_TYPE_PROP(CCMpfaModel, GridVolumeVariables, CCGridVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
-
 //! Set the default for the ElementBoundaryTypes
 SET_TYPE_PROP(CCMpfaModel, ElementBoundaryTypes, CCElementBoundaryTypes);
 
diff --git a/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh b/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh
index db5dd01d84..f28036fb48 100644
--- a/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh
+++ b/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh
@@ -24,7 +24,8 @@
 #ifndef DUMUX_DISCRETIZATION_CCTPFA_ELEMENT_VOLUMEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_CCTPFA_ELEMENT_VOLUMEVARIABLES_HH
 
-#include <dumux/common/properties.hh>
+#include <type_traits>
+
 #include <dumux/discretization/cellcentered/elementsolution.hh>
 
 namespace Dumux {
@@ -33,8 +34,10 @@ namespace Dumux {
  * \ingroup CCTpfaDiscretization
  * \brief The local (stencil) volume variables class for cell centered tpfa models
  * \note The class is specilized for versions with and without caching
+ * \tparam GVV the grid volume variables type
+ * \tparam cachingEnabled if the cache is enabled
  */
-template<class TypeTag, bool enableGridVolVarsCache>
+template<class GVV, bool cachingEnabled>
 class CCTpfaElementVolumeVariables
 {};
 
@@ -43,44 +46,39 @@ class CCTpfaElementVolumeVariables
  * \brief The local (stencil) volume variables class for cell centered tpfa models with caching
  * \note the volume variables are stored for the whole grid view in the corresponding GridVolumeVariables class
  */
-template<class TypeTag>
-class CCTpfaElementVolumeVariables<TypeTag, /*enableGridVolVarsCache*/true>
+template<class GVV>
+class CCTpfaElementVolumeVariables<GVV, /*cachingEnabled*/true>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using SubControlVolume = typename FVElementGeometry::SubControlVolume;
-    using IndexType = typename GridView::IndexSet::IndexType;
-
-    static const int dim = GridView::dimension;
-    using Element = typename GridView::template Codim<0>::Entity;
-
 public:
-    //! Export type of the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    //! export type of the grid volume variables
+    using GridVolumeVariables = GVV;
+
+    //! export type of the volume variables
+    using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
 
     //! Constructor
     CCTpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars)
     : gridVolVarsPtr_(&gridVolVars) {}
 
     //! operator for the access with an scv
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     const VolumeVariables& operator [](const SubControlVolume& scv) const
     { return gridVolVars().volVars(scv.dofIndex()); }
 
     //! operator for the access with an index
-    const VolumeVariables& operator [](const IndexType scvIdx) const
+    const VolumeVariables& operator [](const std::size_t scvIdx) const
     { return gridVolVars().volVars(scvIdx); }
 
     //! precompute all volume variables in a stencil of an element - do nothing volVars: are cached
-    void bind(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const SolutionVector& sol)
     {}
 
     //! precompute the volume variables of an element - do nothing: volVars are cached
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const SolutionVector& sol)
     {}
@@ -97,31 +95,23 @@ private:
  * \ingroup CCTpfaDiscretization
  * \brief The local (stencil) volume variables class for cell centered tpfa models with caching
  */
-template<class TypeTag>
-class CCTpfaElementVolumeVariables<TypeTag, /*enableGridVolVarsCache*/false>
+template<class GVV>
+class CCTpfaElementVolumeVariables<GVV, /*cachingEnabled*/false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename FVGridGeometry::LocalView;
-    using SubControlVolume = typename FVGridGeometry::SubControlVolume;
-    using IndexType = typename GridView::IndexSet::IndexType;
-
-    static const int dim = GridView::dimension;
-    using Element = typename GridView::template Codim<0>::Entity;
-
 public:
-    //! Export type of the solution vector
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    //! export type of the grid volume variables
+    using GridVolumeVariables = GVV;
+
+    //! export type of the volume variables
+    using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
 
     //! Constructor
     CCTpfaElementVolumeVariables(const GridVolumeVariables& gridVolVars)
     : gridVolVarsPtr_(&gridVolVars) {}
 
     //! Prepares the volume variables within the element stencil
-    void bind(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const SolutionVector& sol)
     {
@@ -171,8 +161,7 @@ public:
             const auto bcTypes = problem.boundaryTypes(element, scvf);
             if (bcTypes.hasOnlyDirichlet())
             {
-                const auto dirichletPriVars = elementSolution<SolutionVector, FVGridGeometry>
-                                               (problem.dirichlet(element, scvf));
+                const auto dirichletPriVars = elementSolution<FVElementGeometry>(problem.dirichlet(element, scvf));
 
                 volumeVariables_.resize(localIdx+1);
                 volVarIndices_.resize(localIdx+1);
@@ -207,8 +196,8 @@ public:
         // }
     }
 
-    //! Prepares the volume variables of an element
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class SolutionVector>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const SolutionVector& sol)
     {
@@ -228,19 +217,21 @@ public:
     }
 
     //! access operator with scv
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     const VolumeVariables& operator [](const SubControlVolume& scv) const
     { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
 
     //! access operator with scv
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     VolumeVariables& operator [](const SubControlVolume& scv)
     { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
 
     //! access operator with scv index
-    const VolumeVariables& operator [](IndexType scvIdx) const
+    const VolumeVariables& operator [](std::size_t scvIdx) const
     { return volumeVariables_[getLocalIdx_(scvIdx)]; }
 
     //! access operator with scv index
-    VolumeVariables& operator [](IndexType scvIdx)
+    VolumeVariables& operator [](std::size_t scvIdx)
     { return volumeVariables_[getLocalIdx_(scvIdx)]; }
 
     //! The global volume variables object we are a restriction of
@@ -264,7 +255,7 @@ private:
         return std::distance(volVarIndices_.begin(), it);
     }
 
-    std::vector<IndexType> volVarIndices_;
+    std::vector<std::size_t> volVarIndices_;
     std::vector<VolumeVariables> volumeVariables_;
 };
 
diff --git a/dumux/discretization/cellcentered/tpfa/gridvolumevariables.hh b/dumux/discretization/cellcentered/tpfa/gridvolumevariables.hh
new file mode 100644
index 0000000000..d85279fbf2
--- /dev/null
+++ b/dumux/discretization/cellcentered/tpfa/gridvolumevariables.hh
@@ -0,0 +1,64 @@
+// -*- 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 <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup CCTpfaDiscretization
+ * \brief The grid volume variables class for cell centered tpfa models
+ */
+#ifndef DUMUX_DISCRETIZATION_CC_TPFA_GRID_VOLUMEVARIABLES_HH
+#define DUMUX_DISCRETIZATION_CC_TPFA_GRID_VOLUMEVARIABLES_HH
+
+#include <dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh>
+#include <dumux/discretization/cellcentered/gridvolumevariables.hh>
+
+namespace Dumux {
+
+template<class P, class VV>
+struct CCTpfaDefaultGridVolumeVariablesTraits
+{
+    using Problem = P;
+    using VolumeVariables = VV;
+
+    template<class GridVolumeVariables, bool cachingEnabled>
+    using LocalView = CCTpfaElementVolumeVariables<GridVolumeVariables, cachingEnabled>;
+};
+
+/*!
+ * \ingroup CCTpfaDiscretization
+ * \brief Base class for the grid volume variables
+ * \note This class has a cached version and a non-cached version
+ * \tparam Problem the type of problem we are solving
+ * \tparam VolumeVariables the type of volume variables we are using for the model
+ * \tparam Traits the traits class injecting the problem, volVar and elemVolVars type
+ * \tparam cachingEnabled if the cache is enabled
+ */
+template<class Problem,
+         class VolumeVariables,
+         bool cachingEnabled = false,
+         class Traits = CCTpfaDefaultGridVolumeVariablesTraits<Problem, VolumeVariables> >
+class CCTpfaGridVolumeVariables : public CCGridVolumeVariables<Traits, cachingEnabled>
+{
+public:
+    using ParentType = CCGridVolumeVariables<Traits, cachingEnabled>;
+    using ParentType::ParentType;
+};
+
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/discretization/cellcentered/tpfa/properties.hh b/dumux/discretization/cellcentered/tpfa/properties.hh
index ffeced400b..2206b63d54 100644
--- a/dumux/discretization/cellcentered/tpfa/properties.hh
+++ b/dumux/discretization/cellcentered/tpfa/properties.hh
@@ -34,22 +34,19 @@
 #include <dumux/discretization/methods.hh>
 #include <dumux/discretization/fvproperties.hh>
 
-#include <dumux/discretization/cellcentered/gridvolumevariables.hh>
 #include <dumux/discretization/cellcentered/subcontrolvolume.hh>
 
 #include <dumux/discretization/cellcentered/elementboundarytypes.hh>
 #include <dumux/discretization/cellcentered/elementsolution.hh>
 #include <dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh>
+#include <dumux/discretization/cellcentered/tpfa/gridvolumevariables.hh>
 #include <dumux/discretization/cellcentered/tpfa/gridfluxvariablescache.hh>
-#include <dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh>
-#include <dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh>
 #include <dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh>
 #include <dumux/discretization/cellcentered/tpfa/subcontrolvolumeface.hh>
 
-namespace Dumux
-{
-namespace Properties
-{
+namespace Dumux {
+namespace Properties {
+
 //! Type tag for the cell-centered tpfa scheme.
 NEW_TYPE_TAG(CCTpfaModel, INHERITS_FROM(FiniteVolumeModel));
 
@@ -63,18 +60,26 @@ public:
     using type = CCTpfaFVGridGeometry<GridView, enableCache>;
 };
 
+//! The grid volume variables vector class
+SET_PROP(CCTpfaModel, GridVolumeVariables)
+{
+private:
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+public:
+    using type = CCTpfaGridVolumeVariables<Problem, VolumeVariables, enableCache>;
+};
+
+//! The element volume variables vector class
+SET_TYPE_PROP(CCTpfaModel, ElementVolumeVariables, typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView);
+
 //! The global flux variables cache vector class
 SET_TYPE_PROP(CCTpfaModel, GridFluxVariablesCache, CCTpfaGridFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
 
-//! The global previous volume variables vector class
-SET_TYPE_PROP(CCTpfaModel, ElementVolumeVariables, CCTpfaElementVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
-
 //! The local flux variables cache vector class
 SET_TYPE_PROP(CCTpfaModel, ElementFluxVariablesCache, CCTpfaElementFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
 
-//! The global current volume variables vector class
-SET_TYPE_PROP(CCTpfaModel, GridVolumeVariables, CCGridVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
-
 //! Set the default for the ElementBoundaryTypes
 SET_TYPE_PROP(CCTpfaModel, ElementBoundaryTypes, CCElementBoundaryTypes);
 
diff --git a/dumux/discretization/evalgradients.hh b/dumux/discretization/evalgradients.hh
index eb55e767e3..1c9634fa98 100644
--- a/dumux/discretization/evalgradients.hh
+++ b/dumux/discretization/evalgradients.hh
@@ -45,14 +45,13 @@ namespace Dumux {
  *         the PrimaryVariables object (i.e. numEq). Each entry is
  *         a GlobalCoordinate object holding the priVar gradient.
  */
-template<class Element, class FVGridGeometry, class Sol>
+template<class Element, class FVElementGeometry, class PrimaryVariables>
 auto evalGradients(const Element& element,
                    const typename Element::Geometry& geometry,
-                   const FVGridGeometry& fvGridGeometry,
-                   const BoxElementSolution<FVGridGeometry, Sol>& elemSol,
+                   const typename FVElementGeometry::FVGridGeometry& fvGridGeometry,
+                   const BoxElementSolution<FVElementGeometry, PrimaryVariables>& elemSol,
                    const typename Element::Geometry::GlobalCoordinate& globalPos)
 {
-    using PrimaryVariables = typename BoxElementSolution<FVGridGeometry, Sol>::PrimaryVariables;
     using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
 
     // evaluate gradients using the local finite element basis
@@ -106,13 +105,12 @@ auto evalGradients(const Element& element,
  *         the PrimaryVariables object (i.e. numEq). Each entry is
  *         a GlobalCoordinate object holding the priVar gradient.
  */
-template<class Element, class FVGridGeometry, class Sol>
-Dune::FieldVector<typename Element::Geometry::GlobalCoordinate,
-                  CCElementSolution<FVGridGeometry, Sol>::PrimaryVariables::dimension>
+template<class Element, class FVElementGeometry, class PrimaryVariables>
+Dune::FieldVector<typename Element::Geometry::GlobalCoordinate, PrimaryVariables::dimension>
 evalGradients(const Element& element,
               const typename Element::Geometry& geometry,
-              const FVGridGeometry& fvGridGeometry,
-              const CCElementSolution<FVGridGeometry, Sol>& elemSol,
+              const typename FVElementGeometry::FVGridGeometry& fvGridGeometry,
+              const CCElementSolution<FVElementGeometry, PrimaryVariables>& elemSol,
               const typename Element::Geometry::GlobalCoordinate& globalPos)
 { DUNE_THROW(Dune::NotImplemented, "General gradient evaluation for cell-centered methods"); }
 
diff --git a/dumux/discretization/evalsolution.hh b/dumux/discretization/evalsolution.hh
index 87a797f5b5..230f466f69 100644
--- a/dumux/discretization/evalsolution.hh
+++ b/dumux/discretization/evalsolution.hh
@@ -43,15 +43,13 @@ namespace Dumux {
  * \param elemSol The primary variables at the dofs of the element
  * \param globalPos The global position
  */
-template< class Element, class FVGridGeometry, class Sol>
-typename BoxElementSolution<FVGridGeometry, Sol>::PrimaryVariables
-evalSolution(const Element& element,
-             const typename Element::Geometry& geometry,
-             const FVGridGeometry& fvGridGeometry,
-             const BoxElementSolution<FVGridGeometry, Sol>& elemSol,
-             const typename Element::Geometry::GlobalCoordinate& globalPos)
+template<class Element, class FVElementGeometry, class PrimaryVariables>
+PrimaryVariables evalSolution(const Element& element,
+                              const typename Element::Geometry& geometry,
+                              const typename FVElementGeometry::FVGridGeometry& fvGridGeometry,
+                              const BoxElementSolution<FVElementGeometry, PrimaryVariables>& elemSol,
+                              const typename Element::Geometry::GlobalCoordinate& globalPos)
 {
-    using PrimaryVariables = typename BoxElementSolution<FVGridGeometry, Sol>::PrimaryVariables;
     using Scalar = typename PrimaryVariables::value_type;
 
     // interpolate the solution
@@ -85,14 +83,12 @@ evalSolution(const Element& element,
  * \param elemSol The primary variables at the dofs of the element
  * \param globalPos The global position
  */
-template< class Element, class GG, class Sol>
-typename BoxElementSolution<GG, Sol>::PrimaryVariables
-evalSolution(const Element& element,
-             const typename Element::Geometry& geometry,
-             const BoxElementSolution<GG, Sol>& elemSol,
-             const typename Element::Geometry::GlobalCoordinate& globalPos)
+template<class Element, class FVElementGeometry, class PrimaryVariables>
+PrimaryVariables evalSolution(const Element& element,
+                              const typename Element::Geometry& geometry,
+                              const BoxElementSolution<FVElementGeometry, PrimaryVariables>& elemSol,
+                              const typename Element::Geometry::GlobalCoordinate& globalPos)
 {
-    using PrimaryVariables = typename BoxElementSolution<GG, Sol>::PrimaryVariables;
     using Scalar = typename PrimaryVariables::value_type;
     using CoordScalar = typename Element::Geometry::GlobalCoordinate::value_type;
     static constexpr int dim = Element::Geometry::mydimension;
@@ -132,13 +128,12 @@ evalSolution(const Element& element,
  * \param elemSol The primary variables at the dofs of the element
  * \param globalPos The global position
  */
-template< class Element, class FVGridGeometry, class Sol>
-typename CCElementSolution<FVGridGeometry, Sol>::PrimaryVariables
-evalSolution(const Element& element,
-             const typename Element::Geometry& geometry,
-             const FVGridGeometry& fvGridGeometry,
-             const CCElementSolution<FVGridGeometry, Sol>& elemSol,
-             const typename Element::Geometry::GlobalCoordinate& globalPos)
+template<class Element, class FVElementGeometry, class PrimaryVariables>
+PrimaryVariables evalSolution(const Element& element,
+                              const typename Element::Geometry& geometry,
+                              const typename FVElementGeometry::FVGridGeometry& fvGridGeometry,
+                              const CCElementSolution<FVElementGeometry, PrimaryVariables>& elemSol,
+                              const typename Element::Geometry::GlobalCoordinate& globalPos)
 {
     return elemSol[0];
 }
@@ -155,12 +150,11 @@ evalSolution(const Element& element,
  * \param elemSol The primary variables at the dofs of the element
  * \param globalPos The global position
  */
-template< class Element, class GG, class Sol>
-typename CCElementSolution<GG, Sol>::PrimaryVariables
-evalSolution(const Element& element,
-            const typename Element::Geometry& geometry,
-            const CCElementSolution<GG, Sol>& elemSol,
-            const typename Element::Geometry::GlobalCoordinate& globalPos)
+template< class Element, class FVElementGeometry, class PrimaryVariables>
+PrimaryVariables evalSolution(const Element& element,
+                              const typename Element::Geometry& geometry,
+                              const CCElementSolution<FVElementGeometry, PrimaryVariables>& elemSol,
+                              const typename Element::Geometry::GlobalCoordinate& globalPos)
 {
     return elemSol[0];
 }
diff --git a/dumux/porousmediumflow/1pnc/volumevariables.hh b/dumux/porousmediumflow/1pnc/volumevariables.hh
index 549e37b15e..584592ca00 100644
--- a/dumux/porousmediumflow/1pnc/volumevariables.hh
+++ b/dumux/porousmediumflow/1pnc/volumevariables.hh
@@ -51,8 +51,8 @@ class OnePNCVolumeVariables : public PorousMediumFlowVolumeVariables<TypeTag>
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Element = typename GridView::template Codim<0>::Entity;
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
-    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
@@ -73,10 +73,7 @@ class OnePNCVolumeVariables : public PorousMediumFlowVolumeVariables<TypeTag>
 
     };
 
-    using Element = typename GridView::template Codim<0>::Entity;
-
 public:
-
     using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState);
 
     /*!
@@ -359,30 +356,14 @@ public:
     { return permeability_; }
 
 protected:
+    FluidState fluidState_;
 
-    static Scalar temperature_(const PrimaryVariables &priVars,
-                               const Problem& problem,
-                               const Element &element,
-                               const FVElementGeometry &fvGeometry,
-                               int scvIdx)
-    {
-         return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
-    }
-
-
+private:
     Scalar porosity_;        //!< Effective porosity within the control volume
     PermeabilityType permeability_;
     Scalar density_;
-    FluidState fluidState_;
     Dune::FieldVector<Scalar, numComponents> diffCoeff_;
 
-private:
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-
 };
 
 } // end namespace
diff --git a/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh b/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh
index b762cb3f0d..bcfd37e655 100644
--- a/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh
+++ b/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh
@@ -190,10 +190,10 @@ public:
         const auto& outsideVolVars = curElemVolVars[outsideScvIdx];
         const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element,
                                                                                      insideScv,
-                                                                                     elementSolution<SolutionVector, FVGridGeometry>(insideVolVars.priVars()));
+                                                                                     elementSolution<FVElementGeometry>(insideVolVars.priVars()));
         const auto& outsideMaterialParams = problem.spatialParams().materialLawParams(outsideElement,
                                                                                       outsideScv,
-                                                                                      elementSolution<SolutionVector, FVGridGeometry>(outsideVolVars.priVars()));
+                                                                                      elementSolution<FVElementGeometry>(outsideVolVars.priVars()));
 
         // get references to the two participating derivative matrices
         auto& dI_dI = derivativeMatrices[insideScvIdx];
@@ -450,7 +450,7 @@ public:
         const auto& outsideVolVars = curElemVolVars[scvf.outsideScvIdx()];
         const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element,
                                                                                      insideScv,
-                                                                                     elementSolution<SolutionVector, FVGridGeometry>(insideVolVars.priVars()));
+                                                                                     elementSolution<FVElementGeometry>(insideVolVars.priVars()));
 
         // some quantities to be reused (rho & mu are constant and thus equal for all cells)
         static const auto rho_w = insideVolVars.density(FluidSystem::wPhaseIdx);
diff --git a/dumux/porousmediumflow/2pnc/volumevariables.hh b/dumux/porousmediumflow/2pnc/volumevariables.hh
index 0e8c05a045..919876ac1b 100644
--- a/dumux/porousmediumflow/2pnc/volumevariables.hh
+++ b/dumux/porousmediumflow/2pnc/volumevariables.hh
@@ -503,9 +503,6 @@ public:
      { return fluidState_.moleFraction(phaseIdx, compIdx); }
 
 protected:
-    Scalar porosity_;               //!< Effective porosity within the control volume
-    PermeabilityType permeability_; //!> Effective permeability within the control volume
-    Scalar mobility_[numPhases];    //!< Effective mobility within the control volume
     FluidState fluidState_;
 
 private:
@@ -519,6 +516,9 @@ private:
             DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient for phaseIdx = compIdx doesn't exist");
     }
 
+    Scalar porosity_;               //!< Effective porosity within the control volume
+    PermeabilityType permeability_; //!> Effective permeability within the control volume
+    Scalar mobility_[numPhases];    //!< Effective mobility within the control volume
     std::array<std::array<Scalar, numComponents-1>, numPhases> diffCoefficient_;
 };
 
diff --git a/dumux/porousmediumflow/volumevariables.hh b/dumux/porousmediumflow/volumevariables.hh
index a939ee9b2e..397a4b0f4f 100644
--- a/dumux/porousmediumflow/volumevariables.hh
+++ b/dumux/porousmediumflow/volumevariables.hh
@@ -55,9 +55,10 @@ class PorousMediumFlowVolumeVariablesImplementation<TypeTag, false>
     using Element = typename GridView::template Codim<0>::Entity;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
-    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
 
 public:
+    //! export the primary variables type
+    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
 
     /*!
      * \brief Update all quantities for a given control volume
-- 
GitLab