From a0c1abd6c5bce4cac2b7e894118ca9b87271335e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maximilian=20H=C3=B6rl?=
 <maximilian.hoerl@mathematik.uni-stuttgart.de>
Date: Fri, 17 Jan 2020 20:22:31 +0100
Subject: [PATCH] add problem poisson, move exact solution to problem, add
 parameter problem in ini file

---
 dune/mmdg/dg.hh                 | 42 +++++----------------
 dune/mmdg/problems/dgproblem.hh |  2 +-
 dune/mmdg/problems/poisson.hh   | 67 +++++++++++++++++++++++++++++++++
 src/dg.cc                       | 20 +++++++++-
 src/parameterDG.ini             |  1 +
 5 files changed, 97 insertions(+), 35 deletions(-)
 create mode 100644 dune/mmdg/problems/poisson.hh

diff --git a/dune/mmdg/dg.hh b/dune/mmdg/dg.hh
index f208821..6722715 100644
--- a/dune/mmdg/dg.hh
+++ b/dune/mmdg/dg.hh
@@ -40,40 +40,11 @@ public:
     //NOTE: what would be an appropiate solver here?
     A.solve(d, b);
 
-    for (int i = 0; i < dof; i++)
-      for (int j = 0; j < i; j++)
-        /*assert*/if(std::abs(A[i][j] - A[j][i]) >
-          std::numeric_limits<Scalar>::epsilon())
-            std::cout << i << ", " << j << std::endl;
-
-    //NOTE: dim = 1
-//    auto exactSolution = [](const auto& pos) {return 0.5*pos[0]*(pos[0] - 1);};
-
-    //NOTE: dim = 2
-    auto exactSolution = [](const auto& pos)
-      {
-        double solution = 0.0;
-        for (int m = 1; m <= 21; m = m + 2)
-        {
-          for (int n = 1; n <= 21; n = n + 2)
-          {
-            solution += sin(M_PI * m * pos[0]) * sin(M_PI * n * pos[1])
-              / (m * n * (m*m + n*n));
-          }
-        }
-        solution *= -16 / pow(M_PI, 4);
-        return solution;
-      };
-
-
-
-
     //storage for pressure data, for each element we store the
     //pressure at the corners of the element, the VTKFunction will
     //create the output using a linear interpolation for each element
-    Dune::DynamicVector<Scalar> pressure((dim + 1)*gridView_.size(0), 0.0);
-    Dune::DynamicVector<double>
-      exactPressure((dim + 1)*gridView_.size(0), 0.0);
+    Dune::DynamicVector<Scalar> pressure(dof, 0.0);
+    Dune::DynamicVector<double> exactPressure(dof, 0.0);
 
     for (const auto& elem : elements(gridView_))
     {
@@ -82,7 +53,7 @@ public:
 
       for (int k = 0; k < geo.corners(); k++)
       {
-        exactPressure[elemIdxSLE + k] = exactSolution(geo.corner(k));
+        exactPressure[elemIdxSLE + k] = problem_.exactSolution(geo.corner(k));
 
         //contribution of the basis function
         // phi_elem,0 (x) = indicator(elem);
@@ -401,6 +372,13 @@ private:
         }
       }
     }
+
+    //NOTE: check if A is symmetric
+    for (int i = 0; i < dof; i++)
+      for (int j = 0; j < i; j++)
+        /*assert*/if(std::abs(A[i][j] - A[j][i]) >
+          std::numeric_limits<Scalar>::epsilon())
+            std::cout << i << ", " << j << std::endl;
   }
 
 
diff --git a/dune/mmdg/problems/dgproblem.hh b/dune/mmdg/problems/dgproblem.hh
index 8f62e78..f537415 100644
--- a/dune/mmdg/problems/dgproblem.hh
+++ b/dune/mmdg/problems/dgproblem.hh
@@ -3,7 +3,7 @@
 
 //abstract class providing an interface for a problem that is to be solved with
 //a discontinuous Galerkin scheme
