From 81d60deecbc63a5a65de1ad7a9b3f36455ed3642 Mon Sep 17 00:00:00 2001
From: Lars von Wolff <lars.von-wolff@mathematik.uni-stuttgart.de>
Date: Fri, 26 Aug 2022 12:24:42 +0200
Subject: [PATCH] Final State of Bachelorthesis

---
 dune/phasefield/base_parameters.hh        |  2 +
 dune/phasefield/porenetwork/pn_initial.hh | 98 ++++++++++++++++++++---
 src/pntest/pntest.cc                      | 92 +++++++++++++++------
 3 files changed, 157 insertions(+), 35 deletions(-)

diff --git a/dune/phasefield/base_parameters.hh b/dune/phasefield/base_parameters.hh
index 121e32c..fab0667 100644
--- a/dune/phasefield/base_parameters.hh
+++ b/dune/phasefield/base_parameters.hh
@@ -290,6 +290,8 @@ class Params_Initial
 public:
   const Dune::ParameterTree ptree;
   int shape;
+  float a_test;
+  float b_test;
   Params_Initial(const Dune::ParameterTree& tree) :
     ptree(tree), shape(ptree.get("shape",0))
   {
diff --git a/dune/phasefield/porenetwork/pn_initial.hh b/dune/phasefield/porenetwork/pn_initial.hh
index ee50fb2..6e7f3fd 100644
--- a/dune/phasefield/porenetwork/pn_initial.hh
+++ b/dune/phasefield/porenetwork/pn_initial.hh
@@ -1,9 +1,10 @@
 #pragma once
-
+#include <math.h>
 #define INITIAL_SHAPE_SQUARE 0
 #define INITIAL_SHAPE_CIRCLE 1
 #define INITIAL_SHAPE_ELLIPSE 2
 #define INITIAL_SHAPE_TWOCIRCLES 3
+#define INITIAL_SHAPE_RECTANGLE 4
 
 template<typename GV, typename RF, typename Params>
 class PhiInitial_Quartersquare :
@@ -14,6 +15,8 @@ class PhiInitial_Quartersquare :
   RF eps;
   RF r;
   int myshape;
+  float a;
+  float b;
 
 public:
   typedef Dune::PDELab::AnalyticGridFunctionTraits<GV,RF,1> Traits;
@@ -26,6 +29,8 @@ public:
        r = params.initial.ptree.get("Radius",0.2);
        std::cout << "EPS" << eps;
        myshape = params.initial.shape;
+       a = params.initial.a_test;
+       b = params.initial.b_test;
      }
 
   inline void evaluateGlobal(const  typename Traits::DomainType & x, typename Traits::RangeType & y) const
