From e04bf6737435642d0f9e7add7c43ae465f449859 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maximilian=20H=C3=B6rl?=
 <maximilian.hoerl@mathematik.uni-stuttgart.de>
Date: Fri, 3 Apr 2020 15:34:38 +0200
Subject: [PATCH] add separate EOCs for bulk and interface

---
 dune/mmdg/mmdg.hh   | 13 +++++------
 src/mmdg.cc         | 30 +++++++++++++++++--------
 src/mmdgAnalysis.py | 54 +++++++++++++++++++++++++++++++--------------
 3 files changed, 65 insertions(+), 32 deletions(-)

diff --git a/dune/mmdg/mmdg.hh b/dune/mmdg/mmdg.hh
index 32c5953..b9a9741 100644
--- a/dune/mmdg/mmdg.hh
+++ b/dune/mmdg/mmdg.hh
@@ -48,9 +48,11 @@ public:
     writeVTKoutput();
   }
 
-  //compute L2 error using quadrature rules
+  //compute L2 errors using quadrature rules,
+  //returns {error(bulk), error(interface), error(total)},
+  //the total error is calculated using the norm
   // norm = sqrt( ||.||^2_L2(bulk) + ||.||^2_L2(interface) )
-  Scalar computeL2error(const int quadratureOrder = 5)
+  const std::array<Scalar, 3> computeL2error(const int quadratureOrder = 5)
   {
     const Scalar bulkError = Base::computeL2error(quadratureOrder);
     Scalar interfaceError(0.0);
@@ -87,11 +89,8 @@ public:
       Base::applyQuadratureRule(iGeo, qrule, qlambda);
     }
 
-    //print bulk and interface error
-    std::cout << "ERROR bulk: " << bulkError << "\t ERROR interface: " <<
-      sqrt(interfaceError) << "\n";
-
-    return sqrt(bulkError * bulkError + interfaceError);
+    return {bulkError, sqrt(interfaceError),
+      sqrt(bulkError * bulkError + interfaceError)};
   }
 
   const InterfaceGridView& iGridView_;
diff --git a/src/mmdg.cc b/src/mmdg.cc
index 35ba464..706813e 100644
--- a/src/mmdg.cc
+++ b/src/mmdg.cc
@@ -131,23 +131,33 @@ int main(int argc, char** argv)
     MMDG mmdg(gridView, mapper, iGridView, iMapper, *problem);
     mmdg(mu0, xi);
 
-    //error and total run time
-    const double error = mmdg.computeL2error();
+    //errors and total run time
+    const std::array<double, 3> errors = mmdg.computeL2error();
     const double timeTotal = ClockHelper::elapsedRuntime(timeInitial);
 
-    //determine maximum edge length
-    double largestEdgeLength = 0.;
+    //determine maximum edge lengths
+    double hMax = 0.0; //maximum edge length (bulk)
+    double hMaxInterface = 0.0; //maximum edge length (interface)
+
     for (const auto& edge : edges(gridView))
     {
-      largestEdgeLength = std::max(largestEdgeLength, edge.geometry().volume());
+      if (grid.isInterface(edge))
+      {
+        hMaxInterface = std::max(hMaxInterface, edge.geometry().volume());
+      }
+      else
+      {
+        hMax = std::max(hMax, edge.geometry().volume());
+      }
     }
 
-    //write error, runtime and maximum edge length
+    //write errors, runtime and maximum edge lengths
     std::ofstream errorFile("convergenceData", std::ios::out | std::ios::trunc);
 
     if (errorFile.is_open())
     {
-      errorFile << error << "\n" << timeTotal << "\n" << largestEdgeLength;
+      errorFile << errors[0] << "\n" << errors[1] << "\n" << errors[2] << "\n"
+        << hMax << "\n" << hMaxInterface << "\n" << timeTotal;
       errorFile.close();
     }
     else
