diff --git a/dumux/discretization/box/boxgeometryhelper.hh b/dumux/discretization/box/boxgeometryhelper.hh
index a419df51fdfa3feb38a9ccc4d3a8f2acfb436028..f69fae9ca18a081ea9cc733ddd212230fb2412b2 100644
--- a/dumux/discretization/box/boxgeometryhelper.hh
+++ b/dumux/discretization/box/boxgeometryhelper.hh
@@ -231,6 +231,7 @@ S keyToCornerStorageImpl(const Geo& geo, const KeyArray& key, std::index_sequenc
 {
     using Dune::referenceElement;
     const auto ref = referenceElement(geo);
+    // key is a pair of a local sub-entity index (first) and the sub-entity's codim (second)
     return { geo.global(ref.position(key[I].first, key[I].second))... };
 }
 
@@ -241,6 +242,26 @@ S keyToCornerStorage(const Geo& geo, const std::array<T, N>& key)
     return keyToCornerStorageImpl<S>(geo, key, Indices{});
 }
 
+// convert key array to global corner storage
+// for the i-th sub-entity of codim c (e.g. the i-th facet/codim-1-entity for boundaries)
+template<class S, class Geo, class KeyArray, std::size_t... I>
+S subEntityKeyToCornerStorageImpl(const Geo& geo, unsigned int i, unsigned int c, const KeyArray& key, std::index_sequence<I...>)
+{
+    using Dune::referenceElement;
+    const auto ref = referenceElement(geo);
+    // subEntity gives the subEntity number with respect to the codim-0 reference element
+    // key is a pair of a local sub-entity index (first) and the sub-entity's codim (second) but here w.r.t. the sub-entity i/c
+    return { geo.global(ref.position(ref.subEntity(i, c, key[I].first, c+key[I].second), c+key[I].second))... };
+}
+
+// convert key array to global corner storage
+// for the i-th sub-entity of codim c (e.g. the i-th facet/codim-1-entity for boundaries)
+template<class S, class Geo, class T, std::size_t N, class Indices = std::make_index_sequence<N>>
+S subEntityKeyToCornerStorage(const Geo& geo, unsigned int i, unsigned int c, const std::array<T, N>& key)
+{
+    return subEntityKeyToCornerStorageImpl<S>(geo, i, c, key, Indices{});
+}
+
 } // end namespace Detail
 
 //! Create sub control volumes and sub control volume face geometries
@@ -291,7 +312,8 @@ public:
                                              const typename Intersection::Geometry& geometry,
                                              unsigned int indexInIntersection) const
     {
-        return ScvfCornerStorage{{geometry.corner(0)}};
+        const auto localFacetIndex = is.indexInInside();
+        return ScvfCornerStorage{{ geo_.corner(localFacetIndex) }};
     }
 
     //! get scvf normal vector
@@ -390,15 +412,14 @@ public:
                                              const typename Intersection::Geometry& isGeometry,
                                              unsigned int indexInIntersection) const
     {
-        const auto refElement = referenceElement(geo_);
+        const auto localFacetIndex = is.indexInInside();
+        constexpr int facetCodim = 1;
 
-        const auto vIdxLocal = refElement.subEntity(is.indexInInside(), 1, indexInIntersection, dim);
-        if (indexInIntersection == 0)
-            return ScvfCornerStorage({ geo_.global(refElement.position(vIdxLocal, dim)), isGeometry.center() });
-        else if (indexInIntersection == 1)
-            return ScvfCornerStorage({ isGeometry.center(), geo_.global(refElement.position(vIdxLocal, dim)) });
-        else
-            DUNE_THROW(Dune::InvalidStateException, "local index exceeds the number of corners of 2d intersections");
+        // we have to use the corresponding facet geometry as the intersection geometry
+        // might be rotated or flipped. This makes sure that the corners (dof location)
+        // and corresponding scvfs are sorted in the same way
+        using Corners = Detail::ScvCorners<Dune::GeometryTypes::line>;
+        return Detail::subEntityKeyToCornerStorage<ScvfCornerStorage>(geo_, localFacetIndex, facetCodim, Corners::keys[indexInIntersection]);
     }
 
     //! get scvf normal vector for dim == 2, dimworld == 3
