From e01f364890459b60c9f66ee8a058f48240f8aadf Mon Sep 17 00:00:00 2001
From: Timo Koch <timo.koch@iws.uni-stuttgart.de>
Date: Wed, 17 Jan 2018 15:20:51 +0100
Subject: [PATCH] [disc] Make FVGridGeometry independent of TypeTag
 (box,tpfa,mpfa,staggered)

Mpfa contributed by DennisGlaeser
---
 dumux/common/defaultmappertraits.hh           |  46 +++++
 dumux/common/intersectionmapper.hh            |  15 +-
 dumux/common/properties.hh                    |   2 -
 dumux/discretization/basefvgridgeometry.hh    |  35 ++--
 dumux/discretization/box/fvelementgeometry.hh |  89 ++++------
 dumux/discretization/box/fvgridgeometry.hh    | 142 ++++++++++-----
 dumux/discretization/box/properties.hh        |  99 ++---------
 dumux/discretization/box/subcontrolvolume.hh  |  76 ++++++--
 .../box/subcontrolvolumeface.hh               |  74 ++++++--
 .../cellcentered/connectivitymap.hh           |   2 +-
 .../mpfa/elementfluxvariablescache.hh         |  28 +--
 .../cellcentered/mpfa/fvelementgeometry.hh    |  44 +++--
 .../cellcentered/mpfa/fvgridgeometry.hh       | 167 +++++++++---------
 .../mpfa/gridinteractionvolumeindexsets.hh    |  40 ++---
 .../cellcentered/mpfa/properties.hh           |  73 ++++----
 .../cellcentered/mpfa/subcontrolvolumeface.hh |  30 ++--
 .../cellcentered/subcontrolvolume.hh          |  27 +--
 .../cellcentered/tpfa/fvelementgeometry.hh    |  44 +++--
 .../cellcentered/tpfa/fvgridgeometry.hh       | 143 +++++++++------
 .../cellcentered/tpfa/properties.hh           |  32 ++--
 .../cellcentered/tpfa/subcontrolvolumeface.hh |  37 ++--
 dumux/discretization/fluxstencil.hh           |   2 +-
 .../staggered/freeflow/connectivitymap.hh     |   5 +-
 .../staggered/freeflow/properties.hh          |  48 ++---
 .../freeflow/subcontrolvolumeface.hh          |  27 +--
 .../staggered/fvelementgeometry.hh            |  45 +++--
 .../staggered/fvgridgeometry.hh               |  58 +++---
 dumux/discretization/staggered/properties.hh  |  58 +-----
 .../staggered/subcontrolvolumeface.hh         |  91 ++++++----
 .../staggered/test_staggeredfvgeometry.cc     |  79 +++++----
 30 files changed, 870 insertions(+), 788 deletions(-)
 create mode 100644 dumux/common/defaultmappertraits.hh

diff --git a/dumux/common/defaultmappertraits.hh b/dumux/common/defaultmappertraits.hh
new file mode 100644
index 0000000000..9686dbed96
--- /dev/null
+++ b/dumux/common/defaultmappertraits.hh
@@ -0,0 +1,46 @@
+// -*- 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 Common
+ * \brief Defines the default element and vertex mapper types
+ */
+#ifndef DUMUX_DEFAULT_MAPPER_TRAITS_HH
+#define DUMUX_DEFAULT_MAPPER_TRAITS_HH
+
+#include <dune/common/version.hh>
+#include <dune/grid/common/mcmgmapper.hh>
+
+namespace Dumux {
+
+template <class GridView>
+struct DefaultMapperTraits
+{
+#if DUNE_VERSION_NEWER(DUNE_COMMON,2,6)
+    using ElementMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
+    using VertexMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
+#else
+    using ElementMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGElementLayout>;
+    using VertexMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGVertexLayout>;
+#endif
+};
+
+} // namespace Dumux
+
+#endif
diff --git a/dumux/common/intersectionmapper.hh b/dumux/common/intersectionmapper.hh
index c04dc57384..5599c97eee 100644
--- a/dumux/common/intersectionmapper.hh
+++ b/dumux/common/intersectionmapper.hh
@@ -30,28 +30,25 @@
 #include <dune/grid/common/rangegenerators.hh>
 
 #include <dune/common/version.hh>
-#include <dumux/common/properties.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup Common
  * \brief defines a standard intersection mapper for mapping of global DOFs assigned
  *        to faces. It only works for conforming grids, without hanging nodes.
- * \todo This shouldn't depend on type tag but gridview only
  */
-template<class TypeTag>
+template<class GridView>
 class ConformingGridIntersectionMapper
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
     using IndexType = unsigned int;
 
     static constexpr int codimIntersection =  1;
 public:
 
-    ConformingGridIntersectionMapper(const GridView& gridView) : gridView_(gridView) { }
+    ConformingGridIntersectionMapper(const GridView& gridView)
+    : gridView_(gridView) { }
 
     void update()
     {}
@@ -85,12 +82,10 @@ private:
  * \ingroup Common
  * \brief defines an intersection mapper for mapping of global DOFs assigned
  *        to faces which also works for non-conforming grids and corner-point grids.
- * \todo This shouldn't depend on type tag but gridview only
  */
-template<class TypeTag>
+template<class GridView>
 class NonConformingGridIntersectionMapper
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
     using Element = typename GridView::template Codim<0>::Entity;
     using Intersection = typename GridView::Intersection;
     using IndexType = unsigned int;
diff --git a/dumux/common/properties.hh b/dumux/common/properties.hh
index 4f592b4853..afdf2f6f75 100644
--- a/dumux/common/properties.hh
+++ b/dumux/common/properties.hh
@@ -102,7 +102,6 @@ NEW_PROP_TAG(MaxNumNeighborsPerScvf);              //!< The maximum number of ne
 /////////////////////////////////////////////////////////////////
 // Additional properties used by the cell-centered mpfa schemes:
 /////////////////////////////////////////////////////////////////
-NEW_PROP_TAG(MpfaMethod);                          //!< Specifies the mpfa method to be used
 NEW_PROP_TAG(MpfaHelper);                          //!< A Helper class depending on the mpfa method and grid dimension
 NEW_PROP_TAG(PrimaryInteractionVolume);            //!< The primary interaction volume type
 NEW_PROP_TAG(SecondaryInteractionVolume);          //!< The secondary interaction volume type used e.g. on the boundaries
@@ -189,7 +188,6 @@ NEW_PROP_TAG(CellCenterPrimaryVariables);          //!< The primary variables co
 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(StaggeredGeometryHelper);             //!< Specifies a helper class for the staggered grid geometry
 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
diff --git a/dumux/discretization/basefvgridgeometry.hh b/dumux/discretization/basefvgridgeometry.hh
index 6e5064f905..e303d97b65 100644
--- a/dumux/discretization/basefvgridgeometry.hh
+++ b/dumux/discretization/basefvgridgeometry.hh
@@ -32,31 +32,35 @@
 #include <dumux/common/geometry/boundingboxtree.hh>
 #include <dumux/common/geometry/geometricentityset.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup Discretization
  * \brief Base class for all finite volume grid geometries
+ * \tparam Impl the type of the actual implementation
+ * \tparam GV the grid view type
+ * \tparam Traits the fv geometry traits
  */
-template<class TypeTag>
+template<class Impl, class GV, class Traits>
 class BaseFVGridGeometry
 {
-    using Implementation = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using ElementMapper = typename GET_PROP_TYPE(TypeTag, ElementMapper);
-    using VertexMapper = typename GET_PROP_TYPE(TypeTag, VertexMapper);
-    using ElementMap = EntityMap<GridView, 0>;
-    using ElementSet = GridViewGeometricEntitySet<GridView, 0>;
+    using ElementMap = EntityMap<GV, 0>;
+    using ElementSet = GridViewGeometricEntitySet<GV, 0>;
     using BoundingBoxTree = Dumux::BoundingBoxTree<ElementSet>;
 
-    static const int dim = GridView::dimension;
-    static const int dimWorld = GridView::dimensionworld;
-    using CoordScalar = typename GridView::ctype;
+    static const int dim = GV::dimension;
+    static const int dimWorld = GV::dimensionworld;
+    using CoordScalar = typename GV::ctype;
     using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
 
 public:
+    //! export the grid view type
+    using GridView = GV;
+    //! export the element mapper type
+    using ElementMapper = typename Traits::ElementMapper;
+    //! export the vertex mapper type
+    using VertexMapper = typename Traits::VertexMapper;
+
     //! Constructor computes the bouding box of the entire domain, for e.g. setting boundary conditions
     BaseFVGridGeometry(const GridView& gridView)
     : gridView_(gridView)
@@ -78,8 +82,9 @@ public:
      *        The local object is only functional after calling its bind/bindElement method.
      *        This is a free function that will be found by means of ADL
      */
-    friend inline FVElementGeometry localView(const Implementation& fvGridGeometry)
-    { return FVElementGeometry(fvGridGeometry); }
+    template<class GridGeometry>
+    friend inline typename GridGeometry::LocalView localView(const GridGeometry& fvGridGeometry)
+    { return typename GridGeometry::LocalView(fvGridGeometry); }
 
     /*!
      * \brief Update all fvElementGeometries (do this again after grid adaption)
diff --git a/dumux/discretization/box/fvelementgeometry.hh b/dumux/discretization/box/fvelementgeometry.hh
index 393b8cd8b9..fd1df112b8 100644
--- a/dumux/discretization/box/fvelementgeometry.hh
+++ b/dumux/discretization/box/fvelementgeometry.hh
@@ -18,6 +18,7 @@
  *****************************************************************************/
 /*!
  * \file
+ * \ingroup BoxDiscretization
  * \brief Base class for the local finite volume geometry for box models
  *        This builds up the sub control volumes and sub control volume faces
  *        for an element.
@@ -29,58 +30,44 @@
 #include <dune/geometry/referenceelements.hh>
 #include <dune/localfunctions/lagrange/pqkfactory.hh>
 
-#include <dumux/common/properties.hh>
 #include <dumux/discretization/scvandscvfiterators.hh>
 #include <dumux/discretization/box/boxgeometryhelper.hh>
 
-namespace Dumux
-{
-
-//! forward declaration of the global finite volume geometry
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class BoxFVGridGeometry;
+namespace Dumux {
 
 /*!
- * \ingroup ImplicitModel
+ * \ingroup BoxDiscretization
  * \brief Base class for the finite volume geometry vector for box models
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element.
+ * \tparam GG the finite volume grid geometry type
+ * \tparam enableFVGridGeometryCache if the grid geometry is cached or not
  */
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class BoxFVElementGeometry
-{};
+template<class GG, bool enableFVGridGeometryCache>
+class BoxFVElementGeometry;
 
 //! specialization in case the FVElementGeometries are stored
-template<class TypeTag>
-class BoxFVElementGeometry<TypeTag, true>
+template<class GG>
+class BoxFVElementGeometry<GG, true>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using GridView = typename GG::GridView;
     static constexpr int dim = GridView::dimension;
     static constexpr int dimWorld = GridView::dimensionworld;
+    using IndexType = typename GridView::IndexSet::IndexType;
+    using Element = typename GridView::template Codim<0>::Entity;
+    using CoordScalar = typename GridView::ctype;
+    using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
+    using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
 public:
     //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using SubControlVolume = typename GG::SubControlVolume;
     //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
     //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GG;
     //! the maximum number of scvs per element (2^dim for cubes)
     static constexpr std::size_t maxNumElementScvs = (1<<dim);
 
-private:
-    using ThisType = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using CoordScalar = typename GridView::ctype;
-
-    using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
-    using FeLocalBasis = typename FeCache::FiniteElementType::Traits::LocalBasisType;
-    using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
-
-public:
-
     //! Constructor
     BoxFVElementGeometry(const FVGridGeometry& fvGridGeometry)
     : fvGridGeometryPtr_(&fvGridGeometry) {}
@@ -170,38 +157,33 @@ private:
 };
 
 //! specialization in case the FVElementGeometries are not stored
-template<class TypeTag>
-class BoxFVElementGeometry<TypeTag, false>
+template<class GG>
+class BoxFVElementGeometry<GG, false>
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using GridView = typename GG::GridView;
     static constexpr int dim = GridView::dimension;
     static constexpr int dimWorld = GridView::dimensionworld;
-public:
-    //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    //! the maximum number of scvs per element (2^dim for cubes)
-    static constexpr std::size_t maxNumElementScvs = (1<<dim);
 
-private:
     using IndexType = typename GridView::IndexSet::IndexType;
-    using LocalIndexType = typename SubControlVolumeFace::Traits::LocalIndexType;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
     using Element = typename GridView::template Codim<0>::Entity;
 
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
     using CoordScalar = typename GridView::ctype;
-
-    using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
-    using FeLocalBasis = typename FeCache::FiniteElementType::Traits::LocalBasisType;
+    using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
     using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
 
-    using GeometryHelper = BoxGeometryHelper<GridView, dim, SubControlVolume, SubControlVolumeFace>;
-
+    using GeometryHelper = BoxGeometryHelper<GridView, dim,
+                                             typename GG::SubControlVolume,
+                                             typename GG::SubControlVolumeFace>;
 public:
+    //! export type of subcontrol volume
+    using SubControlVolume = typename GG::SubControlVolume;
+    //! export type of subcontrol volume face
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
+    //! export type of finite volume grid geometry
+    using FVGridGeometry = GG;
+    //! the maximum number of scvs per element (2^dim for cubes)
+    static constexpr std::size_t maxNumElementScvs = (1<<dim);
+
     //! Constructor
     BoxFVElementGeometry(const FVGridGeometry& fvGridGeometry)
     : fvGridGeometryPtr_(&fvGridGeometry) {}
@@ -301,6 +283,7 @@ private:
 
         // construct the sub control volumes
         scvs_.resize(elementGeometry.corners());
+        using LocalIndexType = typename SubControlVolumeFace::Traits::LocalIndexType;
         for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
         {
             // get asssociated dof index
@@ -372,6 +355,6 @@ private:
     std::vector<SubControlVolumeFace> scvfs_;
 };
 
-} // end namespace
+} // end namespace Dumux
 
 #endif
