From ae9d1a422b2122935cfc50aa5a62b4fb158d1a3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maximilian=20H=C3=B6rl?=
 <maximilian.hoerl@mathematik.uni-stuttgart.de>
Date: Tue, 9 Jun 2020 23:50:10 +0200
Subject: [PATCH] add problem dg4

---
 dune/mmdg/problems/dgproblem4.hh | 166 +++++++++++++++++++++++++++++++
 src/dg.cc                        |  18 +++-
 src/parameterDG.ini              |   4 +-
 3 files changed, 186 insertions(+), 2 deletions(-)
 create mode 100644 dune/mmdg/problems/dgproblem4.hh

diff --git a/dune/mmdg/problems/dgproblem4.hh b/dune/mmdg/problems/dgproblem4.hh
new file mode 100644
index 0000000..d00936a
--- /dev/null
+++ b/dune/mmdg/problems/dgproblem4.hh
@@ -0,0 +1,166 @@
+#ifndef __DUNE_MMDG_DGPROBLEM4_HH__
+#define __DUNE_MMDG_DGPROBLEM4_HH__
+
+#include <dune/mmdg/problems/dgproblem.hh>
+#include <cmath>
+
+template<class Coordinate, class Scalar = double>
+class DGProblem4 : public DGProblem<Coordinate, Scalar>
+{
+  public:
+    static constexpr int dim = Coordinate::dimension;
+    using Base = DGProblem<Coordinate, Scalar>;
+    using Matrix = typename Base::Matrix;
+
+    // static constexpr Scalar dmin_ = 0.05; //minimum aperture of the fracture
+    // static constexpr Scalar dmax_ = 0.2; //maximum aperture of the fracture
+
+    //require dim == 2
+    DGProblem4 (const Scalar dmin, const Scalar dmax)
+      : dmin_(dmin), dmax_(dmax) {}
+    //{
+      // if (dim != 2)
+      // {
+      //   DUNE_THROW(Dune::Exception,
+      //     "Problem dg4 is not implemented for dimension = " +
+      //     std::to_string(dim) + "!");
+      // }
+    //}
+
+    //the exact solution at position pos
+    Scalar exactSolution (const Coordinate& pos) const
+    {
+      const Scalar d = aperture(pos);
+
+      if ( pos[0] < 0.5 * ( 1.0 - d ) )
+      { //pos in Omega_1 (left of the fracture)
+        return 2.0 * ( pos[0] + d ) * exp(-d);
+      }
+
+      if ( pos[0] > 0.5 * ( 1.0 + d ) )
+      { //pos in Omega_2 (right of the fracture)
+        return 2.0 * pos[0] * exp(d);
+      }
+
+      //pos in Omega_R (inside the fracture)
+      return ( 1.0 + d ) * exp( 2.0 * pos[0] - 1.0 );
+    }
+
+    //exact solution is implemented
+    bool hasExactSolution() const
+    {
+      return true;
+    };
+
+    //source term at position pos
+    Scalar q (const Coordinate& pos) const
+    {
+      const Scalar d = aperture(pos);
+      Scalar dPrime2 = aperturePrime(pos);
+      dPrime2 *= dPrime2;
+      const Scalar dPrimePrime = aperturePrimePrime(pos);
+
+
+      if ( pos[0] < 0.5 * ( 1.0 - d ) )
+      { //pos in Omega_1 (left of the fracture)
+        return -2.0 * exp(-d) / ( 1.0 - d ) * ( ( 1.0 - pos[0] - d )
+          * ( dPrimePrime + dPrime2 * d / ( 1.0 - d ) ) - dPrime2 );
+      }
+
+      if ( pos[0] > 0.5 * ( 1.0 + d ) )
+      { //pos in Omega_2 (right of the fracture)
+        return -2.0 * pos[0] * exp(d) / ( 1.0 + d )
+          * ( dPrimePrime + dPrime2 * d / ( 1.0 + d ) );
+      }
+
+      //pos in Omega_R (inside the fracture)
+      return
+        -exp(2.0 * pos[0] - 1) * ( 4.0 + dPrimePrime );
+    }
+
+    //permeability tensor at position pos
+    Matrix K (const Coordinate& pos) const
+    {
+      const Scalar d = aperture(pos);
+
+      Matrix permeability(0.0);
+
+      if ( pos[0] < 0.5 * ( 1.0 - d ) )
+      { //pos in Omega_1 (left of the fracture)
+        permeability[0][0] = 1.0;
+
+        for (int i = 1; i < dim; i++)
+        {
+          permeability[i][i] = 1.0 / ( 1.0 - d );
+        }
+      }
+      else if ( pos[0] > 0.5 * ( 1.0 + d ) )
+      { //pos in Omega_2 (right of the fracture)
+        permeability[0][0] = 1.0;
+
+        for (int i = 1; i < dim; i++)
+        {
+          permeability[i][i] = 1.0 / ( 1.0 + d );
+        }
+      }
+      else
+      { //pos in Omega_R (inside the fracture)
+        permeability[0][0] = 1.0 / ( 1.0 + d );
+
+        for (int i = 1; i < dim; i++)
+        {
+          permeability[i][i] = 1.0;
+        }
+      }
+
+      return permeability;
+    }
+
+    //returns the recommended quadrature order to compute an integral
+    //over x * q(x)
+    virtual int quadratureOrder_q () const
+    {
+      return 10;
+    }
+
+    //returns the recommended quadrature order to compute an integral
+    //over x * boundary(x) and K(x) * boundary(x)
+    virtual int quadratureOrderBoundary () const
+    {
+      return 10;
+    }
+
+    //returns the recommended quadrature order to compute an integral
+    //over an entry K[i][j] of the permeability tensor
+    virtual int quadratureOrder_K () const
+    {
+      return 10;
+    }
+
+  private:
+    //aperture of the fracture at position pos
+    const Scalar aperture (const Coordinate& pos) const
+    {
+      return dmin_ + 0.5 * ( dmax_ - dmin_ ) *
+        ( 1.0 + std::cos(8.0 * M_PI * pos[1]) );
+    }
+
+    //derivative of aperture at position pos
+    const Scalar aperturePrime (const Coordinate& pos) const
+    {
+      return -4.0 * M_PI * ( dmax_ - dmin_ ) * std::sin(8.0 * M_PI * pos[1]);
+    }
+
+    //second derivative of aperture at position pos
+    const Scalar aperturePrimePrime (const Coordinate& pos) const
+    {
+      return -32.0 * M_PI * M_PI * ( dmax_ - dmin_ )
+        * std::cos(8.0 * M_PI * pos[1]);
+    }
+
+    const Scalar dmin_; //minimum aperture of the fracture
+    const Scalar dmax_; //maximum aperture of the fracture
+
+};
+
+#endif
diff --git a/src/dg.cc b/src/dg.cc
index 2dedbca..5304bf3 100644
--- a/src/dg.cc
+++ b/src/dg.cc
@@ -24,6 +24,7 @@
 #include <dune/mmdg/problems/dgproblem1.hh>
 #include <dune/mmdg/problems/dgproblem2.hh>
 #include <dune/mmdg/problems/dgproblem3.hh>
