From 15aac20226b7208b9281ef7a01dbdf3d7a42ba81 Mon Sep 17 00:00:00 2001
From: Oliver Sander <oliver.sander@tu-dresden.de>
Date: Thu, 11 Feb 2016 10:52:39 +0100
Subject: [PATCH] Refactor code to make it more flexible

---
 src/compute-disc-error.cc | 231 ++++++++++++++++++++++++--------------
 1 file changed, 144 insertions(+), 87 deletions(-)

diff --git a/src/compute-disc-error.cc b/src/compute-disc-error.cc
index 47b9ab09..4ccd6b9f 100644
--- a/src/compute-disc-error.cc
+++ b/src/compute-disc-error.cc
@@ -39,9 +39,9 @@ const int blocksize = TargetSpace::TangentVector::dimension;
 using namespace Dune;
 
 template <class GridView, int order>
-void measureEOC(const GridView gridView,
-                const GridView referenceGridView,
-                const ParameterTree& parameterSet)
+void measureDiscreteEOC(const GridView gridView,
+                        const GridView referenceGridView,
+                        const ParameterTree& parameterSet)
 {
   typedef std::vector<TargetSpace> SolutionType;
 
@@ -51,6 +51,11 @@ void measureEOC(const GridView gridView,
 
   typedef Dune::Functions::PQkNodalBasis<GridView, order> FEBasis;
   FEBasis feBasis(gridView);
+  FEBasis referenceFEBasis(referenceGridView);
+
+  using FufemFEBasis = DuneFunctionsBasis<FEBasis>;
+  FufemFEBasis fufemReferenceFEBasis(referenceFEBasis);
+  FufemFEBasis fufemFEBasis(feBasis);
 
   //////////////////////////////////////////////////////////////////////////////////
   //  Read the data whose error is to be measured
@@ -70,108 +75,132 @@ void measureEOC(const GridView gridView,
   for (size_t i=0; i<x.size(); i++)
     x[i] = TargetSpace(embeddedX[i]);
 
+  // The numerical solution, as a grid function
+  GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x);
+
+  ///////////////////////////////////////////////////////////////////////////
+  // Read the reference configuration
+  ///////////////////////////////////////////////////////////////////////////
+  EmbeddedVectorType embeddedReferenceX(referenceFEBasis.size());
+  inFile.open(parameterSet.get<std::string>("referenceData"), std::ios_base::binary);
+  if (not inFile)
+    DUNE_THROW(IOError, "File " << parameterSet.get<std::string>("referenceData") << " could not be opened.");
+  GenericVector::readBinary(inFile, embeddedReferenceX);
+
+  SolutionType referenceX(embeddedReferenceX.size());
+  for (size_t i=0; i<referenceX.size(); i++)
+    referenceX[i] = TargetSpace(embeddedReferenceX[i]);
+
+  // The reference solution, as a grid function
+  GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> referenceSolution(fufemReferenceFEBasis, referenceX);
+
   /////////////////////////////////////////////////////////////////
   //   Measure the discretization error
   /////////////////////////////////////////////////////////////////
 
-  if (parameterSet.get<std::string>("discretizationErrorMode")=="analytical")
+  double l2ErrorSquared = 0;
+  double h1ErrorSquared = 0;
+
+  HierarchicSearch<typename GridView::Grid,typename GridView::IndexSet> hierarchicSearch(gridView.grid(), gridView.indexSet());
+
+  for (const auto& rElement : elements(referenceGridView))
   {
-    using FufemFEBasis = DuneFunctionsBasis<FEBasis>;
-    FufemFEBasis fufemFEBasis(feBasis);
+    const auto& quadRule = QuadratureRules<double, dim>::rule(rElement.type(), 6);
+
+    for (const auto& qp : quadRule)
+    {
+      auto integrationElement = rElement.geometry().integrationElement(qp.position());
 
-    // Read reference solution and its derivative into a PythonFunction
-    typedef VirtualDifferentiableFunction<FieldVector<double, dim>, TargetSpace::CoordinateType> FBase;
+      auto globalPos = rElement.geometry().global(qp.position());
 
-    Python::Module module = Python::import(parameterSet.get<std::string>("referenceSolution"));
-    auto referenceSolution = module.get("fdf").toC<std::shared_ptr<FBase>>();
+      auto element = hierarchicSearch.findEntity(globalPos);
+      auto localPos = element.geometry().local(globalPos);
 
-    // The numerical solution, as a grid function
-    GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x);
+      auto diff = referenceSolution(rElement, qp.position()) - numericalSolution(element, localPos);
 
-    // QuadratureRule for the integral of the L^2 error
-    QuadratureRuleKey quadKey(dim,6);
+      l2ErrorSquared += integrationElement * qp.weight() * diff.two_norm2();
 
-    // Compute the embedded L^2 error
-    double l2Error = DiscretizationError<GridView>::computeL2Error(&numericalSolution,
-                                                                   referenceSolution.get(),
-                                                                   quadKey);
+      auto derDiff = referenceSolution.derivative(rElement, qp.position()) - numericalSolution.derivative(element, localPos);
 
-    // Compute the embedded H^1 error
-    double h1Error = DiscretizationError<GridView>::computeH1HalfNormDifferenceSquared(gridView,
-                                                                                       &numericalSolution,
-                                                                                       referenceSolution.get(),
-                                                                                       quadKey);
+      h1ErrorSquared += integrationElement * qp.weight() * derDiff.frobenius_norm2();
 
-    std::cout << "elements: " << gridView.size(0)
-              << "      "
-              << "L^2 error: " << l2Error
-              << "      ";
-    std::cout << "H^1 error: " << std::sqrt(l2Error*l2Error + h1Error) << std::endl;
+    }
   }
 
-  if (parameterSet.get<std::string>("discretizationErrorMode")=="discrete")
-  {
-    FEBasis referenceFEBasis(referenceGridView);
+  std::cout << "levels: " << gridView.grid().maxLevel()+1
+            << "      "
+            << "L^2 error: " << std::sqrt(l2ErrorSquared)
+            << "      "
+            << "H^1 error: " << std::sqrt(l2ErrorSquared + h1ErrorSquared)
+            << std::endl;
+}
 
-    // Reference configuration
-    EmbeddedVectorType embeddedReferenceX(referenceFEBasis.size());
-    inFile.open(parameterSet.get<std::string>("referenceData"), std::ios_base::binary);
-    if (not inFile)
-      DUNE_THROW(IOError, "File " << parameterSet.get<std::string>("referenceData") << " could not be opened.");
-    GenericVector::readBinary(inFile, embeddedReferenceX);
+template <class GridView, int order>
+void measureAnalyticalEOC(const GridView gridView,
+                          const ParameterTree& parameterSet)
+{
+  typedef std::vector<TargetSpace> SolutionType;
 
-    SolutionType referenceX(embeddedReferenceX.size());
-    for (size_t i=0; i<referenceX.size(); i++)
-      referenceX[i] = TargetSpace(embeddedReferenceX[i]);
+  //////////////////////////////////////////////////////////////////////////////////
+  //  Construct the scalar function space bases corresponding to the GFE space
+  //////////////////////////////////////////////////////////////////////////////////
 
-    using FufemFEBasis = DuneFunctionsBasis<FEBasis>;
-    FufemFEBasis fufemReferenceFEBasis(referenceFEBasis);
-    FufemFEBasis fufemFEBasis(feBasis);
+  typedef Dune::Functions::PQkNodalBasis<GridView, order> FEBasis;
+  FEBasis feBasis(gridView);
 
-    // The numerical solution, as a grid function
-    GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> referenceSolution(fufemReferenceFEBasis, referenceX);
+  //////////////////////////////////////////////////////////////////////////////////
+  //  Read the data whose error is to be measured
+  //////////////////////////////////////////////////////////////////////////////////
 
-    // The numerical solution, as a grid function
-    GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x);
+  // Input data
+  typedef BlockVector<TargetSpace::CoordinateType> EmbeddedVectorType;
 
-    double l2ErrorSquared = 0;
-    double h1ErrorSquared = 0;
+  EmbeddedVectorType embeddedX(feBasis.size());
+  std::ifstream inFile(parameterSet.get<std::string>("simulationData"), std::ios_base::binary);
+  if (not inFile)
+    DUNE_THROW(IOError, "File " << parameterSet.get<std::string>("simulationData") << " could not be opened.");
+  GenericVector::readBinary(inFile, embeddedX);
+  inFile.close();
 
-    HierarchicSearch<typename GridView::Grid,typename GridView::IndexSet> hierarchicSearch(gridView.grid(), gridView.indexSet());
+  SolutionType x(embeddedX.size());
+  for (size_t i=0; i<x.size(); i++)
+    x[i] = TargetSpace(embeddedX[i]);
 
-    std::cout << "l2: " << l2ErrorSquared << std::endl;
-    for (const auto& rElement : elements(referenceGridView))
-    {
-      const auto& quadRule = QuadratureRules<double, dim>::rule(rElement.type(), 6);
+  /////////////////////////////////////////////////////////////////
+  //   Measure the discretization error
+  /////////////////////////////////////////////////////////////////
 
-      for (const auto& qp : quadRule)
-      {
-        auto integrationElement = rElement.geometry().integrationElement(qp.position());
+  using FufemFEBasis = DuneFunctionsBasis<FEBasis>;
+  FufemFEBasis fufemFEBasis(feBasis);
 
-        auto globalPos = rElement.geometry().global(qp.position());
+  // Read reference solution and its derivative into a PythonFunction
+  typedef VirtualDifferentiableFunction<FieldVector<double, dim>, TargetSpace::CoordinateType> FBase;
 
-        auto element = hierarchicSearch.findEntity(globalPos);
-        auto localPos = element.geometry().local(globalPos);
+  Python::Module module = Python::import(parameterSet.get<std::string>("referenceSolution"));
+  auto referenceSolution = module.get("fdf").toC<std::shared_ptr<FBase>>();
 
-        auto diff = referenceSolution(rElement, qp.position()) - numericalSolution(element, localPos);
+  // The numerical solution, as a grid function
+  GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x);
 
-        l2ErrorSquared += integrationElement * qp.weight() * diff.two_norm2();
+  // QuadratureRule for the integral of the L^2 error
+  QuadratureRuleKey quadKey(dim,6);
 
-        auto derDiff = referenceSolution.derivative(rElement, qp.position()) - numericalSolution.derivative(element, localPos);
+  // Compute the embedded L^2 error
+  double l2Error = DiscretizationError<GridView>::computeL2Error(&numericalSolution,
+                                                                 referenceSolution.get(),
+                                                                 quadKey);
 
-        h1ErrorSquared += integrationElement * qp.weight() * derDiff.frobenius_norm2();
+  // Compute the embedded H^1 error
+  double h1Error = DiscretizationError<GridView>::computeH1HalfNormDifferenceSquared(gridView,
+                                                                                     &numericalSolution,
+                                                                                     referenceSolution.get(),
+                                                                                     quadKey);
 
-      }
-    }
-    std::cout << "l2: " << l2ErrorSquared << std::endl;
-
-    std::cout << "levels: " << gridView.grid().maxLevel()+1
-              << "      "
-              << "L^2 error: " << std::sqrt(l2ErrorSquared)
-              << "      "
-              << "H^1 error: " << std::sqrt(l2ErrorSquared + h1ErrorSquared)
-              << std::endl;
-  }
+  std::cout << "elements: " << gridView.size(0)
+            << "      "
+            << "L^2 error: " << l2Error
+            << "      ";
+  std::cout << "H^1 error: " << std::sqrt(l2Error*l2Error + h1Error) << std::endl;
 }
 
 
