diff --git a/dumux/assembly/boxlocalassembler.hh b/dumux/assembly/boxlocalassembler.hh
index fd8c7a13d45444caac7767dbdada4a52d790896e..adab4567da70eaee8c55ebdbeb2196ad728446e6 100644
--- a/dumux/assembly/boxlocalassembler.hh
+++ b/dumux/assembly/boxlocalassembler.hh
@@ -56,7 +56,7 @@ class BoxLocalAssemblerBase : public FVLocalAssemblerBase<TypeTag, Assembler, Im
     using JacobianMatrix = typename GET_PROP_TYPE(TypeTag, JacobianMatrix);
     using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
 
     enum { numEq = GET_PROP_TYPE(TypeTag, ModelTraits)::numEq() };
 
diff --git a/dumux/assembly/boxlocalresidual.hh b/dumux/assembly/boxlocalresidual.hh
index cb8cdf25ab9f54875aa28d559c74c70c753777a5..12fd39ca72b18093dbd8f23d7fdb92ddf66f9e81 100644
--- a/dumux/assembly/boxlocalresidual.hh
+++ b/dumux/assembly/boxlocalresidual.hh
@@ -49,9 +49,9 @@ class BoxLocalResidual : public FVLocalResidual<TypeTag>
     using Element = typename GridView::template Codim<0>::Entity;
     using ElementBoundaryTypes = typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
 
 public:
diff --git a/dumux/assembly/cclocalassembler.hh b/dumux/assembly/cclocalassembler.hh
index 7e3f2ec3f99877923f20e024d33e52bbd5554c93..a27e7300f7d07566112e0b2cf7bb82c4bec4e028 100644
--- a/dumux/assembly/cclocalassembler.hh
+++ b/dumux/assembly/cclocalassembler.hh
@@ -60,7 +60,7 @@ class CCLocalAssemblerBase : public FVLocalAssemblerBase<TypeTag, Assembler, Imp
     using JacobianMatrix = typename GET_PROP_TYPE(TypeTag, JacobianMatrix);
     using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
 
 public:
diff --git a/dumux/assembly/cclocalresidual.hh b/dumux/assembly/cclocalresidual.hh
index f8e5995097de9349941dc589699e5cea763f1cec..03314a9ca57eb7b4d050e82b67a21adaebae2a03 100644
--- a/dumux/assembly/cclocalresidual.hh
+++ b/dumux/assembly/cclocalresidual.hh
@@ -44,8 +44,8 @@ class CCLocalResidual : public FVLocalResidual<TypeTag>
     using Element = typename GET_PROP_TYPE(TypeTag, GridView)::template Codim<0>::Entity;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using ElementBoundaryTypes = typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
diff --git a/dumux/assembly/fvlocalassemblerbase.hh b/dumux/assembly/fvlocalassemblerbase.hh
index 39be6aefb1972b165eb30bc9096398e9d68078d2..66257dc6f9968db7d426802ee75f9529a5431e87 100644
--- a/dumux/assembly/fvlocalassemblerbase.hh
+++ b/dumux/assembly/fvlocalassemblerbase.hh
@@ -58,9 +58,9 @@ class FVLocalAssemblerBase
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Element = typename GridView::template Codim<0>::Entity;
 
 public:
diff --git a/dumux/assembly/fvlocalresidual.hh b/dumux/assembly/fvlocalresidual.hh
index 5e1ecde657f27299d1bc66611ee51d8b07d3de41..73a5bbc0abaa2e393deff679449231aa46f4f1ba 100644
--- a/dumux/assembly/fvlocalresidual.hh
+++ b/dumux/assembly/fvlocalresidual.hh
@@ -56,9 +56,9 @@ class FVLocalResidual
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using ElementBoundaryTypes = typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using TimeLoop = TimeLoopBase<Scalar>;
 
diff --git a/dumux/assembly/staggeredfvassembler.hh b/dumux/assembly/staggeredfvassembler.hh
index f9955bcbd2aabfe8f387c9e2c16bc9ca04411f47..710d42ef6b164002188a743f51782195507f2f24 100644
--- a/dumux/assembly/staggeredfvassembler.hh
+++ b/dumux/assembly/staggeredfvassembler.hh
@@ -56,14 +56,11 @@ class StaggeredFVAssembler
     using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
     using TimeLoop = TimeLoopBase<typename GET_PROP_TYPE(TypeTag, Scalar)>;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using LocalAssembler = StaggeredLocalAssembler<TypeTag, diffMethod, isImplicit>;
 
     static constexpr int dim = GridView::dimension;
-
-    using LocalAssembler =StaggeredLocalAssembler<TypeTag, diffMethod, isImplicit>;
-
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
+    static constexpr auto cellCenterIdx = GET_PROP_TYPE(TypeTag, FVGridGeometry)::cellCenterIdx();
+    static constexpr auto faceIdx = GET_PROP_TYPE(TypeTag, FVGridGeometry)::faceIdx();
 
     using CCToCCMatrixBlock = typename GET_PROP(TypeTag, JacobianMatrix)::MatrixBlockCCToCC;
     using CCToFaceMatrixBlock = typename GET_PROP(TypeTag, JacobianMatrix)::MatrixBlockCCToFace;
diff --git a/dumux/assembly/staggeredlocalassembler.hh b/dumux/assembly/staggeredlocalassembler.hh
index 549ba7fff0c247fa8f2907cfa165401bfa5ddb8f..1213bd150afc2e573aad32d7dbb2b586e965ec5d 100644
--- a/dumux/assembly/staggeredlocalassembler.hh
+++ b/dumux/assembly/staggeredlocalassembler.hh
@@ -73,10 +73,10 @@ class StaggeredLocalAssembler<TypeTag,
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FVElementGeometry = typename FVGridGeometry::LocalView;
     using GridFaceVariables = typename GET_PROP_TYPE(TypeTag, GridFaceVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Element = typename GET_PROP_TYPE(TypeTag, GridView)::template Codim<0>::Entity;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
@@ -93,11 +93,13 @@ class StaggeredLocalAssembler<TypeTag,
     using FacePrimaryVariables = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
     using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
     using FaceVariables = typename GET_PROP_TYPE(TypeTag, FaceVariables);
-    using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables);
+    using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, GridFaceVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
     static constexpr bool enableGridFluxVarsCache = GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache);
     static constexpr auto faceOffset = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
+    static constexpr auto cellCenterIdx = FVGridGeometry::cellCenterIdx();
+    static constexpr auto faceIdx = FVGridGeometry::faceIdx();
 
 public:
 
@@ -110,10 +112,6 @@ public:
                                 const Element& element,
                                 const SolutionVector& curSol)
     {
-        using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-        typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-        typename DofTypeIndices::FaceIdx faceIdx;
-
         // get some references for convenience
         const auto& problem = assembler.problem();
         auto& localResidual = assembler.localResidual();
@@ -183,11 +181,6 @@ public:
                                             const Element& element,
                                             const SolutionVector& curSol)
     {
-        using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-        typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-        typename DofTypeIndices::FaceIdx faceIdx;
-
-
         // get some references for convenience
         const auto& problem = assembler.problem();
         auto& localResidual = assembler.localResidual();
@@ -314,9 +307,6 @@ protected:
                  JacobianMatrix& matrix,
                  const NumCellCenterEqVector& ccResidual)
     {
-        using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-        typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-
         const auto& problem = assembler.problem();
         auto& localResidual = assembler.localResidual();
         auto& gridVariables = assembler.gridVariables();
@@ -340,7 +330,7 @@ protected:
 
                const Scalar eps = numericEpsilon(priVars[pvIdx], cellCenterIdx, cellCenterIdx);
                priVars[pvIdx] += eps;
-               auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(priVars));
+               auto elemSol = elementSolution<FVElementGeometry>(std::move(priVars));
                curVolVars.update(elemSol, problem, elementJ, scvJ);
 
                const auto deflectedResidual = localResidual.evalCellCenter(problem, element, fvGeometry, prevElemVolVars, curElemVolVars,
@@ -376,11 +366,6 @@ protected:
                           JacobianMatrix& matrix,
                           const NumCellCenterEqVector& ccResidual)
     {
-       // build derivatives with for cell center dofs w.r.t. face dofs
-       using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-       typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-       typename DofTypeIndices::FaceIdx faceIdx;
-
        const auto& problem = assembler.problem();
        auto& localResidual = assembler.localResidual();
        auto& gridVariables = assembler.gridVariables();
@@ -440,10 +425,6 @@ protected:
     {
        for(auto&& scvf : scvfs(fvGeometry))
        {
-           using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-           typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-           typename DofTypeIndices::FaceIdx faceIdx;
-
            const auto& problem = assembler.problem();
            auto& localResidual = assembler.localResidual();
            auto& gridVariables = assembler.gridVariables();
@@ -467,7 +448,7 @@ protected:
 
                    const Scalar eps = numericEpsilon(priVars[pvIdx], faceIdx, cellCenterIdx);
                    priVars[pvIdx] += eps;
-                   auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(priVars));
+                   auto elemSol = elementSolution<FVElementGeometry>(std::move(priVars));
                    curVolVars.update(elemSol, problem, elementJ, scvJ);
 
                    const auto deflectedResidual = localResidual.evalFace(problem, element, fvGeometry, scvf,
@@ -505,9 +486,6 @@ protected:
                             JacobianMatrix& matrix,
                             const FaceSolutionVector& cachedResidual)
     {
-        using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-        typename DofTypeIndices::FaceIdx faceIdx;
-
         const auto& problem = assembler.problem();
         auto& localResidual = assembler.localResidual();
         const auto& connectivityMap = assembler.fvGridGeometry().connectivityMap();
@@ -612,7 +590,7 @@ protected:
 
     //! Helper function that returns an iterable range of primary variable indices.
     //! Specialization for cell center dofs.
-    static auto priVarIndices_(typename GET_PROP(TypeTag, DofTypeIndices)::CellCenterIdx)
+    static auto priVarIndices_(typename FVGridGeometry::DofTypeIndices::CellCenterIdx)
     {
         constexpr auto numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
 
@@ -625,7 +603,7 @@ protected:
 
     //! Helper function that returns an iterable range of primary variable indices.
     //! Specialization for face dofs.
-    static auto priVarIndices_(typename GET_PROP(TypeTag, DofTypeIndices)::FaceIdx)
+    static auto priVarIndices_(typename FVGridGeometry::DofTypeIndices::FaceIdx)
     {
         constexpr auto numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
         constexpr auto numEqFace = GET_PROP_VALUE(TypeTag, NumEqFace);
diff --git a/dumux/assembly/staggeredlocalresidual.hh b/dumux/assembly/staggeredlocalresidual.hh
index b1f71191d9cd37a22274b723e77d79515a4d6d21..46a2fac4d8aa57cac71a2c92ab972996e3379f64 100644
--- a/dumux/assembly/staggeredlocalresidual.hh
+++ b/dumux/assembly/staggeredlocalresidual.hh
@@ -45,8 +45,8 @@ class StaggeredLocalResidual
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using Element = typename GridView::template Codim<0>::Entity;
     using ElementBoundaryTypes = typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
@@ -55,7 +55,7 @@ class StaggeredLocalResidual
 
     using CellCenterResidual = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
     using FaceResidual = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
-    using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables);
+    using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, GridFaceVariables)::LocalView;
 
     using TimeLoop = TimeLoopBase<Scalar>;
 
diff --git a/dumux/common/fvproblem.hh b/dumux/common/fvproblem.hh
index 08e75df775acece6f2c14998e08333fff160e1a1..9a760be9e1a592930fe18be25b9cd053f826910b 100644
--- a/dumux/common/fvproblem.hh
+++ b/dumux/common/fvproblem.hh
@@ -63,7 +63,7 @@ class FVProblem
     using PointSourceHelper = typename GET_PROP_TYPE(TypeTag, PointSourceHelper);
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
 
     enum {
         dim = GridView::dimension,
diff --git a/dumux/common/pointsource.hh b/dumux/common/pointsource.hh
index 7d5204ff5053f348a925d0513a0e190d2a361849..0bc347a3ef7ae4795fba6a8328e8f2306c850229 100644
--- a/dumux/common/pointsource.hh
+++ b/dumux/common/pointsource.hh
@@ -54,7 +54,7 @@ class PointSource
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using Element = typename GridView::template Codim<0>::Entity;
@@ -220,7 +220,7 @@ class SolDependentPointSource : public PointSource<TypeTag>
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using Element = typename GridView::template Codim<0>::Entity;
diff --git a/dumux/common/properties.hh b/dumux/common/properties.hh
index 423d2bcea979ee0ee246f2616a66b4f135806759..9c2b7bf1bc0e900a451b6be64616b50438af3c88 100644
--- a/dumux/common/properties.hh
+++ b/dumux/common/properties.hh
@@ -80,12 +80,10 @@ NEW_PROP_TAG(FVGridGeometry);                      //!< The type of the global f
 NEW_PROP_TAG(EnableFVGridGeometryCache);           //!< specifies if geometric data is saved (faster, but more memory consuming)
 
 NEW_PROP_TAG(VolumeVariables);                     //!< The secondary variables within a sub-control volume
-NEW_PROP_TAG(ElementVolumeVariables);              //!< The type for a local (element/stencil) container for the volume variables
 NEW_PROP_TAG(GridVolumeVariables);                 //!< The type for a global container for the volume variables
 NEW_PROP_TAG(EnableGridVolumeVariablesCache);      //!< If disabled, the volume variables are not stored (reduces memory, but is slower)
 NEW_PROP_TAG(FluxVariables);                       //!< Container storing the different types of flux variables
 NEW_PROP_TAG(FluxVariablesCache);                  //!< Stores data associated with flux vars
-NEW_PROP_TAG(ElementFluxVariablesCache);           //!< A local vector of flux variable caches per element
 NEW_PROP_TAG(GridFluxVariablesCache);              //!< The global vector of flux variable containers
 NEW_PROP_TAG(EnableGridFluxVariablesCache);        //!< specifies if data on flux vars should be saved (faster, but more memory consuming)
 NEW_PROP_TAG(GridVariables);                       //!< The grid variables object managing variable data on the grid (volvars/fluxvars cache)
@@ -156,13 +154,11 @@ NEW_PROP_TAG(GridFaceVariables);                   //!< Global vector containing
 NEW_PROP_TAG(CellCenterPrimaryVariables);          //!< The primary variables container type for cell-centered dofs
 NEW_PROP_TAG(FacePrimaryVariables);                //!< The primary variables container type for face dofs
 NEW_PROP_TAG(IntersectionMapper);                  //!< Specifies the intersection mapper
-NEW_PROP_TAG(DofTypeIndices);                      //!< Specifies index types for accessing the multi type block vectors/matrices
 NEW_PROP_TAG(StaggeredPrimaryVariables);           //!< The hybrid primary variables container type
 NEW_PROP_TAG(BaseEpsilon);                         //!< A base epsilon for numerical differentiation, can contain multiple values
 NEW_PROP_TAG(FaceVariables);                       //!< Class containing local face-related data
 NEW_PROP_TAG(BoundaryValues);                      //!< Class containing local boundary data
 NEW_PROP_TAG(StaggeredFaceSolution);               //!< A vector containing the solution for a face (similar to ElementSolution)
-NEW_PROP_TAG(ElementFaceVariables);                //!< Face related varibles (similar to volume variables)
 NEW_PROP_TAG(EnableGridFaceVariablesCache);      //!< Switch on/off caching of face variables
 
 /////////////////////////////////////////////////////////////
diff --git a/dumux/common/staggeredfvproblem.hh b/dumux/common/staggeredfvproblem.hh
index d422992f221d8c8c7de047abcd59e7ec8affc85b..7d68b6c00c3ee05dfe2570c3ea75b35bd2d2590b 100644
--- a/dumux/common/staggeredfvproblem.hh
+++ b/dumux/common/staggeredfvproblem.hh
@@ -55,23 +55,15 @@ class StaggeredFVProblem : public FVProblem<TypeTag>
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
+    using FVElementGeometry = typename FVGridGeometry::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
-    enum {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld
-    };
-
     using CoordScalar = typename GridView::ctype;
-    using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
+    using GlobalPosition = Dune::FieldVector<CoordScalar, GridView::dimensionworld>;
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
+    static constexpr auto cellCenterIdx = FVGridGeometry::cellCenterIdx();
+    static constexpr auto faceIdx = FVGridGeometry::faceIdx();
 
 public:
     /*!
@@ -168,7 +160,7 @@ protected:
 
     //! Helper function that returns an iterable range of primary variable indices.
     //! Specialization for cell center dofs.
-    static auto priVarIndices_(typename GET_PROP(TypeTag, DofTypeIndices)::CellCenterIdx)
+    static auto priVarIndices_(typename FVGridGeometry::DofTypeIndices::CellCenterIdx)
     {
         constexpr auto numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
 
@@ -181,7 +173,7 @@ protected:
 
     //! Helper function that returns an iterable range of primary variable indices.
     //! Specialization for face dofs.
-    static auto priVarIndices_(typename GET_PROP(TypeTag, DofTypeIndices)::FaceIdx)
+    static auto priVarIndices_(typename FVGridGeometry::DofTypeIndices::FaceIdx)
     {
         constexpr auto numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
         constexpr auto numEq = GET_PROP_TYPE(TypeTag, ModelTraits)::numEq();
diff --git a/dumux/discretization/box/darcyslaw.hh b/dumux/discretization/box/darcyslaw.hh
index a68e30d723cf4d4e38c0de1196e4ee9611ec682b..bf7d53b48bcc94327ec8906f2be205d6e7f5ebf1 100644
--- a/dumux/discretization/box/darcyslaw.hh
+++ b/dumux/discretization/box/darcyslaw.hh
@@ -47,9 +47,9 @@ class DarcysLawImplementation<TypeTag, DiscretizationMethod::box>
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElemFluxVarCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElemFluxVarCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVarCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Element = typename GridView::template Codim<0>::Entity;
diff --git a/dumux/discretization/box/elementfluxvariablescache.hh b/dumux/discretization/box/elementfluxvariablescache.hh
index 80a3bce49ab34484656315afd0aff3a49ad24856..abd6d85679045593cc1296bf0bc88eaee79a4578 100644
--- a/dumux/discretization/box/elementfluxvariablescache.hh
+++ b/dumux/discretization/box/elementfluxvariablescache.hh
@@ -23,65 +23,66 @@
 #ifndef DUMUX_DISCRETIZATION_BOX_ELEMENT_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_BOX_ELEMENT_FLUXVARSCACHE_HH
 
-#include <dumux/common/properties.hh>
-
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the flux variables cache vector, we store one cache per face
+ * \ingroup BoxDiscretization
+ * \brief The flux variables caches for an element
+ * \note The class is specialized for a version with and without caching
+ * If grid caching is enabled the flux caches are stored for the whole gridview in the corresponding
+ * GridFluxVariablesCache which is memory intensive but faster. For caching disabled the
+ * flux caches are locally computed for each element whenever needed.
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class GFVC, bool cachingEnabled>
 class BoxElementFluxVariablesCache
 {};
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the flux variables cache vector, we store one cache per face
+ * \ingroup BoxDiscretization
+ * \brief The flux variables caches for an element with caching enabled
  */
-template<class TypeTag>
-class BoxElementFluxVariablesCache<TypeTag, true>
+template<class GFVC>
+class BoxElementFluxVariablesCache<GFVC, true>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
-
 public:
+    //! export the type of the grid flux variables cache
+    using GridFluxVariablesCache = GFVC;
+
+    //! export the type of the flux variables cache
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
     BoxElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
 
     // Function is called by the BoxLocalJacobian prior to flux calculations on the element.
     // We assume the FVGeometries to be bound at this point
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars)
     {
         bindElement(element, fvGeometry, elemVolVars);
     }
 
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars)
     {
         eIdx_ = fvGeometry.fvGridGeometry().elementMapper().index(element);
     }
 
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf)
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf)
     {
         bindElement(element, fvGeometry, elemVolVars);
     }
 
     // access operator
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return gridFluxVarsCache().cache(eIdx_, scvf.index()); }
 
@@ -91,41 +92,38 @@ public:
 
 private:
     const GridFluxVariablesCache* gridFluxVarsCachePtr_;
-    // currently bound element
-    IndexType eIdx_;
+    std::size_t eIdx_; //!< currently bound element
 };
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the flux variables cache vector, we store one cache per face
+ * \ingroup BoxDiscretization
+ * \brief The flux variables caches for an element with caching disabled
  */
-template<class TypeTag>
-class BoxElementFluxVariablesCache<TypeTag, false>
+template<class GFVC>
+class BoxElementFluxVariablesCache<GFVC, false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
-
 public:
+    //! export the type of the grid flux variables cache
+    using GridFluxVariablesCache = GFVC;
+
+    //! export the type of the flux variables cache
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
     BoxElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
 
     // Function is called by the BoxLocalJacobian prior to flux calculations on the element.
     // We assume the FVGeometries to be bound at this point
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars)
     {
         bindElement(element, fvGeometry, elemVolVars);
     }
 
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars)
     {
@@ -135,20 +133,23 @@ public:
             (*this)[scvf].update(gridFluxVarsCache().problem(), element, fvGeometry, elemVolVars, scvf);
     }
 
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf)
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf)
     {
         fluxVarsCache_.resize(fvGeometry.numScvf());
         (*this)[scvf].update(gridFluxVarsCache().problem(), element, fvGeometry, elemVolVars, scvf);
     }
 
     // access operator
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return fluxVarsCache_[scvf.index()]; }
 
     // access operator
+    template<class SubControlVolumeFace>
     FluxVariablesCache& operator [](const SubControlVolumeFace& scvf)
     { return fluxVarsCache_[scvf.index()]; }
 
diff --git a/dumux/discretization/box/elementsolution.hh b/dumux/discretization/box/elementsolution.hh
index dbd82c316fb7902ea7aa7beea9b9e5bfb18f7394..d77d714ca2b9c9ede53a9d1b13ce3065c5d3b722 100644
--- a/dumux/discretization/box/elementsolution.hh
+++ b/dumux/discretization/box/elementsolution.hh
@@ -33,33 +33,28 @@ namespace Dumux {
  * \ingroup BoxModel
  * \brief The element solution vector
  */
-template<class FVGridGeometry, class SolutionVector>
+template<class FVElementGeometry, class PV>
 class BoxElementSolution
 {
+    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
     BoxElementSolution() = default;
 
     //! Constructor with element and solution and grid geometry
+    template<class SolutionVector>
     BoxElementSolution(const Element& element, const SolutionVector& sol,
                        const FVGridGeometry& fvGridGeometry)
     {
         update(element, sol, fvGridGeometry);
     }
 
-    //! Constructor with element and solution and element geometry
-    BoxElementSolution(const Element& element, const SolutionVector& sol,
-                       const FVElementGeometry& fvGeometry)
-    {
-        update(element, sol, fvGeometry);
-    }
-
     //! Constructor with element and elemVolVars and fvGeometry
     template<class ElementVolumeVariables>
     BoxElementSolution(const Element& element, const ElementVolumeVariables& elemVolVars,
@@ -72,6 +67,7 @@ public:
     }
 
     //! 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)
     {
@@ -82,6 +78,7 @@ public:
     }
 
     //! extract the element solution from the solution vector using a local fv geometry
+    template<class SolutionVector>
     void update(const Element& element, const SolutionVector& sol,
                 const FVElementGeometry& fvGeometry)
     {
@@ -112,9 +109,12 @@ private:
 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::box,
-                    BoxElementSolution<FVGridGeometry, SolutionVector>>
+                    BoxElementSolution<typename FVGridGeometry::LocalView,
+                                      std::decay_t<decltype(std::declval<SolutionVector>()[0])>>
+                    >
 {
-    return BoxElementSolution<FVGridGeometry, SolutionVector>(element, sol, gg);
+    using PrimaryVariables = std::decay_t<decltype(std::declval<SolutionVector>()[0])>;
+    return BoxElementSolution<typename FVGridGeometry::LocalView, PrimaryVariables>(element, sol, gg);
 }
 
 /*!
@@ -124,11 +124,11 @@ 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);
+    using PrimaryVariables = typename ElementVolumeVariables::VolumeVariables::PrimaryVariables;
+    return BoxElementSolution<FVElementGeometry, PrimaryVariables>(element, elemVolVars, gg);
 }
 
 } // end namespace Dumux
diff --git a/dumux/discretization/box/elementvolumevariables.hh b/dumux/discretization/box/elementvolumevariables.hh
index da0ef0bbf0aba20a9ebbf04304c5d3ed531e0996..5d244927fdfcff6dd588ca916ebc9e52c8f8eb6a 100644
--- a/dumux/discretization/box/elementvolumevariables.hh
+++ b/dumux/discretization/box/elementvolumevariables.hh
@@ -23,54 +23,52 @@
 #ifndef DUMUX_DISCRETIZATION_BOX_ELEMENT_VOLUMEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_BOX_ELEMENT_VOLUMEVARIABLES_HH
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/methods.hh>
+#include <type_traits>
+
 #include <dumux/discretization/box/elementsolution.hh>
 
 namespace Dumux {
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the volume variables vector
+ * \ingroup BoxDiscretization
+ * \brief The local (stencil) volume variables class for box 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>
-class BoxElementVolumeVariables
-{};
+template<class GVV, bool cachingEnabled>
+class BoxElementVolumeVariables;
 
-// specialization in case of storing the volume variables
-template<class TypeTag>
-class BoxElementVolumeVariables<TypeTag,/*enableGlobalVolVarCache*/true>
+/*!
+ * \ingroup BoxDiscretization
+ * \brief The local (stencil) volume variables class for box models with caching
+ * \note the volume variables are stored for the whole grid view in the corresponding GridVolumeVariables class
+ */
+template<class GVV>
+class BoxElementVolumeVariables<GVV, /*cachingEnabled*/true>
 {
-    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 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;
-
-    static constexpr bool isBox = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod == DiscretizationMethod::box;
-
 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
     BoxElementVolumeVariables(const GridVolumeVariables& gridVolVars)
     : gridVolVarsPtr_(&gridVolVars) {}
 
-    const VolumeVariables& operator [](IndexType scvIdx) const
+    const VolumeVariables& operator [](std::size_t scvIdx) const
     { return gridVolVars().volVars(eIdx_, scvIdx); }
 
+    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(eIdx_, scv.indexInElement()); }
 
     // For compatibility reasons with the case of not storing the vol vars.
     // function to be called before assembling an element, preparing the vol vars within the 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)
     {
@@ -78,7 +76,8 @@ public:
     }
 
     // function to prepare the vol vars within the 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)
     {
@@ -91,35 +90,31 @@ public:
 
 private:
     const GridVolumeVariables* gridVolVarsPtr_;
-    IndexType eIdx_;
+    std::size_t eIdx_;
 };
 
 
-// Specialization when the current volume variables are not stored
-template<class TypeTag>
-class BoxElementVolumeVariables<TypeTag, /*enableGlobalVolVarCache*/false>
+/*!
+ * \ingroup BoxDiscretization
+ * \brief The local (stencil) volume variables class for box models without caching
+ */
+template<class GVV>
+class BoxElementVolumeVariables<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 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;
-
 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
     BoxElementVolumeVariables(const GridVolumeVariables& gridVolVars)
     : gridVolVarsPtr_(&gridVolVars) {}
 
     // specialization for box models, simply forwards to the bindElement method
-    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)
     {
@@ -127,7 +122,8 @@ public:
     }
 
     // specialization for box models
-    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)
     {
@@ -144,15 +140,17 @@ public:
         }
     }
 
