From 52705161cb52bf33dfb63dad0645287d48e5285c Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Thu, 2 May 2019 14:49:57 +0200
Subject: [PATCH] add functionality to remove an added marker

---
 src/amdis/ProblemStat.hpp     | 107 +++++++++++++++++++++-------------
 src/amdis/ProblemStat.inc.hpp |  12 +---
 test/MarkerTest.cpp           |   5 ++
 3 files changed, 73 insertions(+), 51 deletions(-)

diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp
index 35cea992..05800f77 100644
--- a/src/amdis/ProblemStat.hpp
+++ b/src/amdis/ProblemStat.hpp
@@ -253,10 +253,11 @@ namespace AMDiS
 
   public:
 
-    /// Implementation of \ref ProblemStatBase::solve
-    void solve(AdaptInfo& adaptInfo,
-               bool createMatrixData = true,
-               bool storeMatrixData = false) override;
+    /// Implementation of \ref StandardProblemIteration::oneIteration.
+    Flag oneIteration(AdaptInfo& adaptInfo, Flag toDo = FULL_ITERATION) override
+    {
+      return StandardProblemIteration::oneIteration(adaptInfo, toDo);
+    }
 
     /// Implementation of \ref ProblemStatBase::buildAfterCoarse
     void buildAfterAdapt(AdaptInfo& adaptInfo,
@@ -271,6 +272,26 @@ namespace AMDiS
       buildAfterAdapt(adaptInfo, Flag{0}, true, true);
     }
 
+    /// Implementation of \ref ProblemStatBase::solve
+    void solve(AdaptInfo& adaptInfo,
+               bool createMatrixData = true,
+               bool storeMatrixData = false) override;
+
+    /// Implementation of \ref ProblemStatBase::estimate.
+    void estimate(AdaptInfo& adaptInfo) override { /* do nothing. */ }
+
+    /// Implementation of \ref ProblemStatBase::refineMesh.
+    Flag adaptGrid(AdaptInfo& adaptInfo) override;
+
+    /// Implementation of \ref ProblemStatBase::markElements.
+    Flag markElements(AdaptInfo& adaptInfo) override;
+
+    /// Uniform global grid coarsening by up to n level
+    Flag globalCoarsen(int n) override;
+
+    /// Uniform global refinement by n level
+    Flag globalRefine(int n) override;
+
     /// Writes output files.
     void writeFiles(AdaptInfo& adaptInfo, bool force = false);
 
@@ -335,14 +356,17 @@ namespace AMDiS
   public: // set-methods
 
     /// Set a new linear solver for the problem
-    void setSolver(std::shared_ptr<LinearSolverType> const& solver)
+    void setSolver(std::shared_ptr<LinearSolverType> solver)
     {
       linearSolver_ = solver;
     }
 
-    void setSolver(LinearSolverType& solver)
+    /// Wrap the solver into a non-destroying shared_ptr, or move it into a new shared_ptr
+    template <class S,
+      REQUIRES(std::is_base_of<LinearSolverType, remove_cvref_t<S>>::value)>
+    void setSolver(S&& solver)
     {
-      setSolver(Dune::stackobject_to_shared_ptr(solver));
+      setSolver(Dune::wrap_or_move(FWD(solver)));
     }
 
 
@@ -357,21 +381,44 @@ namespace AMDiS
       createFileWriter();
     }
 
+    /// Wrap the grid into a non-destroying shared_ptr
     void setGrid(Grid& grid)
     {
       setGrid(Dune::stackobject_to_shared_ptr(grid));
     }
 
-    void addMarker(std::shared_ptr<Marker<Grid>> const& marker)
+
+    /// Store the shared_ptr and the name of the marker in the problem
+    /**
+     * Note: multiple markers can be added but must have different names
+     **/
+    void addMarker(std::shared_ptr<Marker<Grid>> marker)
     {
-      marker_.push_back(marker);
+      auto it = marker_.emplace(marker->name(), std::move(marker));
       if (marker_.size() > 1)
-        marker_.back()->setMaximumMarking(true);
+        it.first->second->setMaximumMarking(true);
     }
 
-    void addMarker(Marker<Grid>& marker)
+    /// Wrap the reference into a non-destroying shared_ptr or move it into a new shared_ptr and
+    /// store it in the problemand store in the problem
+    template <class M,
+      REQUIRES(std::is_base_of<Marker<Grid>, remove_cvref_t<M>>::value)>
+    void addMarker(M&& marker)
     {
-      addMarker(Dune::stackobject_to_shared_ptr(marker));
+      addMarker(Dune::wrap_or_move(FWD(marker)));
+    }
+
+    /// Remove a marker with the given name from the problem
+    void removeMarker(std::string name)
+    {
+      std::size_t num = marker_.erase(name);
+      test_warning(num == 1, "A marker with the given name '{}' does not exist.", name);
+    }
+
+    /// Remove a marker from the problem
+    void removeMarker(Marker<Grid> const& marker)
+    {
+      removeMarker(marker.name());
     }
 
 