@@ -155,9 +165,11 @@ int main(int argc, char** argv)
       std::cout << "Unable to write error data to file.\n";
     }
 
-    //print total run time and error
+    //print total run time and errors
     std::cout << "Finished with a total run time of " << timeTotal <<
-      " Seconds.\nL2-error: " << error << ".\n\n";
+      " Seconds.\nL2-error (bulk): \t" << errors[0] <<
+      "\nL2-error (interface): \t" << errors[1] << "\nL2-error (total): \t"
+      << errors[2] << ".\n\n";
 
     return 0;
   }
diff --git a/src/mmdgAnalysis.py b/src/mmdgAnalysis.py
index c5b972e..a78c888 100644
--- a/src/mmdgAnalysis.py
+++ b/src/mmdgAnalysis.py
@@ -41,14 +41,36 @@ def readData():
     file = open("convergenceData", "r")
 
     # read data
-    error = float(file.readline())
+    errorBulk = float(file.readline())
+    errorInterface = float(file.readline())
+    errorTotal = float(file.readline())
+    hMax = float(file.readline())
+    hMaxInterface = float(file.readline())
     timeTotal = float(file.readline())
-    numberOfElements = float(file.readline())
 
     file.close()
 
     # return data
-    return np.array([error, timeTotal, numberOfElements])
+    return np.array([errorBulk, errorInterface, errorTotal, hMax, \
+        hMaxInterface, timeTotal])
+
+
+# determines experimental order of convergence (EOC),
+# data is assumed to be a numpy array with
+# first column: error,
+# second column: maximum edge length
+def EOCloop (data):
+    EOC = np.empty(data.shape[0] - 1)
+
+    for i in range(len(EOC)):
+        if data[i, 0] != 0:
+            EOC[i] = log(data[i, 0] / data[i+1, 0]) / \
+                log(data[i, 1] / data[i+1, 1])
+        else:
+            EOC[i] = -1.0*float('inf')
+    # end for i
+
+    return EOC
 
 
 # === main ===
@@ -72,7 +94,7 @@ dim = 2
 # column 1: total run time
 # column 2: largest edge length
 # different rows correspond to different numbers of grid elements
-data = np.zeros((len(gridfiles), 3))
+data = np.zeros((len(gridfiles), 6))
 
 for i in range(len(gridfiles)):
     # write dgf file
@@ -92,25 +114,25 @@ for i in range(len(gridfiles)):
 data /= numberOfMeans
 
 # determine experimental order of convergence (EOC)
-EOC = np.empty(len(gridfiles) - 1)
-
-for i in range(len(gridfiles) - 1):
-    if data[i, 0] != 0:
-        EOC[i] = log(data[i, 0] / data[i+1, 0]) / \
-            log(data[i, 2] / data[i+1, 2])
-    else:
-        EOC[i] = -1.0*float('inf')
-# end for i
+EOCbulk = EOCloop(data[:, [0,3]])
+EOCinterface = EOCloop(data[:, [1,4]])
+EOCtotal = \
+    EOCloop(np.column_stack([data[:,2], np.maximum(data[:,3], data[:,4])]))
 
 # print EOCs
 print("\n-------------------------------------------------------------\n")
-print("EOCs (" + str(dim) + "d):\t")
-print(EOC)
+print("EOCs (" + str(dim) + "d):")
+print("\nbulk:")
+print(EOCbulk)
+print("\ninterface:")
+print(EOCinterface)
+print("\ntotal:")
+print(EOCtotal)
 print("\n=============================================================\n\n")
 
 # write data to file
 np.savetxt(join("plots", "mmdgAnalysis_" + str(dim) + "d"), data)
-np.savetxt(join("plots", "mmdgEOC_" + str(dim) + "d"), EOC)
+np.savetxt(join("plots", "mmdgEOC_" + str(dim) + "d"), EOCtotal)
 
 # remove output files
 remove("convergenceData")
-- 
GitLab