-    const VolumeVariables& operator [](IndexType scvIdx) const
+    const VolumeVariables& operator [](std::size_t scvIdx) const
     { return volumeVariables_[scvIdx]; }
 
-    VolumeVariables& operator [](IndexType scvIdx)
+    VolumeVariables& operator [](std::size_t scvIdx)
     { return volumeVariables_[scvIdx]; }
 
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     const VolumeVariables& operator [](const SubControlVolume& scv) const
     { return volumeVariables_[scv.indexInElement()]; }
 
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     VolumeVariables& operator [](const SubControlVolume& scv)
     { return volumeVariables_[scv.indexInElement()]; }
 
@@ -165,6 +163,6 @@ private:
     std::vector<VolumeVariables> volumeVariables_;
 };
 
-} // end namespace
+} // end namespace Dumux
 
 #endif
diff --git a/dumux/discretization/box/fickslaw.hh b/dumux/discretization/box/fickslaw.hh
index 7796a61ea2e10064e3ba16d0b5867c4ce5826928..2c888f7aaaabfe36181b67d2724509db44433fe1 100644
--- a/dumux/discretization/box/fickslaw.hh
+++ b/dumux/discretization/box/fickslaw.hh
@@ -49,8 +49,8 @@ class FicksLawImplementation<TypeTag, DiscretizationMethod::box>
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVarCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using BalanceEqOpts = typename GET_PROP_TYPE(TypeTag, BalanceEqOpts);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
diff --git a/dumux/discretization/box/fourierslaw.hh b/dumux/discretization/box/fourierslaw.hh
index a3a7ba332cf360c5ab2827640e8968fdc7d43f96..475b0adb370edfecd34787e523148a3ea7c08535 100644
--- a/dumux/discretization/box/fourierslaw.hh
+++ b/dumux/discretization/box/fourierslaw.hh
@@ -51,8 +51,8 @@ class FouriersLawImplementation<TypeTag, DiscretizationMethod::box>
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using IndexType = typename GridView::IndexSet::IndexType;
 
diff --git a/dumux/discretization/box/fourierslawnonequilibrium.hh b/dumux/discretization/box/fourierslawnonequilibrium.hh
index 6bfe232dececc68274b7fa6197eb50109afb47b9..9422b57c4c681e01136329004af3fbd780c0fe6b 100644
--- a/dumux/discretization/box/fourierslawnonequilibrium.hh
+++ b/dumux/discretization/box/fourierslawnonequilibrium.hh
@@ -53,8 +53,8 @@ class FouriersLawNonEquilibriumImplementation<TypeTag, DiscretizationMethod::box
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using IndexType = typename GridView::IndexSet::IndexType;
     using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
diff --git a/dumux/discretization/box/gridfluxvariablescache.hh b/dumux/discretization/box/gridfluxvariablescache.hh
index df27485c6a9e9522bdb9358a851e31fc9badc712..22879349b79d3f6d7dc0eb0cb3249aed4fcf21bc 100644
--- a/dumux/discretization/box/gridfluxvariablescache.hh
+++ b/dumux/discretization/box/gridfluxvariablescache.hh
@@ -23,49 +23,61 @@
 #ifndef DUMUX_DISCRETIZATION_BOX_GRID_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_BOX_GRID_FLUXVARSCACHE_HH
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/box/elementfluxvariablescache.hh>
-
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
+#include <dumux/discretization/box/elementfluxvariablescache.hh>
 
 namespace Dumux {
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the flux variables cache vector, we store one cache per face
+ * \ingroup BoxDiscretization
+ * \brief Flux variable caches traits
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class P, class FVC>
+struct BoxDefaultGridFVCTraits
+{
+    using Problem = P;
+    using FluxVariablesCache = FVC;
+
+    template<class GridFluxVariablesCache, bool cachingEnabled>
+    using LocalView = BoxElementFluxVariablesCache<GridFluxVariablesCache, cachingEnabled>;
+};
+
+/*!
+ * \ingroup BoxDiscretization
+ * \brief Flux variable caches on a gridview
+ * \note The class is specialized for a version with and without grid caching
+ */
+template<class Problem,
+         class FluxVariablesCache,
+         bool cachingEnabled = false,
+         class Traits = BoxDefaultGridFVCTraits<Problem, FluxVariablesCache> >
 class BoxGridFluxVariablesCache;
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the flux variables cache vector, we store one cache per face
+ * \ingroup BoxDiscretization
+ * \brief Flux variable caches on a gridview with grid caching enabled
+ * \note The flux caches of the gridview are stored which is memory intensive but faster
  */
-template<class TypeTag>
-class BoxGridFluxVariablesCache<TypeTag, true>
+template<class P, class FVC, class Traits>
+class BoxGridFluxVariablesCache<P, FVC, true, Traits>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using Problem = typename Traits::Problem;
+    using ThisType = BoxGridFluxVariablesCache<P, FVC, true, Traits>;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
 
     //! 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>;
+
     BoxGridFluxVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
 
+    template<class FVGridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry,
                 const GridVolumeVariables& gridVolVars,
                 const SolutionVector& sol,
@@ -96,11 +108,11 @@ public:
     { return *problemPtr_; }
 
     // access operator
-    const FluxVariablesCache& cache(IndexType eIdx, IndexType scvfIdx) const
+    const FluxVariablesCache& cache(std::size_t eIdx, std::size_t scvfIdx) const
     { return fluxVarsCache_[eIdx][scvfIdx]; }
 
     // access operator
-    FluxVariablesCache& cache(IndexType eIdx, IndexType scvfIdx)
+    FluxVariablesCache& cache(std::size_t eIdx, std::size_t scvfIdx)
     { return fluxVarsCache_[eIdx][scvfIdx]; }
 
 private:
@@ -110,33 +122,28 @@ private:
 };
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the flux variables cache vector, we store one cache per face
+ * \ingroup BoxDiscretization
+ * \brief Flux variable caches on a gridview with grid caching disabled
  */
-template<class TypeTag>
-class BoxGridFluxVariablesCache<TypeTag, false>
+template<class P, class FVC, class Traits>
+class BoxGridFluxVariablesCache<P, FVC, false, Traits>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
+    using Problem = typename Traits::Problem;
+    using ThisType = BoxGridFluxVariablesCache<P, FVC, false, Traits>;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
 
     //! 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>;
+
     BoxGridFluxVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
 
+    template<class FVGridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry,
                 const GridVolumeVariables& gridVolVars,
                 const SolutionVector& sol,
diff --git a/dumux/discretization/box/gridvolumevariables.hh b/dumux/discretization/box/gridvolumevariables.hh
index 3c29868f6494b1419cc7c6c86a02d6c8a2057dfb..a5fe851d5eeb3b65cc9d5cfe6ed5e332ec3c4774 100644
--- a/dumux/discretization/box/gridvolumevariables.hh
+++ b/dumux/discretization/box/gridvolumevariables.hh
@@ -23,47 +23,55 @@
 #ifndef DUMUX_DISCRETIZATION_BOX_GRID_VOLUMEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_BOX_GRID_VOLUMEVARIABLES_HH
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/box/elementvolumevariables.hh>
-#include <dumux/discretization/box/elementsolution.hh>
+#include <type_traits>
 
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
+#include <dumux/discretization/box/elementvolumevariables.hh>
+#include <dumux/discretization/box/elementsolution.hh>
 
 namespace Dumux {
 
+template<class P, class VV>
+struct BoxDefaultGridVolumeVariablesTraits
+{
+    using Problem = P;
+    using VolumeVariables = VV;
+
+    template<class GridVolumeVariables, bool cachingEnabled>
+    using LocalView = BoxElementVolumeVariables<GridVolumeVariables, cachingEnabled>;
+};
+
 /*!
  * \ingroup BoxModel
  * \brief Base class for the grid volume variables
  */
-template<class TypeTag, bool enableGridVolVarsCache>
+template<class Problem,
+         class VolumeVariables,
+         bool enableGridVolVarsCache = false,
+         class Traits = BoxDefaultGridVolumeVariablesTraits<Problem, VolumeVariables> >
 class BoxGridVolumeVariables;
 
 // specialization in case of storing the volume variables
-template<class TypeTag>
-class BoxGridVolumeVariables<TypeTag,/*enableGlobalVolVarCache*/true>
+template<class P, class VV, class Traits>
+class BoxGridVolumeVariables<P, VV, /*cachingEnabled*/true, Traits>
 {
-    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 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;
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-
-    static const int dim = GridView::dimension;
-    using Element = typename GridView::template Codim<0>::Entity;
+    using ThisType = BoxGridVolumeVariables<P, VV, true, Traits>;
+    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>;
+
     BoxGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
 
+    template<class FVGridGeometry, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol)
     {
         volumeVariables_.resize(fvGridGeometry.gridView().size(0));
@@ -84,16 +92,18 @@ public:
         }
     }
 
+    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.elementIndex()][scv.indexInElement()]; }
 
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
     VolumeVariables& volVars(const SubControlVolume& scv)
     { return volumeVariables_[scv.elementIndex()][scv.indexInElement()]; }
 
-    const VolumeVariables& volVars(const IndexType eIdx, const IndexType scvIdx) const
+    const VolumeVariables& volVars(const std::size_t eIdx, const std::size_t scvIdx) const
     { return volumeVariables_[eIdx][scvIdx]; }
 
-    VolumeVariables& volVars(const IndexType eIdx, const IndexType scvIdx)
+    VolumeVariables& volVars(const std::size_t eIdx, const std::size_t scvIdx)
     { return volumeVariables_[eIdx][scvIdx]; }
 
     const Problem& problem() const
@@ -106,23 +116,25 @@ private:
 
 
 // Specialization when the current volume variables are not stored
-template<class TypeTag>
-class BoxGridVolumeVariables<TypeTag, /*enableGlobalVolVarCache*/false>
+template<class P, class VV, class Traits>
+class BoxGridVolumeVariables<P, VV, /*cachingEnabled*/false, Traits>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using ThisType = BoxGridVolumeVariables<P, VV, false, Traits>;
+    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>;
+
     BoxGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
 
+    template<class FVGridGeometry, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol) {}
 
     const Problem& problem() const
diff --git a/dumux/discretization/box/maxwellstefanslaw.hh b/dumux/discretization/box/maxwellstefanslaw.hh
index 5a605868bc25bcdd3e0b268de4f77853929ff2fd..8791b3f64c99e1b00407276c5df153abecdf882d 100644
--- a/dumux/discretization/box/maxwellstefanslaw.hh
+++ b/dumux/discretization/box/maxwellstefanslaw.hh
@@ -53,8 +53,8 @@ class MaxwellStefansLawImplementation<TypeTag, DiscretizationMethod::box >
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using IndexType = typename GridView::IndexSet::IndexType;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
diff --git a/dumux/discretization/box/properties.hh b/dumux/discretization/box/properties.hh
index 14d65422673e5a104d366e6f79bafc4fe17cbacb..312c18162683867ed36f2e7c88cb3060d2582bf8 100644
--- a/dumux/discretization/box/properties.hh
+++ b/dumux/discretization/box/properties.hh
@@ -40,16 +40,12 @@
 #include <dumux/discretization/box/elementsolution.hh>
 #include <dumux/discretization/box/elementboundarytypes.hh>
 #include <dumux/discretization/box/gridfluxvariablescache.hh>
-#include <dumux/discretization/box/elementfluxvariablescache.hh>
 #include <dumux/discretization/box/gridvolumevariables.hh>
-#include <dumux/discretization/box/elementvolumevariables.hh>
 #include <dumux/discretization/box/fvgridgeometry.hh>
-#include <dumux/discretization/box/fvelementgeometry.hh>
 
-namespace Dumux
-{
-namespace Properties
-{
+namespace Dumux {
+namespace Properties {
+
 //! Type tag for the box scheme.
 NEW_TYPE_TAG(BoxModel, INHERITS_FROM(FiniteVolumeModel));
 
@@ -64,24 +60,30 @@ public:
     using type = BoxFVGridGeometry<Scalar, GridView, enableCache>;
 };
 
-//! Set the default for the ElementBoundaryTypes
-SET_TYPE_PROP(BoxModel, ElementBoundaryTypes, BoxElementBoundaryTypes<typename GET_PROP_TYPE(TypeTag, BoundaryTypes)>);
-
-//! The global volume variables vector class
-SET_TYPE_PROP(BoxModel, GridVolumeVariables, BoxGridVolumeVariables<TypeTag,
-                            GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
-
-//! The element volume variables vector class
-SET_TYPE_PROP(BoxModel, ElementVolumeVariables, BoxElementVolumeVariables<TypeTag,
-                            GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
+//! The grid volume variables vector class
+SET_PROP(BoxModel, 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 = BoxGridVolumeVariables<Problem, VolumeVariables, enableCache>;
+};
 
-//! The global flux variables cache vector class
-SET_TYPE_PROP(BoxModel, GridFluxVariablesCache, BoxGridFluxVariablesCache<TypeTag,
-                            GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
+//! The grid flux variables cache vector class
+SET_PROP(BoxModel, GridFluxVariablesCache)
+{
+private:
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
+public:
+    using type = BoxGridFluxVariablesCache<Problem, FluxVariablesCache, enableCache>;
+};
 
-//! The local flux variables cache vector class
-SET_TYPE_PROP(BoxModel, ElementFluxVariablesCache, BoxElementFluxVariablesCache<TypeTag,
-                            GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
+//! Set the default for the ElementBoundaryTypes
+SET_TYPE_PROP(BoxModel, ElementBoundaryTypes, BoxElementBoundaryTypes<typename GET_PROP_TYPE(TypeTag, BoundaryTypes)>);
 
 //! Set the BaseLocalResidual to BoxLocalResidual
 SET_TYPE_PROP(BoxModel, BaseLocalResidual, BoxLocalResidual<TypeTag>);
diff --git a/dumux/discretization/cellcentered/elementsolution.hh b/dumux/discretization/cellcentered/elementsolution.hh
index d6295362711d8e279790b24bb1ae7f060b37dd00..e69991f8d3d337ab0afbf4cf3864d0a1c17a9377 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 d71e6b89ebf66f973eb369f6d5d28a0c5f3eb91b..be85257c751df9a57f4e740f8d6452d25406a8ef 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/darcyslaw.hh b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh
index c2c00e061f85f2b2637f3443d0cf7f1614f19588..22a098e387fe66f4a8e473f4f644674a00977aba 100644
--- a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh
+++ b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh
@@ -53,8 +53,8 @@ class DarcysLawImplementation<TypeTag, DiscretizationMethod::ccmpfa>
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FVElementGeometry = typename FVGridGeometry::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
 
     //! Class that fills the cache corresponding to mpfa Darcy's Law
diff --git a/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh b/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh
index e78a5dadcf33825e4ce1274d4e0986c0a8d32f77..6835c183e13a19ed783da6fd9519c0dad57b593f 100644
--- a/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh
+++ b/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh
@@ -24,18 +24,11 @@
 #ifndef DUMUX_DISCRETIZATION_CCMPFA_ELEMENT_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_CCMPFA_ELEMENT_FLUXVARSCACHE_HH
 
+#include <algorithm>
+#include <type_traits>
 #include <dune/common/exceptions.hh>
 
-#include <dumux/common/properties.hh>
-#include <dumux/common/parameters.hh>
-
-#include <dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh>
-
-#include "fluxvariablescachefiller.hh"
-#include "methods.hh"
-
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup CCMpfaDiscretization
@@ -46,56 +39,68 @@ namespace Dumux
  *       intensive but faster. For caching disabled, the flux caches are locally
  *       computed for each element whenever needed.
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class GFVC, bool cachingEnabled>
 class CCMpfaElementFluxVariablesCache;
 
 /*!
  * \ingroup CCMpfaDiscretization
  * \brief The flux variables caches for an element with caching enabled
  */
-template<class TypeTag>
-class CCMpfaElementFluxVariablesCache<TypeTag, true>
+template<class GFVC>
+class CCMpfaElementFluxVariablesCache<GFVC, true>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
+public:
+    //! export the interaction volume types
+    using PrimaryInteractionVolume = typename GFVC::PrimaryInteractionVolume;
+    using SecondaryInteractionVolume = typename GFVC::SecondaryInteractionVolume;
 
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
+    //! export the data handle types used
+    using PrimaryIvDataHandle = typename GFVC::PrimaryIvDataHandle;
+    using SecondaryIvDataHandle = typename GFVC::SecondaryIvDataHandle;
 
-public:
-    //! export the data handle types used by the grid-wide cache
-    using PrimaryIvDataHandle = typename GridFluxVariablesCache::PrimaryIvDataHandle;
-    using SecondaryIvDataHandle = typename GridFluxVariablesCache::SecondaryIvDataHandle;
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
+    //! export the flux variable cache filler type
+    using FluxVariablesCacheFiller = typename GFVC::FluxVariablesCacheFiller;
+
+    //! make it possible to query if caching is enabled
+    static constexpr bool cachingEnabled = true;
+
+    //! export the type of the grid flux variables
+    using GridFluxVariablesCache = GFVC;
 
     //! The constructor
     CCMpfaElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf) {}
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void update(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void update(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                 const FVElementGeometry& fvGeometry,
                 const ElementVolumeVariables& elemVolVars) {}
 
     //! access operators in the case of caching
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return (*gridFluxVarsCachePtr_)[scvf]; }
 
@@ -111,41 +116,29 @@ private:
  * \ingroup CCMpfaDiscretization
  * \brief The flux variables caches for an element with caching disabled
  */
-template<class TypeTag>
-class CCMpfaElementFluxVariablesCache<TypeTag, false>
+template<class GFVC>
+class CCMpfaElementFluxVariablesCache<GFVC, false>
 {
-    using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using GridIndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-
-    using FluxVariablesCacheFiller = CCMpfaFluxVariablesCacheFiller<TypeTag>;
-    using PrimaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
-    using PrimaryMatVecTraits = typename PrimaryInteractionVolume::Traits::MatVecTraits;
-    using SecondaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, SecondaryInteractionVolume);
-    using SecondaryMatVecTraits = typename SecondaryInteractionVolume::Traits::MatVecTraits;
-
-    //! physics traits class to define the data handles
-    struct PhysicsTraits
-    {
-        static constexpr bool enableAdvection = ModelTraits::enableAdvection();
-        static constexpr bool enableMolecularDiffusion = ModelTraits::enableMolecularDiffusion();
-        static constexpr bool enableHeatConduction = ModelTraits::enableEnergyBalance();
-
-        static constexpr int numPhases = ModelTraits::numPhases();
-        static constexpr int numComponents = ModelTraits::numComponents();
-    };
-
 public:
+    //! export the interaction volume types
+    using PrimaryInteractionVolume = typename GFVC::PrimaryInteractionVolume;
+    using SecondaryInteractionVolume = typename GFVC::SecondaryInteractionVolume;
+
     //! export the data handle types used
-    using PrimaryIvDataHandle = InteractionVolumeDataHandle< PrimaryMatVecTraits, PhysicsTraits >;
-    using SecondaryIvDataHandle = InteractionVolumeDataHandle< SecondaryMatVecTraits, PhysicsTraits >;
+    using PrimaryIvDataHandle = typename GFVC::PrimaryIvDataHandle;
+    using SecondaryIvDataHandle = typename GFVC::SecondaryIvDataHandle;
+
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
+    //! export the flux variable cache filler type
+    using FluxVariablesCacheFiller = typename GFVC::FluxVariablesCacheFiller;
+
+    //! make it possible to query if caching is enabled
+    static constexpr bool cachingEnabled = false;
+
+    //! export the type of the grid flux variables
+    using GridFluxVariablesCache = GFVC;
 
     CCMpfaElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
@@ -155,7 +148,8 @@ public:
      * \note the fvGeometry is assumed to be bound to the same element
      * \note this function has to be called prior to flux calculations on the element.
      */
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars)
     {
@@ -169,7 +163,8 @@ public:
      * \note the fvGeometry is assumed to be bound to the same element
      * \note this function has to be called prior to flux calculations on the element.
      */
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars)
     {
@@ -201,10 +196,8 @@ public:
         // We need to avoid reallocation because in the caches we store pointers to the data handles.
         // Default -> each facet has two neighbors (local adaption) and all scvfs belongs to different ivs.
         // If you want to use higher local differences change the parameter below.
-        // TODO should this be a property? Statically allocated memory might be an issue for local adaptivity in general
-        static const std::size_t maxDiff = getParamFromGroup<std::size_t>(GET_PROP_VALUE(TypeTag, ModelParameterGroup),
-                                                                          "Grid.MaxLocalElementLevelDifference", 2);
-        const auto numIvEstimate = FVElementGeometry::maxNumElementScvfs*maxDiff;
+        constexpr auto numIvEstimate = FVElementGeometry::maxNumElementScvfs
+                                       * GridFluxVariablesCache::Traits::maxLocalElementLevelDifference();
         primaryInteractionVolumes_.reserve(numIvEstimate);
         secondaryInteractionVolumes_.reserve(numIvEstimate);
         primaryIvDataHandles_.reserve(numIvEstimate);
@@ -242,10 +235,11 @@ public:
      * \note the fvGeometry is assumed to be bound to the same element
      * \note this function has to be called prior to flux calculations on this scvf.
      */
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf)
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf)
     {
         // For mpfa schemes we will have to prepare the caches of all
         // scvfs that are embedded in the interaction volumes this scvf is embedded
@@ -256,7 +250,8 @@ public:
      * \brief Update the transmissibilities if the volume variables have changed
      * \note Results in undefined behaviour if called before bind() or with a different element
      */
-    void update(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void update(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                 const FVElementGeometry& fvGeometry,
                 const ElementVolumeVariables& elemVolVars)
     {
@@ -298,19 +293,21 @@ public:
     }
 
     //! access operators in the case of no caching
+    template<class SubControlVolumeFace, typename std::enable_if_t<!std::is_integral<SubControlVolumeFace>::value, int> = 0>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; }
 
     //! access operators in the case of no caching
-    const FluxVariablesCache& operator [](const GridIndexType scvfIdx) const
+    const FluxVariablesCache& operator [](const std::size_t scvfIdx) const
     { return fluxVarsCache_[getLocalScvfIdx_(scvfIdx)]; }
 
     //! access operators in the case of no caching
+    template<class SubControlVolumeFace, typename std::enable_if_t<!std::is_integral<SubControlVolumeFace>::value, int> = 0>
     FluxVariablesCache& operator [](const SubControlVolumeFace& scvf)
     { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; }
 
     //! access operators in the case of no caching
-    FluxVariablesCache& operator [](const GridIndexType scvfIdx)
+    FluxVariablesCache& operator [](const std::size_t scvfIdx)
     { return fluxVarsCache_[getLocalScvfIdx_(scvfIdx)]; }
 
     //! access to the stored interaction volumes
@@ -373,7 +370,7 @@ private:
 
     // the local flux vars caches and corresponding indices
     std::vector<FluxVariablesCache> fluxVarsCache_;
-    std::vector<GridIndexType> globalScvfIndices_;
+    std::vector<std::size_t> globalScvfIndices_;
 
     // stored interaction volumes and handles
     std::vector<PrimaryInteractionVolume> primaryInteractionVolumes_;
diff --git a/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh b/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh
index 2bf347145345dcf4a709aa453a71a82586cd5b9b..4e8a7e37c036aa19bc9c56b80513c9e537517a55 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/fickslaw.hh b/dumux/discretization/cellcentered/mpfa/fickslaw.hh
index c9e4bd9b76ec521ef754284d1bd95c7211e4ca02..d0833afe37058e65f0d336594aa8d099e4d043b6 100644
--- a/dumux/discretization/cellcentered/mpfa/fickslaw.hh
+++ b/dumux/discretization/cellcentered/mpfa/fickslaw.hh
@@ -50,8 +50,8 @@ class FicksLawImplementation<TypeTag, DiscretizationMethod::ccmpfa>
     using FVElementGeometry = typename FVGridGeometry::LocalView;
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using BalanceEqOpts = typename GET_PROP_TYPE(TypeTag, BalanceEqOpts);
 
diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh
index ef4db7ff552b04dbd42a6a4b80eca2bf91653a0c..f5e47b57867a2ed2eb30b8c18bf727cb9a3d98d8 100644
--- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh
+++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh
@@ -51,8 +51,8 @@ class CCMpfaFluxVariablesCacheFiller
     using FVElementGeometry = typename FVGridGeometry::LocalView;
     using MpfaHelper = typename FVGridGeometry::MpfaHelper;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
 
     using PrimaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
diff --git a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh
index 5adfe2f6b4eaa592cc1f48cc2f8d84eee99a878a..2af871a1b80dbbc680bd94cc6ec3b9347a0f7c59 100644
--- a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh
+++ b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh
@@ -53,8 +53,8 @@ class FouriersLawImplementation<TypeTag, DiscretizationMethod::ccmpfa>
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FVElementGeometry = typename FVGridGeometry::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
 
diff --git a/dumux/discretization/cellcentered/mpfa/gridfluxvariablescache.hh b/dumux/discretization/cellcentered/mpfa/gridfluxvariablescache.hh
index 21d8069e744b24633945ccbe6b88c0d755500e33..821f33abd8201ba95a7bf3b0d3b5a553fddef9c2 100644
--- a/dumux/discretization/cellcentered/mpfa/gridfluxvariablescache.hh
+++ b/dumux/discretization/cellcentered/mpfa/gridfluxvariablescache.hh
@@ -24,21 +24,64 @@
 #ifndef DUMUX_DISCRETIZATION_CCMPFA_GRID_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_CCMPFA_GRID_FLUXVARSCACHE_HH
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh>
-#include <dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh>
-
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
+#include <dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh>
 
 namespace Dumux {
 
+/*!
+ * \ingroup CCMpfaDiscretization
+ * \brief Data handle physics traits
+ */
+template<class ModelTraits>
+struct IvDataHandlePhysicsTraits
+{
+    static constexpr bool enableAdvection = ModelTraits::enableAdvection();
+    static constexpr bool enableMolecularDiffusion = ModelTraits::enableMolecularDiffusion();
+    static constexpr bool enableHeatConduction = ModelTraits::enableEnergyBalance();
+
+    static constexpr int numPhases = ModelTraits::numPhases();
+    static constexpr int numComponents = ModelTraits::numComponents();
+};
+
+/*!
+ * \ingroup CCMpfaDiscretization
+ * \brief Data handle physics traits
+ */
+template<class P,
+         class FVC, class FVCF,
+         class PIV, class SIV,
+         class PDH, class SDH>
+struct CCMpfaDefaultGridFluxVariablesCacheTraits
+{
+    using Problem = P;
+    using FluxVariablesCache = FVC;
+    using FluxVariablesCacheFiller = FVCF;
+
+    using PrimaryInteractionVolume = PIV;
+    using SecondaryInteractionVolume = SIV;
+    using PrimaryIvDataHandle = PDH;
+    using SecondaryIvDataHandle = SDH;
+
+    template<class GridFluxVariablesCache, bool cachingEnabled>
+    using LocalView = CCMpfaElementFluxVariablesCache<GridFluxVariablesCache, cachingEnabled>;
+
+    // Reserve memory (over-) estimate for interaction volumes and corresponding data.
+    // The overestimate doesn't hurt as we are not in a memory-limited configuration.
+    // We need to avoid reallocation because in the caches we store pointers to the data handles.
+    // Default -> each facet has two neighbors (local adaption) and all scvfs belongs to different ivs.
+    // If you want to use higher local differences change the parameter below.
+    static constexpr std::size_t maxLocalElementLevelDifference()
+    { return 2; };
+};
+
 /*!
  * \ingroup CCMpfaDiscretization
  * \brief Flux variable caches on a gridview
  * \note The class is specialized for a version with and without grid caching
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class Traits, bool cachingEnabled>
 class CCMpfaGridFluxVariablesCache;
 
 /*!
@@ -46,55 +89,40 @@ class CCMpfaGridFluxVariablesCache;
  * \brief Flux variable caches on a gridview with grid caching enabled
  * \note The flux caches of the gridview are stored which is memory intensive but faster
  */
-template<class TypeTag>
-class CCMpfaGridFluxVariablesCache<TypeTag, true>
+template<class TheTraits>
+class CCMpfaGridFluxVariablesCache<TheTraits, true>
 {
-    using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits);
-    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 IndexType = typename GridView::IndexSet::IndexType;
-
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-
-    using FluxVariablesCacheFiller = CCMpfaFluxVariablesCacheFiller<TypeTag>;
-    using PrimaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
-    using PrimaryMatVecTraits = typename PrimaryInteractionVolume::Traits::MatVecTraits;
-    using SecondaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, SecondaryInteractionVolume);
-    using SecondaryMatVecTraits = typename SecondaryInteractionVolume::Traits::MatVecTraits;
-
-    //! physics traits class to define the data handles
-    struct PhysicsTraits
-    {
-        static constexpr bool enableAdvection = ModelTraits::enableAdvection();
-        static constexpr bool enableMolecularDiffusion = ModelTraits::enableMolecularDiffusion();
-        static constexpr bool enableHeatConduction = ModelTraits::enableEnergyBalance();
+    using Problem = typename TheTraits::Problem;
+    using ThisType = CCMpfaGridFluxVariablesCache<TheTraits, true>;
+public:
+    //! export the Traits
+    using Traits = TheTraits;
 
-        static constexpr int numPhases = ModelTraits::numPhases();
-        static constexpr int numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents();
-    };
+    //! export the interaction volume types
+    using PrimaryInteractionVolume = typename Traits::PrimaryInteractionVolume;
+    using SecondaryInteractionVolume = typename Traits::SecondaryInteractionVolume;
 
-public:
-    // export the data handle types used
-    using PrimaryIvDataHandle = InteractionVolumeDataHandle< PrimaryMatVecTraits, PhysicsTraits >;
-    using SecondaryIvDataHandle = InteractionVolumeDataHandle< SecondaryMatVecTraits, PhysicsTraits >;
+    //! export the data handle types used
+    using PrimaryIvDataHandle = typename Traits::PrimaryIvDataHandle;
+    using SecondaryIvDataHandle = typename Traits::SecondaryIvDataHandle;
 
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
+
+    //! export the flux variable cache filler type
+    using FluxVariablesCacheFiller = typename Traits::FluxVariablesCacheFiller;
 
     //! 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>;
+
     //! The constructor
     CCMpfaGridFluxVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
 
     //! When global caching is enabled, precompute transmissibilities for all scv faces
+    template<class FVGridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry,
                 const GridVolumeVariables& gridVolVars,
                 const SolutionVector& sol,
@@ -144,7 +172,8 @@ public:
         }
     }
 
-    void updateElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void updateElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                        const FVElementGeometry& fvGeometry,
                        const ElementVolumeVariables& elemVolVars)
     {
@@ -190,10 +219,12 @@ public:
     }
 
     //! access operators in the case of caching
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return fluxVarsCache_[scvf.index()]; }
 
     //! access operators in the case of caching
+    template<class SubControlVolumeFace>
     FluxVariablesCache& operator [](const SubControlVolumeFace& scvf)
     { return fluxVarsCache_[scvf.index()]; }
 
@@ -258,40 +289,48 @@ private:
  * \ingroup CCMpfaDiscretization
  * \brief Flux variable caches on a gridview with grid caching disabled
  */
-template<class TypeTag>
-class CCMpfaGridFluxVariablesCache<TypeTag, false>
+template<class TheTraits>
+class CCMpfaGridFluxVariablesCache<TheTraits, false>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-
+    using Problem = typename TheTraits::Problem;
+    using ThisType = CCMpfaGridFluxVariablesCache<TheTraits, false>;
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the Traits
+    using Traits = TheTraits;
+
+    //! export the interaction volume types
+    using PrimaryInteractionVolume = typename Traits::PrimaryInteractionVolume;
+    using SecondaryInteractionVolume = typename Traits::SecondaryInteractionVolume;
+
+    //! export the data handle types used
+    using PrimaryIvDataHandle = typename Traits::PrimaryIvDataHandle;
+    using SecondaryIvDataHandle = typename Traits::SecondaryIvDataHandle;
+
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
+
+    //! export the flux variable cache filler type
+    using FluxVariablesCacheFiller = typename Traits::FluxVariablesCacheFiller;
 
     //! make it possible to query if caching is enabled
     static constexpr bool cachingEnabled = false;
 
-    //! export the data handle types used by the local view
-    using PrimaryIvDataHandle = typename LocalView::PrimaryIvDataHandle;
-    using SecondaryIvDataHandle = typename LocalView::SecondaryIvDataHandle;
+    //! export the type of the local view
+    using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
 
     //! The constructor
     CCMpfaGridFluxVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
 
     //! When global flux variables caching is disabled, we don't need to update the cache
+    template<class FVGridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry,
                 const GridVolumeVariables& gridVolVars,
                 const SolutionVector& sol,
                 bool forceUpdate = false) {}
 
     //! When global flux variables caching is disabled, we don't need to update the cache