@@ -390,11 +437,6 @@ namespace AMDiS
       initGlobalBasis();
     }
 
-    void adoptGrid(std::shared_ptr<Grid> const& grid)
-    {
-      adoptGrid(grid, std::make_shared<BoundaryManager<Grid>>(grid));
-    }
-
     void adoptGrid(std::shared_ptr<Grid> const& grid,
                    std::shared_ptr<BoundaryManager<Grid>> const& boundaryManager)
     {
@@ -403,6 +445,11 @@ namespace AMDiS
       Parameters::get(name_ + "->mesh", gridName_);
     }
 
+    void adoptGrid(std::shared_ptr<Grid> const& grid)
+    {
+      adoptGrid(grid, std::make_shared<BoundaryManager<Grid>>(grid));
+    }
+
   private:
 
     void createGlobalBasisImpl(std::true_type);
@@ -410,30 +457,6 @@ namespace AMDiS
 
     void initGlobalBasis();
 
-
-  public: // implementation of iteration interface methods
-
-    /// Implementation of \ref StandardProblemIteration::oneIteration.
-    Flag oneIteration(AdaptInfo& adaptInfo, Flag toDo = FULL_ITERATION) override
-    {
-      return StandardProblemIteration::oneIteration(adaptInfo, toDo);
-    }
-
-    /// Implementation of \ref ProblemStatBase::estimate.
-    void estimate(AdaptInfo& adaptInfo) override { /* do nothing. */ }
-
-    /// Implementation of \ref ProblemStatBase::refineMesh.
-    Flag adaptGrid(AdaptInfo& adaptInfo) override;
-
-    /// Implementation of \ref ProblemStatBase::markElements.
-    Flag markElements(AdaptInfo& adaptInfo) override;
-
-    /// Uniform global grid coarsening by up to n level
-    Flag globalCoarsen(int n) override;
-
-    /// Uniform global refinement by n level
-    Flag globalRefine(int n) override;
-
   private:
     /// Name of this problem.
     std::string name_;
@@ -454,7 +477,7 @@ namespace AMDiS
     std::list<std::shared_ptr<FileWriterInterface>> filewriter_;
 
     /// Pointer to the adaptation markers
-    std::list<std::shared_ptr<Marker<Grid>>> marker_;
+    std::map<std::string, std::shared_ptr<Marker<Grid>>> marker_;
 
     /// Pointer to the estimators for this problem
 //    std::vector<Estimator*> estimator;
diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp
index 66d7615f..db47a586 100644
--- a/src/amdis/ProblemStat.inc.hpp
+++ b/src/amdis/ProblemStat.inc.hpp
@@ -217,14 +217,8 @@ void ProblemStat<Traits>::createMarker()
     std::string tp = to_string(treePath);
     auto newMarker
       = EstimatorMarker<Grid>::createMarker(componentName, tp, estimates_[tp], grid_);
-    if (newMarker)
-      marker_.push_back(std::move(newMarker));
-
-    // If there is more than one marker, and all components are defined
-    // on the same grid, the maximum marking has to be enabled.
-    // TODO: needs to be checked!
-    if (marker_.size() > 1)
-      marker_.back()->setMaximumMarking(true);
+    assert(bool(newMarker));
+    addMarker(std::move(newMarker));
   });
 }
 
@@ -348,7 +342,7 @@ markElements(AdaptInfo& adaptInfo)
 
   Flag markFlag = 0;
   for (auto& currentMarker : marker_)
-    markFlag |= currentMarker->markGrid(adaptInfo);
+    markFlag |= currentMarker.second->markGrid(adaptInfo);
 
   msg("markElements needed {} seconds", t.elapsed());
 
diff --git a/test/MarkerTest.cpp b/test/MarkerTest.cpp
index 10dd4928..a120ce9a 100644
--- a/test/MarkerTest.cpp
+++ b/test/MarkerTest.cpp
@@ -53,5 +53,10 @@ int main(int argc, char** argv)
   prob.solution().interpolate(markerFunc);
   prob.writeFiles(adaptInfo);
 
+  prob.removeMarker(marker.name());
+
+  prob.addMarker(marker);
+  prob.removeMarker(marker);
+
   return report_errors();
 }
-- 
GitLab