@@ -45,25 +50,94 @@ public:
     }
     else if(myshape == INITIAL_SHAPE_ELLIPSE)
     {
-      RF rad = sqrt((x[0]-1)/1.2*(x[0]-1)/1.2 + (x[1]-1)/0.8*(x[1]-1)/0.8);
-      y = param.dw.eval_shape(((1-r)-rad)*1/eps);
+      float xnew1 = (x[1]-1)/a+1;
+      RF rad = sqrt((x[0]-1)*(x[0]-1)  + (xnew1-1)*(xnew1-1));
+      RF y1 = param.dw.eval_shape(((1-r)-rad)*1/eps); //
+      y = y1;
+    }
+    else if(myshape == INITIAL_SHAPE_RECTANGLE) {
+      RF rf1 = param.dw.eval_shape((x[0]-r)*1/eps);
+      RF rf2 = param.dw.eval_shape((x[1]-(1-0.8*a))*1/eps);
+      y=rf1*rf2;
     }
     else if(myshape == INITIAL_SHAPE_TWOCIRCLES)
     {
-      float radius1 = 1.75; //radius circle 1
-      float radius2 = 1.75; //radius circle 2
-      float x01 = 0.9;      //xo circle 1
-      float x11 = 1.5;      //x1 circle 1
-      float x02 = 1.5;      //x0 circle 2
-      float x12 = 1.2;      //x1 circle 2
+      float b_;
+      //convert parameter b to distance of circle centers to corner b_
+      if(b > 10000/10001.0f) {
+        b_ = 10000;
+      }
+      else {
+        b_ = 1/float(1.0f - b) - 1.0f;
+      }
+      int method = 3;
+      if(method == 0) {
+        // Idee: Der Radius eines Kreises wird verkleinert, um Stauchung zu erreichen
+        // Problem: Dadurch wird auch in die andere Richtung gestaucht, besonders auffällig
+        // bei b=0
+      float radius1 = 1.25*b_ + 1; //radius circle 1, Faktor 1.25, weil ja mit 0.8 skaliert wird
+      float radius2 = 1.25*b_ + 1*a; //radius circle 2, nur der Teil, der tatsächlich im "Bild" ist, wird mit a skaliert
+      float x01 = 1;      //xo circle 1
+      float x11 = b_+1;      //x1 circle 1
+      float x02 = b_+1;      //x0 circle 2
+      float x12 = 1;      //x1 circle 2
       RF rad = sqrt((x[0]-x01)*(x[0]-x01) + (x[1]-x11)*(x[1]-x11));
       RF y1 = param.dw.eval_shape(((1-r)*radius1-rad)*1/eps);
       RF rad2 = sqrt((x[0]-x02)*(x[0]-x02) + (x[1]-x12)*(x[1]-x12));
       RF y2 = param.dw.eval_shape(((1-r)*radius2-rad2)*1/eps);
       y = y1 * y2;
-      //RF rad1 = sqrt((x[0]-2)*(x[0]-2) + (x[1]-1)*(x[1]-1));
-      //RF rad2 = sqrt((x[0]-1)*(x[0]-1) + (x[1]-2)*(x[1]-2));
-      //y = param.dw.eval_shape(((1-r)-rad2)*1/eps) * param.dw.eval_shape(((1-r)-rad1)*1/eps);
+      }
+      else if(method == 1){
+        //Idee: Einen Kreis als Ellipse formulieren, um Stauchung in zweite Richtung
+        //zu verhindern
+        //Problem: sehr breite Übergangsregion, besonders auffällig für b = 1
+      //float radius1 = 1.25*b_ + 1; //radius circle 1
+      float radius2 = 1.25*b_ + 1; //radius circle 2
+      float x01 = 1;      //xo circle 1
+      float x11 = b_+1;   //x1 circle 1
+      float x02 = b_+1;   //x0 circle 2
+      float x12 = 1;      //x1 circle 2
+      //Ellipse mit Radien 1.25b+a und 1.25b+1
+      RF rad = sqrt((x[0]-x01)/(1.25*b_+1)*(x[0]-x01)/(1.25*b_+1) + (x[1]-x11)/(1.25*b_ + a)*(x[1]-x11)/(1.25*b_ + a));
+      RF y1 = param.dw.eval_shape(((1-r)-rad)*1/eps); //
+      RF rad2 = sqrt((x[0]-x02)*(x[0]-x02)  + (x[1]-x12)*(x[1]-x12));
+      RF y2 = param.dw.eval_shape(((1-r)*radius2-rad2)*1/eps);
+      y = y1 * y2;
+      }
+      else if ( method == 2) {
+        //rumbasteln/sonstige Tests
+        float radius = 1.25 * b_ + 1;
+        float x01 = 1;      //xo circle 1
+        float x11 = b_+1;   //x1 circle 1
+        float x02 = b_+1;   //x0 circle 2
+        float x12 = 1;      //x1 circle 2
+        RF rad = sqrt((x[0]-x01)*(x[0]-x01) *(a*a)+ (x[1]-x11)*(x[1]-x11));
+        RF y1 = param.dw.eval_shape(((1-r)*radius-rad)*1/eps);
+        RF rad2 = sqrt((x[0]-x02)*(x[0]-x02) + (x[1]-x12)*(x[1]-x12));
+        RF y2 = param.dw.eval_shape(((1-r)*radius-rad2)*1/eps);
+        y = y1 * y2;
+      }
+      else if(method == 3){
+        //Idee: Einen Kreis als Ellipse formulieren, um Stauchung in zweite Richtung
+        //zu verhindern
+        //Problem: sehr breite Übergangsregion, besonders auffällig für b = 1
+      //float radius1 = 1.25*b_ + 1; //radius circle 1
+      //float xnew0 = x[0];
+      float xnew1 = (x[1]-1)/a+1;
+
+      float radius2 = 1.25*b_ + 1; //radius circle 2
+      float x01 = 1;      //xo circle 1
+      float x11 = b_+1;   //x1 circle 1
+      float x02 = b_+1;   //x0 circle 2
+      float x12 = 1;      //x1 circle 2
+      //Ellipse mit Radien 1.25b+a und 1.25b+1
+      RF rad = sqrt((x[0]-x01)*(x[0]-x01)  + (xnew1-x11)*(xnew1-x11));
+      RF y1 = param.dw.eval_shape(((1-r)*radius2-rad)*1/eps); //
+      RF rad2 = sqrt((x[0]-x02)*(x[0]-x02)  + (xnew1-x12)*(xnew1-x12));
+      RF y2 = param.dw.eval_shape(((1-r)*radius2-rad2)*1/eps);
+      y = y1 * y2;
+      }
+
     }
     else
     {
diff --git a/src/pntest/pntest.cc b/src/pntest/pntest.cc
index 5ae546e..6ee5c7f 100644
--- a/src/pntest/pntest.cc
+++ b/src/pntest/pntest.cc
@@ -53,41 +53,87 @@ int main(int argc, char** argv)
     //Set input/output filenamens
     std::string GridFilename = ptree.get("domain.filename","square.msh");
     std::string OutputFilename = ptree.get("output.filename","output");
-
+    bool runAll = false;
     //Set initial Shape
     //param.initial.shape = INITIAL_SHAPE_SQUARE;
     //param.initial.shape = INITIAL_SHAPE_CIRCLE;
     //param.initial.shape = INITIAL_SHAPE_ELLIPSE;
     param.initial.shape = INITIAL_SHAPE_TWOCIRCLES;
-
+    param.initial.a_test = 1;
+    param.initial.b_test = 1;
+    float a_values[20] = {0.05, 0.1,0.15, 0.2, 0.25, 0.3, 0.35, 0.4,0.45,  0.5,0.55, 0.6,0.65, 0.7,0.75, 0.8, 0.85,0.9, 0.95,1.0};
+    float b_values[21] = {0, 0.05, 0.1,0.15, 0.2, 0.25, 0.3, 0.35, 0.4,0.45,  0.5,0.55, 0.6,0.65, 0.7,0.75, 0.8, 0.85,0.9, 0.95,1.0};
     //Create Simulation
-    Pn_1PFlow<Parameters> pn_1pFlow(GridFilename,OutputFilename,param, 10e-6); //Last Parameter is initial pore Radius in m
+    //for (int i = 0; i < 11; ++i) {
+      //param.initial.b_test = b_values[i];
+      //Pn_1PFlow<Parameters> pn_1pFlow(GridFilename,OutputFilename,param, 10e-6); //Last Parameter is initial pore Radius in m
+
+      //Example of usecase for Pn_1PFlow
+      //std::cout << "b= " << param.initial.b_test << std::endl;
+      //std::cout << "Kf = " << pn_1pFlow.getKf() << " phiSolid = " << pn_1pFlow.getPhiSolid() << std::endl;
+      //std::cout << "Pore Area = " << pn_1pFlow.getPoreArea() << " m^2" << std::endl;
+      //std::cout << "Pore Area Fraction (compared to inital values) = " << pn_1pFlow.getPoreAreaFraction() << std::endl;
+      //pn_1pFlow.writeVTK(0.0);
+      //opening stream to write into csv file
+      //std::string filename("squ.csv");
+      //std::ofstream file_out;
+      //file_out.open(filename, std::ios_base::app);
 
-    //Example of usecase for Pn_1PFlow
-    std::cout << "Kf = " << pn_1pFlow.getKf() << " phiSolid = " << pn_1pFlow.getPhiSolid() << std::endl;
-    std::cout << "Pore Area = " << pn_1pFlow.getPoreArea() << " m^2" << std::endl;
-    std::cout << "Pore Area Fraction (compared to inital values) = " << pn_1pFlow.getPoreAreaFraction() << std::endl;
-    pn_1pFlow.writeVTK(0.0);
-    std::string filename("test.csv");
+      //loop until phi solid is > 0.85
+      //int j = 0;
+      //while(1 - pn_1pFlow.getPhiSolid() > 0.55) {
+      //j++;
+      //pn_1pFlow.grow(2e-6);  //Growth is measured in m
+      //pn_1pFlow.growArea((10e-6)*(10e-6)*0.1);   // Growth of Area in m^2
+      //pn_1pFlow.writeVTK(1.0);
+      //pn_1pFlow.writeVTK(j);
+      //std::cout << "Kf = " << pn_1pFlow.getKf() << " phiSolid = " << pn_1pFlow.getPhiSolid() << std::endl;
+      //std::cout << "Total Flux = - Kf/viscosity * gradient p" << std::endl;
+      //std::cout << "Kf has unit m^4" << std::endl;
+
+      //std::cout << "Pore Area = " << pn_1pFlow.getPoreArea()  << " m^2" << std::endl;
+      //std::cout << "Pore Area Fraction (compared to inital values) = " << pn_1pFlow.getPoreAreaFraction() << std::endl;
+      //file_out << pn_1pFlow.getKf() << "," << 1 - pn_1pFlow.getPhiSolid() << "b=" << param.initial.b_test << std::endl;
+    //}
+
+    if(runAll) {
+    //opening stream to write into csv file
+    std::string filename("data_rectangles.csv");
     std::ofstream file_out;
     file_out.open(filename, std::ios_base::app);
-    int i = 0;
-    while(1 - pn_1pFlow.getPhiSolid() > 0.15) {
-    i++;
-    //pn_1pFlow.grow(2e-6);  //Growth is measured in m
-    pn_1pFlow.growArea((10e-6)*(10e-6)*0.1);   // Growth of Area in m^2
-    //pn_1pFlow.writeVTK(1.0);
-    pn_1pFlow.writeVTK(i);
-    std::cout << "Kf = " << pn_1pFlow.getKf() << " phiSolid = " << pn_1pFlow.getPhiSolid() << std::endl;
-    std::cout << "Total Flux = - Kf/viscosity * gradient p" << std::endl;
-    std::cout << "Kf has unit m^4" << std::endl;
+    int step;
+    for(auto const& a: a_values) {
+      for(auto const& b: b_values) {
+        param.initial.b_test = b;
+        param.initial.a_test = a;
+        std::cout << "a= " << a << ", b=" << b << std::endl;
+        Pn_1PFlow<Parameters> pn_1pFlow(GridFilename,OutputFilename,param, 10e-6); //Last Parameter is initial pore Radius in m
+        float kf_init = pn_1pFlow.getKf();
+        float phiSolid_init = pn_1pFlow.getPhiSolid();
+        float poreArea_init = pn_1pFlow.getPoreArea();
+        step = 0;
+        file_out << a << ","<< b <<","<< pn_1pFlow.getKf() << "," << pn_1pFlow.getPhiSolid() << "," << pn_1pFlow.getPoreArea() << "," << kf_init << ","<< phiSolid_init << ","<< poreArea_init << "," << pn_1pFlow.getPoreAreaFraction() << ","<< step << std::endl;
+        while(1 - pn_1pFlow.getPhiSolid() > 0.01) {
+          pn_1pFlow.grow(1e-7);  //Growth is measured in m
+          step++;
+          file_out << a << ","<< b <<","<< pn_1pFlow.getKf() << "," << pn_1pFlow.getPhiSolid() << "," << pn_1pFlow.getPoreArea() << "," << kf_init << ","<< phiSolid_init << ","<< poreArea_init << "," << pn_1pFlow.getPoreAreaFraction() << ","<< step << std::endl;
 
-    std::cout << "Pore Area = " << pn_1pFlow.getPoreArea()  << " m^2" << std::endl;
-    std::cout << "Pore Area Fraction (compared to inital values) = " << pn_1pFlow.getPoreAreaFraction() << std::endl;
-    file_out << pn_1pFlow.getKf() << "," << 1 - pn_1pFlow.getPhiSolid() << std::endl;
+        }
+      }
+    }
+  }//if
+  else {
+    param.initial.shape = INITIAL_SHAPE_SQUARE;
+    Pn_1PFlow<Parameters> pn_1pFlow(GridFilename,OutputFilename,param, 10e-6); //Last Parameter is initial pore Radius in m
+    pn_1pFlow.writeVTK(0);
+    int i = 1;
+    while(1 - pn_1pFlow.getPhiSolid() > 0.01) {
+      pn_1pFlow.grow(1e-7);  //Growth is measured in m
+      pn_1pFlow.writeVTK(i);
+      i++;
+    }
 
   }
-
   }
   catch (Dune::Exception &e){
     std::cerr << "Dune reported error: " << e << std::endl;
-- 
GitLab