From e544c081ea41bb3ab833d1626856075fd4c7aa14 Mon Sep 17 00:00:00 2001
From: podlesny <podlesny@mi.fu-berlin.de>
Date: Thu, 27 Jun 2019 17:27:20 +0200
Subject: [PATCH] supportpatchfactory works

---
 .../levelpatchpreconditioner.hh               | 94 +++++++++----------
 .../multilevelpatchpreconditioner.hh          | 12 +--
 .../preconditioners/supportpatchfactory.hh    | 69 +++++---------
 3 files changed, 74 insertions(+), 101 deletions(-)

diff --git a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh
index d905e4a3..1c8257c1 100644
--- a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh
+++ b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh
@@ -19,33 +19,33 @@
 #include <dune/fufem/functiontools/boundarydofs.hh>
 
 
-template <class PatchSolver, class MatrixType, class VectorType>
+template <class LevelContactNetwork, class PatchSolver, class MatrixType, class VectorType>
 class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorType> {
 
 public:
     enum Mode {additive, multiplicative};
+    static const int dim = LevelContactNetwork::dim;
 
 private:
     using Base = LinearIterationStep<MatrixType, VectorType>;
 
-    using PatchFactory = SupportPatchFactory<GridView, GridView>;
-    using Patch = typename SupportPatchFactory::Patch;
+    using ctype = typename LevelContactNetwork::ctype;
 
-    typedef typename BasisType::GridView GridView;
-    typedef typename GridView::Grid GridType;
-
-    static const int dim = GridType::dimension;
+    using PatchFactory = SupportPatchFactory<LevelContactNetwork>;
+    using Patch = typename PatchFactory::Patch;
 
     const Mode mode_;
 
-    const LevelContactNetwork<GridView, dim>& levelContactNetwork_;
+    const LevelContactNetwork& levelContactNetwork_;
+    const LevelContactNetwork& fineContactNetwork_;
+
+    const int level_;
 
+    PatchFactory patchFactory_;
     std::vector<Patch> patches_;
     PatchSolver patchSolver_;
 
-    const GridType& grid_;
-    const int level_;
-    const BasisType basis_;
+
 
     size_t patchDepth_;
 
@@ -54,30 +54,28 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy
 
 public:
 
-    // for each coarse patch given by patchLevelBasis: set up local problem, compute local correction
-    LevelPatchPreconditioner(const LevelContactNetwork<GridView, dim>& levelContactNetwork,
-                             const BasisType& patchLevelBasis,
-                             const LocalAssembler& localAssembler,
-                             const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers,
+    // for each coarse patch given by levelContactNetwork: set up local problem, compute local correction
+    LevelPatchPreconditioner(const LevelContactNetwork& levelContactNetwork,
+                             const LevelContactNetwork& fineContactNetwork,
                              const Mode mode = LevelPatchPreconditioner::Mode::additive) :
-          levelInterfaceNetwork_(levelInterfaceNetwork),
-          patchLevelBasis_(patchLevelBasis),
-          localAssembler_(localAssembler),
-          localInterfaceAssemblers_(localInterfaceAssemblers),
-          mode_(mode),
-          grid_(levelInterfaceNetwork_.grid()),
-          level_(levelInterfaceNetwork_.level()),
-          basis_(levelInterfaceNetwork_)
-    {
+            mode_(mode),
+            levelContactNetwork_(levelContactNetwork),
+            fineContactNetwork_(fineContactNetwork),
+            level_(levelContactNetwork_.level()),
+            patchFactory_(levelContactNetwork_, fineContactNetwork_) {
+
         setPatchDepth();
         this->verbosity_ = QUIET;
     }
 
     // build support patches
     void build() {
+        size_t totalNVertices = 0;
+        for (size_t i=0; i<levelContactNetwork_.nBodies(); i++) {
+            totalNVertices += levelContactNetwork_.body(i)->nVertices();
+        }
 
-
-        localProblems_.resize(vertexInElements.size());
+        patches_.resize(totalNVertices);
 
         // init local fine level corrections
         if (this->verbosity_ == FULL) {
@@ -90,19 +88,29 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy
             timer.start();
         }
 
-        const int patchLevel = patchLevelBasis_.faultNetwork().level();
-        for (size_t i=0; i<vertexInElements.size(); i++) {
-            if (this->verbosity_ != QUIET) {
-                std::cout << i << std::endl;
-                std::cout << "---------------" << std::endl;
-            }
+        Dune::BitSetVector<1> vertexVisited(totalNVertices);
+        vertexVisited.unsetAll();
 
-            Patch patchDofs;
-            SupportPatchFactory<decltype(coarseGridView), decltype(fineGridView)> patchFactory(coarseGridView, fineGridView, vertexInElementsBody);
-            patchFactory.build(seedObject, patchDofs, patchDepth_);
+        for (size_t bodyIdx=0; bodyIdx<levelContactNetwork_.nBodies(); bodyIdx++) {
+            const auto& gridView = levelContactNetwork_.body(bodyIdx)->gridView();
 
-            if ((i+1) % 10 == 0 && this->verbosity_ == FULL) {
-                std::cout << '\r' << std::floor((i+1.0)/patchLevelBasis_.size()*100) << " % done. Elapsed time: " << timer.elapsed() << " seconds. Predicted total setup time: " << timer.elapsed()/(i+1.0)*patchLevelBasis_.size() << " seconds." << std::flush;
+            for (const auto& e : elements(gridView)) {
+                const auto& refElement = Dune::ReferenceElements<double, dim>::general(e.type());
+
+                for (size_t i=0; i<refElement.size(dim); i++) {
+                    auto globalIdx = patchFactory_.coarseIndices().vertexIndex(bodyIdx, e, i);
+
+                    if (!vertexVisited[globalIdx][0]) {
+                        vertexVisited[globalIdx][0] = true;
+
+                     /*   if (this->verbosity_ != QUIET) {
+                            std::cout << i << std::endl;
+                            std::cout << "---------------" << std::endl;
+                        }*/
+
+                        patchFactory_.build(bodyIdx, e, i, patches_[globalIdx], patchDepth_);
+                    }
+                }
             }
         }
 
@@ -192,16 +200,8 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy
         }
     }
 
-    const GridView& gridView() const {
-        return basis_.getGridView();
-    }
-
-    const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork() const {
-        return levelInterfaceNetwork_;
-    }
-
     size_t size() const {
-        return localProblems_.size();
+        return patches_.size();
     }
 
 };
diff --git a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
index 584cca16..93529434 100644
--- a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
+++ b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
@@ -32,10 +32,9 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec
 
     typedef typename Dune::BitSetVector<1> BitVector;
 
-    const InterfaceNetwork<GridType>& interfaceNetwork_;
+    const ContactNetwork<GridType>& interfaceNetwork_;
     const BitVector& activeLevels_;
-    const std::vector<std::shared_ptr<LocalOperatorAssembler>>& localAssemblers_;
-    const std::vector<std::vector<std::shared_ptr<LocalInterfaceAssembler>>>& localInterfaceAssemblers_;
+
     const Mode mode_;
 
     int itCounter_;
@@ -45,16 +44,11 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec
     std::vector<VectorType> levelX_;
     std::vector<VectorType> levelRhs_;
 
-    std::shared_ptr<LevelInterfaceNetwork<GridView>> allFaultLevelInterfaceNetwork_;
-    std::shared_ptr<BasisType> allFaultBasis_;
-
     std::vector<std::shared_ptr<DGMGTransfer<BasisType>>> mgTransfer_;
 
 public:
-    MultilevelPatchPreconditioner(const InterfaceNetwork<GridType>& interfaceNetwork,
+    MultilevelPatchPreconditioner(const ContactNetwork<GridType>& interfaceNetwork,
                                   const BitVector& activeLevels,
-                                  const std::vector<std::shared_ptr<LocalOperatorAssembler>>& localAssemblers,
-                                  const std::vector<std::vector<std::shared_ptr<LocalInterfaceAssembler>>>& localInterfaceAssemblers,
                                   const Mode mode = MultilevelPatchPreconditioner::Mode::additive) :
           interfaceNetwork_(interfaceNetwork),
           activeLevels_(activeLevels),
diff --git a/src/spatial-solving/preconditioners/supportpatchfactory.hh b/src/spatial-solving/preconditioners/supportpatchfactory.hh
index 8b191cf0..07091fee 100644
--- a/src/spatial-solving/preconditioners/supportpatchfactory.hh
+++ b/src/spatial-solving/preconditioners/supportpatchfactory.hh
@@ -23,7 +23,7 @@ template <class LevelContactNetwork>
 class NetworkIndexMapper {
 private:
     static const int dim = LevelContactNetwork::dim; //TODO
-    using ctype = typename LevelContactNetwork::GridView::ctype;
+    using ctype = typename LevelContactNetwork::ctype;
 
     using FiniteElementCache = Dune::PQkLocalFiniteElementCache<ctype, ctype, dim, 1>; // P1 finite element cache
     using Element = typename LevelContactNetwork::GridView::template Codim<0>::Entity;
@@ -270,16 +270,6 @@ class SupportPatchFactory
     }
 
     void build(const size_t bodyID, const Element& coarseElement, const size_t localVertex, Patch& patchDofs, const size_t patchDepth = 0) {
-        std::cout << "Building SupportPatch... ";
-
-        std::cout << "elemID: " << coarseIndices_.elementIndex(bodyID, coarseElement) << " vertexID: " << coarseIndices_.vertexIndex(bodyID, coarseElement, localVertex) << std::endl;
-
-        patchDofs.resize(nVertices_);
-        patchDofs.setAll();
-
-        BodyElement seedElement;
-        seedElement.set(bodyID, coarseElement);
-
         auto isPatchIntersection = [this](auto& is, const size_t bodyID, const std::set<size_t>& patchVertices, std::set<size_t>& newPatchVertices) {
             std::set<size_t> dofs;
             intersectionDofs(coarseIndices_, is, bodyID, dofs);
@@ -302,24 +292,26 @@ class SupportPatchFactory
             return false;
         };
 
-        // construct coarse patch
-        std::vector<BodyElement> patchElements;
-        patchElements.emplace_back(seedElement);
+        patchDofs.resize(nVertices_);
+        patchDofs.setAll();
 
+        std::vector<BodyElement> patchElements;
         std::set<size_t> visitedElements;
-        //visitedElements.insert(coarseIndices_.elementIndex(seedElement.bodyID, seedElement.element));
 
         std::set<size_t> patchVertices;
         patchVertices.insert(coarseIndices_.vertexIndex(bodyID, coarseElement, localVertex));
 
+        std::set<size_t> visitedBodies;
+
+        BodyElement seedElement;
+        seedElement.set(bodyID, coarseElement);
+
         std::queue<BodyElement> patchSeeds;
         patchSeeds.push(seedElement);
 
-        std::set<size_t> visitedBodies;
-
         for (size_t depth=0; depth<=patchDepth; depth++) {
-            std::vector<BodyElement> nextSeeds;
             std::set<size_t> newPatchVertices;
+            std::vector<BodyElement> nextSeeds;
 
             while (!patchSeeds.empty()) {
                 const auto& patchSeed = patchSeeds.front();
@@ -332,8 +324,8 @@ class SupportPatchFactory
                 }
 
                 visitedBodies.insert(patchSeed.bodyID);
-
                 visitedElements.insert(elemIdx);
+                patchElements.emplace_back(patchSeed);
 
                 size_t bodyIdx = patchSeed.bodyID;
                 const auto& elem = patchSeed.element;
@@ -347,12 +339,9 @@ class SupportPatchFactory
 
                             size_t neighborIdx = coarseIndices_.elementIndex(neighbor.bodyID, neighbor.element);
 
-                            std::cout << "elementID: " << neighborIdx << std::endl;
-
                             if (visitedElements.count(neighborIdx))
                                 continue;
 
-                            patchElements.emplace_back(neighbor);
                             patchSeeds.push(neighbor);
                         } else {
                             size_t faceIdx = coarseIndices_.faceIndex(bodyIdx, it);
@@ -366,24 +355,22 @@ class SupportPatchFactory
                                     BodyElement neighbor;
                                     neighbor.set(coarseContactNetwork_, intersection);
 
-                                    size_t neighborIdx = coarseIndices_.elementIndex(neighbor.bodyID, neighbor.element);
+                                    size_t neighborBody = neighbor.bodyID;
+                                    size_t neighborIdx = coarseIndices_.elementIndex(neighborBody, neighbor.element);
 
-                                    if (visitedElements.count(neighborIdx) || visitedBodies.count(neighbor.bodyID))
+                                    if (visitedElements.count(neighborIdx) || visitedBodies.count(neighborBody))
                                         continue;
 
                                     std::vector<std::set<size_t>> dofs;
-                                    remoteIntersectionDofs(coarseIndices_, rIs, bodyIdx, neighbor.bodyID, dofs, intersection.flip);
+                                    remoteIntersectionDofs(coarseIndices_, rIs, bodyIdx, neighborBody, dofs, intersection.flip);
 
                                     if (isRPatchIntersection(dofs, patchVertices)) {
                                         patchVertices.insert(dofs[1].begin(), dofs[1].end());
-                                        patchElements.emplace_back(neighbor);
                                         patchSeeds.push(neighbor);
                                     } else {
                                         newPatchVertices.insert(dofs[1].begin(), dofs[1].end());
                                         nextSeeds.emplace_back(neighbor);
                                     }
-
-                                    print(patchVertices, "patchVertices: ");
                                 }
                             }
                         }
@@ -392,7 +379,7 @@ class SupportPatchFactory
                             BodyElement neighbor;
                             neighbor.set(bodyIdx, it.outside());
 
-                            size_t neighborIdx = coarseIndices_.elementIndex(neighbor.bodyID, neighbor.element);
+                            size_t neighborIdx = coarseIndices_.elementIndex(bodyIdx, neighbor.element);
 
                             if (visitedElements.count(neighborIdx))
                                 continue;
@@ -407,9 +394,10 @@ class SupportPatchFactory
                                     BodyElement neighbor;
                                     neighbor.set(coarseContactNetwork_, intersections[i]);
 
+                                    size_t neighborBody = neighbor.bodyID;
                                     size_t neighborIdx = coarseIndices_.elementIndex(neighbor.bodyID, neighbor.element);
 
-                                    if (visitedElements.count(neighborIdx) || visitedBodies.count(neighbor.bodyID))
+                                    if (visitedElements.count(neighborIdx) || visitedBodies.count(neighborBody))
                                         continue;
 
                                     newPatchVertices.insert(neighborFaceDofs_[faceIdx].begin(), neighborFaceDofs_[faceIdx].end());
@@ -419,33 +407,22 @@ class SupportPatchFactory
                         }
                     }
                 }