-    void updateElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void updateElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                        const FVElementGeometry& fvGeometry,
                        const ElementVolumeVariables& elemVolVars) {}
 
diff --git a/dumux/discretization/cellcentered/mpfa/gridvolumevariables.hh b/dumux/discretization/cellcentered/mpfa/gridvolumevariables.hh
new file mode 100644
index 0000000000000000000000000000000000000000..cff206c0ba7d4a86d3829a5d9203c093ac831bc9
--- /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 44e093eea611a8850f36373fca6438db4d294097..eaae8dab1c04cab18a882ccb77ca7f62e723806d 100644
--- a/dumux/discretization/cellcentered/mpfa/properties.hh
+++ b/dumux/discretization/cellcentered/mpfa/properties.hh
@@ -34,24 +34,23 @@
 
 #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/interactionvolumedatahandle.hh>
+#include <dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.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,24 +98,43 @@ public:
     using type = CCMpfaFVGridGeometry<GridView, Traits, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>;
 };
 
-//! The global flux variables cache vector class
-SET_TYPE_PROP(CCMpfaModel,
-              GridFluxVariablesCache,
-              CCMpfaGridFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
+//! 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 grid volume variables vector class
+SET_PROP(CCMpfaModel, GridFluxVariablesCache)
+{
+private:
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
+    using FluxVariablesCacheFiller = CCMpfaFluxVariablesCacheFiller<TypeTag>;
 
-//! The local flux variables cache vector class
-SET_TYPE_PROP(CCMpfaModel,
-              ElementFluxVariablesCache,
-              CCMpfaElementFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
+    using PrimaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
+    using SecondaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, SecondaryInteractionVolume);
 
+    using PhysicsTraits = IvDataHandlePhysicsTraits<typename GET_PROP_TYPE(TypeTag, ModelTraits)>;
+    using PrimaryMatVecTraits = typename PrimaryInteractionVolume::Traits::MatVecTraits;
+    using SecondaryMatVecTraits = typename SecondaryInteractionVolume::Traits::MatVecTraits;
 
-//! The global previous volume variables vector class
-SET_TYPE_PROP(CCMpfaModel,
-              ElementVolumeVariables,
-              CCMpfaElementVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
+    using PrimaryIvDataHandle = InteractionVolumeDataHandle<PrimaryMatVecTraits, PhysicsTraits>;
+    using SecondaryIvDataHandle = InteractionVolumeDataHandle<SecondaryMatVecTraits, PhysicsTraits>;
 
-//! The global current volume variables vector class
-SET_TYPE_PROP(CCMpfaModel, GridVolumeVariables, CCGridVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
+    using Traits = CCMpfaDefaultGridFluxVariablesCacheTraits<Problem,
+                                                             FluxVariablesCache, FluxVariablesCacheFiller,
+                                                             PrimaryInteractionVolume, SecondaryInteractionVolume,
+                                                             PrimaryIvDataHandle, SecondaryIvDataHandle>;
+public:
+    using type = CCMpfaGridFluxVariablesCache<Traits, enableCache>;
+};
 
 //! Set the default for the ElementBoundaryTypes
 SET_TYPE_PROP(CCMpfaModel, ElementBoundaryTypes, CCElementBoundaryTypes);
diff --git a/dumux/discretization/cellcentered/tpfa/darcyslaw.hh b/dumux/discretization/cellcentered/tpfa/darcyslaw.hh
index 71b85b6743b5bfe80a972547a937ec19401e458a..cd9c5bcb628baff28719f5556676e6bcb8d35c8c 100644
--- a/dumux/discretization/cellcentered/tpfa/darcyslaw.hh
+++ b/dumux/discretization/cellcentered/tpfa/darcyslaw.hh
@@ -61,7 +61,7 @@ class TpfaDarcysLawCacheFiller
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using Element = typename GET_PROP_TYPE(TypeTag, GridView)::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
 
 public:
@@ -93,7 +93,7 @@ class TpfaDarcysLawCache
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using Element = typename GET_PROP_TYPE(TypeTag, GridView)::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
 
 public:
     using Filler = TpfaDarcysLawCacheFiller<TypeTag>;
@@ -128,9 +128,9 @@ class CCTpfaDarcysLaw<TypeTag, /*isNetwork*/ false>
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams);
     using Element = typename GridView::template Codim<0>::Entity;
@@ -284,9 +284,9 @@ class CCTpfaDarcysLaw<TypeTag, /*isNetwork*/ true>
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams);
     using Element = typename GridView::template Codim<0>::Entity;
diff --git a/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh b/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh
index 353d603462bcafe1133bf163eb07d2a73f508cac..b93bb79ad52f8bd252c339fa0032262aa49c8cac 100644
--- a/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh
+++ b/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh
@@ -24,12 +24,10 @@
 #ifndef DUMUX_DISCRETIZATION_CCTPFA_ELEMENT_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_CCTPFA_ELEMENT_FLUXVARSCACHE_HH
 
+#include <algorithm>
 #include <dune/common/exceptions.hh>
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup CCTpfaDiscretization
@@ -39,48 +37,51 @@ namespace Dumux
  * GridFluxVariablesCache which is memory intensive but faster. For caching disabled the
  * flux caches are locally computed for each element whenever needed.
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class GFVC, bool cachingEnabled>
 class CCTpfaElementFluxVariablesCache;
 
 /*!
  * \ingroup CCTpfaDiscretization
  * \brief The flux variables caches for an element with caching enabled
  */
-template<class TypeTag>
-class CCTpfaElementFluxVariablesCache<TypeTag, true>
+template<class GFVC>
+class CCTpfaElementFluxVariablesCache<GFVC, true>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-
 public:
+    //! export the type of the grid flux variables cache
+    using GridFluxVariablesCache = GFVC;
+
+    //! export the type of the flux variables cache
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
+    //! export the type of the flux variables cache filler
+    using FluxVariablesCacheFiller = typename GFVC::FluxVariablesCacheFiller;
+
     CCTpfaElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf) {}
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void update(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void update(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                 const FVElementGeometry& fvGeometry,
                 const ElementVolumeVariables& elemVolVars)
     {
@@ -88,6 +89,7 @@ public:
     }
 
     //! access operators in the case of caching
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return gridFluxVarsCache()[scvf]; }
 
@@ -103,21 +105,19 @@ private:
  * \ingroup CCTpfaDiscretization
  * \brief The flux variables caches for an element with caching disabled
  */
-template<class TypeTag>
-class CCTpfaElementFluxVariablesCache<TypeTag, false>
+template<class GFVC>
+class CCTpfaElementFluxVariablesCache<GFVC, false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using FluxVariablesCacheFiller = CCTpfaFluxVariablesCacheFiller<TypeTag>;
-
 public:
+    //! export the type of the grid flux variables cache
+    using GridFluxVariablesCache = GFVC;
+
+    //! export the type of the flux variables cache
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
+    //! export the type of the flux variables cache filler
+    using FluxVariablesCacheFiller = typename GFVC::FluxVariablesCacheFiller;
+
     CCTpfaElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
 
@@ -126,7 +126,8 @@ public:
      * \note the fvGeometry is assumed to be bound to the same element
      * \note this function has to be called prior to flux calculations on the element.
      */
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars)
     {
@@ -138,7 +139,7 @@ public:
         // instantiate helper class to fill the caches
         FluxVariablesCacheFiller filler(gridFluxVarsCache().problem());
 
-        IndexType localScvfIdx = 0;
+        std::size_t localScvfIdx = 0;
         // fill the containers
         for (auto&& scvf : scvfs(fvGeometry))
         {
@@ -153,7 +154,8 @@ public:
      * \note the fvGeometry is assumed to be bound to the same element
      * \note this function has to be called prior to flux calculations on the element.
      */
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars)
     {
@@ -201,10 +203,11 @@ public:
      * \note the fvGeometry is assumed to be bound to the same element
      * \note this function has to be called prior to flux calculations on the element.
      */
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf)
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf)
     {
         fluxVarsCache_.resize(1);
         globalScvfIndices_.resize(1);
@@ -220,7 +223,8 @@ public:
      * \brief Update the transmissibilities if the volume variables have changed
      * \note Results in undefined behaviour if called before bind() or with a different element
      */
-    void update(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void update(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                 const FVElementGeometry& fvGeometry,
                 const ElementVolumeVariables& elemVolVars)
     {
@@ -248,10 +252,12 @@ public:
     }
 
     //! access operators in the case of no caching
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; }
 
     //! access operators in the case of no caching
+    template<class SubControlVolumeFace>
     FluxVariablesCache& operator [](const SubControlVolumeFace& scvf)
     { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; }
 
@@ -271,7 +277,7 @@ private:
     }
 
     std::vector<FluxVariablesCache> fluxVarsCache_;
-    std::vector<IndexType> globalScvfIndices_;
+    std::vector<std::size_t> globalScvfIndices_;
 };
 
 } // end namespace Dumux
diff --git a/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh b/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh
index db5dd01d8438c2c8e90b201e72594abc73071dd7..f28036fb4807a7fcbd1dc6c3d6e549e16ce4fa9f 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/fickslaw.hh b/dumux/discretization/cellcentered/tpfa/fickslaw.hh
index 3710b9b64a051d3b45f397cc18e6b41734093a65..d8451a589b963357e47514e911e09b77cf3348d5 100644
--- a/dumux/discretization/cellcentered/tpfa/fickslaw.hh
+++ b/dumux/discretization/cellcentered/tpfa/fickslaw.hh
@@ -52,9 +52,9 @@ class FicksLawImplementation<TypeTag, DiscretizationMethod::cctpfa>
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using IndexType = typename GridView::IndexSet::IndexType;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using BalanceEqOpts = typename GET_PROP_TYPE(TypeTag, BalanceEqOpts);
diff --git a/dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh
index 4fc0c8ed5ddae144ba61690ed7d5de8a4e4bb1b9..69b5b024ff90a8d78d4f04e5338371fef1e262d5 100644
--- a/dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh
+++ b/dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh
@@ -27,8 +27,7 @@
 #include <dumux/common/properties.hh>
 #include <dumux/discretization/methods.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
 * \ingroup CCTpfaDiscretization
@@ -43,7 +42,7 @@ class CCTpfaFluxVariablesCacheFiller
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
 
     using Element = typename GridView::template Codim<0>::Entity;
diff --git a/dumux/discretization/cellcentered/tpfa/fourierslaw.hh b/dumux/discretization/cellcentered/tpfa/fourierslaw.hh
index bd76d9c86bcfa5acd37872e12fa54be91a017444..425114985dd4fcdff00e038ba9eb1a13af6108a2 100644
--- a/dumux/discretization/cellcentered/tpfa/fourierslaw.hh
+++ b/dumux/discretization/cellcentered/tpfa/fourierslaw.hh
@@ -51,9 +51,9 @@ class FouriersLawImplementation<TypeTag, DiscretizationMethod::cctpfa>
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using IndexType = typename GridView::IndexSet::IndexType;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
 
     static const int dim = GridView::dimension;
diff --git a/dumux/discretization/cellcentered/tpfa/gridfluxvariablescache.hh b/dumux/discretization/cellcentered/tpfa/gridfluxvariablescache.hh
index dd599456f60d98624dfd42b93c8a18d87302e1f0..6eef4a02c0ac12204bdaacf40b37fdbc66e08455 100644
--- a/dumux/discretization/cellcentered/tpfa/gridfluxvariablescache.hh
+++ b/dumux/discretization/cellcentered/tpfa/gridfluxvariablescache.hh
@@ -24,20 +24,37 @@
 #ifndef DUMUX_DISCRETIZATION_CCTPFA_GRID_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_CCTPFA_GRID_FLUXVARSCACHE_HH
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh>
-
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
+#include <dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh>
 
 namespace Dumux {
 
+/*!
+ * \ingroup CCTpfaDiscretization
+ * \brief Flux variable caches traits
+ */
+template<class P, class FVC, class FVCF>
+struct CCTpfaDefaultGridFVCTraits
+{
+    using Problem = P;
+    using FluxVariablesCache = FVC;
+    using FluxVariablesCacheFiller = FVCF;
+
+    template<class GridFluxVariablesCache, bool cachingEnabled>
+    using LocalView = CCTpfaElementFluxVariablesCache<GridFluxVariablesCache, cachingEnabled>;
+};
+
 /*!
  * \ingroup CCTpfaDiscretization
  * \brief Flux variable caches on a gridview
  * \note The class is specialized for a version with and without grid caching
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class Problem,
+         class FluxVariablesCache,
+         class FluxVariablesCacheFiller,
+         bool EnableGridFluxVariablesCache = false,
+         class Traits = CCTpfaDefaultGridFVCTraits<Problem, FluxVariablesCache, FluxVariablesCacheFiller> >
 class CCTpfaGridFluxVariablesCache;
 
 /*!
@@ -45,33 +62,30 @@ class CCTpfaGridFluxVariablesCache;
  * \brief Flux variable caches on a gridview with grid caching enabled
  * \note The flux caches of the gridview are stored which is memory intensive but faster
  */
-template<class TypeTag>
-class CCTpfaGridFluxVariablesCache<TypeTag, true>
+template<class P, class FVC, class FVCF, class Traits>
+class CCTpfaGridFluxVariablesCache<P, FVC, FVCF, true, Traits>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using FluxVariablesCacheFiller = CCTpfaFluxVariablesCacheFiller<TypeTag>;
+    using Problem = typename Traits::Problem;
+    using ThisType = CCTpfaGridFluxVariablesCache<P, FVC, FVCF, true, Traits>;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
+
+    //! export the flux variable cache filler type
+    using FluxVariablesCacheFiller = typename Traits::FluxVariablesCacheFiller;
 
     //! 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>;
+
     // The constructor
     CCTpfaGridFluxVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
 
     // When global caching is enabled, precompute transmissibilities and stencils for all the scv faces
+    template<class FVGridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry,
                 const GridVolumeVariables& gridVolVars,
                 const SolutionVector& sol,
@@ -101,7 +115,8 @@ public:
         }
     }
 
-    void updateElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void updateElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                        const FVElementGeometry& fvGeometry,
                        const ElementVolumeVariables& elemVolVars)
     {
@@ -130,9 +145,11 @@ public:
     }
 
     // access operators in the case of caching
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return fluxVarsCache_[scvf.index()]; }
 
+    template<class SubControlVolumeFace>
     FluxVariablesCache& operator [](const SubControlVolumeFace& scvf)
     { return fluxVarsCache_[scvf.index()]; }
 
@@ -143,43 +160,45 @@ private:
     const Problem* problemPtr_;
 
     std::vector<FluxVariablesCache> fluxVarsCache_;
-    std::vector<IndexType> globalScvfIndices_;
+    std::vector<std::size_t> globalScvfIndices_;
 };
 
 /*!
  * \ingroup CCTpfaDiscretization
  * \brief Flux variable caches on a gridview with grid caching disabled
  */
-template<class TypeTag>
-class CCTpfaGridFluxVariablesCache<TypeTag, false>
+template<class P, class FVC, class FVCF, class Traits>
+class CCTpfaGridFluxVariablesCache<P, FVC, FVCF, false, Traits>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using Problem = typename Traits::Problem;
+    using ThisType = CCTpfaGridFluxVariablesCache<P, FVC, FVCF, false, Traits>;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
+
+    //! export the flux variable cache filler type
+    using FluxVariablesCacheFiller = typename Traits::FluxVariablesCacheFiller;
 
     //! 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>;
+
     // The constructor
     CCTpfaGridFluxVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
 
     //! When global flux variables caching is disabled, we don't need to update the cache
+    template<class FVGridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry,
                 const GridVolumeVariables& gridVolVars,
                 const SolutionVector& sol,
                 bool forceUpdate = false) {}
 
     //! When global flux variables caching is disabled, we don't need to update the cache
-    void updateElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void updateElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                        const FVElementGeometry& fvGeometry,
                        const ElementVolumeVariables& elemVolVars) {}
 
diff --git a/dumux/discretization/cellcentered/tpfa/gridvolumevariables.hh b/dumux/discretization/cellcentered/tpfa/gridvolumevariables.hh
new file mode 100644
index 0000000000000000000000000000000000000000..d85279fbf2b478b99de0d8a825f9ac76fac04bcd
--- /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/maxwellstefanslaw.hh b/dumux/discretization/cellcentered/tpfa/maxwellstefanslaw.hh
index 86e347b6acec29a1576a02fbad9f97a09cacfa0f..3fdfefc16ff86e2e6c601b830266e688b1a8603e 100644
--- a/dumux/discretization/cellcentered/tpfa/maxwellstefanslaw.hh
+++ b/dumux/discretization/cellcentered/tpfa/maxwellstefanslaw.hh
@@ -54,9 +54,9 @@ class MaxwellStefansLawImplementation<TypeTag, DiscretizationMethod::cctpfa >
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using IndexType = typename GridView::IndexSet::IndexType;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
diff --git a/dumux/discretization/cellcentered/tpfa/properties.hh b/dumux/discretization/cellcentered/tpfa/properties.hh
index ffeced400b5521ff4dfbb5a0e9aca9d77c5323e8..901a21db8e5d2505e6aebb874fd929cb87953400 100644
--- a/dumux/discretization/cellcentered/tpfa/properties.hh
+++ b/dumux/discretization/cellcentered/tpfa/properties.hh
@@ -34,22 +34,17 @@
 #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/fluxvariablescachefiller.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,17 +58,28 @@ public:
     using type = CCTpfaFVGridGeometry<GridView, enableCache>;
 };
 