@@ -231,25 +260,53 @@ int main (int argc, char *argv[]) try
   referenceGrid->globalRefine(parameterSet.get<int>("numReferenceLevels")-1);
 
   // Do the actual measurement
+
   const int order = parameterSet.get<int>("order");
-  switch (order)
+
+  if (parameterSet.get<std::string>("discretizationErrorMode")=="discrete")
+  {
+    switch (order)
+    {
+      case 1:
+      measureDiscreteEOC<GridType::LeafGridView,1>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
+      break;
+
+      case 2:
+      measureDiscreteEOC<GridType::LeafGridView,2>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
+      break;
+
+      case 3:
+      measureDiscreteEOC<GridType::LeafGridView,3>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
+      break;
+
+      default:
+        DUNE_THROW(NotImplemented, "Order '" << order << "' is not implemented");
+    }
+  }
+
+  if (parameterSet.get<std::string>("discretizationErrorMode")=="analytical")
   {
-    case 1:
-    measureEOC<GridType::LeafGridView,1>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
-    break;
+    switch (order)
+    {
+      case 1:
+      measureAnalyticalEOC<GridType::LeafGridView,1>(grid->leafGridView(), parameterSet);
+      break;
 
-    case 2:
-    measureEOC<GridType::LeafGridView,2>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
-    break;
+      case 2:
+      measureAnalyticalEOC<GridType::LeafGridView,2>(grid->leafGridView(), parameterSet);
+      break;
 
-    case 3:
-    measureEOC<GridType::LeafGridView,3>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
-    break;
+      case 3:
+      measureAnalyticalEOC<GridType::LeafGridView,3>(grid->leafGridView(), parameterSet);
+      break;
 
-    default:
-      DUNE_THROW(NotImplemented, "Order '" << order << "' is not implemented");
+      default:
+        DUNE_THROW(NotImplemented, "Order '" << order << "' is not implemented");
+    }
   }
 
+
+
   return 0;
 }
 catch (Exception e)
-- 
GitLab