diff --git a/dune/mmdg/dg.hh b/dune/mmdg/dg.hh
index b82886f891c8c4c44df0b19fea3c5e7d30754792..4390d219c296afdb1153369168c20d258de52138 100644
--- a/dune/mmdg/dg.hh
+++ b/dune/mmdg/dg.hh
@@ -19,12 +19,13 @@
template<class Grid, class GridView, class Mapper, class Problem>
class DG
-{ //TODO: Ordnung (private / public)
+{
public:
- //using GridView = typename Grid::LeafGridView;
- //using Mapper = typename Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
- using Scalar = typename GridView::ctype;
static constexpr int dim = GridView::dimension;
+ static constexpr auto simplex = Dune::GeometryTypes::simplex(dim);
+ static constexpr auto edge = Dune::GeometryTypes::simplex(dim-1);
+
+ using Scalar = typename GridView::ctype;
using Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,1,1>>;
using Vector = Dune::BlockVector<Dune::FieldVector<Scalar,1>>;
using VTKFunction = Dune::VTKFunction<GridView>;
@@ -34,8 +35,6 @@ public:
using QRulesElem = Dune::QuadratureRules<Scalar, dim>;
using QRuleEdge = Dune::QuadratureRule<Scalar, dim-1>;
using QRulesEdge = Dune::QuadratureRules<Scalar, dim-1>;
- static constexpr auto simplex = Dune::GeometryTypes::simplex(dim);
- static constexpr auto edge = Dune::GeometryTypes::simplex(dim-1);
//constructor
DG (const Grid& grid, const GridView& gridView, const Mapper& mapper, const Problem& problem) :
@@ -50,7 +49,7 @@ public:
d = Vector(dof_);
}
- const void operator() (const Scalar mu)
+ void operator() (const Scalar mu)
{
//assemble stiffness matrix A and load vector b
assembleSLE(mu);
@@ -64,6 +63,48 @@ public:
writeVTKoutput();
}
+ Scalar computeL2error(const int quadratureOrder = 5) const
+ {
+ if (!problem_.hasExactSolution())
+ {
+ DUNE_THROW(Dune::Exception, "ERROR: Problem has no exact solution or "
+ "exact solution is not implemented");
+ }
+
+ Scalar error(0.0);
+
+ for (const auto& elem : elements(gridView_))
+ {
+ const int elemIdxSLE = (dim + 1) * mapper_.index(elem);
+ const auto& geo = elem.geometry();
+ const QRuleElem& qrule = QRulesElem::rule(simplex, quadratureOrder);
+
+ //determine L2-error on element elem using a quadrature rule
+ for (const auto& ip : qrule)
+ {
+ const auto& qpLocal = ip.position();
+ const auto& qpGlobal = geo.global(qpLocal);
+
+ const Scalar quadratureFactor =
+ ip.weight() * geo.integrationElement(qpLocal);
+
+ Scalar numericalSolutionAtQP = d[elemIdxSLE];
+
+ for (int i = 0; i < dim; i++)
+ {
+ numericalSolutionAtQP += d[elemIdxSLE + i + 1] * qpGlobal[i];
+ }
+
+ const Scalar errorEvaluation =
+ numericalSolutionAtQP - problem_.exactSolution(qpGlobal);
+
+ error += quadratureFactor * errorEvaluation * errorEvaluation;
+ }
+ }
+
+ return std::sqrt(error);
+ }
+
const Grid& grid_;
const GridView& gridView_;
const Mapper& mapper_; //element mapper for gridView_
@@ -388,15 +429,15 @@ protected:
const auto& qpLocal = ip.position();
const auto& qpGlobal = intersctGeo.global(qpLocal);
- const Scalar weight(ip.weight());
- const Scalar
- integrationElem(intersctGeo.integrationElement(qpLocal));
+ const Scalar quadratureFactor =
+ ip.weight() * intersctGeo.integrationElement(qpLocal);
+
const Scalar boundaryEvaluation(problem_.boundary(qpGlobal));
const Dune::FieldMatrix<Scalar, dim, dim> KEvaluation =
problem_.K(qpGlobal);
//quadrature for int_intersct mu * g * phi_elem,0 ds
- b[elemIdxSLE] += weight * integrationElem * mu * boundaryEvaluation;
+ b[elemIdxSLE] += quadratureFactor * mu * boundaryEvaluation;
//quadrature for
// int_intersct (mu * phi_elem,i - K[:,i] * normal) * g ds
@@ -404,7 +445,7 @@ protected:
for (int i = 0; i < dim; i++)
{
b[elemIdxSLE + i + 1] +=
- weight * integrationElem * (mu * qpGlobal[i] -
+ quadratureFactor * (mu * qpGlobal[i] -
(KEvaluation[i] * normal)) * boundaryEvaluation;
}
}
@@ -417,7 +458,7 @@ protected:
// int_intersct phi_elem,0 * K*grad(phi_elem,i) * normal ds
//with K*grad(phi_elem,i) = K[:,i]
A->entry(elemIdxSLE + i + 1, elemIdxSLE) +=
- mu * linearIntegrals[i] - 0.5 * KIntegrals[i];
+ mu * linearIntegrals[i] - KIntegrals[i];
for (int j = 0; j <= i; j++)
{
@@ -429,7 +470,7 @@ protected:
//with K*grad(phi_elem,i) = K[:,i]
A->entry(elemIdxSLE + i + 1, elemIdxSLE + j + 1) +=
mu * quadraticIntregrals[i][j]
- - 0.5 * ( KIntegralsX[i][j] + KIntegralsX[j][i] );
+ - ( KIntegralsX[i][j] + KIntegralsX[j][i] );
}
}
}