-//! 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 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 global current volume variables vector class
-SET_TYPE_PROP(CCTpfaModel, GridVolumeVariables, CCGridVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
+//! The grid flux variables cache vector class
+SET_PROP(CCTpfaModel, GridFluxVariablesCache)
+{
+private:
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
+    using FluxVariablesCacheFiller = CCTpfaFluxVariablesCacheFiller<TypeTag>;
+public:
+    using type = CCTpfaGridFluxVariablesCache<Problem, FluxVariablesCache, FluxVariablesCacheFiller, enableCache>;
+};
 
 //! 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 eb55e767e30f2426d7d97d88b17bb885e89ecc0e..1c9634fa98463ea6831dd5735010ec3e858bd9f6 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 87a797f5b5d7f984816a6aa083b9687b0c931d78..230f466f6957b9984103466a3d45413609093a5d 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/discretization/fluxvariablesbase.hh b/dumux/discretization/fluxvariablesbase.hh
index 12ffb50a7b7d508ac310ee304f3623e9f5944f0c..037e1e80315c07c8b9a2b3a796566e5e835f614b 100644
--- a/dumux/discretization/fluxvariablesbase.hh
+++ b/dumux/discretization/fluxvariablesbase.hh
@@ -30,21 +30,21 @@ namespace Dumux {
  * \ingroup Discretization
  * \brief Base class for the flux variables living on a sub control volume face
  *
- * \tparam TypeTag The type tag
+ * \tparam Problem the problem type to solve (for boundary conditions)
+ * \tparam FVElementGeometry the element geometry type
+ * \tparam ElementVolumeVariables the element volume variables type
+ * \tparam ElementFluxVariablesCache the element flux variables cache type
  */
-template<class TypeTag>
+template<class Problem,
+         class FVElementGeometry,
+         class ElementVolumeVariables,
+         class ElementFluxVariablesCache>
 class FluxVariablesBase
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using GridView = typename FVElementGeometry::FVGridGeometry::GridView;
     using Element = typename GridView::template Codim<0>::Entity;
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using Stencil = std::vector<IndexType>;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
+    using Stencil = std::vector<std::size_t>;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
 
 public:
 
diff --git a/dumux/discretization/staggered/elementfacevariables.hh b/dumux/discretization/staggered/elementfacevariables.hh
index 73f382057ec55c3e9981450e1ffbc023b04b76f9..79b26709c8508d72f1f7d822070408f56f8e0a4a 100644
--- a/dumux/discretization/staggered/elementfacevariables.hh
+++ b/dumux/discretization/staggered/elementfacevariables.hh
@@ -24,16 +24,15 @@
 #ifndef DUMUX_DISCRETIZATION_STAGGERED_ELEMENTFACEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_STAGGERED_ELEMENTFACEVARIABLES_HH
 
-#include <dumux/common/properties.hh>
+#include <algorithm>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup StaggeredDiscretization
  * \brief Base class for the face variables vector
  */
-template<class TypeTag, bool enableGridFaceVariablesCache>
+template<class GridFaceVariables, bool cachingEnabled>
 class StaggeredElementFaceVariables
 {};
 
@@ -41,42 +40,41 @@ class StaggeredElementFaceVariables
  * \ingroup StaggeredDiscretization
  * \brief Class for the face variables vector. Specialization for the case of storing the face variables globally.
  */
-template<class TypeTag>
-class StaggeredElementFaceVariables<TypeTag, /*enableGridFaceVariablesCache*/true>
+template<class GFV>
+class StaggeredElementFaceVariables<GFV, /*cachingEnabled*/true>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using GridFaceVariables = typename GET_PROP_TYPE(TypeTag, GridFaceVariables);
-    using FaceVariables = typename GET_PROP_TYPE(TypeTag, FaceVariables);
-    using IndexType = typename GridView::IndexSet::IndexType;
-
 public:
+    //! export type of the grid volume variables
+    using GridFaceVariables = GFV;
+
+    //! export type of the volume variables
+    using FaceVariables = typename GridFaceVariables::FaceVariables;
 
     StaggeredElementFaceVariables(const GridFaceVariables& gridFaceVariables) : gridFaceVariablesPtr_(&gridFaceVariables) {}
 
     //! operator for the access with an scvf
+    template<class SubControlVolumeFace, typename std::enable_if_t<!std::is_integral<SubControlVolumeFace>::value, int> = 0>
     const FaceVariables& operator [](const SubControlVolumeFace& scvf) const
     { return gridFaceVariables().faceVars(scvf.index()); }
 
     //! operator for the access with an index
     //! needed for cc methods for the access to the boundary volume variables
-    const FaceVariables& operator [](const IndexType scvfIdx) const
+    const FaceVariables& operator [](const std::size_t scvfIdx) const
     { return gridFaceVariables().faceVars(scvfIdx); }
 
 
     //! For compatibility reasons with the case of not storing the face vars.
     //! function to be called before assembling an element, preparing the vol vars within the 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)
     {}
 
     //! Binding of an element, prepares only the face variables of the element
     //! specialization for Staggered models
-    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)
     {}
@@ -95,67 +93,67 @@ private:
  * \ingroup StaggeredDiscretization
  * \brief Class for the face variables vector. Specialization for the case of not storing the face variables globally.
  */
-template<class TypeTag>
-class StaggeredElementFaceVariables<TypeTag, /*enableGridFaceVariablesCache*/false>
+template<class GFV>
+class StaggeredElementFaceVariables<GFV, /*cachingEnabled*/false>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using GridFaceVariables = typename GET_PROP_TYPE(TypeTag, GridFaceVariables);
-    using FaceVariables = typename GET_PROP_TYPE(TypeTag, FaceVariables);
-    using IndexType = typename GridView::IndexSet::IndexType;
-
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
 public:
+    //! export type of the grid volume variables
+    using GridFaceVariables = GFV;
+
+    //! export type of the volume variables
+    using FaceVariables = typename GridFaceVariables::FaceVariables;
 
     StaggeredElementFaceVariables(const GridFaceVariables& globalFacesVars) : gridFaceVariablesPtr_(&globalFacesVars) {}
 
     //! const operator for the access with an scvf
+    template<class SubControlVolumeFace, typename std::enable_if_t<!std::is_integral<SubControlVolumeFace>::value, int> = 0>
     const FaceVariables& operator [](const SubControlVolumeFace& scvf) const
     { return faceVariables_[scvf.localFaceIdx()]; }
 
     //! const operator for the access with an index
-    const FaceVariables& operator [](const IndexType scvfIdx) const
+    const FaceVariables& operator [](const std::size_t scvfIdx) const
     { return faceVariables_[getLocalIdx_(scvfIdx)]; }
 
     //! operator for the access with an scvf
+    template<class SubControlVolumeFace, typename std::enable_if_t<!std::is_integral<SubControlVolumeFace>::value, int> = 0>
     FaceVariables& operator [](const SubControlVolumeFace& scvf)
     { return faceVariables_[scvf.localFaceIdx()]; }
 
     // operator for the access with an index
-    FaceVariables& operator [](const IndexType scvfIdx)
+    FaceVariables& operator [](const std::size_t scvfIdx)
     { return faceVariables_[getLocalIdx_(scvfIdx)]; }
 
     //! For compatibility reasons with the case of not storing the vol vars.
     //! function to be called before assembling an element, preparing the vol vars within the 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)
     {
         faceVariables_.resize(fvGeometry.numScvf());
         faceVarIndices_.resize(fvGeometry.numScvf());
 
+        constexpr auto faceIdx = FVElementGeometry::FVGridGeometry::faceIdx();
+
         for(auto&& scvf : scvfs(fvGeometry))
         {
-            faceVariables_[scvf.localFaceIdx()].update(sol[faceIdx], GridFaceVariables().problem(), element, fvGeometry, scvf);
+            faceVariables_[scvf.localFaceIdx()].update(sol[faceIdx], gridFaceVariables().problem(), element, fvGeometry, scvf);
             faceVarIndices_[scvf.localFaceIdx()] = scvf.index();
         }
     }
 
     //! Binding of an element, prepares only the face variables of the element
     //! specialization for Staggered models
-    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)
     {
         faceVariables_.resize(fvGeometry.numScvf());
         faceVarIndices_.resize(fvGeometry.numScvf());
 
+        constexpr auto faceIdx = FVElementGeometry::FVGridGeometry::faceIdx();
+
         for(auto&& scvf : scvfs(fvGeometry))
         {
             faceVariables_[scvf.localFaceIdx()].updateOwnFaceOnly(sol[faceIdx][scvf.dofIndex()]);
@@ -177,7 +175,7 @@ private:
     }
 
     const GridFaceVariables* gridFaceVariablesPtr_;
-    std::vector<IndexType> faceVarIndices_;
+    std::vector<std::size_t> faceVarIndices_;
     std::vector<FaceVariables> faceVariables_;
 };
 
diff --git a/dumux/discretization/staggered/elementfluxvariablescache.hh b/dumux/discretization/staggered/elementfluxvariablescache.hh
index eb77c9aac79d585bf48371cbc2101aa85a8da9f1..e0a5274ad4a8f12de1f4afbe867a06a2ddb3a689 100644
--- a/dumux/discretization/staggered/elementfluxvariablescache.hh
+++ b/dumux/discretization/staggered/elementfluxvariablescache.hh
@@ -24,16 +24,16 @@
 #ifndef DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_FLUXVARSCACHE_HH
 
-#include <dumux/common/properties.hh>
+#include <algorithm>
+#include <iterator>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup StaggeredDiscretization
  * \brief Base class for the stencil local flux variables cache for the staggered model
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class GridFluxVariablesCache, bool cachingEnabled>
 class StaggeredElementFluxVariablesCache;
 
 /*!
@@ -41,40 +41,40 @@ class StaggeredElementFluxVariablesCache;
  * \brief Class for the stencil local flux variables cache for the staggered model.
           Specialization for the case of storing the fluxvars cache globally.
  */
-template<class TypeTag>
-class StaggeredElementFluxVariablesCache<TypeTag, true>
+template<class GFVC>
+class StaggeredElementFluxVariablesCache<GFVC, true>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-
 public:
+    //! export the type of the grid flux variables cache
+    using GridFluxVariablesCache = GFVC;
+
+    //! export the type of the flux variables cache
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
     StaggeredElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars) {}
 
     //! Specialization for the global caching being enabled - do nothing here
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf) {}
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf) {}
 
     //! operators in the case of caching
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return (*gridFluxVarsCachePtr_)[scvf.index()]; }
 
@@ -91,26 +91,23 @@ private:
  * \brief Class for the stencil local flux variables cache for the staggered model.
           Specialization for the case of not storing the fluxvars cache globally.
  */
-template<class TypeTag>
-class StaggeredElementFluxVariablesCache<TypeTag, false>
+template<class GFVC>
+class StaggeredElementFluxVariablesCache<GFVC, false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using GridFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-
 public:
+    //! export the type of the grid flux variables cache
+    using GridFluxVariablesCache = GFVC;
+
+    //! export the type of the flux variables cache
+    using FluxVariablesCache = typename GFVC::FluxVariablesCache;
+
     StaggeredElementFluxVariablesCache(const GridFluxVariablesCache& global)
     : gridFluxVarsCachePtr_(&global) {}
 
     //! This function has to be called prior to flux calculations on the element.
     //! Prepares the transmissibilities of the scv faces in an element. The FvGeometry is assumed to be bound.
-    void bindElement(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindElement(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                      const FVElementGeometry& fvGeometry,
                      const ElementVolumeVariables& elemVolVars)
     {
@@ -118,7 +115,7 @@ public:
         const auto numScvf = fvGeometry.numScvf();
         fluxVarsCache_.resize(numScvf);
         globalScvfIndices_.resize(numScvf);
-        IndexType localScvfIdx = 0;
+        std::size_t localScvfIdx = 0;
 
         // fill the containers
         for (auto&& scvf : scvfs(fvGeometry))
@@ -131,7 +128,8 @@ public:
 
     //! This function is called by the StaggeredLocalResidual before flux calculations during assembly.
     //! Prepares the transmissibilities of the scv faces in the stencil. The FvGeometries are assumed to be bound.
-    void bind(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bind(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
               const FVElementGeometry& fvGeometry,
               const ElementVolumeVariables& elemVolVars)
     {
@@ -141,7 +139,7 @@ public:
 
         // find the number of scv faces that need to be prepared
         auto numScvf = fvGeometry.numScvf();
-        for (IndexType localIdxJ = 0; localIdxJ < numNeighbors; ++localIdxJ)
+        for (std::size_t localIdxJ = 0; localIdxJ < numNeighbors; ++localIdxJ)
         {
             const auto& fluxVarIndicesJ = gridFluxVarsCache().problem_().model().localJacobian().assemblyMap()[globalI][localIdxJ];
             numScvf += fluxVarIndicesJ.size();
@@ -150,7 +148,7 @@ public:
         // fill the containers with the data on the scv faces inside the actual element
         fluxVarsCache_.resize(numScvf);
         globalScvfIndices_.resize(numScvf);
-        IndexType localScvfIdx = 0;
+        std::size_t localScvfIdx = 0;
         for (auto&& scvf : scvfs(fvGeometry))
         {
             fluxVarsCache_[localScvfIdx].update(gridFluxVarsCache().problem_(), element, fvGeometry, elemVolVars, scvf);
@@ -159,7 +157,7 @@ public:
         }
 
         // add required data on the scv faces in the neighboring elements
-        for (IndexType localIdxJ = 0; localIdxJ < numNeighbors; ++localIdxJ)
+        for (std::size_t localIdxJ = 0; localIdxJ < numNeighbors; ++localIdxJ)
         {
             const auto& fluxVarIndicesJ = gridFluxVarsCache().problem_().model().localJacobian().assemblyMap()[globalI][localIdxJ];
             const auto elementJ = fvGeometry.fvGridGeometry().element(neighborStencil[localIdxJ]);
@@ -174,10 +172,11 @@ public:
         }
     }
 
-    void bindScvf(const Element& element,
+    template<class FVElementGeometry, class ElementVolumeVariables>
+    void bindScvf(const typename FVElementGeometry::FVGridGeometry::GridView::template Codim<0>::Entity& element,
                   const FVElementGeometry& fvGeometry,
                   const ElementVolumeVariables& elemVolVars,
-                  const SubControlVolumeFace& scvf)
+                  const typename FVElementGeometry::SubControlVolumeFace& scvf)
     {
         fluxVarsCache_.resize(1);
         globalScvfIndices_.resize(1);
@@ -187,9 +186,11 @@ public:
     }
 
     //! access operators in the case of no caching
+    template<class SubControlVolumeFace>
     const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const
     { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; }
 
+    template<class SubControlVolumeFace>
     FluxVariablesCache& operator [](const SubControlVolumeFace& scvf)
     { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; }
 
@@ -209,9 +210,9 @@ private:
     }
 
     std::vector<FluxVariablesCache> fluxVarsCache_;
-    std::vector<IndexType> globalScvfIndices_;
+    std::vector<std::size_t> globalScvfIndices_;
 };
 
-} // end namespace
+} // end namespace Dumux
 
 #endif
diff --git a/dumux/discretization/staggered/elementsolution.hh b/dumux/discretization/staggered/elementsolution.hh
index 29a3b87fd5bfa0946ffeeafb8d20b463b1904e8d..bbf02febef3db8ee0ee433a5062e71e33e0ceddd 100644
--- a/dumux/discretization/staggered/elementsolution.hh
+++ b/dumux/discretization/staggered/elementsolution.hh
@@ -38,9 +38,9 @@ using StaggeredElementSolution = Dune::BlockVector<PrimaryVariables>;
  * \brief  Make an element solution for staggered 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::staggered,