-template<class Coordinate, class ctype>
+template<class Coordinate, class ctype = double>
 class DGProblem
 {
   public:
diff --git a/dune/mmdg/problems/poisson.hh b/dune/mmdg/problems/poisson.hh
new file mode 100644
index 0000000..516a7c0
--- /dev/null
+++ b/dune/mmdg/problems/poisson.hh
@@ -0,0 +1,67 @@
+#ifndef __DUNE_MMDG_POISSON_HH__
+#define __DUNE_MMDG_POISSON_HH__
+
+#include <cmath>
+#include <string>
+
+#include <dune/mmdg/problems/dgproblem.hh>
+
+
+//Poisson problem with right side q = -1
+template<int dim, class ctype = double>
+class Poisson : public DGProblem<Dune::FieldVector<ctype, dim>, ctype>
+{
+  public:
+    using Scalar = ctype;
+    using Vector = Dune::FieldVector<Scalar, dim>;
+
+    //the exact solution at position pos
+    virtual Scalar exactSolution (const Vector& pos) const
+    {
+      if (dim == 1)
+      {
+        return 0.5*pos[0]*(pos[0] - 1);
+      }
+
+      if (dim == 2)
+      {
+        const int cutoff = 21; //NOTE: error?
+        double solution = 0.0;
+        for (int m = 1; m <= cutoff; m = m + 2)
+        {
+          for (int n = 1; n <= cutoff; n = n + 2)
+          {
+            solution += sin(M_PI * m * pos[0]) * sin(M_PI * n * pos[1])
+              / (m * n * (m*m + n*n));
+          }
+        }
+        solution *= -16 / pow(M_PI, 4);
+        return solution;
+      }
+
+      DUNE_THROW(Dune::Exception,
+        "Exact Solution not implemented for dimension = " +
+        std::to_string(dim) + "!");
+    }
+
+    //exact solution is implemented for dim = 1, 2
+    bool hasExactSolution() const
+    {
+      return (dim == 1 || dim == 2);
+    };
+
+    //source term
+    Scalar q (const Vector& pos) const
+    {
+      return Scalar(-1.0);
+    }
+
+    //NOTE: necessary or already default?
+    //homogeneous Dirichlet boundary conditions
+    virtual Scalar boundary (const Vector& pos) const
+    {
+      return Scalar(0.0);
+    }
+};
+
+#endif
diff --git a/src/dg.cc b/src/dg.cc
index 945503e..e087fd0 100644
--- a/src/dg.cc
+++ b/src/dg.cc
@@ -21,6 +21,7 @@
 #include <dune/mmdg/dg.hh>
 #include <dune/mmdg/clockhelper.hh>
 #include <dune/mmdg/problems/dgproblem.hh>
+#include <dune/mmdg/problems/poisson.hh>
 
 int main(int argc, char** argv)
 {
@@ -39,6 +40,7 @@ int main(int argc, char** argv)
     using GridFactory = Dune::DGFGridFactory<Grid>;
     using GridView = typename Grid::LeafGridView;
     using Mapper = typename Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
+    using Coordinate = Dune::FieldVector<double, dim>;
 
     //Message Passing Interface (MPI) for parallel computation
     Dune::MPIHelper::instance(argc, argv);
@@ -62,9 +64,23 @@ int main(int argc, char** argv)
     //element mapper for the leaf grid view
     const Mapper mapper(gridView, Dune::mcmgElementLayout());
 
-    const DGProblem<Dune::FieldVector<double, dim>, double> dummyProblem;
+//    const DGProblem<Dune::FieldVector<double, dim>, double> dummyProblem;
 
-    const DG dg(gridView, mapper, dummyProblem);
+    DGProblem<Coordinate>* problem; //problem to be solved
+
+    //determine problem type
+    if (pt["problem"] == "poisson")
+    {
+      problem = new Poisson<dim>();
+    }
+    else
+    {
+      DUNE_THROW(Dune::Exception,
+        "Invalid problem type or parameter 'problem' not specified in file "
+        "parameterDG.ini (use 'poisson' or TODO)");
+    }
+
+    const DG dg(gridView, mapper, *problem);
 
     dg(K, mu);
 
diff --git a/src/parameterDG.ini b/src/parameterDG.ini
index 860cc1e..808b309 100644
--- a/src/parameterDG.ini
+++ b/src/parameterDG.ini
@@ -1,2 +1,3 @@
 K = 1
 mu = 1000
+problem = poisson
-- 
GitLab