+#include <dune/mmdg/problems/dgproblem4.hh>
 
 int main(int argc, char** argv)
 {
@@ -85,11 +86,26 @@ int main(int argc, char** argv)
           "an infinite series; increase the cut-off if necessary!\n\n";
       }
     }
+    else if (pt["problem"] == "dg4")
+    {
+      if ( pt.hasKey("dmin") && pt.hasKey("dmax") )
+      {
+        const double dmin = std::stod(pt["dmin"]);
+        const double dmax = std::stod(pt["dmax"]);
+        problem = new DGProblem4<Coordinate>(dmin, dmax);
+      }
+      else
+      {
+        DUNE_THROW(Dune::Exception,
+          "Problem dg4 requires the parameters 'dmin' and 'dmax'. Check the "
+          "file parameterDG.ini and make sure that they are specified.");
+      }
+    }
     else
     {
       DUNE_THROW(Dune::Exception,
         "Invalid problem type or parameter 'problem' not specified in file "
-        "parameterDG.ini (use 'dg1' to 'dg3')");
+        "parameterDG.ini (use 'dg1' to 'dg4')");
     }
 
     DG dg(gridView, mapper, *problem);
diff --git a/src/parameterDG.ini b/src/parameterDG.ini
index 275babc..f6448b0 100644
--- a/src/parameterDG.ini
+++ b/src/parameterDG.ini
@@ -1,3 +1,5 @@
 mu0 = 1000
-problem = dg2
+problem = dg4
 fastEOC = true
+dmin = 1e-1
+dmax = 3e-1
-- 
GitLab