From 343b3c1ae22bb9082b7fde19037003baab98f4d8 Mon Sep 17 00:00:00 2001
From: Timo Koch <timo.koch@iws.uni-stuttgart.de>
Date: Fri, 31 May 2019 20:37:20 +0200
Subject: [PATCH] [common] Implement function to integrate grid functions

We assume the grid function to model a Dune::Functions::GridFunction.
---
 dumux/common/integrate.hh | 108 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)
 create mode 100644 dumux/common/integrate.hh

diff --git a/dumux/common/integrate.hh b/dumux/common/integrate.hh
new file mode 100644
index 0000000000..9ea524a6da
--- /dev/null
+++ b/dumux/common/integrate.hh
@@ -0,0 +1,108 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 3 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup Common
+ * \brief Define helper functions for integration
+ */
+#ifndef DUMUX_COMMON_INTEGRATE_HH
+#define DUMUX_COMMON_INTEGRATE_HH
+
+#include <cmath>
+#include <type_traits>
+
+#include <dune/geometry/quadraturerules.hh>
+
+namespace Dumux {
+
+/*!
+ * \brief Integrate a grid function over a grid view
+ * \param gv the grid view
+ * \param f the grid function
+ * \param order the order of the quadrature rule
+ */
+template<class GridView, class F>
+auto integrateGridFunction(const GridView& gv, F&& f, std::size_t order)
+{
+    auto fLocal = localFunction(f);
+
+    using Element = typename GridView::template Codim<0>::Entity;
+    using LocalPosition = typename Element::Geometry::LocalCoordinate;
+    using Scalar = std::decay_t<decltype(fLocal(std::declval<LocalPosition>()))>;
+
+    Scalar integral = 0.0;
+    for (const auto& element : elements(gv))
+    {
+        fLocal.bind(element);
+
+        const auto geometry = element.geometry();
+        const auto& quad = Dune::QuadratureRules<Scalar, GridView::dimension>::rule(geometry.type(), order);
+        for (auto&& qp : quad)
+            integral += fLocal(qp.position())*qp.weight()*geometry.integrationElement(qp.position());
+
+        fLocal.unbind();
+    }
+    return integral;
+}
+
+/*!
+ * \brief Integrate a function over a grid view
+ * \param gv the grid view
+ * \param f the first function
+ * \param g the second function
+ * \param order the order of the quadrature rule
+ * \note dune functions currently doesn't support composing two functions
+ */
+template<class GridView, class F, class G>
+auto integrateL2Error(const GridView& gv, F&& f, G&& g, std::size_t order)
+{
+    auto fLocal = localFunction(f);
+    auto gLocal = localFunction(g);
+
+    using Element = typename GridView::template Codim<0>::Entity;
+    using LocalPosition = typename Element::Geometry::LocalCoordinate;
+    using FScalar = std::decay_t<decltype(fLocal(std::declval<LocalPosition>()))>;
+    using GScalar = std::decay_t<decltype(gLocal(std::declval<LocalPosition>()))>;
+
+    using Scalar = std::decay_t<decltype((std::declval<FScalar>()-std::declval<GScalar>())
+                                        *(std::declval<FScalar>()-std::declval<GScalar>()))>;
+    Scalar l2norm = 0.0;
+    for (const auto& element : elements(gv))
+    {
+        fLocal.bind(element);
+        gLocal.bind(element);
+
+        const auto geometry = element.geometry();
+        const auto& quad = Dune::QuadratureRules<Scalar, GridView::dimension>::rule(geometry.type(), order);
+        for (auto&& qp : quad)
+        {
+            const auto error = fLocal(qp.position()) - gLocal(qp.position());
+            l2norm += error*error*qp.weight()*geometry.integrationElement(qp.position());
+        }
+
+        gLocal.unbind();
+        fLocal.unbind();
+    }
+    using std::sqrt;
+    return sqrt(l2norm);
+}
+
+} // end namespace Dumux
+
+#endif
-- 
GitLab