diff --git a/dumux/discretization/box/fvgridgeometry.hh b/dumux/discretization/box/fvgridgeometry.hh
index 71ea05f596..58f3194d99 100644
--- a/dumux/discretization/box/fvgridgeometry.hh
+++ b/dumux/discretization/box/fvgridgeometry.hh
@@ -18,6 +18,7 @@
  *****************************************************************************/
 /*!
  * \file
+ * \ingroup BoxDiscretization
  * \brief Base class for the finite volume geometry vector for box models
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element of the grid partition.
@@ -29,59 +30,93 @@
 #include <dune/localfunctions/lagrange/pqkfactory.hh>
 
 #include <dumux/discretization/methods.hh>
+#include <dumux/common/defaultmappertraits.hh>
 #include <dumux/discretization/basefvgridgeometry.hh>
 #include <dumux/discretization/box/boxgeometryhelper.hh>
 #include <dumux/discretization/box/fvelementgeometry.hh>
+#include <dumux/discretization/box/subcontrolvolume.hh>
+#include <dumux/discretization/box/subcontrolvolumeface.hh>
 
-namespace Dumux
+namespace Dumux {
+
+/*!
+ * \ingroup BoxDiscretization
+ * \brief The default traits for the box finite volume grid geometry
+ *        Defines the scv and scvf types and the mapper types
+ * \tparam the grid view type
+ */
+template<class GridView>
+struct BoxDefaultGridGeometryTraits
+: public DefaultMapperTraits<GridView>
 {
+    using SubControlVolume = BoxSubControlVolume<GridView>;
+    using SubControlVolumeFace = BoxSubControlVolumeFace<GridView>;
+
+    template<class FVGridGeometry, bool enableCache>
+    using LocalView = BoxFVElementGeometry<FVGridGeometry, enableCache>;
+};
 
 /*!
- * \ingroup ImplicitModel
- * \brief Base class for the finite volume geometry vector for box models
+ * \ingroup BoxDiscretization
+ * \brief Base class for the finite volume geometry vector for box schemes
  *        This builds up the sub control volumes and sub control volume faces
- *        for each element.
+ * \note This class is specialized for versions with and without caching the fv geometries on the grid view
  */
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class BoxFVGridGeometry
-{};
+template<class Scalar,
+         class GridView,
+         bool enableFVGridGeometryCache = false,
+         class Traits = BoxDefaultGridGeometryTraits<GridView> >
+class BoxFVGridGeometry;
 
