diff --git a/dune/mmdg/dg.hh b/dune/mmdg/dg.hh
index 4390d219c296afdb1153369168c20d258de52138..f352e238227638252af237c20fcb6b7ab31c65e3 100644
--- a/dune/mmdg/dg.hh
+++ b/dune/mmdg/dg.hh
@@ -63,6 +63,7 @@ public:
writeVTKoutput();
}
+ //compute L2 error using a quadrature rule
Scalar computeL2error(const int quadratureOrder = 5) const
{
if (!problem_.hasExactSolution())
diff --git a/dune/mmdg/mmdg.hh b/dune/mmdg/mmdg.hh
index 69a48fe128f643eb37bd60d7ddf86d33f97e46f9..62d2d0b0c325eeec680f291656c60b170ff1c9e5 100644
--- a/dune/mmdg/mmdg.hh
+++ b/dune/mmdg/mmdg.hh
@@ -44,6 +44,51 @@ public:
writeVTKoutput();
}
+ //compute L2 error using quadrature rules
+ // norm = sqrt( ||.||^2_L2(bulk) + ||.||^2_L2(interface) )
+ Scalar computeL2error(const int quadratureOrder = 5) const
+ {
+ const Scalar bulkError = Base::computeL2error(quadratureOrder);
+ Scalar interfaceError(0.0);
+
+ for (const auto& iElem : elements(iGridView_))
+ {
+ const auto& iGeo = iElem.geometry();
+ const int iElemIdxSLE =
+ (dim + 1) * Base::gridView_.size(0) + dim * iMapper_.index(iElem);
+ const QRuleInterface& qrule =
+ QRulesInterface::rule(iSimplex, quadratureOrder);
+ const InterfaceBasis iFrame = interfaceFrame(
+ Base::grid_.asIntersection(iElem).centerUnitOuterNormal());
+
+ //determine L2-error on the interface element iElem using a
+ //quadrature rule
+ for (const auto& ip : qrule)
+ {
+ const auto& qpLocal = ip.position();
+ const auto& qpGlobal = iGeo.global(qpLocal);
+
+ const Scalar quadratureFactor =
+ ip.weight() * iGeo.integrationElement(qpLocal);
+
+ Scalar numericalSolutionAtQP = Base::d[iElemIdxSLE];
+
+ for (int i = 0; i < dim - 1; i++)
+ {
+ numericalSolutionAtQP +=
+ Base::d[iElemIdxSLE + i + 1] * (qpGlobal * iFrame[i]);
+ }
+
+ const Scalar errorEvaluation = numericalSolutionAtQP
+ - Base::problem_.exactInterfaceSolution(qpGlobal);
+
+ interfaceError += quadratureFactor * errorEvaluation * errorEvaluation;
+ }
+ }
+
+ return sqrt(bulkError * bulkError + interfaceError);
+ }
+
const InterfaceGridView& iGridView_;
const InterfaceMapper& iMapper_;
diff --git a/src/mmdg.cc b/src/mmdg.cc
index 4d567e270cc203f4a28909349221f5cdf073e78a..e2d4348fb89b91e95047dc57c48bdc8dd7cbf06a 100644
--- a/src/mmdg.cc
+++ b/src/mmdg.cc
@@ -83,7 +83,7 @@ int main(int argc, char** argv)
//print total run time
const double timeTotal = ClockHelper::elapsedRuntime(timeInitial);
std::cout << "Finished with a total run time of " << timeTotal <<
- " Seconds.\n";
+ " Seconds.\nL2-error: " << mmdg.computeL2error() << ".\n";
return 0;
}