+-> std::enable_if_t<FVElementGeometry::FVGridGeometry::discMethod == DiscretizationMethod::staggered,
                     StaggeredElementSolution<PrimaryVariables>>
 {
     return StaggeredElementSolution<PrimaryVariables>({std::move(priVars)});
diff --git a/dumux/discretization/staggered/elementvolumevariables.hh b/dumux/discretization/staggered/elementvolumevariables.hh
index 276cddb74086ca31891a12f59a773c7e3ac99186..885a47a6363adf097c36d31e94e7987844b3a717 100644
--- a/dumux/discretization/staggered/elementvolumevariables.hh
+++ b/dumux/discretization/staggered/elementvolumevariables.hh
@@ -24,9 +24,9 @@
 #ifndef DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_VOLUMEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_VOLUMEVARIABLES_HH
 
+#include <algorithm>
+#include <iterator>
 #include <dune/common/exceptions.hh>
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/staggered/elementsolution.hh>
 
 namespace Dumux {
 
@@ -34,7 +34,7 @@ namespace Dumux {
  * \ingroup StaggeredDiscretization
  * \brief Base class for the element volume variables vector for the staggered model
  */
-template<class TypeTag, bool enableGridVolVarsCache>
+template<class GVV, bool cachingEnabled>
 class StaggeredElementVolumeVariables
 {};
 
@@ -43,46 +43,41 @@ class StaggeredElementVolumeVariables
  * \brief Class for the element volume variables vector for the staggered model.
           Specialization in case the volume variables are stored globally.
  */
-template<class TypeTag>
-class StaggeredElementVolumeVariables<TypeTag, /*enableGridVolVarsCache*/true>
+template<class GVV>
+class StaggeredElementVolumeVariables<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
     StaggeredElementVolumeVariables(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
     //! needed for Staggered methods for the access to the boundary volume variables
-    const VolumeVariables& operator [](const IndexType scvIdx) const
+    const VolumeVariables& operator [](const std::size_t scvIdx) const
     { return gridVolVars().volVars(scvIdx); }
 
     //! For compatibility reasons with the case of not storing the vol vars.
     //! function to be called before assembling an element, preparing the vol vars within the 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)
     {}
 
     //! function to prepare the vol vars within the 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)
     {}
@@ -101,32 +96,17 @@ private:
  * \brief Class for the element volume variables vector for the staggered model.
           Specialization in case the volume variables are not stored globally.
  */
-template<class TypeTag>
-class StaggeredElementVolumeVariables<TypeTag, /*enableGridVolVarsCache*/false>
+template<class GVV>
+class StaggeredElementVolumeVariables<GVV, /*cachingEnabled*/false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
-    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;
-
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
-    static constexpr auto numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
+    using Indices = typename GVV::Indices; //TODO: get them out of the volvars
 
 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
     StaggeredElementVolumeVariables(const GridVolumeVariables& gridVolVars)
@@ -134,7 +114,8 @@ public:
 
     //! Binding of an element, prepares the volume variables within the element stencil
     //! called by the local jacobian to prepare element assembly
-    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)
     {
@@ -144,6 +125,7 @@ public:
         const auto& fvGridGeometry = fvGeometry.fvGridGeometry();
         const auto globalI = fvGridGeometry.elementMapper().index(element);
         const auto map = fvGridGeometry.connectivityMap();
+        constexpr auto cellCenterIdx = FVElementGeometry::FVGridGeometry::cellCenterIdx();
         const auto& connectivityMapI = map(cellCenterIdx, cellCenterIdx, globalI);
         const auto numDofs = connectivityMapI.size();
 
@@ -154,6 +136,8 @@ public:
         volVarIndices_.resize(numDofs);
         int localIdx = 0;
 
+        using CellCenterPrimaryVariables = typename SolutionVector::value_type;
+
         // Update the volume variables of the element at hand and the neighboring elements
         for (auto globalJ : connectivityMapI)
         {
@@ -161,7 +145,7 @@ public:
             auto&& scvJ = fvGeometry.scv(globalJ);
             CellCenterPrimaryVariables priVars(0.0);
             priVars = sol[cellCenterIdx][globalJ];
-            auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(priVars));
+            auto elemSol = elementSolution<FVElementGeometry>(std::move(priVars));
             volumeVariables_[localIdx].update(elemSol,
                                               problem,
                                               elementJ,
@@ -181,7 +165,7 @@ public:
 
             CellCenterPrimaryVariables boundaryPriVars(0.0);
 
-            for(int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx)
+            for(int eqIdx = 0; eqIdx < CellCenterPrimaryVariables::dimension; ++eqIdx)
             {
                 if(bcTypes.isDirichlet(eqIdx) || bcTypes.isDirichletCell(eqIdx))
                     boundaryPriVars[eqIdx] = problem.dirichlet(element, scvf)[cellCenterIdx][eqIdx];
@@ -197,7 +181,7 @@ public:
             volumeVariables_.resize(localIdx+1);
             volVarIndices_.resize(localIdx+1);
 
-            auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(boundaryPriVars));
+            auto elemSol = elementSolution<FVElementGeometry>(std::move(boundaryPriVars));
             volumeVariables_[localIdx].update(elemSol,
                                               problem,
                                               element,
@@ -209,7 +193,8 @@ public:
 
     //! Binding of an element, prepares only the volume variables of the element.
     //! Specialization for Staggered models
-    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)
     {
@@ -221,9 +206,11 @@ public:
 
         // update the volume variables of the element
         auto&& scv = fvGeometry.scv(eIdx);
+        using CellCenterPrimaryVariables = typename SolutionVector::value_type;
         CellCenterPrimaryVariables priVars(0.0);
+        constexpr auto cellCenterIdx = FVElementGeometry::FVGridGeometry::cellCenterIdx();
         priVars = sol[cellCenterIdx][eIdx];
-        auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(priVars));
+        auto elemSol = elementSolution<FVElementGeometry>(std::move(priVars));
         volumeVariables_[0].update(elemSol,
                                    gridVolVars().problem(),
                                    element,
@@ -232,19 +219,21 @@ public:
     }
 
     //! const 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 volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
 
     //! operator for the access with an 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())]; }
 
     //! const operator for the access with an index
-    const VolumeVariables& operator [](IndexType scvIdx) const
+    const VolumeVariables& operator [](std::size_t scvIdx) const
     { return volumeVariables_[getLocalIdx_(scvIdx)]; }
 
     //! operator for the access with an 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
@@ -268,10 +257,10 @@ private:
         return std::distance(volVarIndices_.begin(), it);
     }
 
-    std::vector<IndexType> volVarIndices_;
+    std::vector<std::size_t> volVarIndices_;
     std::vector<VolumeVariables> volumeVariables_;
 };
 
-} // end namespace
+} // end namespace Dumux
 
 #endif
diff --git a/dumux/discretization/staggered/facesolution.hh b/dumux/discretization/staggered/facesolution.hh
index 25299bedcb7e6350dc9a3aaa4fc4ecc65709f841..745a81eec373bb76cae64cca8d82be0e5bd97ed9 100644
--- a/dumux/discretization/staggered/facesolution.hh
+++ b/dumux/discretization/staggered/facesolution.hh
@@ -25,9 +25,7 @@
 #define DUMUX_DISCRETIZATION_STAGGERED_FACE_SOLUTION_HH
 
 #include <vector>
-#include <algorithm>
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/staggered/elementvolumevariables.hh>
+#include <type_traits>
 
 namespace Dumux
 {
@@ -36,29 +34,20 @@ namespace Dumux
  * \ingroup StaggeredDiscretization
  * \brief The global face variables class for staggered models
  */
-template<class TypeTag>
+template<class FaceSolutionVector>
 class StaggeredFaceSolution
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FaceSolutionVector = typename GET_PROP_TYPE(TypeTag, FaceSolutionVector);
-    using FacePrimaryVariables = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
+    using FacePrimaryVariables = std::decay_t<decltype(std::declval<FaceSolutionVector>()[0])>;
 
 public:
 
+    template<class SubControlVolumeFace, class FVGridGeometry>
     StaggeredFaceSolution(const SubControlVolumeFace& scvf, const FaceSolutionVector& sol,
                           const FVGridGeometry& fvGridGeometry)
     {
+
         const auto& connectivityMap = fvGridGeometry.connectivityMap();
-        const auto& stencil = connectivityMap(faceIdx, faceIdx, scvf.index());
+        const auto& stencil = connectivityMap(FVGridGeometry::faceIdx(), FVGridGeometry::faceIdx(), scvf.index());
 
         facePriVars_.reserve(stencil.size());
         map_.reserve(stencil.size());
@@ -88,7 +77,6 @@ public:
         return facePriVars_[pos - map_.begin()];
     }
 
-
 private:
 
     std::vector<FacePrimaryVariables> facePriVars_;
diff --git a/dumux/discretization/staggered/freeflow/connectivitymap.hh b/dumux/discretization/staggered/freeflow/connectivitymap.hh
index 1f0ec37cf51663a6899e3998b54ddaf486db6b5f..5cde268b1cd6f0089fc30752ca346ed1806dc801 100644
--- a/dumux/discretization/staggered/freeflow/connectivitymap.hh
+++ b/dumux/discretization/staggered/freeflow/connectivitymap.hh
@@ -33,7 +33,7 @@ namespace Dumux {
  * \brief Stores the dof indices corresponding to the neighboring cell centers and faces
  *        that contribute to the derivative calculation. Specialization for the staggered free flow model.
  */
-template<class FVGridGeometry, class DofTypeIndices>
+template<class FVGridGeometry>
 class StaggeredFreeFlowConnectivityMap
 {
     using GridView = typename FVGridGeometry::GridView;
@@ -43,11 +43,8 @@ class StaggeredFreeFlowConnectivityMap
     using Element = typename GridView::template Codim<0>::Entity;
     using IndexType = typename GridView::IndexSet::IndexType;
 
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
-    using CellCenterIdxType = typename DofTypeIndices::CellCenterIdx;
-    using FaceIdxType = typename DofTypeIndices::FaceIdx;
+    using CellCenterIdxType = typename FVGridGeometry::DofTypeIndices::CellCenterIdx;
+    using FaceIdxType = typename FVGridGeometry::DofTypeIndices::FaceIdx;
 
     using CellCenterToCellCenterMap = std::vector<std::vector<IndexType>>;
     using CellCenterToFaceMap = std::vector<std::vector<IndexType>>;
diff --git a/dumux/discretization/staggered/freeflow/facevariables.hh b/dumux/discretization/staggered/freeflow/facevariables.hh
index b84abd27c42d494478df2c7a86fb5ad9d8f82809..470ce0365e70066683171985f368db8ab2a4ea70 100644
--- a/dumux/discretization/staggered/freeflow/facevariables.hh
+++ b/dumux/discretization/staggered/freeflow/facevariables.hh
@@ -24,8 +24,7 @@
 #ifndef DUMUX_DISCRETIZATION_STAGGERED_FREEFLOW_FACEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_STAGGERED_FREEFLOW_FACEVARIABLES_HH
 
-#include <dune/common/fvector.hh>
-#include <dumux/common/properties.hh>
+#include <array>
 
 namespace Dumux
 {
@@ -35,27 +34,14 @@ namespace Dumux
  * \brief The face variables class for free flow staggered grid models.
  *        Contains all relevant velocities for the assembly of the momentum balance.
  */
-template<class TypeTag>
+template<class FacePrimaryVariables, int dim>
 class StaggeredFaceVariables
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using FacePrimaryVariables = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-
-    static constexpr int dimWorld = GridView::dimensionworld;
-    static constexpr int numPairs = (dimWorld == 2) ? 2 : 4;
-
-    using Element = typename GridView::template Codim<0>::Entity;
-
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
+    static constexpr int numPairs = (dim == 2) ? 2 : 4;
+    using Scalar = typename FacePrimaryVariables::block_type;
 
 public:
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+
     /*!
     * \brief Partial update of the face variables. Only the face itself is considered.
     *
@@ -76,7 +62,8 @@ public:
     * \param fvGeometry The finite-volume geometry
     * \param scvf The sub-control volume face of interest
     */
-    template<class SolVector>
+    template<class SolVector, class Problem, class Element,
+             class FVElementGeometry, class SubControlVolumeFace>
     void update(const SolVector& faceSol,
                 const Problem& problem,
                 const Element& element,
diff --git a/dumux/discretization/staggered/freeflow/fickslaw.hh b/dumux/discretization/staggered/freeflow/fickslaw.hh
index 749733adf4200a65c0325322c76ff8b510a7fac5..58dedfe952338f94f1f99cd37e7785bb074727a5 100644
--- a/dumux/discretization/staggered/freeflow/fickslaw.hh
+++ b/dumux/discretization/staggered/freeflow/fickslaw.hh
@@ -52,7 +52,7 @@ class FicksLawImplementation<TypeTag, DiscretizationMethod::staggered >
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
diff --git a/dumux/discretization/staggered/freeflow/fourierslaw.hh b/dumux/discretization/staggered/freeflow/fourierslaw.hh
index a3ec20d548a0021c1b4df9a37a660e97f0f5dc0c..f6ad42bdac90d55f053f582ce94585aef64fbab9 100644
--- a/dumux/discretization/staggered/freeflow/fourierslaw.hh
+++ b/dumux/discretization/staggered/freeflow/fourierslaw.hh
@@ -49,7 +49,7 @@ class FouriersLawImplementation<TypeTag, DiscretizationMethod::staggered >
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using Element = typename GridView::template Codim<0>::Entity;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
diff --git a/dumux/discretization/staggered/freeflow/fvgridgeometrytraits.hh b/dumux/discretization/staggered/freeflow/fvgridgeometrytraits.hh
new file mode 100644
index 0000000000000000000000000000000000000000..29514118cb68b066a6d2f750aa2452578e153b27
--- /dev/null
+++ b/dumux/discretization/staggered/freeflow/fvgridgeometrytraits.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 StaggeredDiscretization
+ * \copydoc Dumux::StaggeredFreeFlowDefaultFVGridGeometryTraits
+ */
+#ifndef DUMUX_DISCRETIZATION_STAGGERED_FREEFLOW_FV_GRID_GEOMETRY_TRAITS
+#define DUMUX_DISCRETIZATION_STAGGERED_FREEFLOW_FV_GRID_GEOMETRY_TRAITS
+
+#include <dumux/discretization/cellcentered/subcontrolvolume.hh>
+#include <dumux/discretization/staggered/fvelementgeometry.hh>
+#include <dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh>
+
+#include "subcontrolvolumeface.hh"
+#include "connectivitymap.hh"
+#include "staggeredgeometryhelper.hh"
+
+namespace Dumux {
+
+/*!
+ * \ingroup StaggeredDiscretization
+ * \brief Default traits for the finite volume grid geometry.
+ */
+template<class GridView>
+struct StaggeredFreeFlowDefaultFVGridGeometryTraits : public DefaultMapperTraits<GridView>
+{
+    using SubControlVolume = CCSubControlVolume<GridView>;
+    using SubControlVolumeFace = FreeFlowStaggeredSubControlVolumeFace<GridView>;
+    using IntersectionMapper = ConformingGridIntersectionMapper<GridView>;
+    using GeometryHelper = FreeFlowStaggeredGeometryHelper<GridView>;
+
+    struct DofTypeIndices
+    {
+        using CellCenterIdx = Dune::index_constant<0>;
+        using FaceIdx = Dune::index_constant<1>;
+    };
+
+    template<class FVGridGeometry>
+    using ConnectivityMap = StaggeredFreeFlowConnectivityMap<FVGridGeometry>;
+
+    template<class FVGridGeometry, bool cachingEnabled>
+    using LocalView = StaggeredFVElementGeometry<FVGridGeometry, cachingEnabled>;
+};
+
+}
+
+#endif
diff --git a/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh b/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh
index 7476e9902702c54ff35493365e2f8487f3834db5..843c7dfaddd1b97785ebf028ed3c5ea9d6f5749e 100644
--- a/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh
+++ b/dumux/discretization/staggered/freeflow/maxwellstefanslaw.hh
@@ -51,7 +51,7 @@ class MaxwellStefansLawImplementation<TypeTag, DiscretizationMethod::staggered >
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
diff --git a/dumux/discretization/staggered/freeflow/properties.hh b/dumux/discretization/staggered/freeflow/properties.hh
index b0f0fabf6c93218ef6519287ed33d24fc64c8a7c..62a44bbac91317bc3621f889c8a708b54f3c8873 100644
--- a/dumux/discretization/staggered/freeflow/properties.hh
+++ b/dumux/discretization/staggered/freeflow/properties.hh
@@ -33,18 +33,13 @@
 #include <dumux/common/defaultmappertraits.hh>
 
 #include <dumux/discretization/staggered/properties.hh>
-#include <dumux/freeflow/properties.hh>
-
-#include <dumux/discretization/cellcentered/subcontrolvolume.hh>
-#include <dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh>
 #include <dumux/discretization/staggered/fvgridgeometry.hh>
+#include <dumux/freeflow/properties.hh>
 
-#include "subcontrolvolumeface.hh"
-#include "connectivitymap.hh"
 #include "facevariables.hh"
 #include "boundarytypes.hh"
 #include "velocityoutput.hh"
-#include "staggeredgeometryhelper.hh"
+#include "fvgridgeometrytraits.hh"
 
 namespace Dumux
 {
@@ -83,29 +78,21 @@ SET_PROP(StaggeredFreeFlowModel, FVGridGeometry)
 {
 private:
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
+    using Traits = StaggeredFreeFlowDefaultFVGridGeometryTraits<GridView>;
     static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache);
-
-    struct Traits : public DefaultMapperTraits<GridView>
-    {
-        using SubControlVolume = CCSubControlVolume<GridView>;
-        using SubControlVolumeFace = FreeFlowStaggeredSubControlVolumeFace<GridView>;
-        using IntersectionMapper = ConformingGridIntersectionMapper<GridView>;
-        using GeometryHelper = FreeFlowStaggeredGeometryHelper<GridView>;
-
-        template<class FVGridGeometry>
-        using ConnectivityMap = StaggeredFreeFlowConnectivityMap<FVGridGeometry, DofTypeIndices>;
-
-        template<class FVGridGeometry, bool enableCache>
-        using LocalView = StaggeredFVElementGeometry<FVGridGeometry, enableCache>;
-    };
-
 public:
     using type = StaggeredFVGridGeometry<GridView, enableCache, Traits>;
 };
 
 //! The variables living on the faces
-SET_TYPE_PROP(StaggeredFreeFlowModel, FaceVariables, StaggeredFaceVariables<TypeTag>);
+SET_PROP(StaggeredFreeFlowModel, FaceVariables)
+{
+private:
+    using FacePrimaryVariables = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+public:
+    using type = StaggeredFaceVariables<FacePrimaryVariables, GridView::dimension>;
+};
 
 //! Boundary types at a single degree of freedom
 SET_PROP(StaggeredFreeFlowModel, BoundaryTypes)
diff --git a/dumux/discretization/staggered/freeflow/velocityoutput.hh b/dumux/discretization/staggered/freeflow/velocityoutput.hh
index 556c32cc27b617bfe29b8fb0b9679bb68439e641..4191ca41e9ac4d4ded8e9f9dff69c33d37348d11 100644
--- a/dumux/discretization/staggered/freeflow/velocityoutput.hh
+++ b/dumux/discretization/staggered/freeflow/velocityoutput.hh
@@ -42,7 +42,7 @@ class StaggeredFreeFlowVelocityOutput
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
 
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
diff --git a/dumux/discretization/staggered/fvgridgeometry.hh b/dumux/discretization/staggered/fvgridgeometry.hh
index 1edb5f41f6a6c6bb0b0255a47af43f6251ea4489..2c657875190d9fc9cde42fcaf474820010f99f22 100644
--- a/dumux/discretization/staggered/fvgridgeometry.hh
+++ b/dumux/discretization/staggered/fvgridgeometry.hh
@@ -35,9 +35,9 @@ namespace Dumux {
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element.
  */
- template<class GridView,
-          bool enableFVGridGeometryCache,
-          class Traits>
+template<class GridView,
+         bool cachingEnabled,
+         class Traits>
 class StaggeredFVGridGeometry;
 
 /*!
@@ -55,12 +55,6 @@ class StaggeredFVGridGeometry<GV, true, Traits>
     using IndexType = typename GV::IndexSet::IndexType;
     using Element = typename GV::template Codim<0>::Entity;
 
-    enum {
-        // Grid and world dimension
-        dim = GV::dimension,
-        dimWorld = GV::dimensionworld
-    };
-
     using IntersectionMapper = typename Traits::IntersectionMapper;
     using GeometryHelper = typename Traits::GeometryHelper;
     using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
@@ -77,6 +71,16 @@ public:
     using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
     //! export the grid view type
     using GridView = GV;
+    //! export the dof type indices
+    using DofTypeIndices = typename Traits::DofTypeIndices;
+
+    //! return a integral constant for cell center dofs
+    static constexpr auto cellCenterIdx()
+    { return typename DofTypeIndices::CellCenterIdx{}; }
+
+    //! return a integral constant for face dofs
+    static constexpr auto faceIdx()
+    { return typename DofTypeIndices::FaceIdx{}; }
 
     //! Constructor
     StaggeredFVGridGeometry(const GridView& gridView)
diff --git a/dumux/discretization/staggered/gridfacevariables.hh b/dumux/discretization/staggered/gridfacevariables.hh
index ec5032a86ef43200bb1022341df0044c8e447594..dbcb429729b909a03a1e4ea6c400299ef6b02236 100644
--- a/dumux/discretization/staggered/gridfacevariables.hh
+++ b/dumux/discretization/staggered/gridfacevariables.hh
@@ -24,19 +24,37 @@
 #ifndef DUMUX_DISCRETIZATION_STAGGERED_GRID_FACEVARIABLES_HH
 #define DUMUX_DISCRETIZATION_STAGGERED_GRID_FACEVARIABLES_HH
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/staggered/facesolution.hh>
-
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
+#include <dumux/discretization/staggered/elementfacevariables.hh>
 
 namespace Dumux {
 
+/*!
+ * \ingroup StaggeredDiscretization
+ * \brief Traits class to be used for the StaggeredGridFaceVariables.
+ *
+ * \tparam P The problem type
+ * \tparam FV The face variables type
+ */
+template<class P, class FV>
+struct StaggeredDefaultGridFaceVariablesTraits
+{
+    template<class GridFaceVariables, bool enableCache>
+    using LocalView = StaggeredElementFaceVariables<GridFaceVariables, enableCache>;
+
+    using FaceVariables = FV;
+    using Problem = P;
+};
+
 /*!
  * \ingroup StaggeredDiscretization
  * \brief Face variables cache class for staggered models
  */
-template<class TypeTag, bool enableGlobalFaceVarsCache>
+template<class Problem,
+         class FaceVariables,
+         bool cachingEnabled = false,
+         class Traits = StaggeredDefaultGridFaceVariablesTraits<Problem, FaceVariables> >
 class StaggeredGridFaceVariables;
 
 /*!
@@ -44,29 +62,29 @@ class StaggeredGridFaceVariables;
  * \brief Face variables cache class for staggered models.
           Specialization in case of storing the face variables.
  */
-template<class TypeTag>
-class StaggeredGridFaceVariables<TypeTag, /*enableGlobalFaceVarsCache*/true>
+template<class P, class FV, class Traits>
+class StaggeredGridFaceVariables<P, FV, /*cachingEnabled*/true, Traits>
 {
-    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 FaceVariables = typename GET_PROP_TYPE(TypeTag, FaceVariables);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using IndexType = typename GridView::IndexSet::IndexType;
-
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::FaceIdx faceIdx;
+    using ThisType = StaggeredGridFaceVariables<P, FV, /*cachingEnabled*/true, Traits>;
+    using Problem = typename Traits::Problem;
 
 public:
+    //! make it possible to query if caching is enabled
+    static constexpr bool cachingEnabled = true;
+
     //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables);
+    using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
+
+    //! export the type of the face variables
+    using FaceVariables = typename Traits::FaceVariables;
 
     StaggeredGridFaceVariables(const Problem& problem) : problemPtr_(&problem) {}
 
     //! Update all face variables
-    void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol)
+    template<class FVGridGeometry, class SolutionVector>
+    void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& faceSol)
     {
-        const auto& faceSol = sol[faceIdx];
+
         faceVariables_.resize(fvGridGeometry.numScvf());
 
         for(auto&& element : elements(fvGridGeometry.gridView()))
@@ -81,19 +99,17 @@ public:
         }
     }
 
-    const FaceVariables& faceVars(const IndexType facetIdx) const
+    const FaceVariables& faceVars(const std::size_t facetIdx) const
     { return faceVariables_[facetIdx]; }
 
-    FaceVariables& faceVars(const IndexType facetIdx)
+    FaceVariables& faceVars(const std::size_t facetIdx)
     { return faceVariables_[facetIdx]; }
 
     const Problem& problem() const
     { return *problemPtr_; }
 
 private:
-
     const Problem* problemPtr_;
-
     std::vector<FaceVariables> faceVariables_;
 };
 
@@ -102,20 +118,26 @@ private:
  * \brief Face variables cache class for staggered models.
           Specialization in case of not storing the face variables.
  */
-template<class TypeTag>
-class StaggeredGridFaceVariables<TypeTag, /*enableGlobalFaceVarsCache*/false>
+template<class P, class FV, class Traits>
+class StaggeredGridFaceVariables<P, FV, /*cachingEnabled*/false, Traits>
 {
-    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 = StaggeredGridFaceVariables<P, FV, /*cachingEnabled*/false, Traits>;
+    using Problem = typename Traits::Problem;
 
 public:
+    //! make it possible to query if caching is enabled
+    static constexpr bool cachingEnabled = false;
+
     //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables);
+    using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
+
+    //! export the type of the face variables
+    using FaceVariables = typename Traits::FaceVariables;
 
     StaggeredGridFaceVariables(const Problem& problem) : problemPtr_(&problem) {}
 
     //! Do nothing here.
+    template<class FVGridGeometry, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol) {}
 
     const Problem& problem() const
diff --git a/dumux/discretization/staggered/gridfluxvariablescache.hh b/dumux/discretization/staggered/gridfluxvariablescache.hh
index bf3a6836cd0476f7231bc2970cd24b42855d4c25..4d02b339f1df6c7216962d815e648857880f3bca 100644
--- a/dumux/discretization/staggered/gridfluxvariablescache.hh
+++ b/dumux/discretization/staggered/gridfluxvariablescache.hh
@@ -24,19 +24,36 @@
 #ifndef DUMUX_DISCRETIZATION_STAGGERED_GRID_FLUXVARSCACHE_HH
 #define DUMUX_DISCRETIZATION_STAGGERED_GRID_FLUXVARSCACHE_HH
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/staggered/elementfluxvariablescache.hh>
-
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
+#include <dumux/discretization/staggered/elementfluxvariablescache.hh>
 
 namespace Dumux {
 
+/*!
+ * \ingroup StaggeredDiscretization
+ * \brief Traits class to be used for the StaggeredGridVFluxVariablesCache.
+ * \tparam P The problem type
+ * \tparam FVC The flux variables cache type
+ */
+template<class P, class FVC>
+struct StaggeredDefaultGridFluxVariablesCacheTraits
+{
+    using Problem = P;
+    using FluxVariablesCache = FVC;
+
+    template<class GridFluxVariablesCache, bool cachingEnabled>
+    using LocalView = StaggeredElementFluxVariablesCache<GridFluxVariablesCache, cachingEnabled>;
+};
+
 /*!
  * \ingroup StaggeredDiscretization
  * \brief Flux variables cache class for staggered models
  */
-template<class TypeTag, bool EnableGridFluxVariablesCache>
+template<class Problem,
+         class FluxVariablesCache,
+         bool cachingEnabled = false,
+         class Traits = StaggeredDefaultGridFluxVariablesCacheTraits<Problem, FluxVariablesCache> >
 class StaggeredGridFluxVariablesCache;
 
 /*!
@@ -44,31 +61,26 @@ class StaggeredGridFluxVariablesCache;
  * \brief Flux variables cache class for staggered models.
           Specialization in case of storing the flux cache.
  */
-template<class TypeTag>
-class StaggeredGridFluxVariablesCache<TypeTag, true>
+template<class P, class FVC, class Traits>
+class StaggeredGridFluxVariablesCache<P, FVC, true, Traits>
 {
-    // the local class needs access to the problem
-    friend StaggeredElementFluxVariablesCache<TypeTag, true>;
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using GridVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
+    using ThisType = StaggeredGridFluxVariablesCache<P, FVC, true, Traits>;
+    using Problem = typename Traits::Problem;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
 
     //! 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>;
+
     StaggeredGridFluxVariablesCache(const Problem& problem) : problemPtr_(&problem) {}
 
     // When global caching is enabled, precompute transmissibilities and stencils for all the scv faces
+    template<class FVGridGeometry, class GridVolumeVariables, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry,
                 const GridVolumeVariables& gridVolVars,
                 const SolutionVector& sol,
@@ -94,18 +106,18 @@ public:
     const Problem& problem() const
     { return *problemPtr_; }
 
-private:
     // access operators in the case of caching
-    const FluxVariablesCache& operator [](IndexType scvfIdx) const
+    const FluxVariablesCache& operator [](std::size_t scvfIdx) const
     { return fluxVarsCache_[scvfIdx]; }
 
-    FluxVariablesCache& operator [](IndexType scvfIdx)
+    FluxVariablesCache& operator [](std::size_t scvfIdx)
     { return fluxVarsCache_[scvfIdx]; }
 
+private:
     const Problem* problemPtr_;
 
     std::vector<FluxVariablesCache> fluxVarsCache_;
-    std::vector<IndexType> globalScvfIndices_;
+    std::vector<std::size_t> globalScvfIndices_;
 };
 
 /*!
@@ -113,19 +125,21 @@ private:
  * \brief Flux variables cache class for staggered models.
           Specialization in case of not storing the flux cache.
  */
-template<class TypeTag>
-class StaggeredGridFluxVariablesCache<TypeTag, false>
+template<class P, class FVC, class Traits>
+class StaggeredGridFluxVariablesCache<P, FVC, false, Traits>
 {
-    // the local class needs access to the problem
-    friend StaggeredElementFluxVariablesCache<TypeTag, false>;
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using ThisType = StaggeredGridFluxVariablesCache<P, FVC, false, Traits>;
+    using Problem = typename Traits::Problem;
 
 public:
-    //! export the type of the local view
-    using LocalView = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    //! export the flux variable cache type
+    using FluxVariablesCache = typename Traits::FluxVariablesCache;
 
     //! make it possible to query if caching is enabled
-    static constexpr bool cachingEnabled = false;
+    static constexpr bool cachingEnabled = true;
+
+    //! export the type of the local view
+    using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
 
     // When global flux variables caching is disabled, we don't need to update the cache
     void update(Problem& problem)
diff --git a/dumux/discretization/staggered/gridvariables.hh b/dumux/discretization/staggered/gridvariables.hh
index c9fb8940ec77f9f3af31843d04fce4190491c55e..dd7643ff2c4e717875182398fe7f64da06978438 100644
--- a/dumux/discretization/staggered/gridvariables.hh
+++ b/dumux/discretization/staggered/gridvariables.hh
@@ -41,11 +41,18 @@ class StaggeredGridVariables : public FVGridVariables<GG, GVV, GFVC>
 {
     using ParentType = FVGridVariables<GG, GVV, GFVC>;
     using FVGridGeometry = GG;
+
+    static constexpr auto cellCenterIdx = FVGridGeometry::cellCenterIdx();
+    static constexpr auto faceIdx = FVGridGeometry::faceIdx();
+
+public:
+    //! export the type of the grid volume variables
     using GridVolumeVariables = GVV;
+    //! export the type of the grid flux variables cache
     using GridFluxVariablesCache = GFVC;
+    //! export the type of the grid face variables
     using GridFaceVariables = GFV;
 
-public:
     //! Constructor
     template<class Problem>
     StaggeredGridVariables(std::shared_ptr<Problem> problem,
@@ -59,25 +66,25 @@ public:
     template<class SolutionVector>
     void update(const SolutionVector& curSol)
     {
-        ParentType::update(curSol);
-        curGridFaceVariables_.update(*this->fvGridGeometry_, curSol);
+        ParentType::update(curSol[cellCenterIdx]);
+        curGridFaceVariables_.update(*this->fvGridGeometry_, curSol[faceIdx]);
     }
 
     //! initialize all variables (stationary case)
     template<class SolutionVector>
     void init(const SolutionVector& curSol)
     {
-        ParentType::init(curSol);
-        curGridFaceVariables_.update(*this->fvGridGeometry_, curSol);
+        ParentType::init(curSol[cellCenterIdx]);
+        curGridFaceVariables_.update(*this->fvGridGeometry_, curSol[faceIdx]);
     }
 
     //! initialize all variables (instationary case)
     template<class SolutionVector>
     void init(const SolutionVector& curSol, const SolutionVector& initSol)
     {
-        ParentType::init(curSol, initSol);
-        curGridFaceVariables_.update(*this->fvGridGeometry_, curSol);
-        prevGridFaceVariables_.update(*this->fvGridGeometry_, initSol);
+        ParentType::init(curSol[cellCenterIdx], initSol[cellCenterIdx]);
+        curGridFaceVariables_.update(*this->fvGridGeometry_, curSol[faceIdx]);
+        prevGridFaceVariables_.update(*this->fvGridGeometry_, initSol[faceIdx]);
     }
 
     //! Sets the current state as the previous for next time step
diff --git a/dumux/discretization/staggered/gridvariablestraits.hh b/dumux/discretization/staggered/gridvariablestraits.hh
new file mode 100644
index 0000000000000000000000000000000000000000..4120bd3db4f781bef19b40d53be7283e5248d209
--- /dev/null
+++ b/dumux/discretization/staggered/gridvariablestraits.hh
@@ -0,0 +1,53 @@
+// -*- 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 StaggeredDiscretization
+ * \brief Traits class to be used in conjunction with the StaggeredGridFaceVariables.
+ */
+#ifndef DUMUX_DISCRETIZATION_STAGGERED_GRID_VARIABLES_TRAITS_HH
+#define DUMUX_DISCRETIZATION_STAGGERED_GRID_VARIABLES_TRAITS_HH
+
+#include <dumux/discretization/staggered/elementvolumevariables.hh>
+
+namespace Dumux {
+
+/*!
+ * \ingroup StaggeredDiscretization
+ * \brief Traits class to be used for the StaggeredGridVolumeVariables.
+ *
+ * \tparam P The problem type
+ * \tparam VV The volume variables type
+ * \tparam I The indices type
+ * TODO: Remove the indices (get out of volvar) and do a default class like in tpfa
+ */
+template<class P, class VV, class I>
+struct StaggeredGridVolumeVariablesTraits
+{
+    template<class GridVolumeVariables, bool enableCache>
+    using LocalView = StaggeredElementVolumeVariables<GridVolumeVariables, enableCache>;
+
+    using Problem = P;
+    using VolumeVariables = VV;
+    using Indices = I;
+};
+
+} // end namespace Dumux
+
+#endif
diff --git a/dumux/discretization/staggered/gridvolumevariables.hh b/dumux/discretization/staggered/gridvolumevariables.hh
index 7b6a4c332fca6b5c19c920f75e794f74ec03ded8..d1f2716aed0e1a9a32368c9ba09eb3fc73abf618 100644
--- a/dumux/discretization/staggered/gridvolumevariables.hh
+++ b/dumux/discretization/staggered/gridvolumevariables.hh
@@ -25,7 +25,6 @@
 #define DUMUX_DISCRETIZATION_STAGGERED_GRID_VOLUMEVARIABLES_HH
 
 #include <dune/common/exceptions.hh>
-#include <dumux/common/properties.hh>
 
 //! make the local view function available whenever we use this class
 #include <dumux/discretization/localview.hh>
@@ -37,7 +36,7 @@ namespace Dumux {
  * \ingroup StaggeredDiscretization
  * \brief Grid volume variables class for staggered models
  */
-template<class TypeTag, bool enableGridVolVarsCache>
+template<class Traits, bool cachingEnabled>
 class StaggeredGridVolumeVariables;
 
 /*!
@@ -45,40 +44,32 @@ class StaggeredGridVolumeVariables;
  * \brief Grid volume variables class for staggered models.
           Specialization in case of storing the volume variables
  */
-template<class TypeTag>
-class StaggeredGridVolumeVariables<TypeTag, /*enableGridVolVarsCache*/true>
+template<class Traits>
+class StaggeredGridVolumeVariables<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 FVGridGeometry::LocalView;
-    using SubControlVolume = typename FVElementGeometry::SubControlVolume;
-    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-    using IndexType = typename GridView::IndexSet::IndexType;
-
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-
-    static const int dim = GridView::dimension;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
-
-    enum { numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter) };
+    using ThisType = StaggeredGridVolumeVariables<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 type of the indices TODO: get them out of the volvars
+    using Indices = typename Traits::Indices;
+
+    //! export the type of the VolumeVariables
+    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>;
+
     StaggeredGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
 
     //! Update all volume variables
+    template<class FVGridGeometry, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol)
     {
+        using CellCenterPrimaryVariables = typename SolutionVector::value_type;
         auto numScv = fvGridGeometry.numScv();
         auto numBoundaryScvf = fvGridGeometry.numBoundaryScvf();
 
@@ -90,9 +81,8 @@ public:
 
             for (auto&& scv : scvs(fvGeometry))
             {
-                CellCenterPrimaryVariables priVars(0.0);
-                priVars = sol[cellCenterIdx][scv.dofIndex()];
-                auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(priVars));
+                CellCenterPrimaryVariables priVars = sol[scv.dofIndex()];
+                auto elemSol = elementSolution<typename FVGridGeometry::LocalView>(std::move(priVars));
                 volumeVariables_[scv.dofIndex()].update(elemSol, problem(), element, scv);
             }
 
@@ -109,34 +99,36 @@ public:
 
                 CellCenterPrimaryVariables boundaryPriVars(0.0);
 
-                for(int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx)
+                for(int eqIdx = 0; eqIdx < CellCenterPrimaryVariables::dimension; ++eqIdx)
                 {
                     if(bcTypes.isDirichlet(eqIdx) || bcTypes.isDirichletCell(eqIdx))
                         boundaryPriVars[eqIdx] = problem().dirichlet(element, scvf)[eqIdx];
                     else if(bcTypes.isNeumann(eqIdx) || bcTypes.isOutflow(eqIdx) || bcTypes.isSymmetry())
-                        boundaryPriVars[eqIdx] = sol[cellCenterIdx][scvf.insideScvIdx()][eqIdx];
+                        boundaryPriVars[eqIdx] = sol[scvf.insideScvIdx()][eqIdx];
                     //TODO: this assumes a zero-gradient for e.g. the pressure on the boundary
                     // could be made more general by allowing a non-zero-gradient, provided in problem file
                     else
                         if(eqIdx == Indices::pressureIdx)
                             DUNE_THROW(Dune::InvalidStateException, "Face at: " << scvf.center() << " has neither Dirichlet nor Neumann BC.");
                 }
-                auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(boundaryPriVars));
+                auto elemSol = elementSolution<typename FVGridGeometry::LocalView>(std::move(boundaryPriVars));
                 volumeVariables_[scvf.outsideScvIdx()].update(elemSol, problem(), element, insideScv);
             }
         }
     }
 
-    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]; }
 
-    const VolumeVariables& volVars(const SubControlVolume scv) const
+    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()]; }
 