-
                 patchSeeds.pop();
             }
 
-            for (size_t i=0; i<nextSeeds.size(); i++) {
-                patchSeeds.push(nextSeeds[i]);
+            for (size_t j=0; j<nextSeeds.size(); j++) {
+                patchSeeds.push(nextSeeds[j]);
             }
             patchVertices.insert(newPatchVertices.begin(), newPatchVertices.end());
-            print(patchVertices, "patchVertices: ");
         }
 
-        std::cout << "constructing fine patch... " << std::endl;
-
         // construct fine patch
         using HierarchicLevelIteratorType = HierarchicLevelIterator<typename LevelContactNetwork::GridType>;
-        std::set<size_t> visited;
         std::set<size_t> patchBoundary;
         for (size_t i=0; i<patchElements.size(); ++i) {
             const auto& coarseElem = patchElements[i];
 
             size_t elemIdx = coarseIndices_.elementIndex(coarseElem.bodyID, coarseElem.element);
-            if (visited.count(elemIdx))
-                continue;
-
-            std::cout << "coarse element: " << elemIdx << std::endl;
-
-            visited.insert(elemIdx);
 
             const auto& grid = coarseContactNetwork_.body(coarseElem.bodyID)->gridView().grid();
             const auto fineLevel = fineContactNetwork_.body(coarseElem.bodyID)->level();
@@ -458,14 +435,16 @@ class SupportPatchFactory
                 addLocalDofs(coarseElem, fineElem, visitedElements, patchBoundary, patchDofs);
             }
         }
-
-        std::cout << "Success!" << std::endl;
     }
 
     const auto& coarseContactNetwork() {
         return coarseContactNetwork_;
     }
 
+    const auto& coarseIndices() const {
+        return coarseIndices_;
+    }
+
 private:
     void setup(const LevelContactNetwork& levelContactNetwork, const NetworkIndexMapper& indices, std::map<size_t, std::vector<RemoteIntersection>>& faceToRIntersections) {
         for (size_t i=0; i<levelContactNetwork.nCouplings(); i++) {
-- 
GitLab