From fd36a40a72de51470fc995e89d608be40bf75b21 Mon Sep 17 00:00:00 2001
From: Martin Schneider <martin.schneider@iws.uni-stuttgart.de>
Date: Fri, 21 Jul 2017 13:16:36 +0200
Subject: [PATCH] [intersectionmapper] Intersectionmapper for non-conforming
 grids

---
 dumux/common/intersectionmapper.hh | 105 ++++++++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 2 deletions(-)

diff --git a/dumux/common/intersectionmapper.hh b/dumux/common/intersectionmapper.hh
index 0bb6ceddb6..8b46290774 100644
--- a/dumux/common/intersectionmapper.hh
+++ b/dumux/common/intersectionmapper.hh
@@ -26,13 +26,16 @@
 
 /*!
  * \file
- * \brief defines an intersection mapper for mapping of global DOFs assigned
- *        to faces which also works for adaptive grids.
+ * \brief defines intersection mappers.
  */
 
 namespace Dumux
 {
 
+/*!
+ * \brief defines a standard intersection mapper for mapping of global DOFs assigned
+ *        to faces. It only works for conforming grids, without hanging nodes.
+ */
 template<class TypeTag>
 class ConformingGridIntersectionMapper
 {
@@ -73,6 +76,104 @@ private:
     const GridView gridView_;
 };
 
+/*!
+ * \brief defines an intersection mapper for mapping of global DOFs assigned
+ *        to faces which also works for non-conforming grids and corner-point grids.
+ */
+template<class TypeTag>
+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;
+
+public:
+    NonConformingGridIntersectionMapper(const GridView& gridview)
+    : gridView_(gridview),
+      numIntersections_(gridView_.size(1)),
+      intersectionMapGlobal_(gridView_.size(0))
+    {
+
+    }
+
+    //! The total number of intersections
+    std::size_t numIntersections() const
+    {
+        return numIntersections_;
+    }
+
+    IndexType globalIntersectionIndex(const Element& element, const IndexType localFaceIdx) const
+    {
+        return (intersectionMapGlobal_[index(element)].find(localFaceIdx))->second; //use find() for const function!
+    }
+
+    std::size_t numFaces(const Element& element)
+    {
+        return intersectionMapGlobal_[index(element)].size();
+    }
+
+    void update()
+    {
+        intersectionMapGlobal_.clear();
+        intersectionMapGlobal_.resize(gridView_.size(0));
+
+        int globalIntersectionIdx = 0;
+        for (const auto& element : elements(gridView_))
+        {
+            int eIdx = index(element);
+            int fIdx = 0;
+
+            // run through all intersections with neighbors
+            for (const auto& intersection : intersections(gridView_, element))
+            {
+                if (intersection.neighbor())
+                {
+                    auto neighbor = intersection.outside();
+                    int eIdxN = index(neighbor);
+
+                    if (element.level() > neighbor.level() || (element.level() == neighbor.level() && eIdx < eIdxN))
+                    {
+                        int fIdxN = 0;
+                        for (const auto& intersectionNeighbor : intersections(gridView_, neighbor))
+                        {
+                            if (intersectionNeighbor.neighbor())
+                            {
+                                if (intersectionNeighbor.outside() == element)
+                                {
+                                    break;
+                                }
+                            }
+                            fIdxN++;
+                        }
+                        intersectionMapGlobal_[eIdx][fIdx] = globalIntersectionIdx;
+                        intersectionMapGlobal_[eIdxN][fIdxN] = globalIntersectionIdx;
+                        globalIntersectionIdx++;
+                    }
+                }
+                else
+                {
+                    intersectionMapGlobal_[eIdx][fIdx] = globalIntersectionIdx;
+                    globalIntersectionIdx++;
+                }
+
+                fIdx++;
+            }
+        }
+        numIntersections_ = globalIntersectionIdx;
+    }
+
+private:
+    IndexType index(const Element& element) const
+    {
+        return gridView_.indexSet().index(element);
+    }
+
+    const GridView gridView_;
+    unsigned int numIntersections_;
+    std::vector<std::unordered_map<int, int> > intersectionMapGlobal_;
+};
+
 /*!
  * \brief defines an intersection mapper for mapping of global DOFs assigned
  *        to faces which also works for adaptive grids.
-- 
GitLab