-    VolumeVariables& volVars(const SubControlVolume scv)
+    template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
+    VolumeVariables& volVars(const SubControlVolume& scv)
     { return volumeVariables_[scv.dofIndex()]; }
 
     const Problem& problem() const
@@ -153,22 +145,25 @@ private:
  * \brief Grid volume variables class for staggered models.
           Specialization in case of not storing the volume variables
  */
-template<class TypeTag>
-class StaggeredGridVolumeVariables<TypeTag, /*enableGridVolVarsCache*/false>
+template<class Traits>
+class StaggeredGridVolumeVariables<Traits, /*cachingEnabled*/false>
 {
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using ThisType = StaggeredGridVolumeVariables<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 type of the VolumeVariables
+    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>;
+
     StaggeredGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
 
+    template<class FVGridGeometry, class SolutionVector>
     void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol) {}
 
     const Problem& problem() const
diff --git a/dumux/discretization/staggered/properties.hh b/dumux/discretization/staggered/properties.hh
index afe98aab5dd7185ed50bed8a61b49894a09ee28e..a05602903685c4e909563823af82775d1b5ffa2c 100644
--- a/dumux/discretization/staggered/properties.hh
+++ b/dumux/discretization/staggered/properties.hh
@@ -39,19 +39,17 @@
 #include <dumux/discretization/cellcentered/subcontrolvolume.hh>
 #include <dumux/discretization/staggered/gridvariables.hh>
 #include <dumux/discretization/staggered/gridfluxvariablescache.hh>
-#include <dumux/discretization/staggered/elementfluxvariablescache.hh>
 #include <dumux/discretization/staggered/gridvolumevariables.hh>
-#include <dumux/discretization/staggered/elementvolumevariables.hh>
 #include <dumux/discretization/staggered/fvgridgeometry.hh>
-#include <dumux/discretization/staggered/fvelementgeometry.hh>
 #include <dumux/discretization/staggered/gridfacevariables.hh>
 #include <dumux/discretization/staggered/facesolution.hh>
-#include <dumux/discretization/staggered/elementfacevariables.hh>
 #include <dumux/discretization/staggered/subcontrolvolumeface.hh>
 
 #include <dune/istl/multitypeblockvector.hh>
 #include <dune/istl/multitypeblockmatrix.hh>
 
+#include <dumux/discretization/staggered/gridvariablestraits.hh>
+
 namespace Dumux {
 
 // forward declarations
@@ -63,28 +61,56 @@ namespace Properties
 NEW_TYPE_TAG(StaggeredModel, INHERITS_FROM(FiniteVolumeModel));
 
 //! Set the default global face variables cache vector class
-SET_TYPE_PROP(StaggeredModel, GridFaceVariables, StaggeredGridFaceVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFaceVariablesCache)>);
-
-//! Set the default element face variables
-SET_TYPE_PROP(StaggeredModel, ElementFaceVariables, StaggeredElementFaceVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFaceVariablesCache)>);
+SET_PROP(StaggeredModel, GridFaceVariables)
+{
+private:
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FaceVariables = typename GET_PROP_TYPE(TypeTag, FaceVariables);
+    static constexpr auto enableCache = GET_PROP_VALUE(TypeTag, EnableGridFaceVariablesCache);
+public:
+    using type = StaggeredGridFaceVariables<Problem, FaceVariables, enableCache>;
+};
 
 //! Cache the face variables per default
 SET_BOOL_PROP(StaggeredModel, EnableGridFaceVariablesCache, true);
 
 //! Set the default global volume variables cache vector class
-SET_TYPE_PROP(StaggeredModel, GridVolumeVariables, StaggeredGridVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
+SET_PROP(StaggeredModel, GridVolumeVariables)
+{
+private:
+    using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices); // TODO extract indices from volumevariables
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
 
-//! Set the element volume variables class
-SET_TYPE_PROP(StaggeredModel, ElementVolumeVariables, StaggeredElementVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
+    static constexpr auto enableCache = GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache);
 
-//! Set the global flux variables cache vector class
-SET_TYPE_PROP(StaggeredModel, GridFluxVariablesCache, StaggeredGridFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
+    using Traits = StaggeredGridVolumeVariablesTraits<Problem, VolumeVariables, Indices>; // TODO extract indices from volumevariables
 
-//! Set the local flux variables cache vector class
-SET_TYPE_PROP(StaggeredModel, ElementFluxVariablesCache, StaggeredElementFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache)>);
+public:
+    using type = StaggeredGridVolumeVariables<Traits, enableCache>;
+};
+
+//! Set the global flux variables cache vector class
+SET_PROP(StaggeredModel, GridFluxVariablesCache)
+{
+private:
+    static constexpr auto enableCache = GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache);
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
+public:
+    using type = StaggeredGridFluxVariablesCache<Problem, FluxVariablesCache, enableCache>;
+};
 
 //! Set the face solution type
-SET_TYPE_PROP(StaggeredModel, StaggeredFaceSolution, StaggeredFaceSolution<TypeTag>);
+SET_PROP(StaggeredModel, StaggeredFaceSolution)
+{
+private:
+    using FaceSolutionVector = typename GET_PROP_TYPE(TypeTag, FaceSolutionVector);
+public:
+    using type = StaggeredFaceSolution<FaceSolutionVector>;
+};
 
 //! Set the grid variables (volume, flux and face variables)
 SET_PROP(StaggeredModel, GridVariables)
@@ -104,13 +130,6 @@ SET_TYPE_PROP(StaggeredModel, ElementBoundaryTypes, CCElementBoundaryTypes);
 //! Set the BaseLocalResidual to StaggeredLocalResidual
 SET_TYPE_PROP(StaggeredModel, BaseLocalResidual, StaggeredLocalResidual<TypeTag>);
 
-//! Definition of the indices for cell center and face dofs in the global solution vector
-SET_PROP(StaggeredModel, DofTypeIndices)
-{
-    using CellCenterIdx = Dune::index_constant<0>;
-    using FaceIdx = Dune::index_constant<1>;
-};
-
 //! The cell center primary variables
 SET_TYPE_PROP(StaggeredModel,
               CellCenterPrimaryVariables,
diff --git a/dumux/freeflow/navierstokes/fluxvariablescache.hh b/dumux/freeflow/navierstokes/fluxvariablescache.hh
index a2c03e8931f9948b70a33712af4c92674be91ff9..dd712ab3dee09cf7a84a485b6bf6303e3497f67d 100644
--- a/dumux/freeflow/navierstokes/fluxvariablescache.hh
+++ b/dumux/freeflow/navierstokes/fluxvariablescache.hh
@@ -54,7 +54,7 @@ class FreeFlowFluxVariablesCacheImplementation<TypeTag, DiscretizationMethod::st
     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 ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using Element = typename GridView::template Codim<0>::Entity;
 
diff --git a/dumux/freeflow/navierstokes/problem.hh b/dumux/freeflow/navierstokes/problem.hh
index d0fdad020329dfcce35c82eb237b470db4c8da59..9d987984bdba9240ac40ad3933205145b47de0a3 100644
--- a/dumux/freeflow/navierstokes/problem.hh
+++ b/dumux/freeflow/navierstokes/problem.hh
@@ -62,11 +62,10 @@ class NavierStokesProblem : public NavierStokesParentProblem<TypeTag>
     using ParentType = NavierStokesParentProblem<TypeTag>;
     using Implementation = typename GET_PROP_TYPE(TypeTag, Problem);
 
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Grid = typename GridView::Grid;
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using GridView = typename FVGridGeometry::GridView;
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
 
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
@@ -74,10 +73,10 @@ class NavierStokesProblem : public NavierStokesParentProblem<TypeTag>
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
     enum {
-        dim = Grid::dimension,
-        dimWorld = Grid::dimensionworld
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld
       };
-    // TODO: dim or dimWorld appropriate here?
+
     using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
 
 public:
@@ -119,15 +118,14 @@ public:
     { return gravity_; }
 
     //! Applys the initial face solution (velocities on the faces). Specialization for staggered grid discretization.
-    template <class T = TypeTag>
-    typename std::enable_if<GET_PROP_TYPE(T, FVGridGeometry)::discMethod == DiscretizationMethod::staggered, void>::type
+    template <class G = FVGridGeometry>
+    typename std::enable_if<G::discMethod == DiscretizationMethod::staggered, void>::type
     applyInititalFaceSolution(SolutionVector& sol,
                               const SubControlVolumeFace& scvf,
                               const PrimaryVariables& initSol) const
     {
-        typename GET_PROP(TypeTag, DofTypeIndices)::FaceIdx faceIdx;
         const auto numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
-        sol[faceIdx][scvf.dofIndex()][numEqCellCenter] = initSol[Indices::velocity(scvf.directionIndex())];
+        sol[FVGridGeometry::faceIdx()][scvf.dofIndex()][numEqCellCenter] = initSol[Indices::velocity(scvf.directionIndex())];
     }
 
 private:
diff --git a/dumux/freeflow/navierstokes/staggered/fluxoverplane.hh b/dumux/freeflow/navierstokes/staggered/fluxoverplane.hh
index 0f0056e94706c3881af1104f092a288bf5e85fc6..cb1420e263a59d045d949bdfe93fc7aebe3ef82a 100644
--- a/dumux/freeflow/navierstokes/staggered/fluxoverplane.hh
+++ b/dumux/freeflow/navierstokes/staggered/fluxoverplane.hh
@@ -58,10 +58,6 @@ class FluxOverPlane
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using Element = typename GridView::template Codim<0>::Entity;
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
     enum {
         // Grid and world dimension
         dim = GridView::dimension,
diff --git a/dumux/freeflow/navierstokes/staggered/fluxvariables.hh b/dumux/freeflow/navierstokes/staggered/fluxvariables.hh
index 835674a14ce9b3bebd58710a96fa36cf72dc8c1e..f86dc0cbeb315c3c9a3c6f57f09a6daf360d49d0 100644
--- a/dumux/freeflow/navierstokes/staggered/fluxvariables.hh
+++ b/dumux/freeflow/navierstokes/staggered/fluxvariables.hh
@@ -43,32 +43,42 @@ class NavierStokesFluxVariablesImpl;
  */
 template<class TypeTag>
 class NavierStokesFluxVariablesImpl<TypeTag, DiscretizationMethod::staggered>
-: public FluxVariablesBase<TypeTag>
+: public FluxVariablesBase<typename GET_PROP_TYPE(TypeTag, Problem),
+                           typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView,
+                           typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView,
+                           typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+
+    using GridVolumeVariables = typename GridVariables::GridVolumeVariables;
+    using ElementVolumeVariables = typename GridVolumeVariables::LocalView;
+    using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
+
+    using GridFluxVariablesCache = typename GridVariables::GridFluxVariablesCache;
+    using FluxVariablesCache = typename GridFluxVariablesCache::FluxVariablesCache;
+
+    using GridFaceVariables = typename GridVariables::GridFaceVariables;
+    using ElementFaceVariables = typename GridFaceVariables::LocalView;
+    using FaceVariables = typename GridFaceVariables::FaceVariables;
+
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVElementGeometry = typename FVGridGeometry::LocalView;
+    using GridView = typename FVGridGeometry::GridView;
     using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
     using FacePrimaryVariables = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
 
-    using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables);
-    using FaceVariables = typename GET_PROP_TYPE(TypeTag, FaceVariables);
-
     static constexpr bool enableInertiaTerms = GET_PROP_VALUE(TypeTag, EnableInertiaTerms);
     static constexpr bool normalizePressure = GET_PROP_VALUE(TypeTag, NormalizePressure);
 
     using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimensionworld>;
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
+    static constexpr auto cellCenterIdx = FVGridGeometry::cellCenterIdx();
+    static constexpr auto faceIdx = FVGridGeometry::faceIdx();
 
 public:
 
diff --git a/dumux/freeflow/navierstokes/staggered/localresidual.hh b/dumux/freeflow/navierstokes/staggered/localresidual.hh
index 132a554a749692aa65e7231553f0de99647a8ca8..c0155ee5154cb3534e4eecce51d24ac7073d2258 100644
--- a/dumux/freeflow/navierstokes/staggered/localresidual.hh
+++ b/dumux/freeflow/navierstokes/staggered/localresidual.hh
@@ -46,38 +46,35 @@ class NavierStokesResidualImpl<TypeTag, DiscretizationMethod::staggered>
 {
     using ParentType = StaggeredLocalResidual<TypeTag>;
     friend class StaggeredLocalResidual<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+
+    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+
+    using GridVolumeVariables = typename GridVariables::GridVolumeVariables;
+    using ElementVolumeVariables = typename GridVolumeVariables::LocalView;
+    using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
+
+    using GridFluxVariablesCache = typename GridVariables::GridFluxVariablesCache;
+    using ElementFluxVariablesCache = typename GridFluxVariablesCache::LocalView;
+
+    using GridFaceVariables = typename GridVariables::GridFaceVariables;
+    using ElementFaceVariables = typename GridFaceVariables::LocalView;
 
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Implementation = typename GET_PROP_TYPE(TypeTag, LocalResidual);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVElementGeometry = typename FVGridGeometry::LocalView;
+    using GridView = typename FVGridGeometry::GridView;
     using Element = typename GridView::template Codim<0>::Entity;
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using ElementBoundaryTypes = typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
     using FacePrimaryVariables = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
-    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables);
-
-    using CellCenterResidual = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
-    using FaceResidual = typename GET_PROP_TYPE(TypeTag, FacePrimaryVariables);
-
-    static constexpr auto numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter);
-
-    enum {
-        pressureIdx = Indices::pressureIdx,
-
-        totalMassBalanceIdx = Indices::totalMassBalanceIdx,
-        momentumBalanceIdx = Indices::momentumBalanceIdx
-    };
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using CellCenterResidual = CellCenterPrimaryVariables;
+    using FaceResidual = FacePrimaryVariables;
 
     using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits);
 
@@ -119,8 +116,7 @@ public:
         const auto sourceValues = problem.sourceAtPos(scv.center());
 
         // copy the respective cell center related values to the result
-        for(int i = 0; i < numEqCellCenter; ++i)
-            result[i] = sourceValues[i];
+        std::copy_n(sourceValues.begin(), result.size(), result.begin());
 
         return result;
     }