@@ -552,73 +573,28 @@ public:
                                              const typename Intersection::Geometry& isGeometry,
                                              unsigned int indexInIntersection) const
     {
-        const auto refElement = referenceElement(geo_);
-        const auto faceRefElem = referenceElement(isGeometry);
-
-        GlobalPosition pi[9];
-        auto corners = isGeometry.corners();
-
-        // the facet center
-        pi[0] = isGeometry.center();
-
-        // corners
-        const auto idxInInside = is.indexInInside();
-        for (int i = 0; i < corners; ++i)
-        {
-            const auto vIdxLocal = refElement.subEntity(idxInInside, 1, i, dim);
-            pi[i+1] = geo_.corner(vIdxLocal);
-        }
-
-        // edge midpoints
-        for (int i = 0; i < faceRefElem.size(1); ++i)
-        {
-            const auto edgeIdxLocal = refElement.subEntity(idxInInside, 1, i, dim-1);
-            pi[i+corners+1] = geo_.global(refElement.position(edgeIdxLocal, dim-1));
-        }
-
-        // procees according to number of corners
-        switch (corners)
-        {
-        case 3: // triangle
+        const auto localFacetIndex = is.indexInInside();
+        constexpr int facetCodim = 1;
+
+        // we have to use the corresponding facet geometry as the intersection geometry
+        // might be rotated or flipped. This makes sure that the corners (dof location)
+        // and corresponding scvfs are sorted in the same way
+        using Dune::referenceElement;
+        const auto type = referenceElement(geo_).type(localFacetIndex, facetCodim);
+        if (type == Dune::GeometryTypes::triangle)
         {
-            //! Only build the maps the first time we encounter a triangle
-            static const std::uint8_t vo = 1; //!< vertex offset in point vector pi
-            static const std::uint8_t eo = 4; //!< edge offset in point vector pi
-            static const std::uint8_t map[3][4] =
-            {
-                {vo+0, eo+0, eo+1, 0},
-                {vo+1, eo+2, eo+0, 0},
-                {vo+2, eo+1, eo+2, 0}
-            };
-
-            return ScvfCornerStorage{ {pi[map[indexInIntersection][0]],
-                                       pi[map[indexInIntersection][1]],
-                                       pi[map[indexInIntersection][2]],
-                                       pi[map[indexInIntersection][3]]} };
+            using Corners = Detail::ScvCorners<Dune::GeometryTypes::triangle>;
+            return Detail::subEntityKeyToCornerStorage<ScvfCornerStorage>(geo_, localFacetIndex, facetCodim, Corners::keys[indexInIntersection]);
         }
-        case 4: // quadrilateral
+        else if (type == Dune::GeometryTypes::quadrilateral)
         {
-            //! Only build the maps the first time we encounter a quadrilateral
-            static const std::uint8_t vo = 1; //!< vertex offset in point vector pi
-            static const std::uint8_t eo = 5; //!< edge offset in point vector pi
-            static const std::uint8_t map[4][4] =
-            {
-                {vo+0, eo+2, eo+0, 0},
-                {vo+1, eo+1, eo+2, 0},
-                {vo+2, eo+0, eo+3, 0},
-                {vo+3, eo+3, eo+1, 0}
-            };
-
-            return ScvfCornerStorage{ {pi[map[indexInIntersection][0]],
-                                       pi[map[indexInIntersection][1]],
-                                       pi[map[indexInIntersection][2]],
-                                       pi[map[indexInIntersection][3]]} };
+            using Corners = Detail::ScvCorners<Dune::GeometryTypes::quadrilateral>;
+            return Detail::subEntityKeyToCornerStorage<ScvfCornerStorage>(geo_, localFacetIndex, facetCodim, Corners::keys[indexInIntersection]);
         }
-        default:
-            DUNE_THROW(Dune::NotImplemented, "Box scvf boundary geometries for dim=" << dim
+        else
+            DUNE_THROW(Dune::NotImplemented, "Box boundary scvf geometries for dim=" << dim
                                                             << " dimWorld=" << dimWorld
-                                                            << " corners=" << corners);
-        }
+                                                            << " type=" << type);
     }
 
     //! get scvf normal vector