-// specialization in case the FVElementGeometries are stored
-template<class TypeTag>
-class BoxFVGridGeometry<TypeTag, true> : public BaseFVGridGeometry<TypeTag>
+/*!
+ * \ingroup BoxDiscretization
+ * \brief Base class for the finite volume geometry vector for box schemes
+ *        This builds up the sub control volumes and sub control volume faces
+ * \note For caching enabled we store the fv geometries for the whole grid view which is memory intensive but faster
+ */
+template<class Scalar, class GV, class Traits>
+class BoxFVGridGeometry<Scalar, GV, true, Traits>
+: public BaseFVGridGeometry<BoxFVGridGeometry<Scalar, GV, true, Traits>, GV, Traits>
 {
-    using ParentType = BaseFVGridGeometry<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    using LocalIndexType = typename SubControlVolumeFace::Traits::LocalIndexType;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using VertexMapper = typename GET_PROP_TYPE(TypeTag, VertexMapper);
-    using Element = typename GridView::template Codim<0>::Entity;
-
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using CoordScalar = typename GridView::ctype;
-
-    static const int dim = GridView::dimension;
-    static const int dimWorld = GridView::dimensionworld;
+    using ThisType = BoxFVGridGeometry<Scalar, GV, true, Traits>;
+    using ParentType = BaseFVGridGeometry<ThisType, GV, Traits>;
+    using IndexType = typename GV::IndexSet::IndexType;
+
+    using Element = typename GV::template Codim<0>::Entity;
+    using CoordScalar = typename GV::ctype;
+    static const int dim = GV::dimension;
+    static const int dimWorld = GV::dimensionworld;
 
-    using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
     using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
 
-    using GeometryHelper = BoxGeometryHelper<GridView, dim, SubControlVolume, SubControlVolumeFace>;
+    using GeometryHelper = BoxGeometryHelper<GV, dim,
+                                             typename Traits::SubControlVolume,
+                                             typename Traits::SubControlVolumeFace>;
 
 public:
     //! export discretization method
     static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::Box;
 
+    //! export the type of the fv element geometry (the local view type)
+    using LocalView = typename Traits::template LocalView<ThisType, true>;
+    //! export the type of sub control volume
+    using SubControlVolume = typename Traits::SubControlVolume;
+    //! export the type of sub control volume
+    using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
+    //! export dof mapper type
+    using DofMapper = typename Traits::VertexMapper;
+    //! export the finite element cache type
+    using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
+    //! export the grid view type
+    using GridView = GV;
+
     //! Constructor
     BoxFVGridGeometry(const GridView gridView)
     : ParentType(gridView) {}
 
     //! the vertex mapper is the dofMapper
     //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa...
-    const VertexMapper& dofMapper() const
+    const DofMapper& dofMapper() const
     { return this->vertexMapper(); }
 
     //! The total number of sub control volumes
@@ -141,6 +176,7 @@ public:
 
             // construct the sub control volumes
             scvs_[eIdx].resize(elementGeometry.corners());
+            using LocalIndexType = typename SubControlVolumeFace::Traits::LocalIndexType;
             for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
             {
                 const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
@@ -242,41 +278,53 @@ private:
     std::vector<bool> boundaryDofIndices_;
 };
 
-// specialization in case the FVElementGeometries are not stored
-template<class TypeTag>
-class BoxFVGridGeometry<TypeTag, false> : public BaseFVGridGeometry<TypeTag>
+/*!
+ * \ingroup BoxDiscretization
+ * \brief Base class for the finite volume geometry vector for box schemes
+ *        This builds up the sub control volumes and sub control volume faces
+ * \note For caching disabled we store only some essential index maps to build up local systems on-demand in
+ *       the corresponding FVElementGeometry
+ */
+template<class Scalar, class GV, class Traits>
+class BoxFVGridGeometry<Scalar, GV, false, Traits>
+: public BaseFVGridGeometry<BoxFVGridGeometry<Scalar, GV, false, Traits>, GV, Traits>
 {
-    using ParentType = BaseFVGridGeometry<TypeTag>;
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using VertexMapper = typename GET_PROP_TYPE(TypeTag, VertexMapper);
-
-    static const int dim = GridView::dimension;
-    static const int dimWorld = GridView::dimensionworld;
+    using ThisType = BoxFVGridGeometry<Scalar, GV, false, Traits>;
+    using ParentType = BaseFVGridGeometry<ThisType, GV, Traits>;
+    using IndexType = typename GV::IndexSet::IndexType;
 
-    using Element = typename GridView::template Codim<0>::Entity;
-    using Vertex = typename GridView::template Codim<dim>::Entity;
+    static const int dim = GV::dimension;
+    static const int dimWorld = GV::dimensionworld;
 
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using CoordScalar = typename GridView::ctype;
+    using Element = typename GV::template Codim<0>::Entity;
+    using CoordScalar = typename GV::ctype;
 
-    using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
     using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
 
 public:
     //! export discretization method
     static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::Box;
 
+    //! export the type of the fv element geometry (the local view type)
+    using LocalView = typename Traits::template LocalView<ThisType, false>;
+    //! export the type of sub control volume
+    using SubControlVolume = typename Traits::SubControlVolume;
+    //! export the type of sub control volume
+    using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
+    //! export dof mapper type
+    using DofMapper = typename Traits::VertexMapper;
+    //! export the finite element cache type
+    using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
+    //! export the grid view type
+    using GridView = GV;
+
     //! Constructor
     BoxFVGridGeometry(const GridView gridView)
     : ParentType(gridView) {}
 
     //! the vertex mapper is the dofMapper
     //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa...
-    const VertexMapper& dofMapper() const
+    const DofMapper& dofMapper() const
     { return this->vertexMapper(); }
 
     //! The total number of sub control volumes
diff --git a/dumux/discretization/box/properties.hh b/dumux/discretization/box/properties.hh
index aa940ef714..fbe5191681 100644
--- a/dumux/discretization/box/properties.hh
+++ b/dumux/discretization/box/properties.hh
@@ -37,8 +37,6 @@
 #include <dumux/discretization/methods.hh>
 #include <dumux/discretization/fvproperties.hh>
 
-#include <dumux/discretization/box/subcontrolvolume.hh>
-#include <dumux/discretization/box/subcontrolvolumeface.hh>
 #include <dumux/discretization/box/elementsolution.hh>
 #include <dumux/discretization/box/elementboundarytypes.hh>
 #include <dumux/discretization/box/gridfluxvariablescache.hh>
@@ -61,97 +59,20 @@ SET_PROP(BoxModel, DiscretizationMethod)
     static const DiscretizationMethods value = DiscretizationMethods::Box;
 };
 
-//! Set the default for the FVElementGeometry vector
-SET_TYPE_PROP(BoxModel, FVGridGeometry, BoxFVGridGeometry<TypeTag,
-                            GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
-
-//! Set the default for the FVElementGeometry vector
-SET_TYPE_PROP(BoxModel, FVElementGeometry, BoxFVElementGeometry<TypeTag,
-                            GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
-
-//! The sub control volume
-SET_PROP(BoxModel, SubControlVolume)
-{
-private:
-    using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
-    static const int dim = Grid::dimension;
-    static const int dimWorld = Grid::dimensionworld;
-
-    // we use geometry traits that use static corner vectors to and a fixed geometry type
-    template <class ct>
-    struct ScvfMLGTraits : public Dune::MultiLinearGeometryTraits<ct>
-    {
-        // we use static vectors to store the corners as we know
-        // the number of corners in advance (2^(dim) corners (1<<(dim))
-        template< int mydim, int cdim >
-        struct CornerStorage
-        {
-            using Type = std::array< Dune::FieldVector< ct, cdim >, (1<<(dim)) >;
-        };
-
-        // we know all scvfs will have the same geometry type
-        template< int mydim >
-        struct hasSingleGeometryType
-        {
-            static const bool v = true;
-            static const unsigned int topologyId = Dune::Impl::CubeTopology< mydim >::type::id;
-        };
-    };
-
-    struct ScvGeometryTraits
-    {
-        using GridIndexType = typename Grid::LeafGridView::IndexSet::IndexType;
-        using LocalIndexType = unsigned int;
-        using Scalar = typename Grid::ctype;
-        using Geometry = Dune::MultiLinearGeometry<Scalar, dim, dimWorld, ScvfMLGTraits<Scalar>>;
-        using CornerStorage = typename ScvfMLGTraits<Scalar>::template CornerStorage<dim, dimWorld>::Type;
-        using GlobalPosition = typename CornerStorage::value_type;
-    };
-public:
-    using type = BoxSubControlVolume<ScvGeometryTraits>;
-};
-
-SET_PROP(BoxModel, SubControlVolumeFace)
+//! Set the default for the global finite volume geometry
+SET_PROP(BoxModel, FVGridGeometry)
 {
 private:
-    using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
-    static const int dim = Grid::dimension;
-    static const int dimWorld = Grid::dimensionworld;
-
-    // we use geometry traits that use static corner vectors to and a fixed geometry type
-    template <class ct>
-    struct ScvfMLGTraits : public Dune::MultiLinearGeometryTraits<ct>
-    {
-        // we use static vectors to store the corners as we know
-        // the number of corners in advance (2^(dim-1) corners (1<<(dim-1))
-        template< int mydim, int cdim >
-        struct CornerStorage
-        {
-            using Type = std::array< Dune::FieldVector< ct, cdim >, (1<<(dim-1)) >;
-        };
-
-        // we know all scvfs will have the same geometry type
-        template< int mydim >
-        struct hasSingleGeometryType
-        {
-            static const bool v = true;
-            static const unsigned int topologyId = Dune::Impl::CubeTopology< mydim >::type::id;
-        };
-    };
-
-    struct ScvfGeometryTraits
-    {
-        using GridIndexType = typename Grid::LeafGridView::IndexSet::IndexType;
-        using LocalIndexType = unsigned int;
-        using Scalar = typename Grid::ctype;
-        using Geometry = Dune::MultiLinearGeometry<Scalar, dim-1, dimWorld, ScvfMLGTraits<Scalar>>;
-        using CornerStorage = typename ScvfMLGTraits<Scalar>::template CornerStorage<dim-1, dimWorld>::Type;
-        using GlobalPosition = typename CornerStorage::value_type;
-        using BoundaryFlag = Dumux::BoundaryFlag<Grid>;
-    };
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache);
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
 public:
-    using type = BoxSubControlVolumeFace<ScvfGeometryTraits>;
+    using type = BoxFVGridGeometry<Scalar, GridView, enableCache>;
 };
+//! Set the default for the FVElementGeometry vector
+SET_TYPE_PROP(BoxModel, FVElementGeometry,
+                BoxFVElementGeometry<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
+                                     GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
 
 //! Set the solution vector type for an element
 SET_TYPE_PROP(BoxModel, ElementSolutionVector, BoxElementSolution<TypeTag>);
diff --git a/dumux/discretization/box/subcontrolvolume.hh b/dumux/discretization/box/subcontrolvolume.hh
index 0ab8ad0cbd..a258e4b10e 100644
--- a/dumux/discretization/box/subcontrolvolume.hh
+++ b/dumux/discretization/box/subcontrolvolume.hh
@@ -18,7 +18,8 @@
  *****************************************************************************/
 /*!
  * \file
- * \brief Base class for a sub control volume
+ * \ingroup BoxDiscretization
+ * \brief the sub control volume for the box scheme
  */
 #ifndef DUMUX_DISCRETIZATION_BOX_SUBCONTROLVOLUME_HH
 #define DUMUX_DISCRETIZATION_BOX_SUBCONTROLVOLUME_HH
@@ -29,23 +30,74 @@
 #include <dumux/discretization/box/boxgeometryhelper.hh>
 #include <dumux/common/math.hh>
 
-namespace Dumux
+namespace Dumux {
+
+/*!
+ * \ingroup BoxDiscretization
+ * \brief Default traits class to be used for the sub-control volumes
+ *        for the box scheme
+ * \tparam GV the type of the grid view
+ */
+template<class GridView>
+struct BoxDefaultScvGeometryTraits
 {
-template<class ScvGeometryTraits>
-class BoxSubControlVolume : public SubControlVolumeBase<BoxSubControlVolume<ScvGeometryTraits>, ScvGeometryTraits>
+    using Grid = typename GridView::Grid;
+
+    static const int dim = Grid::dimension;
+    static const int dimWorld = Grid::dimensionworld;
+
+    template <class ct>
+    struct ScvMLGTraits : public Dune::MultiLinearGeometryTraits<ct>
+    {
+        // we use static vectors to store the corners as we know
+        // the number of corners in advance (2^(dim) corners (1<<(dim))
+        template< int mydim, int cdim >
+        struct CornerStorage
+        {
+            using Type = std::array< Dune::FieldVector< ct, cdim >, (1<<(dim)) >;
+        };
+
+        // we know all scvfs will have the same geometry type
+        template< int mydim >
+        struct hasSingleGeometryType
+        {
+            static const bool v = true;
+            static const unsigned int topologyId = Dune::Impl::CubeTopology< mydim >::type::id;
+        };
+    };
+
+    using GridIndexType = typename Grid::LeafGridView::IndexSet::IndexType;
+    using LocalIndexType = unsigned int;
+    using Scalar = typename Grid::ctype;
+    using Geometry = Dune::MultiLinearGeometry<Scalar, dim, dimWorld, ScvMLGTraits<Scalar>>;
+    using CornerStorage = typename ScvMLGTraits<Scalar>::template CornerStorage<dim, dimWorld>::Type;
+    using GlobalPosition = typename CornerStorage::value_type;
+};
+
+/*!
+ * \ingroup BoxDiscretization
+ * \brief the sub control volume for the box scheme
+ * \tparam GV the type of the grid view
+ * \tparam T the scvf geometry traits
+ */
+template<class GV,
+         class T = BoxDefaultScvGeometryTraits<GV> >
+class BoxSubControlVolume
+: public SubControlVolumeBase<BoxSubControlVolume<GV, T>, T>
 {
-    using ParentType = SubControlVolumeBase<BoxSubControlVolume<ScvGeometryTraits>, ScvGeometryTraits>;
-    using Geometry = typename ScvGeometryTraits::Geometry;
-    using GridIndexType = typename ScvGeometryTraits::GridIndexType;
-    using LocalIndexType = typename ScvGeometryTraits::LocalIndexType;
-    using Scalar = typename ScvGeometryTraits::Scalar;
-    using GlobalPosition = typename ScvGeometryTraits::GlobalPosition;
-    using CornerStorage = typename ScvGeometryTraits::CornerStorage;
+    using ThisType = BoxSubControlVolume<GV, T>;
+    using ParentType = SubControlVolumeBase<ThisType, T>;
+    using Geometry = typename T::Geometry;
+    using GridIndexType = typename T::GridIndexType;
+    using LocalIndexType = typename T::LocalIndexType;
+    using Scalar = typename T::Scalar;
+    using GlobalPosition = typename T::GlobalPosition;
+    using CornerStorage = typename T::CornerStorage;
     enum { dim = Geometry::mydimension };
 
 public:
     //! state the traits public and thus export all types
-    using Traits = ScvGeometryTraits;
+    using Traits = T;
 
     //! The default constructor
     BoxSubControlVolume() = default;
diff --git a/dumux/discretization/box/subcontrolvolumeface.hh b/dumux/discretization/box/subcontrolvolumeface.hh
index 291a051e01..ea10657072 100644
--- a/dumux/discretization/box/subcontrolvolumeface.hh
+++ b/dumux/discretization/box/subcontrolvolumeface.hh
@@ -26,31 +26,81 @@
 #include <utility>
 #include <dune/geometry/type.hh>
 #include <dune/common/version.hh>
+#include <dumux/common/boundaryflag.hh>
 #include <dumux/discretization/subcontrolvolumefacebase.hh>
 #include <dumux/discretization/box/boxgeometryhelper.hh>
 
-namespace Dumux
+namespace Dumux {
+
+/*!
+ * \ingroup BoxDiscretization
+ * \brief Default traits class to be used for the sub-control volume faces
+ *        for the box scheme
+ * \tparam GV the type of the grid view
+ */
+template<class GridView>
+struct BoxDefaultScvfGeometryTraits
 {
+    using Grid = typename GridView::Grid;
+    static constexpr int dim = Grid::dimension;
+    static constexpr int dimWorld = Grid::dimensionworld;
+
+    // we use geometry traits that use static corner vectors to and a fixed geometry type
+    template <class ct>
+    struct ScvfMLGTraits : public Dune::MultiLinearGeometryTraits<ct>
+    {
+        // we use static vectors to store the corners as we know
+        // the number of corners in advance (2^(dim-1) corners (1<<(dim-1))
+        template< int mydim, int cdim >
+        struct CornerStorage
+        {
+            using Type = std::array< Dune::FieldVector< ct, cdim >, (1<<(dim-1)) >;
+        };
+
+        // we know all scvfs will have the same geometry type
+        template< int mydim >
+        struct hasSingleGeometryType
+        {
+            static const bool v = true;
+            static const unsigned int topologyId = Dune::Impl::CubeTopology< mydim >::type::id;
+        };
+    };
+
+    using GridIndexType = typename Grid::LeafGridView::IndexSet::IndexType;
+    using LocalIndexType = unsigned int;
+    using Scalar = typename Grid::ctype;
+    using Geometry = Dune::MultiLinearGeometry<Scalar, dim-1, dimWorld, ScvfMLGTraits<Scalar>>;
+    using CornerStorage = typename ScvfMLGTraits<Scalar>::template CornerStorage<dim-1, dimWorld>::Type;
+    using GlobalPosition = typename CornerStorage::value_type;
+    using BoundaryFlag = Dumux::BoundaryFlag<Grid>;
+};
 
 /*!
- * \ingroup Discretization
+ * \ingroup BoxDiscretization
  * \brief Class for a sub control volume face in the box method, i.e a part of the boundary
  *        of a sub control volume we compute fluxes on. We simply use the base class here.
+ * \tparam GV the type of the grid view
+ * \tparam T the scvf geometry traits
  */
-template<class ScvfGeometryTraits>
+template<class GV,
+         class T = BoxDefaultScvfGeometryTraits<GV> >
 class BoxSubControlVolumeFace
-: public SubControlVolumeFaceBase<BoxSubControlVolumeFace<ScvfGeometryTraits>, ScvfGeometryTraits>
+: public SubControlVolumeFaceBase<BoxSubControlVolumeFace<GV, T>, T>
 {
-    using ParentType = SubControlVolumeFaceBase<BoxSubControlVolumeFace<ScvfGeometryTraits>, ScvfGeometryTraits>;
-    using GridIndexType = typename ScvfGeometryTraits::GridIndexType;
-    using LocalIndexType = typename ScvfGeometryTraits::LocalIndexType;
-    using Scalar = typename ScvfGeometryTraits::Scalar;
-    using GlobalPosition = typename ScvfGeometryTraits::GlobalPosition;
-    using CornerStorage = typename ScvfGeometryTraits::CornerStorage;
-    using Geometry = typename ScvfGeometryTraits::Geometry;
-    using BoundaryFlag = typename ScvfGeometryTraits::BoundaryFlag;
+    using ThisType = BoxSubControlVolumeFace<GV, T>;
+    using ParentType = SubControlVolumeFaceBase<ThisType, T>;
+    using GridIndexType = typename T::GridIndexType;
+    using LocalIndexType = typename T::LocalIndexType;
+    using Scalar = typename T::Scalar;
+    using GlobalPosition = typename T::GlobalPosition;
+    using CornerStorage = typename T::CornerStorage;
+    using Geometry = typename T::Geometry;
+    using BoundaryFlag = typename T::BoundaryFlag;
 
 public:
+    //! state the traits public and thus export all types
+    using Traits = T;
+
     //! The default constructor
     BoxSubControlVolumeFace() = default;
 
diff --git a/dumux/discretization/cellcentered/connectivitymap.hh b/dumux/discretization/cellcentered/connectivitymap.hh
index 7cb4753e5b..b4297fa1c3 100644
--- a/dumux/discretization/cellcentered/connectivitymap.hh
+++ b/dumux/discretization/cellcentered/connectivitymap.hh
@@ -48,7 +48,7 @@ namespace Dumux {
 template<class FVGridGeometry>
 class CCSimpleConnectivityMap
 {
-    using FVElementGeometry = typename FVGridGeometry::FVElementGeometry;
+    using FVElementGeometry = typename FVGridGeometry::LocalView;
     using GridView = typename FVGridGeometry::GridView;
     using IndexType = typename GridView::IndexSet::IndexType;
     using FluxStencil = Dumux::FluxStencil<FVElementGeometry>;
diff --git a/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh b/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh
index 9fe7435b1b..f830c045e7 100644
--- a/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh
+++ b/dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh
@@ -178,7 +178,12 @@ public:
         // 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.
-        const auto numIvEstimate = getNoInteractionVolumesEstimate_(element, assemblyMapI);
+        // 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;
         primaryInteractionVolumes_.reserve(numIvEstimate);
         secondaryInteractionVolumes_.reserve(numIvEstimate);
         primaryIvDataHandles_.reserve(numIvEstimate);
@@ -337,26 +342,6 @@ private:
         secondaryIvDataHandles_.clear();
     }
 
-    //! get estimate of interaction volumes that are going to be required
-    template<class AssemblyMap>
-    std::size_t getNoInteractionVolumesEstimate_(const Element& element, const AssemblyMap& assemblyMap)
-    {
-        // if statements are optimized away by the compiler
-        if (GET_PROP_VALUE(TypeTag, MpfaMethod) == MpfaMethods::oMethod)
-        {
-            // Reserve memory for the case of each facet having neighbors being 4 levels higher. Memory limitations
-            // do not play an important role here as global caching is disabled. In the unlikely case you want
-            // to use higher local differences in element levels set a higher value for the parameter below
-            // in your input file (note that some grids might only support levels differences of one anyway)
-            static const unsigned int maxDiff = getParamFromGroup<unsigned int>(GET_PROP_VALUE(TypeTag, ModelParameterGroup),
-                                                                                "Grid.MaxLocalElementLevelDifference",
-                                                                                4);
-            return element.subEntities(GridView::dimension)*maxDiff;
-        }
-        else
-            DUNE_THROW(Dune::NotImplemented, "number of interaction volumes estimate for chosen mpfa scheme");
-    }
-
     //! get index of an scvf in the local container
     unsigned int getLocalScvfIdx_(const int scvfIdx) const
     {
@@ -365,7 +350,6 @@ private:
         return std::distance(globalScvfIndices_.begin(), it);
     }
 
-
     // the local flux vars caches and corresponding indices
     std::vector<FluxVariablesCache> fluxVarsCache_;
     std::vector<GridIndexType> globalScvfIndices_;
diff --git a/dumux/discretization/cellcentered/mpfa/fvelementgeometry.hh b/dumux/discretization/cellcentered/mpfa/fvelementgeometry.hh
index 66928c9121..557b70dad7 100644
--- a/dumux/discretization/cellcentered/mpfa/fvelementgeometry.hh
+++ b/dumux/discretization/cellcentered/mpfa/fvelementgeometry.hh
@@ -31,7 +31,6 @@
 #include <dune/common/iteratorrange.hh>
 #include <dune/geometry/referenceelements.hh>
 
-#include <dumux/common/properties.hh>
 #include <dumux/common/parameters.hh>
 #include <dumux/discretization/scvandscvfiterators.hh>
 
@@ -42,9 +41,11 @@ namespace Dumux
  * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered mpfa models
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element in the local scope we are restricting to, e.g. stencil or element.
+ * \tparam GG the finite volume grid geometry type
+ * \tparam enableFVGridGeometryCache if the grid geometry is cached or not
  * \note This class is specialized for versions with and without caching the fv geometries on the grid view
  */
-template<class TypeTag, bool EnableFVGridGeometryCache>
+template<class GG, bool EnableFVGridGeometryCache>
 class CCMpfaFVElementGeometry;
 
 /*!
@@ -53,11 +54,11 @@ class CCMpfaFVElementGeometry;
  *        Specialization for grid caching enabled
  * \note The finite volume geometries are stored in the corresponding FVGridGeometry
  */
-template<class TypeTag>
-class CCMpfaFVElementGeometry<TypeTag, true>
+template<class GG>
+class CCMpfaFVElementGeometry<GG, true>
 {
-    using ThisType = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using ThisType = CCMpfaFVElementGeometry<GG, true>;
+    using GridView = typename GG::GridView;
     using Element = typename GridView::template Codim<0>::Entity;
     using GridIndexType = typename GridView::IndexSet::IndexType;
 
@@ -65,11 +66,11 @@ class CCMpfaFVElementGeometry<TypeTag, true>
 
 public:
     //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using SubControlVolume = typename GG::SubControlVolume;
     //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
     //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GG;
     //! the maximum number of scvs per element
     static constexpr std::size_t maxNumElementScvs = 1;
     //! the maximum number of scvfs per element (use cubes for maximum)
@@ -165,31 +166,28 @@ private:
  * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered TPFA models
  *        Specialization for grid caching disabled
  */
-template<class TypeTag>
-class CCMpfaFVElementGeometry<TypeTag, false>
+template<class GG>
+class CCMpfaFVElementGeometry<GG, false>
 {
-    using ThisType = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using ThisType = CCMpfaFVElementGeometry<GG, false>;
+    using GridView = typename GG::GridView;
     using Element = typename GridView::template Codim<0>::Entity;
     using GridIndexType = typename GridView::IndexSet::IndexType;
-
-    using MpfaHelper = typename GET_PROP_TYPE(TypeTag, MpfaHelper);
+    using MpfaHelper = typename GG::MpfaHelper;
 
     static const int dim = GridView::dimension;
     static const int dimWorld = GridView::dimensionworld;
     using CoordScalar = typename GridView::ctype;
     using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
-    using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
+    using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
 
 public:
     //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using SubControlVolume = typename GG::SubControlVolume;
     //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
     //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GG;
     //! the maximum number of scvs per element
     static constexpr std::size_t maxNumElementScvs = 1;
     //! the maximum number of scvfs per element (use cubes for maximum)
@@ -357,7 +355,7 @@ private:
         const auto& neighborVolVarIndices = fvGridGeometry().neighborVolVarIndices(eIdx);
 
         // the quadrature point parameterizaion to be used on scvfs
-        static const Scalar q = getParamFromGroup<Scalar>(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Mpfa.Q");
+        static const auto q = getParam<CoordScalar>("Mpfa.Q");
 
         // reserve memory for the scv faces
         const auto numLocalScvf = scvFaceIndices.size();
@@ -446,7 +444,7 @@ private:
         const auto& neighborVolVarIndices = fvGridGeometry().neighborVolVarIndices(eIdxGlobal);
 
         // the quadrature point parameterizaion to be used on scvfs
-        static const Scalar q = getParamFromGroup<Scalar>(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Mpfa.Q");
+        static const auto q = getParam<CoordScalar>("Mpfa.Q");
 
         // for network grids we only want to do one scvf per half facet
         // this approach assumes conforming grids at branching facets
diff --git a/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh b/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh
index 1406adf4dd..36a380d900 100644
--- a/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh
+++ b/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh
@@ -26,28 +26,26 @@
 #ifndef DUMUX_DISCRETIZATION_CC_MPFA_FV_GRID_GEOMETRY_HH
 #define DUMUX_DISCRETIZATION_CC_MPFA_FV_GRID_GEOMETRY_HH
 
-#include <dune/geometry/multilineargeometry.hh>
 #include <dune/geometry/referenceelements.hh>
 
-#include <dumux/common/properties.hh>
 #include <dumux/common/parameters.hh>
-
 #include <dumux/discretization/methods.hh>
 #include <dumux/discretization/basefvgridgeometry.hh>
-#include <dumux/discretization/cellcentered/mpfa/fvelementgeometry.hh>
-#include <dumux/discretization/cellcentered/mpfa/connectivitymap.hh>
-#include <dumux/discretization/cellcentered/mpfa/dualgridindexset.hh>
-#include <dumux/discretization/cellcentered/mpfa/gridinteractionvolumeindexsets.hh>
 
-namespace Dumux
-{
+namespace Dumux {
+
 /*!
  * \ingroup CCMpfaDiscretization
  * \brief The finite volume geometry (scvs and scvfs) for cell-centered mpfa models on a grid view
  *        This builds up the sub control volumes and sub control volume faces
  * \note This class is specialized for versions with and without caching the fv geometries on the grid view
+ *
+ * \tparam GridView the grid view
+ * \tparam GridIvIs the interaction volume index sets
+ * \tparam Traits traits class
+ * \tparam enableCache
  */
-template<class TypeTag, bool EnableFVElementGeometryCache>
+template<class GridView, class Traits, bool enableCache>
 class CCMpfaFVGridGeometry;
 
 /*!
@@ -56,49 +54,46 @@ class CCMpfaFVGridGeometry;
  *        This builds up the sub control volumes and sub control volume faces
  * \note For caching enabled we store the fv geometries for the whole grid view which is memory intensive but faster
  */
-template<class TypeTag>
-class CCMpfaFVGridGeometry<TypeTag, true> : public BaseFVGridGeometry<TypeTag>
+template<class GV, class Traits>
+class CCMpfaFVGridGeometry<GV, Traits, true>
+: public BaseFVGridGeometry<CCMpfaFVGridGeometry<GV, Traits, true>, GV, Traits>
 {
-public:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using DualGridNodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet);
+    using ThisType = CCMpfaFVGridGeometry<GV, Traits, true>;
+    using ParentType = BaseFVGridGeometry<ThisType, GV, Traits>;
 
-    //! Export the discretization method this geometry belongs to
-    static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::CCMpfa;
-
-    //! Export the mpfa method
-    static constexpr MpfaMethods mpfaMethod = GET_PROP_VALUE(TypeTag, MpfaMethod);
-
-private:
-    using ThisType = CCMpfaFVGridGeometry<TypeTag, true>;
-    using ParentType = BaseFVGridGeometry<TypeTag>;
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using MpfaHelper = typename GET_PROP_TYPE(TypeTag, MpfaHelper);
-    using ElementMapper = typename GET_PROP_TYPE(TypeTag, ElementMapper);
-    using PrimaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
-
-    static constexpr int dim = GridView::dimension;
-    static constexpr int dimWorld = GridView::dimensionworld;
-
-    using Element = typename GridView::template Codim<0>::Entity;
-    using Vertex = typename GridView::template Codim<dim>::Entity;
-    using Intersection = typename GridView::Intersection;
-    using CoordScalar = typename GridView::ctype;
-    using GridIndexType = typename GridView::IndexSet::IndexType;
-    using LocalIndexType = typename PrimaryInteractionVolume::Traits::LocalIndexType;
-    using ScvfOutsideGridIndexStorage = typename SubControlVolumeFace::Traits::OutsideGridIndexStorage;
-
-    using GridIVIndexSets = CCMpfaGridInteractionVolumeIndexSets<TypeTag>;
-    using ConnectivityMap = CCMpfaConnectivityMap<ThisType, mpfaMethod>;
+    static constexpr int dim = GV::dimension;
+    static constexpr int dimWorld = GV::dimensionworld;
 
+    using Element = typename GV::template Codim<0>::Entity;
+    using Vertex = typename GV::template Codim<dim>::Entity;
+    using Intersection = typename GV::Intersection;
+    using GridIndexType = typename GV::IndexSet::IndexType;
+    using CoordScalar = typename GV::ctype;
     using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
 
 public:
+    //! export the mpfa helper type
+    using MpfaHelper = typename Traits::MpfaHelper;
+    //! export the grid interaction volume index set type
+    using GridIVIndexSets = typename Traits::template GridIvIndexSets<ThisType>;
+    //! export the type to be used for indicators where to use the secondary ivs
     using SecondaryIvIndicatorType = std::function<bool(const Element&, const Intersection&, bool)>;
 
+    //! export the type of the fv element geometry (the local view type)
+    using LocalView = typename Traits::template LocalView<ThisType, true>;
+    //! export the type of sub control volume
+    using SubControlVolume = typename Traits::SubControlVolume;
+    //! export the type of sub control volume
+    using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
+    //! export the connectivity map type
+    using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
+    //! export dof mapper type
+    using DofMapper = typename Traits::ElementMapper;
+    //! export the grid view type
+    using GridView = GV;
+
+    //! export the discretization method this geometry belongs to
+    static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::CCMpfa;
     //! The maximum admissible stencil size (used for static memory allocation during assembly)
     // TODO: Re-implement and obtain from nodal index set (for now we use a high value)
     static constexpr int maxElementStencilSize = (dim < dimWorld || dim == 3) ? 45 : 15;
@@ -119,7 +114,7 @@ public:
 
     //! the element mapper is the dofMapper
     //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa...
-    const ElementMapper& dofMapper() const { return this->elementMapper(); }
+    const DofMapper& dofMapper() const { return this->elementMapper(); }
 
     //! The total number of sub control volumes
     std::size_t numScv() const { return scvs_.size(); }
@@ -179,7 +174,7 @@ public:
         const auto isGhostVertex = MpfaHelper::findGhostVertices(this->gridView(), this->vertexMapper());
 
         // instantiate the dual grid index set (to be used for construction of interaction volumes)
-        CCMpfaDualGridIndexSet< DualGridNodalIndexSet > dualIdSet(this->gridView());
+        typename GridIVIndexSets::DualGridIndexSet dualIdSet(this->gridView());
 
         // Build the SCVs and SCV faces
         GridIndexType scvfIdx = 0;
@@ -197,6 +192,7 @@ public:
 
             // for network grids there might be multiple intersection with the same geometryInInside
             // we indentify those by the indexInInside for now (assumes conforming grids at branching facets)
+            using ScvfOutsideGridIndexStorage = typename SubControlVolumeFace::Traits::OutsideGridIndexStorage;
             std::vector<ScvfOutsideGridIndexStorage> outsideIndices;
             if (dim < dimWorld)
             {
@@ -260,7 +256,7 @@ public:
                         secondaryInteractionVolumeVertices_[vIdxGlobal] = true;
 
                     // the quadrature point parameterizarion to be used on scvfs
-                    static const Scalar q = getParamFromGroup<Scalar>(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Mpfa.Q");
+                    static const auto q = getParam<CoordScalar>("Mpfa.Q");
 
                     // make the scv face (for non-boundary scvfs on network grids, use precalculated outside indices)
                     const auto& outsideScvIndices = [&] ()
@@ -361,7 +357,7 @@ public:
     //! have derivatives with respect to a given dof.
     const ConnectivityMap& connectivityMap() const { return connectivityMap_; }
 
-    //! Returns the grid interaction volume seeds class.
+    //! Returns the grid interaction volume index set class.
     const GridIVIndexSets& gridInteractionVolumeIndexSets() const { return ivIndexSets_; }
 
     //! Get the scvf on the same face but from the other side
@@ -403,49 +399,48 @@ private:
  * \note For caching disabled we store only some essential index maps to build up local systems on-demand in
  *       the corresponding FVElementGeometry
  */
-template<class TypeTag>
-class CCMpfaFVGridGeometry<TypeTag, false> : public BaseFVGridGeometry<TypeTag>
+template<class GV, class Traits>
+class CCMpfaFVGridGeometry<GV, Traits, false>
+: public BaseFVGridGeometry<CCMpfaFVGridGeometry<GV, Traits, false>, GV, Traits>
 {
-public:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using DualGridNodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet);
-
-    //! Export the discretization method this geometry belongs to
-    static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::CCMpfa;
+    using ThisType = CCMpfaFVGridGeometry<GV, Traits, false>;
+    using ParentType = BaseFVGridGeometry<ThisType, GV, Traits>;
 
-    //! Export the mpfa method
-    static constexpr MpfaMethods mpfaMethod = GET_PROP_VALUE(TypeTag, MpfaMethod);
-
-private:
-    using ThisType = CCMpfaFVGridGeometry<TypeTag, false>;
-    using ParentType = BaseFVGridGeometry<TypeTag>;
-    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
-    using MpfaHelper = typename GET_PROP_TYPE(TypeTag, MpfaHelper);
-    using ElementMapper = typename GET_PROP_TYPE(TypeTag, ElementMapper);
-    using PrimaryInteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
-
-    static constexpr int dim = GridView::dimension;
-    static constexpr int dimWorld = GridView::dimensionworld;
-
-    using Element = typename GridView::template Codim<0>::Entity;
-    using Vertex = typename GridView::template Codim<dim>::Entity;
-    using Intersection = typename GridView::Intersection;
-    using CoordScalar = typename GridView::ctype;
-    using GridIndexType = typename GridView::IndexSet::IndexType;
-    using LocalIndexType = typename PrimaryInteractionVolume::Traits::LocalIndexType;
-    using ScvfOutsideGridIndexStorage = typename SubControlVolumeFace::Traits::OutsideGridIndexStorage;
-
-    using GridIVIndexSets = CCMpfaGridInteractionVolumeIndexSets<TypeTag>;
-    using ConnectivityMap = CCMpfaConnectivityMap<ThisType, mpfaMethod>;
+    static constexpr int dim = GV::dimension;
+    static constexpr int dimWorld = GV::dimensionworld;
 
+    using Element = typename GV::template Codim<0>::Entity;
+    using Vertex = typename GV::template Codim<dim>::Entity;
+    using Intersection = typename GV::Intersection;
+    using GridIndexType = typename GV::IndexSet::IndexType;
+    using CoordScalar = typename GV::ctype;
     using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
 
+    using ScvfOutsideGridIndexStorage = typename Traits::SubControlVolumeFace::Traits::OutsideGridIndexStorage;
+
 public:
+    //! export the mpfa helper type
+    using MpfaHelper = typename Traits::MpfaHelper;
+    //! export the grid interaction volume index set type
+    using GridIVIndexSets = typename Traits::template GridIvIndexSets<ThisType>;
+    //! export the type to be used for indicators where to use the secondary ivs
     using SecondaryIvIndicatorType = std::function<bool(const Element&, const Intersection&, bool)>;
 
+    //! export the type of the fv element geometry (the local view type)
+    using LocalView = typename Traits::template LocalView<ThisType, false>;
+    //! export the type of sub control volume
+    using SubControlVolume = typename Traits::SubControlVolume;
+    //! export the type of sub control volume
+    using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
+    //! export the connectivity map type
+    using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
+    //! export dof mapper type
+    using DofMapper = typename Traits::ElementMapper;
+    //! export the grid view type
+    using GridView = GV;
+
+    //! export the discretization method this geometry belongs to
+    static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::CCMpfa;
     //! The maximum admissible stencil size (used for static memory allocation during assembly)
     // TODO: Re-implement and obtain from nodal index set (for now we use a high value)
     static constexpr int maxElementStencilSize = (dim < dimWorld || dim == 3) ? 45 : 15;
@@ -466,7 +461,7 @@ public:
 
     //! the element mapper is the dofMapper
     //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa...
-    const ElementMapper& dofMapper() const
+    const DofMapper& dofMapper() const
     { return this->elementMapper(); }
 
     //! Returns the total number of sub control volumes.
@@ -526,7 +521,7 @@ public:
         isGhostVertex_ = MpfaHelper::findGhostVertices(this->gridView(), this->vertexMapper());
 
         // instantiate the dual grid index set (to be used for construction of interaction volumes)
-        CCMpfaDualGridIndexSet< DualGridNodalIndexSet > dualIdSet(this->gridView());
+        typename GridIVIndexSets::DualGridIndexSet dualIdSet(this->gridView());
 
         // Build the SCVs and SCV faces
         numScvf_ = 0;
diff --git a/dumux/discretization/cellcentered/mpfa/gridinteractionvolumeindexsets.hh b/dumux/discretization/cellcentered/mpfa/gridinteractionvolumeindexsets.hh
index e502e5cd44..7a6875ca5c 100644
--- a/dumux/discretization/cellcentered/mpfa/gridinteractionvolumeindexsets.hh
+++ b/dumux/discretization/cellcentered/mpfa/gridinteractionvolumeindexsets.hh
@@ -35,27 +35,27 @@ namespace Dumux
 /*!
  * \ingroup CCMpfaDiscretization
  * \brief Class that holds all interaction volume index sets on a grid view.
+ *
+ * \tparam FVG the finite volume grid geometry
+ * \tparam NI the type used for nodal index sets
+ * \tparam PI primary interaction volume type
+ * \tparam SI secondary interaction volume type
  */
-template<class TypeTag>
+template<class FVG, class NI, class PI, class SI = PI>
 class CCMpfaGridInteractionVolumeIndexSets
 {
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using GridIndexType = typename GridView::IndexSet::IndexType;
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using DualGridNodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet);
-
-    using PrimaryIV = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
-    using PrimaryIVIndexSet = typename PrimaryIV::Traits::IndexSet;
-    using SecondaryIV = typename GET_PROP_TYPE(TypeTag, SecondaryInteractionVolume);
-    using SecondaryIVIndexSet = typename SecondaryIV::Traits::IndexSet;
-
-    static constexpr int dim = GridView::dimension;
-    using LocalIndexType = typename PrimaryIV::Traits::LocalIndexType;
-    using DualGridIndexSet = CCMpfaDualGridIndexSet< DualGridNodalIndexSet >;
+    using SubControlVolumeFace = typename FVG::SubControlVolumeFace;
+    using PrimaryIVIndexSet = typename PI::Traits::IndexSet;
+    using SecondaryIVIndexSet = typename SI::Traits::IndexSet;
 
 public:
+    using FVGridGeometry = FVG;
+    using PrimaryInteractionVolume = PI;
+    using SecondaryInteractionVolume = SI;
+
+    using GridIndexType = typename FVGridGeometry::GridView::IndexSet::IndexType;
+    using DualGridIndexSet = CCMpfaDualGridIndexSet< NI >;
+
     /*!
      * \brief Construct all interaction volume index sets on the grid view
      *
@@ -78,9 +78,9 @@ public:
         {
             const auto vIdxGlobal = fvGridGeometry.vertexMapper().index(vertex);
             if (!fvGridGeometry.vertexUsesSecondaryInteractionVolume(vIdxGlobal))
-                numPrimaryIV_ += PrimaryIV::numInteractionVolumesAtVertex((*dualGridIndexSet_)[vIdxGlobal]);
+                numPrimaryIV_ += PrimaryInteractionVolume::numInteractionVolumesAtVertex((*dualGridIndexSet_)[vIdxGlobal]);
             else
-                numSecondaryIV_ += SecondaryIV::numInteractionVolumesAtVertex((*dualGridIndexSet_)[vIdxGlobal]);
+                numSecondaryIV_ += SecondaryInteractionVolume::numInteractionVolumesAtVertex((*dualGridIndexSet_)[vIdxGlobal]);
         }
 
         // reserve memory
@@ -93,9 +93,9 @@ public:
         {
             const auto vIdxGlobal = fvGridGeometry.vertexMapper().index(vertex);
             if (!fvGridGeometry.vertexUsesSecondaryInteractionVolume(vIdxGlobal))
-                PrimaryIV::addInteractionVolumeIndexSets(primaryIVIndexSets_, scvfIndexMap_, (*dualGridIndexSet_)[vIdxGlobal]);
+                PrimaryInteractionVolume::addInteractionVolumeIndexSets(primaryIVIndexSets_, scvfIndexMap_, (*dualGridIndexSet_)[vIdxGlobal]);
             else
-                SecondaryIV::addInteractionVolumeIndexSets(secondaryIVIndexSets_, scvfIndexMap_, (*dualGridIndexSet_)[vIdxGlobal]);
+                SecondaryInteractionVolume::addInteractionVolumeIndexSets(secondaryIVIndexSets_, scvfIndexMap_, (*dualGridIndexSet_)[vIdxGlobal]);
         }
     }
 
diff --git a/dumux/discretization/cellcentered/mpfa/properties.hh b/dumux/discretization/cellcentered/mpfa/properties.hh
index 00f6914d57..ba5c59b468 100644
--- a/dumux/discretization/cellcentered/mpfa/properties.hh
+++ b/dumux/discretization/cellcentered/mpfa/properties.hh
@@ -26,24 +26,27 @@
 #define DUMUX_CC_MPFA_PROPERTIES_HH
 
 #include <dumux/common/properties.hh>
+#include <dumux/common/defaultmappertraits.hh>
 
 #include <dumux/assembly/cclocalresidual.hh>
 
-#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/elementsolution.hh>
 #include <dumux/discretization/cellcentered/elementboundarytypes.hh>
+#include <dumux/discretization/cellcentered/subcontrolvolume.hh>
 
+#include <dumux/discretization/cellcentered/mpfa/methods.hh>
 #include <dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh>
 #include <dumux/discretization/cellcentered/mpfa/gridfluxvariablescache.hh>
 #include <dumux/discretization/cellcentered/mpfa/fvelementgeometry.hh>
+#include <dumux/discretization/cellcentered/mpfa/subcontrolvolumeface.hh>
 #include <dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh>
 #include <dumux/discretization/cellcentered/mpfa/elementfluxvariablescache.hh>
-#include <dumux/discretization/cellcentered/mpfa/subcontrolvolumeface.hh>
 #include <dumux/discretization/cellcentered/mpfa/dualgridindexset.hh>
+#include <dumux/discretization/cellcentered/mpfa/connectivitymap.hh>
+#include <dumux/discretization/cellcentered/mpfa/gridinteractionvolumeindexsets.hh>
 #include <dumux/discretization/cellcentered/mpfa/helper.hh>
 
 #include <dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh>
@@ -61,12 +64,6 @@ SET_PROP(CCMpfaModel, DiscretizationMethod)
     static const DiscretizationMethods value = DiscretizationMethods::CCMpfa;
 };
 
-//! Extract the used mpfa method from the primary interaction volume
-SET_PROP(CCMpfaModel, MpfaMethod)
-{
-    static const MpfaMethods value = GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume)::MpfaMethod;
-};
-
 //! Set the maximum admissible number of branches per scvf
 SET_PROP(CCMpfaModel, MaxNumNeighborsPerScvf)
 {
@@ -129,14 +126,44 @@ public:
 };
 
 //! Set the default for the global finite volume geometry
-SET_TYPE_PROP(CCMpfaModel,
-              FVGridGeometry,
-              CCMpfaFVGridGeometry<TypeTag, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
+SET_PROP(CCMpfaModel, FVGridGeometry)
+{
+private:
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using PrimaryIV = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
+    using SecondaryIV = typename GET_PROP_TYPE(TypeTag, SecondaryInteractionVolume);
+
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache);
+
+    struct Traits : public DefaultMapperTraits<GridView>
+    {
+        using SubControlVolume = CCSubControlVolume<GridView>;
+        using SubControlVolumeFace = CCMpfaSubControlVolumeFace<GridView>;
+        using MpfaHelper = typename GET_PROP_TYPE(TypeTag, MpfaHelper);
+        using NodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet);
+
+        template< class FVGridGeometry >
+        using GridIvIndexSets = CCMpfaGridInteractionVolumeIndexSets< FVGridGeometry,
+                                                                      NodalIndexSet,
+                                                                      PrimaryIV,
+                                                                      SecondaryIV >;
+
+        template< class FVGridGeometry, bool enableCache >
+        using LocalView = CCMpfaFVElementGeometry<FVGridGeometry, enableCache>;
+
+        //! Per default, we use the o-method and thus the simple assembly map
+        template< class FVGridGeometry >
+        using ConnectivityMap = CCMpfaConnectivityMap<FVGridGeometry, FVGridGeometry::GridIVIndexSets::PrimaryInteractionVolume::MpfaMethod>;
+    };
+public:
+    using type = CCMpfaFVGridGeometry<GridView, Traits, enableCache>;
+};
 
 //! Set the default for the local finite volume geometry
 SET_TYPE_PROP(CCMpfaModel,
               FVElementGeometry,
-              CCMpfaFVElementGeometry<TypeTag, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
+              CCMpfaFVElementGeometry<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
+                                      GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
 
 //! The global flux variables cache vector class
 SET_TYPE_PROP(CCMpfaModel,
@@ -157,26 +184,6 @@ SET_TYPE_PROP(CCMpfaModel,
 //! The global current volume variables vector class
 SET_TYPE_PROP(CCMpfaModel, GridVolumeVariables, CCGridVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
 
-//! The sub control volume
-SET_PROP(CCMpfaModel, SubControlVolume)
-{
-private:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Traits = CCDefaultScvGeometryTraits<GridView>;
-public:
-    using type = CCSubControlVolume<Traits>;
-};
-
-//! The sub-control volume face class
-SET_PROP(CCMpfaModel, SubControlVolumeFace)
-{
-private:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Traits = CCMpfaDefaultScvfGeometryTraits<GridView>;
-public:
-    using type = Dumux::CCMpfaSubControlVolumeFace<Traits>;
-};
-
 //! Set the solution vector type for an element
 SET_TYPE_PROP(CCMpfaModel, ElementSolutionVector, CCElementSolution<TypeTag>);
 
diff --git a/dumux/discretization/cellcentered/mpfa/subcontrolvolumeface.hh b/dumux/discretization/cellcentered/mpfa/subcontrolvolumeface.hh
index dfc14bfc61..96122d5982 100644
--- a/dumux/discretization/cellcentered/mpfa/subcontrolvolumeface.hh
+++ b/dumux/discretization/cellcentered/mpfa/subcontrolvolumeface.hh
@@ -32,9 +32,14 @@
 #include <dune/geometry/type.hh>
 #include <dune/geometry/multilineargeometry.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
+/*!
+ * \ingroup CCMpfaDiscretization
+ * \brief Default traits class to be used for the sub-control volume faces
+ *        for the cell-centered finite volume scheme using MPFA
+ * \tparam GV the type of the grid view
+ */
 template<class GridView>
 struct CCMpfaDefaultScvfGeometryTraits
 {
@@ -80,22 +85,23 @@ struct CCMpfaDefaultScvfGeometryTraits
  * \ingroup CCMpfaDiscretization
  * \brief Class for a sub control volume face in mpfa methods, i.e a part of the boundary
  *        of a control volume we compute fluxes on.
- *
- * \param ScvfGeometryTraits the traits class for the geometry type
+ * \tparam GV the type of the grid view
+ * \tparam T the scvf geometry traits
  */
-template<class ScvfGeometryTraits>
+template<class GV,
+         class T = CCMpfaDefaultScvfGeometryTraits<GV> >
 class CCMpfaSubControlVolumeFace
 {
-    using GridIndexType = typename ScvfGeometryTraits::GridIndexType;
-    using Scalar = typename ScvfGeometryTraits::Scalar;
-    using GlobalPosition = typename ScvfGeometryTraits::GlobalPosition;
-    using CornerStorage = typename ScvfGeometryTraits::CornerStorage;
-    using OutsideGridIndexStorage = typename ScvfGeometryTraits::OutsideGridIndexStorage;
-    using Geometry = typename ScvfGeometryTraits::Geometry;
+    using GridIndexType = typename T::GridIndexType;
+    using Scalar = typename T::Scalar;
+    using GlobalPosition = typename T::GlobalPosition;
+    using CornerStorage = typename T::CornerStorage;
+    using OutsideGridIndexStorage = typename T::OutsideGridIndexStorage;
+    using Geometry = typename T::Geometry;
 
 public:
     //! state the traits public and thus export all types
-    using Traits = ScvfGeometryTraits;
+    using Traits = T;
 
     /*!
      * \brief Constructor
diff --git a/dumux/discretization/cellcentered/subcontrolvolume.hh b/dumux/discretization/cellcentered/subcontrolvolume.hh
index 1c6cd9db19..8ec5d6c7d0 100644
--- a/dumux/discretization/cellcentered/subcontrolvolume.hh
+++ b/dumux/discretization/cellcentered/subcontrolvolume.hh
@@ -28,13 +28,13 @@
 #include <dumux/discretization/subcontrolvolumebase.hh>
 #include <dumux/common/optional.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup CCDiscretization
  * \brief Default traits class to be used for the sub-control volumes
  *        for the cell-centered finite volume scheme using TPFA
+ * \tparam GV the type of the grid view
  */
 template<class GridView>
 struct CCDefaultScvGeometryTraits
@@ -49,20 +49,25 @@ struct CCDefaultScvGeometryTraits
 /*!
  * \ingroup CCDiscretization
  * \brief Sub control volumes for cell-centered discretization schemes
+ * \tparam GV the type of the grid view
+ * \tparam T the scv geometry traits
  */
-template<class ScvGeometryTraits>
-class CCSubControlVolume : public SubControlVolumeBase<CCSubControlVolume<ScvGeometryTraits>, ScvGeometryTraits>
+template<class GV,
+         class T = CCDefaultScvGeometryTraits<GV> >
+class CCSubControlVolume
+: public SubControlVolumeBase<CCSubControlVolume<GV, T>, T>
 {
-    using ParentType = SubControlVolumeBase<CCSubControlVolume<ScvGeometryTraits>, ScvGeometryTraits>;
-    using Geometry = typename ScvGeometryTraits::Geometry;
-    using GridIndexType = typename ScvGeometryTraits::GridIndexType;
-    using LocalIndexType = typename ScvGeometryTraits::LocalIndexType;
-    using Scalar = typename ScvGeometryTraits::Scalar;
-    using GlobalPosition = typename ScvGeometryTraits::GlobalPosition;
+    using ThisType = CCSubControlVolume<GV, T>;
+    using ParentType = SubControlVolumeBase<ThisType, T>;
+    using Geometry = typename T::Geometry;
+    using GridIndexType = typename T::GridIndexType;
+    using LocalIndexType = typename T::LocalIndexType;
+    using Scalar = typename T::Scalar;
+    using GlobalPosition = typename T::GlobalPosition;
 
 public:
     //! state the traits public and thus export all types
-    using Traits = ScvGeometryTraits;
+    using Traits = T;
 
     CCSubControlVolume() = default;
 
diff --git a/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh b/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh
index 4ff6ebcdd9..a4f64384f1 100644
--- a/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh
+++ b/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh
@@ -27,29 +27,25 @@
 #define DUMUX_DISCRETIZATION_CCTPFA_FV_ELEMENT_GEOMETRY_HH
 
 #include <algorithm>
+#include <array>
 
 #include <dune/common/exceptions.hh>
 #include <dune/common/iteratorrange.hh>
-#include <dumux/common/properties.hh>
 #include <dumux/discretization/scvandscvfiterators.hh>
 
-namespace Dumux
-{
-
-//! forward declaration of the global finite volume geometry
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class CCTpfaFVGridGeometry;
+namespace Dumux {
 
 /*!
  * \ingroup CCTpfaDiscretization
  * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered TPFA models
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element in the local scope we are restricting to, e.g. stencil or element.
+ * \tparam GG the finite volume grid geometry type
+ * \tparam enableFVGridGeometryCache if the grid geometry is cached or not
  * \note This class is specialized for versions with and without caching the fv geometries on the grid view
  */
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class CCTpfaFVElementGeometry
-{};
+template<class GG, bool enableFVGridGeometryCache>
+class CCTpfaFVElementGeometry;
 
 /*!
  * \ingroup CCTpfaDiscretization
@@ -57,21 +53,21 @@ class CCTpfaFVElementGeometry
  *        Specialization for grid caching enabled
  * \note The finite volume geometries are stored in the corresponding FVGridGeometry
  */
-template<class TypeTag>
-class CCTpfaFVElementGeometry<TypeTag, true>
+template<class GG>
+class CCTpfaFVElementGeometry<GG, true>
 {
-    using ThisType = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using ThisType = CCTpfaFVElementGeometry<GG, true>;
+    using GridView = typename GG::GridView;
     using IndexType = typename GridView::IndexSet::IndexType;
     using Element = typename GridView::template Codim<0>::Entity;
 
 public:
     //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using SubControlVolume = typename GG::SubControlVolume;
     //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
     //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GG;
     //! the maximum number of scvs per element
     static constexpr std::size_t maxNumElementScvs = 1;
     //! the maximum number of scvfs per element (use cubes for maximum)
@@ -171,11 +167,11 @@ private:
  * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered TPFA models
  *        Specialization for grid caching disabled
  */
-template<class TypeTag>
-class CCTpfaFVElementGeometry<TypeTag, false>
+template<class GG>
+class CCTpfaFVElementGeometry<GG, false>
 {
-    using ThisType = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using ThisType = CCTpfaFVElementGeometry<GG, false>;
+    using GridView = typename GG::GridView;
     using IndexType = typename GridView::IndexSet::IndexType;
     using Element = typename GridView::template Codim<0>::Entity;
 
@@ -184,11 +180,11 @@ class CCTpfaFVElementGeometry<TypeTag, false>
 
 public:
     //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using SubControlVolume = typename GG::SubControlVolume;
     //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
     //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GG;
     //! the maximum number of scvs per element
     static constexpr std::size_t maxNumElementScvs = 1;
     //! the maximum number of scvfs per element (use cubes for maximum)
diff --git a/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh b/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh
index 0f9a7c00b9..536027447f 100644
--- a/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh
+++ b/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh
@@ -28,15 +28,35 @@
 
 #include <algorithm>
 
-#include <dune/common/version.hh>
-
+#include <dumux/common/defaultmappertraits.hh>
 #include <dumux/discretization/methods.hh>
 #include <dumux/discretization/basefvgridgeometry.hh>
-#include <dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh>
+#include <dumux/discretization/cellcentered/subcontrolvolume.hh>
 #include <dumux/discretization/cellcentered/connectivitymap.hh>
+#include <dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh>
+#include <dumux/discretization/cellcentered/tpfa/subcontrolvolumeface.hh>
 
-namespace Dumux
+namespace Dumux {
+
+/*!
+ * \ingroup CCTpfaDiscretization
+ * \brief The default traits for the tpfa finite volume grid geometry
+ *        Defines the scv and scvf types and the mapper types
+ * \tparam the grid view type
+ */
+template<class GridView>
+struct CCTpfaDefaultGridGeometryTraits
+: public DefaultMapperTraits<GridView>
 {
+    using SubControlVolume = CCSubControlVolume<GridView>;
+    using SubControlVolumeFace = CCTpfaSubControlVolumeFace<GridView>;
+
+    template<class FVGridGeometry>
+    using ConnectivityMap = CCSimpleConnectivityMap<FVGridGeometry>;
+
+    template<class FVGridGeometry, bool enableCache>
+    using LocalView = CCTpfaFVElementGeometry<FVGridGeometry, enableCache>;
+};
 
 /*!
  * \ingroup CCTpfaDiscretization
@@ -44,9 +64,10 @@ namespace Dumux
  *        This builds up the sub control volumes and sub control volume faces
  * \note This class is specialized for versions with and without caching the fv geometries on the grid view
  */
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class CCTpfaFVGridGeometry
-{};
+template<class GridView,
+         bool enableFVGridGeometryCache = false,
+         class Traits = CCTpfaDefaultGridGeometryTraits<GridView> >
+class CCTpfaFVGridGeometry;
 
 /*!
  * \ingroup CCTpfaDiscretization
@@ -54,41 +75,40 @@ class CCTpfaFVGridGeometry
  *        This builds up the sub control volumes and sub control volume faces
  * \note For caching enabled we store the fv geometries for the whole grid view which is memory intensive but faster
  */
-template<class TypeTag>
-class CCTpfaFVGridGeometry<TypeTag, true> : public BaseFVGridGeometry<TypeTag>
+template<class GV, class Traits>
+class CCTpfaFVGridGeometry<GV, true, Traits>
+: public BaseFVGridGeometry<CCTpfaFVGridGeometry<GV, true, Traits>, GV, Traits>
 {
-public:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-
-private:
-    using ThisType = CCTpfaFVGridGeometry<TypeTag, true>;
-    using ParentType = BaseFVGridGeometry<TypeTag>;
-    using ConnectivityMap = CCSimpleConnectivityMap<ThisType>;
-    using ElementMapper = typename GET_PROP_TYPE(TypeTag, ElementMapper);
-    using ScvfGridIndexStorage = typename SubControlVolumeFace::Traits::GridIndexStorage;
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-
-    static const int dim = GridView::dimension;
-    static const int dimWorld = GridView::dimensionworld;
-    using CoordScalar = typename GridView::ctype;
+    using ThisType = CCTpfaFVGridGeometry<GV, true, Traits>;
+    using ParentType = BaseFVGridGeometry<ThisType, GV, Traits>;
+    using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
+    using IndexType = typename GV::IndexSet::IndexType;
+    using Element = typename GV::template Codim<0>::Entity;
+
+    static const int dim = GV::dimension;
+    static const int dimWorld = GV::dimensionworld;
+    using CoordScalar = typename GV::ctype;
     using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
 
-    //! The local class needs access to the scv, scvfs and the fv element geometry
-    //! as they are globally cached
-    friend typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-
 public:
-    //! Export the discretization method this geometry belongs to
+    //! export the type of the fv element geometry (the local view type)
+    using LocalView = typename Traits::template LocalView<ThisType, true>;
+    //! export the type of sub control volume
+    using SubControlVolume = typename Traits::SubControlVolume;
+    //! export the type of sub control volume
+    using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
+    //! export dof mapper type
+    using DofMapper = typename Traits::ElementMapper;
+
+    //! export the discretization method this geometry belongs to
     static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::CCTpfa;
 
     //! The maximum admissible stencil size (used for static memory allocation during assembly)
     //! Per default, we allow for 9 branches per scvf on network/surface grids
-    static constexpr int maxElementStencilSize = (dim < dimWorld) ? FVElementGeometry::maxNumElementScvfs*8 + 1
-                                                                  : FVElementGeometry::maxNumElementScvfs + 1;
+    static constexpr int maxElementStencilSize = (dim < dimWorld) ? LocalView::maxNumElementScvfs*8 + 1
+                                                                  : LocalView::maxNumElementScvfs + 1;
+    //! export the grid view type
+    using GridView = GV;
 
     //! Constructor
     CCTpfaFVGridGeometry(const GridView& gridView)
@@ -97,7 +117,7 @@ public:
 
     //! the element mapper is the dofMapper
     //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa...
-    const ElementMapper& dofMapper() const
+    const DofMapper& dofMapper() const
     { return this->elementMapper(); }
 
     //! The total number of sub control volumes
@@ -166,6 +186,7 @@ public:
 
             // for network grids there might be multiple intersection with the same geometryInInside
             // we indentify those by the indexInInside for now (assumes conforming grids at branching facets)
+            using ScvfGridIndexStorage = typename SubControlVolumeFace::Traits::GridIndexStorage;
             std::vector<ScvfGridIndexStorage> outsideIndices;
             if (dim < dimWorld)
             {
@@ -324,42 +345,48 @@ private:
  * \note For caching disabled we store only some essential index maps to build up local systems on-demand in
  *       the corresponding FVElementGeometry
  */
-template<class TypeTag>
-class CCTpfaFVGridGeometry<TypeTag, false>  : public BaseFVGridGeometry<TypeTag>
+template<class GV, class Traits>
+class CCTpfaFVGridGeometry<GV, false, Traits>
+: public BaseFVGridGeometry<CCTpfaFVGridGeometry<GV, false, Traits>, GV, Traits>
 {
-public:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using ThisType = CCTpfaFVGridGeometry<GV, false, Traits>;
+    using ParentType = BaseFVGridGeometry<ThisType, GV, Traits>;
+    using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
 
-private:
-    using ThisType = CCTpfaFVGridGeometry<TypeTag, false>;
-    using ParentType = BaseFVGridGeometry<TypeTag>;
-    using ConnectivityMap = CCSimpleConnectivityMap<ThisType>;
-    using ElementMapper = typename GET_PROP_TYPE(TypeTag, ElementMapper);
-    using ScvfGridIndexStorage = typename SubControlVolumeFace::Traits::GridIndexStorage;
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-
-    static const int dim = GridView::dimension;
-    static const int dimWorld = GridView::dimensionworld;
-
-    using CoordScalar = typename GridView::ctype;
+    using IndexType = typename GV::IndexSet::IndexType;
+    using Element = typename GV::template Codim<0>::Entity;
+
+    static const int dim = GV::dimension;
+    static const int dimWorld = GV::dimensionworld;
+
+    using CoordScalar = typename GV::ctype;
     using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
 
+    using ScvfGridIndexStorage = typename Traits::SubControlVolumeFace::Traits::GridIndexStorage;
     using NeighborVolVarIndices = typename std::conditional_t< (dim<dimWorld),
                                                                ScvfGridIndexStorage,
                                                                Dune::ReservedVector<IndexType, 1> >;
 
 public:
+    //! export the type of the fv element geometry (the local view type)
+    using LocalView = typename Traits::template LocalView<ThisType, false>;
+    //! export the type of sub control volume
+    using SubControlVolume = typename Traits::SubControlVolume;
+    //! export the type of sub control volume
+    using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
+    //! export dof mapper type
+    using DofMapper = typename Traits::ElementMapper;
+
     //! Export the discretization method this geometry belongs to
     static constexpr DiscretizationMethods discretizationMethod = DiscretizationMethods::CCTpfa;
 
     //! The maximum admissible stencil size (used for static memory allocation during assembly)
     //! Per default, we allow for 9 branches per scvf on network/surface grids
-    static constexpr int maxElementStencilSize = (dim < dimWorld) ? FVElementGeometry::maxNumElementScvfs*8 + 1
-                                                                  : FVElementGeometry::maxNumElementScvfs + 1;
+    static constexpr int maxElementStencilSize = (dim < dimWorld) ? LocalView::maxNumElementScvfs*8 + 1
+                                                                  : LocalView::maxNumElementScvfs + 1;
+
+    //! Export the type of the grid view
+    using GridView = GV;
 
     //! Constructor
     CCTpfaFVGridGeometry(const GridView& gridView)
@@ -368,7 +395,7 @@ public:
 
     //! the element mapper is the dofMapper
     //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa...
-    const ElementMapper& dofMapper() const
+    const DofMapper& dofMapper() const
     { return this->elementMapper(); }
 
     //! The total number of sub control volumes
diff --git a/dumux/discretization/cellcentered/tpfa/properties.hh b/dumux/discretization/cellcentered/tpfa/properties.hh
index 854abf0413..3af083e2b4 100644
--- a/dumux/discretization/cellcentered/tpfa/properties.hh
+++ b/dumux/discretization/cellcentered/tpfa/properties.hh
@@ -64,13 +64,21 @@ SET_PROP(CCTpfaModel, DiscretizationMethod)
 };
 
 //! Set the default for the global finite volume geometry
-SET_TYPE_PROP(CCTpfaModel, FVGridGeometry, CCTpfaFVGridGeometry<TypeTag, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
+SET_PROP(CCTpfaModel, FVGridGeometry)
+{
+private:
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache);
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+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)>);
 
 //! Set the default for the local finite volume geometry
-SET_TYPE_PROP(CCTpfaModel, FVElementGeometry, CCTpfaFVElementGeometry<TypeTag, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
+SET_TYPE_PROP(CCTpfaModel, FVElementGeometry, CCTpfaFVElementGeometry<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
+                                                                      GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
 
 //! The global previous volume variables vector class
 SET_TYPE_PROP(CCTpfaModel, ElementVolumeVariables, CCTpfaElementVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>);
@@ -94,26 +102,6 @@ public:
     static constexpr std::size_t value = dim < dimWorld ? 9 : 2;
 };
 
-//! The sub control volume
-SET_PROP(CCTpfaModel, SubControlVolume)
-{
-private:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Traits = CCDefaultScvGeometryTraits<GridView>;
-public:
-    using type = CCSubControlVolume<Traits>;
-};
-
-//! The sub control volume face
-SET_PROP(CCTpfaModel, SubControlVolumeFace)
-{
-private:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using Traits = CCTpfaDefaultScvfGeometryTraits<GridView>;
-public:
-    using type = Dumux::CCTpfaSubControlVolumeFace<Traits>;
-};
-
 //! Set the solution vector type for an element
 SET_TYPE_PROP(CCTpfaModel, ElementSolutionVector, CCElementSolution<TypeTag>);
 
diff --git a/dumux/discretization/cellcentered/tpfa/subcontrolvolumeface.hh b/dumux/discretization/cellcentered/tpfa/subcontrolvolumeface.hh
index 755dbeef0d..7717311313 100644
--- a/dumux/discretization/cellcentered/tpfa/subcontrolvolumeface.hh
+++ b/dumux/discretization/cellcentered/tpfa/subcontrolvolumeface.hh
@@ -25,16 +25,22 @@
 #define DUMUX_DISCRETIZATION_CC_TPFA_SUBCONTROLVOLUMEFACE_HH
 
 #include <utility>
+#include <vector>
+
+#include <dune/common/reservedvector.hh>
 #include <dune/geometry/type.hh>
+#include <dune/geometry/multilineargeometry.hh>
+
+#include <dumux/common/boundaryflag.hh>
 #include <dumux/discretization/subcontrolvolumefacebase.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup CCDiscretization
  * \brief Default traits class to be used for the sub-control volume faces
  *        for the cell-centered finite volume scheme using TPFA
+ * \tparam GV the type of the grid view
  */
 template<class GridView>
 struct CCTpfaDefaultScvfGeometryTraits
@@ -73,22 +79,27 @@ struct CCTpfaDefaultScvfGeometryTraits
 /*!
  * \ingroup CCTpfaDiscretization
  * \brief The sub control volume face
+ * \tparam GV the type of the grid view
+ * \tparam T the scvf geometry traits
  */
-template<class ScvfGeometryTraits>
-class CCTpfaSubControlVolumeFace : public SubControlVolumeFaceBase<CCTpfaSubControlVolumeFace<ScvfGeometryTraits>,ScvfGeometryTraits>
+template<class GV,
+         class T = CCTpfaDefaultScvfGeometryTraits<GV> >
+class CCTpfaSubControlVolumeFace
+: public SubControlVolumeFaceBase<CCTpfaSubControlVolumeFace<GV, T>, T>
 {
-    using ParentType = SubControlVolumeFaceBase<CCTpfaSubControlVolumeFace<ScvfGeometryTraits>, ScvfGeometryTraits>;
-    using GridIndexType = typename ScvfGeometryTraits::GridIndexType;
-    using Scalar = typename ScvfGeometryTraits::Scalar;
-    using GlobalPosition = typename ScvfGeometryTraits::GlobalPosition;
-    using CornerStorage = typename ScvfGeometryTraits::CornerStorage;
-    using GridIndexStorage = typename ScvfGeometryTraits::GridIndexStorage;
-    using Geometry = typename ScvfGeometryTraits::Geometry;
-    using BoundaryFlag = typename ScvfGeometryTraits::BoundaryFlag;
+    using ThisType = CCTpfaSubControlVolumeFace<GV, T>;
+    using ParentType = SubControlVolumeFaceBase<ThisType, T>;
+    using GridIndexType = typename T::GridIndexType;
+    using Scalar = typename T::Scalar;
+    using GlobalPosition = typename T::GlobalPosition;
+    using CornerStorage = typename T::CornerStorage;
+    using GridIndexStorage = typename T::GridIndexStorage;
+    using Geometry = typename T::Geometry;
+    using BoundaryFlag = typename T::BoundaryFlag;
 
 public:
     //! state the traits public and thus export all types
-    using Traits = ScvfGeometryTraits;
+    using Traits = T;
 
     // the default constructor
     CCTpfaSubControlVolumeFace() = default;
diff --git a/dumux/discretization/fluxstencil.hh b/dumux/discretization/fluxstencil.hh
index d86cc68c19..e34321cf03 100644
--- a/dumux/discretization/fluxstencil.hh
+++ b/dumux/discretization/fluxstencil.hh
@@ -97,7 +97,7 @@ class FluxStencil<FVElementGeometry, DiscretizationMethods::CCMpfa>
     using IndexType = typename GridView::IndexSet::IndexType;
 
     // Use the stencil type of the primary interaction volume
-    using NodalIndexSet = typename FVGridGeometry::DualGridNodalIndexSet;
+    using NodalIndexSet = typename FVGridGeometry::GridIVIndexSets::DualGridIndexSet::NodalIndexSet;
 
 public:
     //! We don't know yet how many faces couple to a neighboring element
diff --git a/dumux/discretization/staggered/freeflow/connectivitymap.hh b/dumux/discretization/staggered/freeflow/connectivitymap.hh
index d38d1a8731..1f0ec37cf5 100644
--- a/dumux/discretization/staggered/freeflow/connectivitymap.hh
+++ b/dumux/discretization/staggered/freeflow/connectivitymap.hh
@@ -26,8 +26,7 @@
 
 #include <vector>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup StaggeredDiscretization
@@ -38,7 +37,7 @@ template<class FVGridGeometry, class DofTypeIndices>
 class StaggeredFreeFlowConnectivityMap
 {
     using GridView = typename FVGridGeometry::GridView;
-    using FVElementGeometry = typename FVGridGeometry::FVElementGeometry;
+    using FVElementGeometry = typename FVGridGeometry::LocalView;
     using SubControlVolumeFace = typename FVGridGeometry::SubControlVolumeFace;
 
     using Element = typename GridView::template Codim<0>::Entity;
diff --git a/dumux/discretization/staggered/freeflow/properties.hh b/dumux/discretization/staggered/freeflow/properties.hh
index 9808a0b77d..a1c6f6be95 100644
--- a/dumux/discretization/staggered/freeflow/properties.hh
+++ b/dumux/discretization/staggered/freeflow/properties.hh
@@ -29,14 +29,22 @@
 #define DUMUX_STAGGERD_FREE_FLOW_PROPERTIES_HH
 
 #include <dumux/common/properties.hh>
+#include <dumux/common/intersectionmapper.hh>
+#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 "subcontrolvolumeface.hh"
 #include "connectivitymap.hh"
 #include "facevariables.hh"
 #include "boundarytypes.hh"
 #include "velocityoutput.hh"
+#include "staggeredgeometryhelper.hh"
 
 namespace Dumux
 {
@@ -69,34 +77,30 @@ public:
     static constexpr int value = GET_PROP_VALUE(TypeTag, NumEq) - dim;
 };
 
-//! The default sub-controlvolume face
-SET_PROP(StaggeredFreeFlowModel, SubControlVolumeFace)
+//! The default fv grid geometry
+SET_PROP(StaggeredFreeFlowModel, FVGridGeometry)
 {
 private:
-    using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
-    static constexpr int dim = Grid::dimension;
-    static constexpr int dimWorld = Grid::dimensionworld;
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
+    static constexpr bool enableCache = GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache);
 
-    struct ScvfGeometryTraits
+    struct Traits : public DefaultMapperTraits<GridView>
     {
-        using GridIndexType = typename Grid::LeafGridView::IndexSet::IndexType;
-        using LocalIndexType = unsigned int;
-        using Scalar = typename Grid::ctype;
-        using Geometry = typename Grid::template Codim<1>::Geometry;
-        using GlobalPosition = Dune::FieldVector<Scalar, dim>;
-    };
+        using SubControlVolume = CCSubControlVolume<GridView>;
+        using SubControlVolumeFace = FreeFlowStaggeredSubControlVolumeFace<GridView>;
+        using IntersectionMapper = ConformingGridIntersectionMapper<GridView>;
+        using GeometryHelper = FreeFlowStaggeredGeometryHelper<GridView>;
 
-public:
-    using type = FreeFlowStaggeredSubControlVolumeFace<ScvfGeometryTraits>;
-};
+        template<class FVGridGeometry>
+        using ConnectivityMap = StaggeredFreeFlowConnectivityMap<FVGridGeometry, DofTypeIndices>;
+
+        template<class FVGridGeometry, bool enableCache>
+        using LocalView = StaggeredFVElementGeometry<FVGridGeometry, enableCache>;
+    };
 
-//! The default geometry helper required for the stencils, etc.
-SET_PROP(StaggeredFreeFlowModel, StaggeredGeometryHelper)
-{
-private:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
 public:
-    using type = FreeFlowStaggeredGeometryHelper<GridView>;
+    using type = StaggeredFVGridGeometry<GridView, enableCache, Traits>;
 };
 
 //! The variables living on the faces
@@ -114,8 +118,6 @@ public:
 //! The velocity output
 SET_TYPE_PROP(StaggeredFreeFlowModel, VelocityOutput, StaggeredFreeFlowVelocityOutput<TypeTag>);
 
-SET_TYPE_PROP(StaggeredFreeFlowModel, AssemblyMap, StaggeredFreeFlowConnectivityMap<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
-                                                                                    typename GET_PROP(TypeTag, DofTypeIndices)>);
 } // namespace Properties
 } // namespace Dumux
 
diff --git a/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh b/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh
index 9742c3c12a..be10af48e9 100644
--- a/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh
+++ b/dumux/discretization/staggered/freeflow/subcontrolvolumeface.hh
@@ -28,38 +28,41 @@
 #include <dune/common/fvector.hh>
 
 #include <dumux/discretization/subcontrolvolumefacebase.hh>
+#include <dumux/discretization/staggered/subcontrolvolumeface.hh>
 #include <dumux/discretization/staggered/freeflow/staggeredgeometryhelper.hh>
 #include <dumux/common/properties.hh>
 #include <dumux/common/optional.hh>
 
 #include <typeinfo>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup StaggeredDiscretization
  * \brief Class for a sub control volume face in the staggered method, i.e a part of the boundary
  *        of a sub control volume we compute fluxes on. This is a specialization for free flow models.
  */
-template<class ScvfGeometryTraits>
-class FreeFlowStaggeredSubControlVolumeFace : public SubControlVolumeFaceBase<FreeFlowStaggeredSubControlVolumeFace<ScvfGeometryTraits>, ScvfGeometryTraits>
+template<class GV,
+         class T = StaggeredDefaultScvfGeometryTraits<GV> >
+class FreeFlowStaggeredSubControlVolumeFace
+: public SubControlVolumeFaceBase<FreeFlowStaggeredSubControlVolumeFace<GV, T>, T>
 {
-    using ParentType = SubControlVolumeFaceBase<FreeFlowStaggeredSubControlVolumeFace<ScvfGeometryTraits>,ScvfGeometryTraits>;
-    using Geometry = typename ScvfGeometryTraits::Geometry;
-    using GridIndexType = typename ScvfGeometryTraits::GridIndexType;
+    using ThisType = FreeFlowStaggeredSubControlVolumeFace<GV, T>;
+    using ParentType = SubControlVolumeFaceBase<ThisType, T>;
+    using Geometry = typename T::Geometry;
+    using GridIndexType = typename T::GridIndexType;
 
-    using Scalar = typename ScvfGeometryTraits::Scalar;
+    using Scalar = typename T::Scalar;
     static const int dim = Geometry::mydimension;
     static const int dimworld = Geometry::coorddimension;
 
-    using GlobalPosition = typename ScvfGeometryTraits::GlobalPosition;
+    using GlobalPosition = typename T::GlobalPosition;
 
     static constexpr int numPairs = (dimworld == 2) ? 2 : 4;
 
 public:
     //! State the traits public and thus export all types
-    using Traits = ScvfGeometryTraits;
+    using Traits = T;
 
     // The default constructor
     FreeFlowStaggeredSubControlVolumeFace() = default;
@@ -252,8 +255,6 @@ private:
     bool isGhostFace_;
 };
 
-
-
-} // end namespace
+} // end namespace Dumux
 
 #endif
diff --git a/dumux/discretization/staggered/fvelementgeometry.hh b/dumux/discretization/staggered/fvelementgeometry.hh
index ab1518b904..eb9773e075 100644
--- a/dumux/discretization/staggered/fvelementgeometry.hh
+++ b/dumux/discretization/staggered/fvelementgeometry.hh
@@ -26,48 +26,43 @@
 
 #include <dune/common/iteratorrange.hh>
 
-#include <dumux/common/properties.hh>
 #include <dumux/discretization/scvandscvfiterators.hh>
 
-namespace Dumux
-{
-
-// forward declaration
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class StaggeredFVGridGeometry;
+namespace Dumux {
 
 /*!
  * \ingroup StaggeredDiscretization
  * \brief Base class for the finite volume geometry vector for staggered models
  *        This locally builds up the sub control volumes and sub control volume faces
  *        for each element.
+ * \tparam GG the finite volume grid geometry type
+ * \tparam enableFVGridGeometryCache if the grid geometry is cached or not
  */
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class StaggeredFVElementGeometry
-{};
+template<class GG, bool enableFVGridGeometryCache>
+class StaggeredFVElementGeometry;
 
 /*!
  * \ingroup StaggeredDiscretization
  * \brief Class for the finite volume geometry vector for staggered models
  *        This locally builds up the sub control volumes and sub control volume faces
  *        for each element. Specialization in case the FVElementGeometries are stored globally.
-          In this case we just forward internally to the global object.
+ *        In this case we just forward internally to the global object.
  */
-template<class TypeTag>
-class StaggeredFVElementGeometry<TypeTag, true>
+template<class GG>
+class StaggeredFVElementGeometry<GG, true>
 {
-    using ThisType = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using ThisType = StaggeredFVElementGeometry<GG, true>;
+    using GridView = typename GG::GridView;
     using IndexType = typename GridView::IndexSet::IndexType;
     using Element = typename GridView::template Codim<0>::Entity;
 
 public:
     //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using SubControlVolume = typename GG::SubControlVolume;
     //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
     //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GG;
 
     //! Constructor
     StaggeredFVElementGeometry(const FVGridGeometry& fvGridGeometry)
@@ -160,21 +155,21 @@ private:
  *        This locally builds up the sub control volumes and sub control volume faces
  *        for each element. Specialization in case the FVElementGeometries are not stored globally.
  */
-template<class TypeTag>
-class StaggeredFVElementGeometry<TypeTag, false>
+template<class GG>
+class StaggeredFVElementGeometry<GG, false>
 {
-    using ThisType = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using ThisType = StaggeredFVElementGeometry<GG, false>;
+    using GridView = typename GG::GridView;
     using IndexType = typename GridView::IndexSet::IndexType;
     using Element = typename GridView::template Codim<0>::Entity;
 
 public:
     //! export type of subcontrol volume
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using SubControlVolume = typename GG::SubControlVolume;
     //! export type of subcontrol volume face
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using SubControlVolumeFace = typename GG::SubControlVolumeFace;
     //! export type of finite volume grid geometry
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using FVGridGeometry = GG;
 
     //! Constructor
     StaggeredFVElementGeometry(const FVGridGeometry& fvGridGeometry)
diff --git a/dumux/discretization/staggered/fvgridgeometry.hh b/dumux/discretization/staggered/fvgridgeometry.hh
index 597ca659ad..1d111be528 100644
--- a/dumux/discretization/staggered/fvgridgeometry.hh
+++ b/dumux/discretization/staggered/fvgridgeometry.hh
@@ -24,11 +24,9 @@
 #ifndef DUMUX_DISCRETIZATION_STAGGERED_FV_GRID_GEOMETRY
 #define DUMUX_DISCRETIZATION_STAGGERED_FV_GRID_GEOMETRY
 
-#include <dumux/common/properties.hh>
 #include <dumux/discretization/basefvgridgeometry.hh>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup StaggeredDiscretization
@@ -36,9 +34,10 @@ namespace Dumux
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element.
  */
-template<class TypeTag, bool EnableFVGridGeometryCache>
-class StaggeredFVGridGeometry
-{};
+ template<class GridView,
+          bool enableFVGridGeometryCache,
+          class Traits>
+class StaggeredFVGridGeometry;
 
 /*!
  * \ingroup StaggeredDiscretization
@@ -46,34 +45,35 @@ class StaggeredFVGridGeometry
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element. Specialization in case the FVElementGeometries are stored.
  */
-template<class TypeTag>
-class StaggeredFVGridGeometry<TypeTag, true> : public BaseFVGridGeometry<TypeTag>
+template<class GV, class Traits>
+class StaggeredFVGridGeometry<GV, true, Traits>
+: public BaseFVGridGeometry<StaggeredFVGridGeometry<GV, true, Traits>, GV, Traits>
 {
-public:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
-    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
-
-private:
-    using ParentType = BaseFVGridGeometry<TypeTag>;
-    using IndexType = typename GridView::IndexSet::IndexType;
-    using Element = typename GridView::template Codim<0>::Entity;
-    using IntersectionMapper = typename GET_PROP_TYPE(TypeTag, IntersectionMapper);
-    //! The local class needs access to the scv, scvfs and the fv element geometry
-    //! as they are globally cached
-    friend typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using ThisType = StaggeredFVGridGeometry<GV, true, Traits>;
+    using ParentType = BaseFVGridGeometry<ThisType, GV, Traits>;
+    using IndexType = typename GV::IndexSet::IndexType;
+    using Element = typename GV::template Codim<0>::Entity;
 
     enum {
         // Grid and world dimension
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld
+        dim = GV::dimension,
+        dimWorld = GV::dimensionworld
     };
 
-    using GeometryHelper = typename GET_PROP_TYPE(TypeTag, StaggeredGeometryHelper);
-    using ConnectivityMap = typename GET_PROP_TYPE(TypeTag, AssemblyMap);
+    using IntersectionMapper = typename Traits::IntersectionMapper;
+    using GeometryHelper = typename Traits::GeometryHelper;
+    using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
 
 public:
+    //! export the type of the fv element geometry (the local view type)
+    using LocalView = typename Traits::template LocalView<ThisType, true>;
+    //! export the type of sub control volume
+    using SubControlVolume = typename Traits::SubControlVolume;
+    //! export the type of sub control volume
+    using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
+    //! export the grid view type
+    using GridView = GV;
+
     //! Constructor
     StaggeredFVGridGeometry(const GridView& gridView)
     : ParentType(gridView)
@@ -201,8 +201,6 @@ public:
         connectivityMap_.update(*this);
     }
 
-//private:
-
     //! Get a sub control volume with a global scv index
     const SubControlVolume& scv(IndexType scvIdx) const
     {
@@ -258,8 +256,8 @@ private:
  *        This builds up the sub control volumes and sub control volume faces
  *        for each element. Specialization in case the FVElementGeometries are stored.
  */
-template<class TypeTag>
-class StaggeredFVGridGeometry<TypeTag, false>
+template<class GV, class Traits>
+class StaggeredFVGridGeometry<GV, false, Traits>
 {
     // TODO: implement without caching
 };
diff --git a/dumux/discretization/staggered/properties.hh b/dumux/discretization/staggered/properties.hh
index 2b7ce7c9dc..ea7a3a4205 100644
--- a/dumux/discretization/staggered/properties.hh
+++ b/dumux/discretization/staggered/properties.hh
@@ -49,7 +49,6 @@
 #include <dumux/discretization/staggered/elementfacevariables.hh>
 #include <dumux/discretization/staggered/subcontrolvolumeface.hh>
 
-#include <dumux/common/intersectionmapper.hh>
 #include <dune/istl/multitypeblockvector.hh>
 #include <dune/istl/multitypeblockmatrix.hh>
 
@@ -71,57 +70,9 @@ SET_PROP(StaggeredModel, DiscretizationMethod)
 };
 
 //! Set the default for the FVElementGeometry vector
-SET_TYPE_PROP(StaggeredModel, FVGridGeometry, StaggeredFVGridGeometry<TypeTag, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
-
-//! Set the default for the FVElementGeometry vector
-SET_TYPE_PROP(StaggeredModel, FVElementGeometry, StaggeredFVElementGeometry<TypeTag, GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
-
-//! The default sub control volume
-SET_PROP(StaggeredModel, SubControlVolume)
-{
-private:
-    using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
-    struct ScvGeometryTraits
-    {
-        using Geometry = typename Grid::template Codim<0>::Geometry;
-        using GridIndexType = typename Grid::LeafGridView::IndexSet::IndexType;
-        using LocalIndexType = unsigned int;
-        using Scalar = typename Grid::ctype;
-        using GlobalPosition = Dune::FieldVector<Scalar, Grid::dimensionworld>;
-    };
-public:
-        using type = CCSubControlVolume<ScvGeometryTraits>;
-};
-
-//! The default sub-controlvolume face
-SET_PROP(StaggeredModel, SubControlVolumeFace)
-{
-private:
-    using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
-    static constexpr int dim = Grid::dimension;
-    static constexpr int dimWorld = Grid::dimensionworld;
-
-    struct ScvfGeometryTraits
-    {
-        using GridIndexType = typename Grid::LeafGridView::IndexSet::IndexType;
-        using LocalIndexType = unsigned int;
-        using Scalar = typename Grid::ctype;
-        using Geometry = typename Grid::template Codim<1>::Geometry;
-        using GlobalPosition = Dune::FieldVector<Scalar, dim>;
-    };
-
-public:
-    using type = StaggeredSubControlVolumeFace<ScvfGeometryTraits>;
-};
-
-//! The default geometry helper required for the stencils, etc.
-SET_PROP(StaggeredModel, StaggeredGeometryHelper)
-{
-private:
-    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
-public:
-    using type = BaseStaggeredGeometryHelper<GridView>;
-};
+SET_TYPE_PROP(StaggeredModel, FVElementGeometry,
+                StaggeredFVElementGeometry<typename GET_PROP_TYPE(TypeTag, FVGridGeometry),
+                                           GET_PROP_VALUE(TypeTag, EnableFVGridGeometryCache)>);
 
 //! Set the default global face variables cache vector class
 SET_TYPE_PROP(StaggeredModel, GridFaceVariables, StaggeredGridFaceVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGridFaceVariablesCache)>);
@@ -156,9 +107,6 @@ SET_TYPE_PROP(StaggeredModel, GridVariables, StaggeredGridVariables<TypeTag>);
 //! Use the cell center element boundary types per default
 SET_TYPE_PROP(StaggeredModel, ElementBoundaryTypes, CCElementBoundaryTypes<TypeTag>);
 
-//! Set the intersection mapper
-SET_TYPE_PROP(StaggeredModel, IntersectionMapper, ConformingGridIntersectionMapper<TypeTag>);
-
 //! Set the BaseLocalResidual to StaggeredLocalResidual
 SET_TYPE_PROP(StaggeredModel, BaseLocalResidual, StaggeredLocalResidual<TypeTag>);
 
diff --git a/dumux/discretization/staggered/subcontrolvolumeface.hh b/dumux/discretization/staggered/subcontrolvolumeface.hh
index 0ad970c173..c969a91540 100644
--- a/dumux/discretization/staggered/subcontrolvolumeface.hh
+++ b/dumux/discretization/staggered/subcontrolvolumeface.hh
@@ -34,8 +34,7 @@
 
 #include <typeinfo>
 
-namespace Dumux
-{
+namespace Dumux {
 
 /*!
  * \ingroup StaggeredDiscretization
@@ -50,7 +49,9 @@ class BaseStaggeredGeometryHelper
 
 public:
 
-    BaseStaggeredGeometryHelper(const Element& element, const GridView& gridView) : element_(element), gridView_(gridView)
+    BaseStaggeredGeometryHelper(const Element& element, const GridView& gridView)
+    : element_(element)
+    , gridView_(gridView)
     { }
 
     /*!
@@ -86,28 +87,47 @@ private:
    const GridView gridView_;
 };
 
+
+/*!
+ * \ingroup StaggeredDiscretization
+ * \brief Default traits class to be used for the sub-control volume faces
+ *        for the staggered finite volume scheme
+ * \tparam GV the type of the grid view
+ */
+template<class GridView>
+struct StaggeredDefaultScvfGeometryTraits
+{
+    using Geometry = typename GridView::template Codim<1>::Geometry;
+    using GridIndexType = typename GridView::IndexSet::IndexType;
+    using LocalIndexType = unsigned int;
+    using Scalar = typename GridView::ctype;
+    using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimensionworld>;
+};
+
 /*!
- * \ingroup Discretization
+ * \ingroup StaggeredDiscretization
  * \brief Class for a sub control volume face in the staggered method, i.e a part of the boundary
  *        of a sub control volume we compute fluxes on.
  */
-template<class ScvfGeometryTraits>
-class StaggeredSubControlVolumeFace : public SubControlVolumeFaceBase<StaggeredSubControlVolumeFace<ScvfGeometryTraits>, ScvfGeometryTraits>
+template<class GV,
+         class T = StaggeredDefaultScvfGeometryTraits<GV> >
+class StaggeredSubControlVolumeFace
+: public SubControlVolumeFaceBase<StaggeredSubControlVolumeFace<GV, T>, T>
 {
-    using ParentType = SubControlVolumeFaceBase<StaggeredSubControlVolumeFace<ScvfGeometryTraits>,ScvfGeometryTraits>;
-    using Geometry = typename ScvfGeometryTraits::Geometry;
-    using GridIndexType = typename ScvfGeometryTraits::GridIndexType;
+    using ThisType = StaggeredSubControlVolumeFace<GV, T>;
+    using ParentType = SubControlVolumeFaceBase<ThisType, T>;
+    using Geometry = typename T::Geometry;
+    using GridIndexType = typename T::GridIndexType;
 
-    using Scalar = typename ScvfGeometryTraits::Scalar;
+    using Scalar = typename T::Scalar;
     static const int dim = Geometry::mydimension;
     static const int dimworld = Geometry::coorddimension;
 
-    using GlobalPosition = typename ScvfGeometryTraits::GlobalPosition;
-
+    using GlobalPosition = typename T::GlobalPosition;
 
 public:
     //! state the traits public and thus export all types
-    using Traits = ScvfGeometryTraits;
+    using Traits = T;
 
     // the default constructor
     StaggeredSubControlVolumeFace() = default;
@@ -115,27 +135,26 @@ public:
     //! Constructor with intersection
     template <class Intersection, class GeometryHelper>
     StaggeredSubControlVolumeFace(const Intersection& is,
-                               const typename Intersection::Geometry& isGeometry,
-                               GridIndexType scvfIndex,
-                               const std::vector<GridIndexType>& scvIndices,
-                               const GeometryHelper& geometryHelper
-                           )
-    : ParentType(),
-      geomType_(isGeometry.type()),
-      area_(isGeometry.volume()),
-      center_(isGeometry.center()),
-      unitOuterNormal_(is.centerUnitOuterNormal()),
-      scvfIndex_(scvfIndex),
-      scvIndices_(scvIndices),
-      boundary_(is.boundary())
-      {
-          corners_.resize(isGeometry.corners());
-          for (int i = 0; i < isGeometry.corners(); ++i)
-              corners_[i] = isGeometry.corner(i);
-
-          dofIdx_ = geometryHelper.dofIndex();
-          localFaceIdx_ = geometryHelper.localFaceIndex();
-      }
+                                  const typename Intersection::Geometry& isGeometry,
+                                  GridIndexType scvfIndex,
+                                  const std::vector<GridIndexType>& scvIndices,
+                                  const GeometryHelper& geometryHelper)
+    : ParentType()
+    , geomType_(isGeometry.type())
+    , area_(isGeometry.volume())
+    , center_(isGeometry.center())
+    , unitOuterNormal_(is.centerUnitOuterNormal())
+    , scvfIndex_(scvfIndex)
+    , scvIndices_(scvIndices)
+    , boundary_(is.boundary())
+    {
+        corners_.resize(isGeometry.corners());
+        for (int i = 0; i < isGeometry.corners(); ++i)
+            corners_[i] = isGeometry.corner(i);
+
+        dofIdx_ = geometryHelper.dofIndex();
+        localFaceIdx_ = geometryHelper.localFaceIndex();
+    }
 
     //! The center of the sub control volume face
     const GlobalPosition& center() const
@@ -232,8 +251,6 @@ private:
     int localFaceIdx_;
 };
 
-
-
-} // end namespace
+} // end namespace Dumux
 
 #endif
diff --git a/test/discretization/staggered/test_staggeredfvgeometry.cc b/test/discretization/staggered/test_staggeredfvgeometry.cc
index a15bc13e52..7191b03fac 100644
--- a/test/discretization/staggered/test_staggeredfvgeometry.cc
+++ b/test/discretization/staggered/test_staggeredfvgeometry.cc
@@ -31,61 +31,68 @@
 #include <dune/grid/utility/structuredgridfactory.hh>
 #include <dune/grid/yaspgrid.hh>
 
-#include <dumux/common/properties.hh>
-#include <dumux/discretization/staggered/properties.hh>
-
-namespace Dumux
-{
-
-//! Dummy connectivity map, required by FVGridGeometry
-class MockConnectivityMap
-{
+#include <dumux/common/intersectionmapper.hh>
+#include <dumux/common/defaultmappertraits.hh>
+#include <dumux/discretization/cellcentered/subcontrolvolume.hh>
+#include <dumux/discretization/staggered/fvelementgeometry.hh>
+#include <dumux/discretization/staggered/fvgridgeometry.hh>
+#include <dumux/discretization/staggered/subcontrolvolumeface.hh>
+
+#ifndef DOXYGEN
+namespace Dumux {
+namespace Detail {
+template<class T>
+class NoopFunctor {
 public:
-    template<class FVGridGeometry>
-    void update(const FVGridGeometry& fvGridGeometry)
-    {}
+  NoopFunctor() {}
+  void operator()(const T& t){}
 };
+} // end namespace Detail
 
-namespace Properties
+//! the fv grid geometry traits for this test
+template<class GridView>
+struct TestFVGGTraits : public DefaultMapperTraits<GridView>
 {
-NEW_TYPE_TAG(TestFVGeometry, INHERITS_FROM(StaggeredModel));
-
-SET_TYPE_PROP(TestFVGeometry, Grid, Dune::YaspGrid<2>);
-
-SET_TYPE_PROP(TestFVGeometry, AssemblyMap, MockConnectivityMap);
+    using SubControlVolume = CCSubControlVolume<GridView>;
+    using SubControlVolumeFace = StaggeredSubControlVolumeFace<GridView>;
+    using IntersectionMapper = ConformingGridIntersectionMapper<GridView>;
+    using GeometryHelper = BaseStaggeredGeometryHelper<GridView>;
 
-SET_BOOL_PROP(TestFVGeometry, EnableFVGridGeometryCache, true);
-}
+    //! Dummy connectivity map, required by FVGridGeometry
+    template<class FVGridGeometry>
+    struct MockConnectivityMap
+    { void update(const FVGridGeometry& fvGridGeometry) {} };
 
-}
+    template<class FVGridGeometry>
+    using ConnectivityMap = MockConnectivityMap<FVGridGeometry>;
 
-template<class T>
-class NoopFunctor {
-public:
-  NoopFunctor() {}
-  void operator()(const T& t){}
+    template<class FVGridGeometry, bool enableCache>
+    using LocalView = StaggeredFVElementGeometry<FVGridGeometry, enableCache>;
 };
 
+} // end namespace Dumux
+#endif
+
 int main (int argc, char *argv[]) try
 {
+    using namespace Dumux;
+
     // maybe initialize mpi
     Dune::MPIHelper::instance(argc, argv);
 
     std::cout << "Checking the FVGeometries, SCVs and SCV faces" << std::endl;
 
-    // aliases
-    using TypeTag = TTAG(TestFVGeometry);
-    using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
-    using GridView = typename Grid::LeafGridView;
+    using Grid = Dune::YaspGrid<2>;
 
-    constexpr int dim = GridView::dimension;
-    constexpr int dimworld = GridView::dimensionworld;
+    constexpr int dim = Grid::dimension;
+    constexpr int dimworld = Grid::dimensionworld;
 
     using GlobalPosition = typename Dune::FieldVector<Grid::ctype, dimworld>;
-    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using FVGridGeometry = StaggeredFVGridGeometry<typename Grid::LeafGridView, /*enable caching=*/ true,
+                                                   TestFVGGTraits<typename Grid::LeafGridView> >;
+    using FVElementGeometry = typename FVGridGeometry::LocalView;
     using SubControlVolume = typename FVElementGeometry::SubControlVolume;
     using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
-    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
 
     // make a grid
     GlobalPosition lower(0.0);
@@ -106,7 +113,7 @@ int main (int argc, char *argv[]) try
         fvGeometry.bind(element);
 
         auto range = scvs(fvGeometry);
-        NoopFunctor<SubControlVolume> op;
+        Detail::NoopFunctor<SubControlVolume> op;
         if(0 != testForwardIterator(range.begin(), range.end(), op))
             DUNE_THROW(Dune::Exception, "Iterator does not fulfill the forward iterator concept");
 
@@ -116,7 +123,7 @@ int main (int argc, char *argv[]) try
         }
 
         auto range2 = scvfs(fvGeometry);
-        NoopFunctor<SubControlVolumeFace> op2;
+        Detail::NoopFunctor<SubControlVolumeFace> op2;
         if(0 != testForwardIterator(range2.begin(), range2.end(), op2))
             DUNE_THROW(Dune::Exception, "Iterator does not fulfill the forward iterator concept");
 
-- 
GitLab