@@ -132,7 +128,7 @@ public:
                                                            const VolumeVariables& volVars) const
     {
         CellCenterPrimaryVariables storage;
-        storage[totalMassBalanceIdx] = volVars.density();
+        storage[Indices::totalMassBalanceIdx] = volVars.density();
 
         computeStorageForCellCenterNonIsothermal_(std::integral_constant<bool, ModelTraits::enableEnergyBalance() >(),
                                                   problem, scv, volVars, storage);
@@ -183,26 +179,28 @@ public:
 
 protected:
 
-//      /*!
-//      * \brief Evaluate boundary conditions
-//      */
-//     void evalBoundary_(const Element& element,
-//                        const FVElementGeometry& fvGeometry,
-//                        const ElementVolumeVariables& elemVolVars,
-//                        const ElementFaceVariables& elemFaceVars,
-//                        const ElementBoundaryTypes& elemBcTypes,
-//                        const ElementFluxVariablesCache& elemFluxVarsCache)
-//     {
-//         evalBoundaryForCellCenter_(element, fvGeometry, elemVolVars, elemFaceVars, elemBcTypes, elemFluxVarsCache);
-//         for (auto&& scvf : scvfs(fvGeometry))
-//         {
-//             evalBoundaryForFace_(element, fvGeometry, scvf, elemVolVars, elemFaceVars, elemBcTypes, elemFluxVarsCache);
-//         }
-//     }
+    //  /*!
+    //  * \brief Evaluate boundary conditions
+    //  */
+    // template<class ElementBoundaryTypes>
+    // void evalBoundary_(const Element& element,
+    //                    const FVElementGeometry& fvGeometry,
+    //                    const ElementVolumeVariables& elemVolVars,
+    //                    const ElementFaceVariables& elemFaceVars,
+    //                    const ElementBoundaryTypes& elemBcTypes,
+    //                    const ElementFluxVariablesCache& elemFluxVarsCache)
+    // {
+    //     evalBoundaryForCellCenter_(element, fvGeometry, elemVolVars, elemFaceVars, elemBcTypes, elemFluxVarsCache);
+    //     for (auto&& scvf : scvfs(fvGeometry))
+    //     {
+    //         evalBoundaryForFace_(element, fvGeometry, scvf, elemVolVars, elemFaceVars, elemBcTypes, elemFluxVarsCache);
+    //     }
+    // }
 
      /*!
      * \brief Evaluate boundary conditions for a cell center dof
      */
+    template<class ElementBoundaryTypes>
     void evalBoundaryForCellCenter_(CellCenterResidual& residual,
                                     const Problem& problem,
                                     const Element& element,
@@ -223,8 +221,9 @@ protected:
 
                 if(bcTypes.hasNeumann())
                 {
+                    static constexpr auto numEqCellCenter = CellCenterResidual::dimension;
                     // handle Neumann BCs, i.e. overwrite certain fluxes by user-specified values
-                    for(int eqIdx = 0; eqIdx < GET_PROP_VALUE(TypeTag, NumEqCellCenter); ++eqIdx)
+                    for(int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx)
                         if(bcTypes.isNeumann(eqIdx))
                         {
                             const auto extrusionFactor = 1.0; //TODO: get correct extrusion factor
@@ -244,6 +243,7 @@ protected:
      * \brief Sets a fixed Dirichlet value for a cell (such as pressure) at the boundary.
      *        This is a provisional alternative to setting the Dirichlet value on the boundary directly.
      */
+    template<class BoundaryTypes>
     void setFixedCell_(CellCenterResidual& residual,
                        const Problem& problem,
                        const SubControlVolume& insideScv,
@@ -251,16 +251,17 @@ protected:
                        const BoundaryTypes& bcTypes) const
     {
         // set a fixed pressure for cells adjacent to a wall
-        if(bcTypes.isDirichletCell(totalMassBalanceIdx))
+        if(bcTypes.isDirichletCell(Indices::totalMassBalanceIdx))
         {
             const auto& insideVolVars = elemVolVars[insideScv];
-            residual[pressureIdx] = insideVolVars.pressure() - problem.dirichletAtPos(insideScv.center())[pressureIdx];
+            residual[Indices::pressureIdx] = insideVolVars.pressure() - problem.dirichletAtPos(insideScv.center())[Indices::pressureIdx];
         }
     }
 
      /*!
      * \brief Evaluate boundary conditions for a face dof
      */
+    template<class ElementBoundaryTypes>
     void evalBoundaryForFace_(FaceResidual& residual,
                               const Problem& problem,
                               const Element& element,
@@ -277,7 +278,7 @@ protected:
             const auto bcTypes = problem.boundaryTypes(element, scvf);
 
             // set a fixed value for the velocity for Dirichlet boundary conditions
-            if(bcTypes.isDirichlet(momentumBalanceIdx))
+            if(bcTypes.isDirichlet(Indices::momentumBalanceIdx))
             {
                 const Scalar velocity = elementFaceVars[scvf].velocitySelf();
                 const Scalar dirichletValue = problem.dirichlet(element, scvf)[Indices::velocity(scvf.directionIndex())];
@@ -295,9 +296,9 @@ protected:
             }
 
             // outflow condition for the momentum balance equation
-            if(bcTypes.isOutflow(momentumBalanceIdx))
+            if(bcTypes.isOutflow(Indices::momentumBalanceIdx))
             {
-                if(bcTypes.isDirichlet(totalMassBalanceIdx))
+                if(bcTypes.isDirichlet(Indices::totalMassBalanceIdx))
                     residual += computeFluxForFace(problem, element, scvf, fvGeometry, elemVolVars, elementFaceVars, elemFluxVarsCache);
                 else
                     DUNE_THROW(Dune::InvalidStateException, "Face at " << scvf.center()  << " has an outflow BC for the momentum balance but no Dirichlet BC for the pressure!");
diff --git a/dumux/freeflow/navierstokes/volumevariables.hh b/dumux/freeflow/navierstokes/volumevariables.hh
index d13997dba8520cce84cefab57b1a195268aee1cc..862285c1d69e1c5412f03dd4bdabb0e6d2c4fc6c 100644
--- a/dumux/freeflow/navierstokes/volumevariables.hh
+++ b/dumux/freeflow/navierstokes/volumevariables.hh
@@ -50,13 +50,8 @@ template <class TypeTag>
 class NavierStokesVolumeVariablesImplementation<TypeTag, false>
 {
     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, Indices);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Element = typename GridView::template Codim<0>::Entity;
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
     static const int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx);
 
@@ -73,7 +68,7 @@ public:
      * \param element An element which contains part of the control volume
      * \param scv The sub-control volume
      */
-    template<class ElementSolution>
+    template<class ElementSolution, class Problem, class Element, class SubControlVolume>
     void update(const ElementSolution &elemSol,
                 const Problem &problem,
                 const Element &element,
@@ -87,7 +82,7 @@ public:
     /*!
      * \brief Returns the primary variables at the dof associated with a given scv.
      */
-    template<class ElementSolution>
+    template<class ElementSolution, class SubControlVolume>
     static const auto& extractDofPriVars(const ElementSolution& elemSol,
                                          const SubControlVolume& scv)
     { return elemSol[0]; }
@@ -95,7 +90,7 @@ public:
     /*!
      * \brief Update the fluid state
      */
-    template<class ElementSolution>
+    template<class ElementSolution, class Problem, class Element, class SubControlVolume>
     static void completeFluidState(const ElementSolution& elemSol,
                                    const Problem& problem,
                                    const Element& element,
@@ -197,7 +192,7 @@ public:
     { return fluidState_; }
 
     //! The temperature is obtained from the problem as a constant for isothermal models
-    template<class ElementSolution>
+    template<class ElementSolution, class Problem, class Element, class SubControlVolume>
     static Scalar temperature(const ElementSolution &elemSol,
                               const Problem& problem,
                               const Element &element,
@@ -208,7 +203,7 @@ public:
 
     //! The phase enthalpy is zero for isothermal models
     //! This is needed for completing the fluid state
-    template<class FluidState, class ParameterCache>
+    template<class ParameterCache>
     static Scalar enthalpy(const FluidState& fluidState,
                            const ParameterCache& paramCache)
     {
@@ -230,18 +225,12 @@ class NavierStokesVolumeVariablesImplementation<TypeTag, true>
 {
     using ParentType = NavierStokesVolumeVariablesImplementation<TypeTag, false>;
     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 FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
     static const int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx);
     static const int temperatureIdx = Indices::temperatureIdx;
 
-
 public:
 
     using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState);
@@ -255,7 +244,7 @@ public:
      * \param element An element which contains part of the control volume
      * \param scv The sub-control volume
      */
-    template<class ElementSolution>
+    template<class ElementSolution, class Problem, class Element, class SubControlVolume>
     void update(const ElementSolution &elemSol,
                 const Problem &problem,
                 const Element &element,
@@ -269,7 +258,7 @@ public:
     /*!
      * \brief Update the fluid state
      */
-    template<class ElementSolution>
+    template<class ElementSolution, class Problem, class Element, class SubControlVolume>
     static void completeFluidState(const ElementSolution& elemSol,
                                    const Problem& problem,
                                    const Element& element,
@@ -334,7 +323,7 @@ public:
 
     //! The temperature is a primary variable for non-isothermal models
     using ParentType::temperature;
-    template<class ElementSolution>
+    template<class ElementSolution, class Problem, class Element, class SubControlVolume>
     static Scalar temperature(const ElementSolution &elemSol,
                               const Problem& problem,
                               const Element &element,
diff --git a/dumux/freeflow/navierstokesnc/staggered/fluxvariables.hh b/dumux/freeflow/navierstokesnc/staggered/fluxvariables.hh
index 517f3aa0f46e947d6e1e74c7d4e262ad0064031c..841a0ffa9dba79a4b344af1957770801552513df 100644
--- a/dumux/freeflow/navierstokesnc/staggered/fluxvariables.hh
+++ b/dumux/freeflow/navierstokesnc/staggered/fluxvariables.hh
@@ -45,16 +45,14 @@ template<class TypeTag>
 class NavierStokesNCFluxVariablesImpl<TypeTag, DiscretizationMethod::staggered>
 : public NavierStokesFluxVariables<TypeTag>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using ParentType = NavierStokesFluxVariables<TypeTag>;
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using Element = typename GridView::template Codim<0>::Entity;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables);
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVElementGeometry = typename FVGridGeometry::LocalView;
+    using Element = typename FVGridGeometry::GridView::template Codim<0>::Entity;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
     using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
+    using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
     using MolecularDiffusionType = typename GET_PROP_TYPE(TypeTag, MolecularDiffusionType);
 
@@ -62,18 +60,13 @@ class NavierStokesNCFluxVariablesImpl<TypeTag, DiscretizationMethod::staggered>
 
     static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
 
-    // The index of the component balance equation that gets replaced with the total mass balance
-    static const int replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx);
-
-    using ParentType = NavierStokesFluxVariables<TypeTag>;
-
-    enum { conti0EqIdx = Indices::conti0EqIdx };
 
 public:
 
     /*!
     * \brief Computes the flux for the cell center residual.
     */
+    template<class ElementVolumeVariables, class ElementFaceVariables, class FluxVariablesCache>
     CellCenterPrimaryVariables computeFluxForCellCenter(const Problem& problem,
                                                         const Element &element,
                                                         const FVElementGeometry& fvGeometry,
@@ -87,7 +80,7 @@ public:
         for (int compIdx = 0; compIdx < numComponents; ++compIdx)
         {
             // get equation index
-            const auto eqIdx = conti0EqIdx + compIdx;
+            const auto eqIdx = Indices::conti0EqIdx + compIdx;
 
             bool isOutflow = false;
             if(scvf.boundary())
@@ -108,9 +101,9 @@ public:
         }
 
         // in case one balance is substituted by the total mass balance
-        if (replaceCompEqIdx < numComponents)
+        if (Indices::replaceCompEqIdx < numComponents)
         {
-            flux[replaceCompEqIdx] = std::accumulate(flux.begin(), flux.end(), 0.0);
+            flux[Indices::replaceCompEqIdx] = std::accumulate(flux.begin(), flux.end(), 0.0);
         }
 
         flux += MolecularDiffusionType::diffusiveFluxForCellCenter(problem, fvGeometry, elemVolVars, scvf);
diff --git a/dumux/freeflow/navierstokesnc/staggered/localresidual.hh b/dumux/freeflow/navierstokesnc/staggered/localresidual.hh
index 9cd326e89bd4147fcb140b8f6a2a42b204b6653d..511732d8a86bff209ea4d6883bd9339d8258c499 100644
--- a/dumux/freeflow/navierstokesnc/staggered/localresidual.hh
+++ b/dumux/freeflow/navierstokesnc/staggered/localresidual.hh
@@ -24,7 +24,6 @@
 #ifndef DUMUX_STAGGERED_NAVIERSTOKES_NC_LOCAL_RESIDUAL_HH
 #define DUMUX_STAGGERED_NAVIERSTOKES_NC_LOCAL_RESIDUAL_HH
 
-#include <dune/common/hybridutilities.hh>
 #include <dumux/common/properties.hh>
 #include <dumux/discretization/methods.hh>
 #include <dumux/freeflow/navierstokes/localresidual.hh>
@@ -53,20 +52,8 @@ class NavierStokesNCResidualImpl<TypeTag, DiscretizationMethod::staggered>
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
 
-    using CellCenterResidual = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables);
-
-    enum {
-        conti0EqIdx = Indices::conti0EqIdx,
-
-        // The index of the component balance equation
-        // that gets replaced with the total mass balance
-        replaceCompEqIdx = Indices::replaceCompEqIdx
-    };
-
-    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using CellCenterResidual = CellCenterPrimaryVariables;
 
     using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits);
 
@@ -77,6 +64,7 @@ public:
     using ParentType::ParentType;
 
     //! Evaluate fluxes entering or leaving the cell center control volume.
+    template<class VolumeVariables>
     CellCenterPrimaryVariables computeStorageForCellCenter(const Problem& problem,
                                                            const SubControlVolume& scv,
                                                            const VolumeVariables& volVars) const
@@ -88,18 +76,18 @@ public:
         // compute storage term of all components
         for (int compIdx = 0; compIdx < numComponents; ++compIdx)
         {
-            const int eqIdx = conti0EqIdx + compIdx;
+            const int eqIdx = Indices::conti0EqIdx + compIdx;
 
             const Scalar massOrMoleFraction = useMoles ? volVars.moleFraction(compIdx) : volVars.massFraction(compIdx);
             const Scalar s =  density * massOrMoleFraction;
 
-            if (eqIdx != replaceCompEqIdx)
+            if (eqIdx != Indices::replaceCompEqIdx)
                 storage[eqIdx] += s;
         }
 
         // in case one balance is substituted by the total mass balance
-        if(replaceCompEqIdx < numComponents)
-            storage[replaceCompEqIdx] = density;
+        if(Indices::replaceCompEqIdx < numComponents)
+            storage[Indices::replaceCompEqIdx] = density;
 
         this->computeStorageForCellCenterNonIsothermal_(std::integral_constant<bool, ModelTraits::enableEnergyBalance() >(),
                                                         problem, scv, volVars, storage);
@@ -113,6 +101,7 @@ protected:
      * \brief Sets a fixed Dirichlet value for a cell (such as pressure) at the boundary.
      *        This is a provisional alternative to setting the Dirichlet value on the boundary directly.
      */
+    template<class ElementVolumeVariables, class BoundaryTypes>
     void setFixedCell_(CellCenterResidual& residual,
                        const Problem& problem,
                        const SubControlVolume& insideScv,
@@ -124,10 +113,10 @@ protected:
         for (int compIdx = 0; compIdx < numComponents; ++compIdx)
         {
             // get equation index
-            const auto eqIdx = conti0EqIdx + compIdx;
+            const auto eqIdx = Indices::conti0EqIdx + compIdx;
 
             // set a fixed mole fraction for cells
-            if(eqIdx != conti0EqIdx && bcTypes.isDirichletCell(eqIdx))
+            if(eqIdx != Indices::conti0EqIdx && bcTypes.isDirichletCell(eqIdx))
             {
                 const auto& insideVolVars = elemVolVars[insideScv];
                 const Scalar massOrMoleFraction = useMoles ? insideVolVars.moleFraction(compIdx) : insideVolVars.massFraction(compIdx);
diff --git a/dumux/freeflow/rans/problem.hh b/dumux/freeflow/rans/problem.hh
index 4a16c81fc1379cb6a177b0c50caf950e0da3cff4..06f5ec7108fb3a19c920f4fc37b491667d963a47 100644
--- a/dumux/freeflow/rans/problem.hh
+++ b/dumux/freeflow/rans/problem.hh
@@ -70,10 +70,6 @@ class RANSProblem : public NavierStokesProblem<TypeTag>
     using DimVector = Dune::FieldVector<Scalar, dim>;
     using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
 public:
     //! The constructor sets the gravity, if desired by the user.
     RANSProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
@@ -232,7 +228,7 @@ public:
             for (auto&& scvf : scvfs(fvGeometry))
             {
                 const int dofIdxFace = scvf.dofIndex();
-                const auto numericalSolutionFace = curSol[faceIdx][dofIdxFace][Indices::momentumBalanceIdx];
+                const auto numericalSolutionFace = curSol[FVGridGeometry::faceIdx()][dofIdxFace][Indices::momentumBalanceIdx];
                 velocityTemp[scvf.directionIndex()] += numericalSolutionFace;
             }
             for (unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
@@ -288,8 +284,8 @@ public:
             for (auto&& scv : scvs(fvGeometry))
             {
                 const int dofIdx = scv.dofIndex();
-                CellCenterPrimaryVariables priVars(curSol[cellCenterIdx][dofIdx]);
-                auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(priVars));
+                CellCenterPrimaryVariables priVars(curSol[FVGridGeometry::cellCenterIdx()][dofIdx]);
+                auto elemSol = elementSolution<FVElementGeometry>(std::move(priVars));
                 VolumeVariables volVars;
                 volVars.update(elemSol, asImp_(), element, scv);
                 kinematicViscosity_[elementID] = volVars.viscosity() / volVars.density();
diff --git a/dumux/freeflow/rans/zeroeq/problem.hh b/dumux/freeflow/rans/zeroeq/problem.hh
index 2d6804870a84d3e119fd5dbea6c0766e22df1928..6144277a31a6165fa859658b83d3a03d040b42b2 100644
--- a/dumux/freeflow/rans/zeroeq/problem.hh
+++ b/dumux/freeflow/rans/zeroeq/problem.hh
@@ -70,10 +70,6 @@ class ZeroEqProblem : public RANSProblem<TypeTag>
     using DimVector = Dune::FieldVector<Scalar, dim>;
     using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
 public:
     //! The constructor sets the gravity, if desired by the user.
     ZeroEqProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
@@ -120,8 +116,8 @@ public:
                 using std::exp;
 
                 const int dofIdx = scv.dofIndex();
-                CellCenterPrimaryVariables priVars(curSol[cellCenterIdx][dofIdx]);
-                auto elemSol = elementSolution<SolutionVector, FVGridGeometry>(std::move(priVars));
+                CellCenterPrimaryVariables priVars(curSol[FVGridGeometry::cellCenterIdx()][dofIdx]);
+                auto elemSol = elementSolution<FVElementGeometry>(std::move(priVars));
                 VolumeVariables volVars;
                 volVars.update(elemSol, asImp_(), element, scv);
 
diff --git a/dumux/io/staggeredvtkoutputmodule.hh b/dumux/io/staggeredvtkoutputmodule.hh
index 400b2cace7311e9b26e7139b57c5763af0220d04..266a2b508112cf68d1b1110945717fdc0ea7b232 100644
--- a/dumux/io/staggeredvtkoutputmodule.hh
+++ b/dumux/io/staggeredvtkoutputmodule.hh
@@ -64,10 +64,6 @@ class StaggeredVtkOutputModule : public VtkOutputModule<TypeTag, phaseIdxOffset>
 
     using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
     struct FaceVarScalarDataInfo { std::function<Scalar(const FaceVariables&)> get; std::string name; };
     struct FaceVarVectorDataInfo { std::function<GlobalPosition(const SubControlVolumeFace& scvf, const FaceVariables&)> get; std::string name; };
 
diff --git a/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh b/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh
index 70dabf9d3402bb0b53461ea4bbf36fe47fa39dfb..c30045de5899c5bfafb9fdfb4cc1b0d5f29e957f 100644
--- a/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh
+++ b/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh
@@ -43,10 +43,10 @@ class OnePIncompressibleLocalResidual : public ImmiscibleLocalResidual<TypeTag>
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/dumux/porousmediumflow/1pnc/volumevariables.hh b/dumux/porousmediumflow/1pnc/volumevariables.hh
index 549e37b15eb973c9301a33cc1f1ea15bcb17aa6d..584592ca00d8b1ca0ed5961e93f00d6a6e51ff1b 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 b762cb3f0d44d0855e43cec6ff28b3adc321ffa8..ebc00a415e5cc9e5ad7a26fe043fdf4a9b3c11bc 100644
--- a/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh
+++ b/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh
@@ -46,10 +46,10 @@ class TwoPIncompressibleLocalResidual : public ImmiscibleLocalResidual<TypeTag>
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FVElementGeometry = typename FVGridGeometry::LocalView;
@@ -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/2p1c/darcyslaw.hh b/dumux/porousmediumflow/2p1c/darcyslaw.hh
index 75a85d718665de6dd2d029c92968a4592bc9ef65..d872f635927d768fd055f8806135d056d93e3733 100644
--- a/dumux/porousmediumflow/2p1c/darcyslaw.hh
+++ b/dumux/porousmediumflow/2p1c/darcyslaw.hh
@@ -52,9 +52,9 @@ class TwoPOneCDarcysLaw : public DarcysLaw<TypeTag>
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElemFluxVarCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElemFluxVarCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FluxVarCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
diff --git a/dumux/porousmediumflow/2p1c/localresidual.hh b/dumux/porousmediumflow/2p1c/localresidual.hh
index 6bbebc4dc31204b78aec644a504630eebe4d3ca0..e46738384b733e0d5198ea20f11208b92499c878 100644
--- a/dumux/porousmediumflow/2p1c/localresidual.hh
+++ b/dumux/porousmediumflow/2p1c/localresidual.hh
@@ -41,9 +41,9 @@ class TwoPOneCLocalResidual : public ImmiscibleLocalResidual<TypeTag>
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/dumux/porousmediumflow/2pnc/volumevariables.hh b/dumux/porousmediumflow/2pnc/volumevariables.hh
index 0e8c05a0454c3c84d898d2c67bb49d91b9d2fe66..919876ac1b4ccac412b8a1739e247a3a9e2d0259 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/3p3c/localresidual.hh b/dumux/porousmediumflow/3p3c/localresidual.hh
index df127346e46c423ca8ad7240478f3d053d4d7e15..ce42b0113862c178d6d3e4531ed99ad93b6274cd 100644
--- a/dumux/porousmediumflow/3p3c/localresidual.hh
+++ b/dumux/porousmediumflow/3p3c/localresidual.hh
@@ -48,11 +48,11 @@ class ThreePThreeCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using EnergyLocalResidual = typename GET_PROP_TYPE(TypeTag, EnergyLocalResidual);
 
diff --git a/dumux/porousmediumflow/3pwateroil/localresidual.hh b/dumux/porousmediumflow/3pwateroil/localresidual.hh
index d4f456af651419b56dc38bcc6306f8095c28330f..95697b854ddad84ae802856d2994c30de7eca4da 100644
--- a/dumux/porousmediumflow/3pwateroil/localresidual.hh
+++ b/dumux/porousmediumflow/3pwateroil/localresidual.hh
@@ -50,11 +50,11 @@ protected:
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using EnergyLocalResidual = typename GET_PROP_TYPE(TypeTag, EnergyLocalResidual);
 
diff --git a/dumux/porousmediumflow/compositional/localresidual.hh b/dumux/porousmediumflow/compositional/localresidual.hh
index 098e70f9dfff7af529cc39f2097f3050e877a244..70013c544bacc046f748a1812a32f2844c3d32c7 100644
--- a/dumux/porousmediumflow/compositional/localresidual.hh
+++ b/dumux/porousmediumflow/compositional/localresidual.hh
@@ -47,11 +47,11 @@ class CompositionalLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidua
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using EnergyLocalResidual = typename GET_PROP_TYPE(TypeTag, EnergyLocalResidual);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
diff --git a/dumux/porousmediumflow/fluxvariables.hh b/dumux/porousmediumflow/fluxvariables.hh
index 654b681c057b845a0cbea6f472753b33cb6f9188..3d8056fce1ee4ff4f071fde227d1faf6100e7896 100644
--- a/dumux/porousmediumflow/fluxvariables.hh
+++ b/dumux/porousmediumflow/fluxvariables.hh
@@ -43,7 +43,11 @@ namespace Dumux {
  */
 template<class TypeTag,
          class UpwindScheme = UpwindScheme<typename GET_PROP_TYPE(TypeTag, FVGridGeometry)> >
-class PorousMediumFluxVariables : public FluxVariablesBase<TypeTag>
+class PorousMediumFluxVariables
+: public FluxVariablesBase<typename GET_PROP_TYPE(TypeTag, Problem),
+                           typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView,
+                           typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView,
+                           typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView>
 {
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits);
@@ -55,8 +59,8 @@ class PorousMediumFluxVariables : public FluxVariablesBase<TypeTag>
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
 
     enum
     {
diff --git a/dumux/porousmediumflow/fluxvariablescache.hh b/dumux/porousmediumflow/fluxvariablescache.hh
index 8c13835056a8c607f4f02efd527e721610fae8b4..32699d57d963f18931851a77f24bd16bb24fb9e5 100644
--- a/dumux/porousmediumflow/fluxvariablescache.hh
+++ b/dumux/porousmediumflow/fluxvariablescache.hh
@@ -61,7 +61,7 @@ class PorousMediumFluxVariablesCacheImplementation<TypeTag, DiscretizationMethod
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using Element = typename GridView::template Codim<0>::Entity;
     using IndexType = typename GridView::IndexSet::IndexType;
diff --git a/dumux/porousmediumflow/immiscible/localresidual.hh b/dumux/porousmediumflow/immiscible/localresidual.hh
index 0b60c613ff730b6c03a8107241fe893415256d4a..fc81af5500baa86d10cf6f92deefcbc7b732eeb5 100644
--- a/dumux/porousmediumflow/immiscible/localresidual.hh
+++ b/dumux/porousmediumflow/immiscible/localresidual.hh
@@ -42,9 +42,9 @@ class ImmiscibleLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/dumux/porousmediumflow/mpnc/localresidual.hh b/dumux/porousmediumflow/mpnc/localresidual.hh
index 2605a68f736955313112d5acbee19630dab4fe9b..96d085609012e7f09119da0d01c093590efb96cf 100644
--- a/dumux/porousmediumflow/mpnc/localresidual.hh
+++ b/dumux/porousmediumflow/mpnc/localresidual.hh
@@ -48,8 +48,8 @@ class MPNCLocalResidual : public CompositionalLocalResidual<TypeTag>
     using Element = typename GET_PROP_TYPE(TypeTag, GridView)::template Codim<0>::Entity;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using ElementBoundaryTypes = typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
     enum {numPhases = GET_PROP_TYPE(TypeTag, ModelTraits)::numPhases()};
diff --git a/dumux/porousmediumflow/nonequilibrium/localresidual.hh b/dumux/porousmediumflow/nonequilibrium/localresidual.hh
index 87031244378919f58e186c3d0315a250c2f2dd94..4bc8d8288f3288838d52ec36bc1e97a5c80875f0 100644
--- a/dumux/porousmediumflow/nonequilibrium/localresidual.hh
+++ b/dumux/porousmediumflow/nonequilibrium/localresidual.hh
@@ -52,11 +52,11 @@ class NonEquilibriumLocalResidualImplementation<TypeTag, true, false>: public GE
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using EnergyLocalResidual = typename GET_PROP_TYPE(TypeTag, EnergyLocalResidual);
 
     static constexpr int numPhases = GET_PROP_TYPE(TypeTag, ModelTraits)::numPhases();
@@ -163,12 +163,12 @@ class NonEquilibriumLocalResidualImplementation<TypeTag, true, true>: public GET
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using EnergyLocalResidual = typename GET_PROP_TYPE(TypeTag, EnergyLocalResidual);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
diff --git a/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh b/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh
index ee8c2976177b7636d755b7460f5c22dc40b908da..63ee4d49e207875a54b96617a7e03a6265abbbd7 100644
--- a/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh
+++ b/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh
@@ -53,7 +53,7 @@ class EnergyLocalResidualNonEquilibrium<TypeTag, 1/*numEnergyEqFluid*/>
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
     enum { numEnergyEqFluid = GET_PROP_VALUE(TypeTag, NumEnergyEqFluid) };
@@ -322,7 +322,7 @@ class EnergyLocalResidualNonEquilibrium<TypeTag, 2 /*numEnergyEqFluid*/>
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
     enum { numPhases        = GET_PROP_TYPE(TypeTag, ModelTraits)::numPhases() };
diff --git a/dumux/porousmediumflow/richards/localresidual.hh b/dumux/porousmediumflow/richards/localresidual.hh
index a74420e0d2e8f7b5f87de24c74383220bfad9e95..117b14a91a95095a44486d00791b8fdafd446e59 100644
--- a/dumux/porousmediumflow/richards/localresidual.hh
+++ b/dumux/porousmediumflow/richards/localresidual.hh
@@ -44,9 +44,9 @@ class RichardsLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/dumux/porousmediumflow/tracer/localresidual.hh b/dumux/porousmediumflow/tracer/localresidual.hh
index ea845f1c59bad54e849c1e346a2b6166a50fa015..5783b45f07e530d52cc3dfc160fda869e04b0f2a 100644
--- a/dumux/porousmediumflow/tracer/localresidual.hh
+++ b/dumux/porousmediumflow/tracer/localresidual.hh
@@ -49,10 +49,10 @@ class TracerLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
 
diff --git a/dumux/porousmediumflow/velocityoutput.hh b/dumux/porousmediumflow/velocityoutput.hh
index ac2572875bea94077977d105b2a375dabfc51871..cb10fe222a47853c0903f559014dbc97aef3aaef 100644
--- a/dumux/porousmediumflow/velocityoutput.hh
+++ b/dumux/porousmediumflow/velocityoutput.hh
@@ -47,7 +47,7 @@ class PorousMediumFlowVelocityOutput
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
diff --git a/dumux/porousmediumflow/volumevariables.hh b/dumux/porousmediumflow/volumevariables.hh
index a939ee9b2e7239bcc48f9ea04ddb38974654570f..397a4b0f4f04e675b7a74905c0c9f7af6e4fffee 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
diff --git a/test/discretization/staggered/test_staggered_free_flow_geometry.cc b/test/discretization/staggered/test_staggered_free_flow_geometry.cc
index b6f72ef7a1ae7194d11dfa774e730015377984f9..3fdacbc911f95ef3958a7f1f78ac6a60b1f86298 100644
--- a/test/discretization/staggered/test_staggered_free_flow_geometry.cc
+++ b/test/discretization/staggered/test_staggered_free_flow_geometry.cc
@@ -67,7 +67,7 @@ struct TestFVGGTraits : public DefaultMapperTraits<GridView>
     };
 
     template<class FVGridGeometry>
-    using ConnectivityMap = StaggeredFreeFlowConnectivityMap<FVGridGeometry, DofTypeIndices>;
+    using ConnectivityMap = StaggeredFreeFlowConnectivityMap<FVGridGeometry>;
 
     template<class FVGridGeometry, bool enableCache>
     using LocalView = StaggeredFVElementGeometry<FVGridGeometry, enableCache>;
diff --git a/test/discretization/staggered/test_staggeredfvgeometry.cc b/test/discretization/staggered/test_staggeredfvgeometry.cc
index 7191b03face3b32cb762ad033f303e8901f05351..b23013d12abe9f97ef1f68399bfd703b50788c04 100644
--- a/test/discretization/staggered/test_staggeredfvgeometry.cc
+++ b/test/discretization/staggered/test_staggeredfvgeometry.cc
@@ -58,6 +58,12 @@ struct TestFVGGTraits : public DefaultMapperTraits<GridView>
     using IntersectionMapper = ConformingGridIntersectionMapper<GridView>;
     using GeometryHelper = BaseStaggeredGeometryHelper<GridView>;
 
+    struct DofTypeIndices
+    {
+        using CellCenterIdx = Dune::index_constant<0>;
+        using FaceIdx = Dune::index_constant<1>;
+    };
+
     //! Dummy connectivity map, required by FVGridGeometry
     template<class FVGridGeometry>
     struct MockConnectivityMap
diff --git a/test/freeflow/navierstokes/angelitestproblem.hh b/test/freeflow/navierstokes/angelitestproblem.hh
index 1bf48f17c8316f764a701c6fb334eb719ebdcf8e..69c8a21a9c372fb8edbab8688348177cb1d7cb3c 100644
--- a/test/freeflow/navierstokes/angelitestproblem.hh
+++ b/test/freeflow/navierstokes/angelitestproblem.hh
@@ -102,10 +102,6 @@ class AngeliTestProblem : public NavierStokesProblem<TypeTag>
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using TimeLoopPtr = std::shared_ptr<TimeLoop<Scalar>>;
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
 public:
     AngeliTestProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
     : ParentType(fvGridGeometry), eps_(1e-6)
@@ -269,7 +265,7 @@ public:
                 const auto dofIdxCellCenter = scv.dofIndex();
                 const auto& posCellCenter = scv.dofPosition();
                 const auto analyticalSolutionCellCenter = dirichletAtPos(posCellCenter)[pressureIdx];
-                const auto numericalSolutionCellCenter = curSol[cellCenterIdx][dofIdxCellCenter][pressureIdx];
+                const auto numericalSolutionCellCenter = curSol[FVGridGeometry::cellCenterIdx()][dofIdxCellCenter][pressureIdx];
                 sumError[pressureIdx] += squaredDiff_(analyticalSolutionCellCenter, numericalSolutionCellCenter) * scv.volume();
                 sumReference[pressureIdx] += analyticalSolutionCellCenter * analyticalSolutionCellCenter * scv.volume();
                 totalVolume += scv.volume();
@@ -280,7 +276,7 @@ public:
                     const int dofIdxFace = scvf.dofIndex();
                     const int dirIdx = scvf.directionIndex();
                     const auto analyticalSolutionFace = dirichletAtPos(scvf.center())[Indices::velocity(dirIdx)];
-                    const auto numericalSolutionFace = curSol[faceIdx][dofIdxFace][momentumBalanceIdx];
+                    const auto numericalSolutionFace = curSol[FVGridGeometry::faceIdx()][dofIdxFace][momentumBalanceIdx];
                     directionIndex[dofIdxFace] = dirIdx;
                     errorVelocity[dofIdxFace] = squaredDiff_(analyticalSolutionFace, numericalSolutionFace);
                     velocityReference[dofIdxFace] = squaredDiff_(analyticalSolutionFace, 0.0);
diff --git a/test/freeflow/navierstokes/doneatestproblem.hh b/test/freeflow/navierstokes/doneatestproblem.hh
index aa37532b29b9bd12f8c77072ff5dbd35bc7dac30..bcced08b37db337d0d384e5cbb196d22e5d7ae3b 100644
--- a/test/freeflow/navierstokes/doneatestproblem.hh
+++ b/test/freeflow/navierstokes/doneatestproblem.hh
@@ -107,10 +107,6 @@ class DoneaTestProblem : public NavierStokesProblem<TypeTag>
 
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
 public:
     DoneaTestProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
     : ParentType(fvGridGeometry), eps_(1e-6)
@@ -289,7 +285,7 @@ public:
                 const auto dofIdxCellCenter = scv.dofIndex();
                 const auto& posCellCenter = scv.dofPosition();
                 const auto analyticalSolutionCellCenter = analyticalSolution(posCellCenter)[pressureIdx];
-                const auto numericalSolutionCellCenter = curSol[cellCenterIdx][dofIdxCellCenter][pressureIdx];
+                const auto numericalSolutionCellCenter = curSol[FVGridGeometry::cellCenterIdx()][dofIdxCellCenter][pressureIdx];
                 sumError[pressureIdx] += squaredDiff_(analyticalSolutionCellCenter, numericalSolutionCellCenter) * scv.volume();
                 sumReference[pressureIdx] += analyticalSolutionCellCenter * analyticalSolutionCellCenter * scv.volume();
                 totalVolume += scv.volume();
@@ -300,7 +296,7 @@ public:
                     const int dofIdxFace = scvf.dofIndex();
                     const int dirIdx = scvf.directionIndex();
                     const auto analyticalSolutionFace = analyticalSolution(scvf.center())[Indices::velocity(dirIdx)];
-                    const auto numericalSolutionFace = curSol[faceIdx][dofIdxFace][momentumBalanceIdx];
+                    const auto numericalSolutionFace = curSol[FVGridGeometry::faceIdx()][dofIdxFace][momentumBalanceIdx];
                     directionIndex[dofIdxFace] = dirIdx;
                     errorVelocity[dofIdxFace] = squaredDiff_(analyticalSolutionFace, numericalSolutionFace);
                     velocityReference[dofIdxFace] = squaredDiff_(analyticalSolutionFace, 0.0);
diff --git a/test/freeflow/navierstokes/kovasznaytestproblem.hh b/test/freeflow/navierstokes/kovasznaytestproblem.hh
index a48d460850db0a9c2f561984a3abb05f9cff3aa3..42e39273408323b0db3dd1014df6bde84325ffd5 100644
--- a/test/freeflow/navierstokes/kovasznaytestproblem.hh
+++ b/test/freeflow/navierstokes/kovasznaytestproblem.hh
@@ -100,10 +100,6 @@ class KovasznayTestProblem : public NavierStokesProblem<TypeTag>
 
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
 
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
-
 public:
     KovasznayTestProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
     : ParentType(fvGridGeometry), eps_(1e-6)
@@ -278,7 +274,7 @@ public:
                 const auto dofIdxCellCenter = scv.dofIndex();
                 const auto& posCellCenter = scv.dofPosition();
                 const auto analyticalSolutionCellCenter = dirichletAtPos(posCellCenter)[pressureIdx];
-                const auto numericalSolutionCellCenter = curSol[cellCenterIdx][dofIdxCellCenter][pressureIdx];
+                const auto numericalSolutionCellCenter = curSol[FVGridGeometry::cellCenterIdx()][dofIdxCellCenter][pressureIdx];
                 sumError[pressureIdx] += squaredDiff_(analyticalSolutionCellCenter, numericalSolutionCellCenter) * scv.volume();
                 sumReference[pressureIdx] += analyticalSolutionCellCenter * analyticalSolutionCellCenter * scv.volume();
                 totalVolume += scv.volume();
@@ -289,7 +285,7 @@ public:
                     const int dofIdxFace = scvf.dofIndex();
                     const int dirIdx = scvf.directionIndex();
                     const auto analyticalSolutionFace = dirichletAtPos(scvf.center())[Indices::velocity(dirIdx)];
-                    const auto numericalSolutionFace = curSol[faceIdx][dofIdxFace][momentumBalanceIdx];
+                    const auto numericalSolutionFace = curSol[FVGridGeometry::faceIdx()][dofIdxFace][momentumBalanceIdx];
                     directionIndex[dofIdxFace] = dirIdx;
                     errorVelocity[dofIdxFace] = squaredDiff_(analyticalSolutionFace, numericalSolutionFace);
                     velocityReference[dofIdxFace] = squaredDiff_(analyticalSolutionFace, 0.0);
diff --git a/test/freeflow/navierstokes/test_angeli.cc b/test/freeflow/navierstokes/test_angeli.cc
index f03d587cc24a29e62abc095ff89390cc4406bf68..8ced7b487033e8b2d1f36cfeedcfa8b1eb522a48 100644
--- a/test/freeflow/navierstokes/test_angeli.cc
+++ b/test/freeflow/navierstokes/test_angeli.cc
@@ -139,14 +139,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     auto xOld = x;
 
diff --git a/test/freeflow/navierstokes/test_channel.cc b/test/freeflow/navierstokes/test_channel.cc
index a8ed792f882d8ada5a16759c29d4c5d72a9c2c2a..1ac6b724a67d80c8e9ebf14c080486b9efe0308a 100644
--- a/test/freeflow/navierstokes/test_channel.cc
+++ b/test/freeflow/navierstokes/test_channel.cc
@@ -140,14 +140,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     auto xOld = x;
 
diff --git a/test/freeflow/navierstokes/test_closedsystem.cc b/test/freeflow/navierstokes/test_closedsystem.cc
index a9a0f9146144f6c50ef835e52baf02ce915f515d..0fdd3bd631a8a7648fe9a84599b46f2621a31d40 100644
--- a/test/freeflow/navierstokes/test_closedsystem.cc
+++ b/test/freeflow/navierstokes/test_closedsystem.cc
@@ -122,14 +122,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     auto xOld = x;
 
diff --git a/test/freeflow/navierstokes/test_donea.cc b/test/freeflow/navierstokes/test_donea.cc
index 22f2060dd62953a7c74470fbae2d73fc85b8de1a..acfc16266215fe0addeef62cfa8e26b69dcf8af6 100644
--- a/test/freeflow/navierstokes/test_donea.cc
+++ b/test/freeflow/navierstokes/test_donea.cc
@@ -124,14 +124,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
 
     // the grid variables
     using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
diff --git a/test/freeflow/navierstokes/test_kovasznay.cc b/test/freeflow/navierstokes/test_kovasznay.cc
index fe78ec1ac4bb26cc1ba01893a577f66c6497353b..882aca078b467608847bdc292d2e325079bd6455 100644
--- a/test/freeflow/navierstokes/test_kovasznay.cc
+++ b/test/freeflow/navierstokes/test_kovasznay.cc
@@ -123,14 +123,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
 
     // the grid variables
     using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
diff --git a/test/freeflow/navierstokesnc/test_channel.cc b/test/freeflow/navierstokesnc/test_channel.cc
index 4804fe67d8dcc6459eb925d8710188fad0e2b2ff..9198f5df82b599af9b7837ac1db0b8f30518ae17 100644
--- a/test/freeflow/navierstokesnc/test_channel.cc
+++ b/test/freeflow/navierstokesnc/test_channel.cc
@@ -138,14 +138,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     auto xOld = x;
 
diff --git a/test/freeflow/navierstokesnc/test_densitydrivenflow.cc b/test/freeflow/navierstokesnc/test_densitydrivenflow.cc
index 878279e13f86bd324dc201b874e7ede84a13dd78..614df58447027d2ccc0522e1f458c7d88acd1792 100644
--- a/test/freeflow/navierstokesnc/test_densitydrivenflow.cc
+++ b/test/freeflow/navierstokesnc/test_densitydrivenflow.cc
@@ -137,14 +137,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     auto xOld = x;
 
diff --git a/test/freeflow/navierstokesnc/test_msfreeflow.cc b/test/freeflow/navierstokesnc/test_msfreeflow.cc
index 60dfb7cbafbb568304d5d0f5e68843e89123340f..88c23a75a6304f3901075b590db2183b2cb2b2cc 100644
--- a/test/freeflow/navierstokesnc/test_msfreeflow.cc
+++ b/test/freeflow/navierstokesnc/test_msfreeflow.cc
@@ -137,14 +137,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     auto xOld = x;
 
diff --git a/test/freeflow/rans/test_pipe_laufer.cc b/test/freeflow/rans/test_pipe_laufer.cc
index 44145ade4ac862e6e8de08cbabe66194898a5fef..c017d6f1060c00dc67a6847c8720a549a5a40c7b 100644
--- a/test/freeflow/rans/test_pipe_laufer.cc
+++ b/test/freeflow/rans/test_pipe_laufer.cc
@@ -133,14 +133,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     problem->updateStaticWallProperties();
     problem->updateDynamicWallProperties(x);
diff --git a/test/freeflow/ransnc/test_channel_zeroeq.cc b/test/freeflow/ransnc/test_channel_zeroeq.cc
index b5ec7fb8b77df1438ab542144395b68a5603dab1..da76773a4e2b33670a271084d507e40d90259393 100644
--- a/test/freeflow/ransnc/test_channel_zeroeq.cc
+++ b/test/freeflow/ransnc/test_channel_zeroeq.cc
@@ -127,14 +127,11 @@ int main(int argc, char** argv) try
 
     // the solution vector
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
-    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
-    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
-    typename DofTypeIndices::FaceIdx faceIdx;
     const auto numDofsCellCenter = leafGridView.size(0);
     const auto numDofsFace = leafGridView.size(1);
     SolutionVector x;
-    x[cellCenterIdx].resize(numDofsCellCenter);
-    x[faceIdx].resize(numDofsFace);
+    x[FVGridGeometry::cellCenterIdx()].resize(numDofsCellCenter);
+    x[FVGridGeometry::faceIdx()].resize(numDofsFace);
     problem->applyInitialSolution(x);
     problem->updateStaticWallProperties();
     problem->updateDynamicWallProperties(x);
diff --git a/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh b/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh
index 051db2b52e2fc13c79b980a6cd18c4a72e49e1ab..e7b2f33d601dee11af466b50b657e26b88d93519 100644
--- a/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh
+++ b/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh
@@ -105,7 +105,7 @@ class OnePNIConvectionProblem : public PorousMediumFlowProblem<TypeTag>
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using IapwsH2O = H2O<Scalar>;
diff --git a/test/porousmediumflow/1p/implicit/pointsources/1psingularityproblemtimedependent.hh b/test/porousmediumflow/1p/implicit/pointsources/1psingularityproblemtimedependent.hh
index 0ae5be43708f1076e6225fc9a8adcb9085beb03d..05a70dced761f9027512e40e5eb082beec728330 100644
--- a/test/porousmediumflow/1p/implicit/pointsources/1psingularityproblemtimedependent.hh
+++ b/test/porousmediumflow/1p/implicit/pointsources/1psingularityproblemtimedependent.hh
@@ -69,7 +69,7 @@ class OnePSingularityProblemTimeDependent : public OnePSingularityProblem<TypeTa
     using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
     using Element = typename GridView::template Codim<0>::Entity;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
 
diff --git a/test/porousmediumflow/1p/implicit/tubesproblem.hh b/test/porousmediumflow/1p/implicit/tubesproblem.hh
index 831e7d4da6b5629df48e9e0545c38dc102514889..71ee8eb5a8545c1204e468dadb69a054331c0bd9 100644
--- a/test/porousmediumflow/1p/implicit/tubesproblem.hh
+++ b/test/porousmediumflow/1p/implicit/tubesproblem.hh
@@ -78,7 +78,7 @@ class TubesTestProblem : public PorousMediumFlowProblem<TypeTag>
     using ParentType = PorousMediumFlowProblem<TypeTag>;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
 
     // Grid and world dimension
     static const int dim = GridView::dimension;
diff --git a/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh b/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh
index 6996c812cc0bd5e5ab49ebba78652f1261bd5de7..4e8ad85c8ca280c03acb443b298aa12831bcdca5 100644
--- a/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh
+++ b/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh
@@ -110,7 +110,7 @@ class OnePTwoCNIConvectionProblem : public PorousMediumFlowProblem<TypeTag>
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using Element = typename GridView::template Codim<0>::Entity;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
diff --git a/test/porousmediumflow/1pnc/implicit/1p2ctestproblem.hh b/test/porousmediumflow/1pnc/implicit/1p2ctestproblem.hh
index b99f987cc8fe872336c7d305c16d537cfb393281..175c0a628a0fd737f9ed5012f8148f9408fc62d5 100644
--- a/test/porousmediumflow/1pnc/implicit/1p2ctestproblem.hh
+++ b/test/porousmediumflow/1pnc/implicit/1p2ctestproblem.hh
@@ -110,7 +110,7 @@ class OnePTwoCTestProblem : public PorousMediumFlowProblem<TypeTag>
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using Element = typename GridView::template Codim<0>::Entity;
 
diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh
index 85c73e4b7987bf8cd21e593378880bf7d8ab1e76..5e669a82b889478aadd5f600195196a3429d265e 100644
--- a/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh
+++ b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh
@@ -90,7 +90,7 @@ class ThermoChemProblem : public PorousMediumFlowProblem<TypeTag>
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using Element = typename GridView::template Codim<0>::Entity;
diff --git a/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh b/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh
index 53479eb7ec5e1582b7dbe51d7752d8c88f47edaa..9691077087cd2f78a019a655da5c556d30d02cd2 100644
--- a/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh
+++ b/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh
@@ -124,7 +124,7 @@ class InjectionProblem2PNI : public PorousMediumFlowProblem<TypeTag>
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
 
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
diff --git a/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh b/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh
index 124a0f56e9bef640411ed90f9a11e84a082e0f17..f6780bf4e4405dd277efe54824c2ffcee779f936 100644
--- a/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh
+++ b/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh
@@ -87,7 +87,7 @@ class InjectionProblem : public PorousMediumFlowProblem<TypeTag>
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/test/porousmediumflow/2p2c/implicit/injectionproblem.hh b/test/porousmediumflow/2p2c/implicit/injectionproblem.hh
index d28db992a08d7e72e73682dfdd6b9ef74aa6e79d..3706e9f57dbdddca87f5cf9ea9b703451972710f 100644
--- a/test/porousmediumflow/2p2c/implicit/injectionproblem.hh
+++ b/test/porousmediumflow/2p2c/implicit/injectionproblem.hh
@@ -126,7 +126,7 @@ class InjectionProblem : public PorousMediumFlowProblem<TypeTag>
 
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using Element = typename GridView::template Codim<0>::Entity;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
diff --git a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh
index 3b01a027ad9cec55f5e603d882a225141eea64b1..10e8ddaacaa8c6fd7286447d2fa323e5e0a2bca7 100644
--- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh
+++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh
@@ -100,7 +100,7 @@ class TwoPTwoCComparisonProblem
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NeumannFluxes = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
diff --git a/test/porousmediumflow/2p2c/implicit/waterairproblem.hh b/test/porousmediumflow/2p2c/implicit/waterairproblem.hh
index 4bd91d27c1db5aa1ecc1acd6496a36471b25714d..0c63dfe74c420c8c228b8bbbcdcdbbc287fa5a4b 100644
--- a/test/porousmediumflow/2p2c/implicit/waterairproblem.hh
+++ b/test/porousmediumflow/2p2c/implicit/waterairproblem.hh
@@ -134,7 +134,7 @@ class WaterAirProblem : public PorousMediumFlowProblem<TypeTag>
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
 
     using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
 
diff --git a/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh b/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh
index 89c86c7d11ef68f0a6c5b02840843a364a594927..43339c3b368c23fc56290c6e132f7b7b0007d8f5 100644
--- a/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh
+++ b/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh
@@ -86,7 +86,7 @@ class FuelCellProblem : public PorousMediumFlowProblem<TypeTag>
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
index 7be67396b04bfc5143688adf82cc77dc07c8379d..40f2f7e57720a5c25354234f24be0c616ad6f9ab 100644
--- a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
+++ b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
@@ -128,7 +128,7 @@ class DissolutionProblem : public PorousMediumFlowProblem<TypeTag>
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using Element = typename GridView::template Codim<0>::Entity;
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
diff --git a/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh b/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh
index 239ff94903397e457cf02dc15ab81d676de4ca9b..d5c67f5afe581c02ca1629cf522d6d3619b392ee 100644
--- a/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh
+++ b/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh
@@ -113,7 +113,7 @@ class ThreePNIConvectionProblem : public PorousMediumFlowProblem<TypeTag>
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using IapwsH2O = H2O<Scalar>;
diff --git a/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh b/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh
index dbfe8d9659467add145b601bc71b8ff0f1cd5064..228530d693e3ab5650a40d495825dc1685dac8bb 100644
--- a/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh
+++ b/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh
@@ -120,7 +120,7 @@ class ColumnProblem : public PorousMediumFlowProblem<TypeTag>
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GlobalPosition = Dune::FieldVector<typename GridView::ctype, dimWorld>;
 
diff --git a/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh b/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh
index eca71a09304dc72818303c5e6a8c96e93645bda9..3a854ac6548f13780629ef7c6a15f475d2e8b7e1 100644
--- a/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh
+++ b/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh
@@ -137,7 +137,7 @@ class KuevetteProblem : public PorousMediumFlowProblem<TypeTag>
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
 
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
     using GlobalPosition = Dune::FieldVector<typename GridView::ctype, dimWorld>;
diff --git a/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh b/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh
index 044c8618988224af1455345231baa95fd2a38b06..d92a0af07cbb611f57717011fe7099437d3ad32b 100644
--- a/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh
+++ b/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh
@@ -102,7 +102,7 @@ class SagdProblem : public PorousMediumFlowProblem<TypeTag>
 
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using Element = typename GridView::template Codim<0>::Entity;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
diff --git a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh
index 33ad7ac3e6fabde6cb4f0ce86ffa5a6d9c43c20e..19da7b2f06fd67fed5c9eb4ac679c61b07be69bb 100644
--- a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh
+++ b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh
@@ -123,7 +123,7 @@ class HeterogeneousProblem : public PorousMediumFlowProblem<TypeTag>
     using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
 
     enum { dimWorld = GridView::dimensionworld };
diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh
index d4797d87da943eb9b3e5994bdbebc08b6e541d12..7d7476b8c7995f8fecf854fe7f07e68e0b0f4abe 100644
--- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh
+++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh
@@ -101,7 +101,7 @@ class MPNCComparisonProblem
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NeumannFluxes = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
diff --git a/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh b/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh
index 73100f151a5595dd3d35043cbbcf2010530d3421..7ae025b8ffd77921ee06381ad0f6ac40e60f3f18 100644
--- a/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh
+++ b/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh
@@ -131,7 +131,7 @@ class CombustionProblemOneComponent: public PorousMediumFlowProblem<TypeTag>
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh b/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh
index 63b04283ba414ea1a015165c39c4a87bf855c767..71167cf3c4996847b167617cac8d70499a508847 100644
--- a/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh
+++ b/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh
@@ -106,7 +106,7 @@ class EvaporationAtmosphereProblem: public PorousMediumFlowProblem<TypeTag>
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh b/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh
index 254547d31e92fe1f15d6c43b5a7d518ded60814e..aa53c388c3264178511501384ba80174267f62c9 100644
--- a/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh
+++ b/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh
@@ -114,7 +114,7 @@ class ObstacleProblem
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
diff --git a/test/porousmediumflow/mpnc/implicit/plotoverline2d.hh b/test/porousmediumflow/mpnc/implicit/plotoverline2d.hh
index 1db898201b600c0e233fec1c5fe2a326f2cb9dbc..bed0a2db53df3553eaf8fc20efb662482f85ea03 100644
--- a/test/porousmediumflow/mpnc/implicit/plotoverline2d.hh
+++ b/test/porousmediumflow/mpnc/implicit/plotoverline2d.hh
@@ -51,7 +51,6 @@ namespace Properties
     NEW_PROP_TAG(TwoPIAIndices);
     NEW_PROP_TAG(NumEq);
     NEW_PROP_TAG(MaterialLaw);
-    NEW_PROP_TAG(ElementVolumeVariables);
     NEW_PROP_TAG(AwnSurface);
     NEW_PROP_TAG(AwnSurfaceParams);
 }
@@ -69,7 +68,7 @@ class PlotOverLine2D
     using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw);
     using aterialLawParams = typename MaterialLaw::Params;
 
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
 
     enum {
diff --git a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh
index ecf909b6e116f6346ac4a5be01c6204d5f36d031..3647305dd3ab9b227e1eeb104489fad340987dfb 100644
--- a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh
+++ b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh
@@ -111,7 +111,7 @@ class RichardsNIConvectionProblem : public PorousMediumFlowProblem<TypeTag>
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
     using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using IapwsH2O = H2O<Scalar>;
diff --git a/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh b/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh
index b91f35ab157b037905c665c2855f9826a91eb359..048843e3d7cd24594baf6920b8282b0d2c3f9533 100644
--- a/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh
+++ b/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh
@@ -97,7 +97,7 @@ class RichardsWellTracerProblem : public PorousMediumFlowProblem<TypeTag>
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
     using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw);
     using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
diff --git a/test/porousmediumflow/tracer/1ptracer/tracertestspatialparams.hh b/test/porousmediumflow/tracer/1ptracer/tracertestspatialparams.hh
index eb7e62a30fc41244ca6ccae5645eec0273ba5062..864e9b2195173c163f28728ccf12b08b7b44a0d0 100644
--- a/test/porousmediumflow/tracer/1ptracer/tracertestspatialparams.hh
+++ b/test/porousmediumflow/tracer/1ptracer/tracertestspatialparams.hh
@@ -41,7 +41,7 @@ class TracerTestSpatialParams : public FVSpatialParamsOneP<TypeTag>
     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 ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
diff --git a/test/porousmediumflow/tracer/constvel/tracertestspatialparams.hh b/test/porousmediumflow/tracer/constvel/tracertestspatialparams.hh
index b91d384265ee39033be290ccaa1895b8b48ae1d8..fbb48e31ab8190fcedd1b70962e65ece1f5f99bf 100644
--- a/test/porousmediumflow/tracer/constvel/tracertestspatialparams.hh
+++ b/test/porousmediumflow/tracer/constvel/tracertestspatialparams.hh
@@ -41,7 +41,7 @@ class TracerTestSpatialParams : public FVSpatialParamsOneP<TypeTag>
     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 ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
diff --git a/test/porousmediumflow/tracer/multicomp/maxwellstefantestspatialparams.hh b/test/porousmediumflow/tracer/multicomp/maxwellstefantestspatialparams.hh
index 9b916850cdb2dffabd02150197241850048e47e8..6cc5cdb495c14f5b413ec28889ec50d4edc36537 100644
--- a/test/porousmediumflow/tracer/multicomp/maxwellstefantestspatialparams.hh
+++ b/test/porousmediumflow/tracer/multicomp/maxwellstefantestspatialparams.hh
@@ -41,7 +41,7 @@ class MaxwellStefanTestSpatialParams : public FVSpatialParamsOneP<TypeTag>
     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 ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
 
diff --git a/tutorial/ex2/mylocalresidual.hh b/tutorial/ex2/mylocalresidual.hh
index ed03160ffde951e7e74c1ed98f75da9f6f7d4972..bebb514dc0058dcf9f0708458097782f15970b6c 100644
--- a/tutorial/ex2/mylocalresidual.hh
+++ b/tutorial/ex2/mylocalresidual.hh
@@ -48,11 +48,11 @@ class MyCompositionalLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResid
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using ResidualVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using EnergyLocalResidual = typename GET_PROP_TYPE(TypeTag, EnergyLocalResidual);
 
diff --git a/tutorial/solution/ex2/mylocalresidual.hh b/tutorial/solution/ex2/mylocalresidual.hh
index 33cdbb163960381a69b626ec34065183200d4403..0f3fa62ea9caf386a10a92f31f6665da2b0d2845 100644
--- a/tutorial/solution/ex2/mylocalresidual.hh
+++ b/tutorial/solution/ex2/mylocalresidual.hh
@@ -49,11 +49,11 @@ class MyCompositionalLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResid
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
     using ResidualVector = typename GET_PROP_TYPE(TypeTag, NumEqVector);
     using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables);
-    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache);
+    using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GridFluxVariablesCache)::LocalView;
     using Indices = typename GET_PROP_TYPE(TypeTag, Indices);
     using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
-    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView;
     using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
     using EnergyLocalResidual = typename GET_PROP_TYPE(TypeTag, EnergyLocalResidual);