From 1a8c1edbc655f98e8e267da83cc84951def0981d Mon Sep 17 00:00:00 2001
From: Felix Schindler <felix.schindler@wwu.de>
Date: Fri, 14 Aug 2020 06:44:31 +0200
Subject: [PATCH] [functions] add divergence(grid_function)

---
 .../base/derivatives-of-element-functions.hh  |   4 +-
 .../base/derivatives-of-grid-functions.hh     | 110 ++++++++++++++++++
 dune/xt/functions/derivatives.hh              |  19 ++-
 3 files changed, 129 insertions(+), 4 deletions(-)
 create mode 100644 dune/xt/functions/base/derivatives-of-grid-functions.hh

diff --git a/dune/xt/functions/base/derivatives-of-element-functions.hh b/dune/xt/functions/base/derivatives-of-element-functions.hh
index f96941199..7e355ee90 100644
--- a/dune/xt/functions/base/derivatives-of-element-functions.hh
+++ b/dune/xt/functions/base/derivatives-of-element-functions.hh
@@ -27,7 +27,7 @@ namespace internal {
 template <class ElementFunctionType, DerivativeType derivative>
 class DerivativeElementFunctionHelper
 {
-  static_assert(is_element_function<ElementFunctionType>::value, "");
+  static_assert(is_element_function<ElementFunctionType>::value || is_grid_function<ElementFunctionType>::value, "");
 
 public:
   using E = typename ElementFunctionType::E;
@@ -201,7 +201,7 @@ public:
   {}
 
 protected:
-  void post_bind(const ElementType& element)
+  void post_bind(const ElementType& element) override final
   {
     if (do_post_bind_)
       func_.access().bind(element);
diff --git a/dune/xt/functions/base/derivatives-of-grid-functions.hh b/dune/xt/functions/base/derivatives-of-grid-functions.hh
new file mode 100644
index 000000000..e5c0e1af4
--- /dev/null
+++ b/dune/xt/functions/base/derivatives-of-grid-functions.hh
@@ -0,0 +1,110 @@
+// This file is part of the dune-xt project:
+//   https://github.com/dune-community/dune-xt
+// Copyright 2009-2020 dune-xt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2019)
+//   René Fritze     (2019)
+//   Tobias Leibner  (2020)
+
+#ifndef DUNE_XT_FUNCTIONS_BASE_DERIVATIVES_OF_GRID_FUNCTIONS_HH
+#define DUNE_XT_FUNCTIONS_BASE_DERIVATIVES_OF_GRID_FUNCTIONS_HH
+
+#include <dune/xt/common/memory.hh>
+
+#include <dune/xt/functions/grid-function.hh>
+#include <dune/xt/functions/interfaces/grid-function.hh>
+#include <dune/xt/functions/type_traits.hh>
+
+#include "derivatives-of-element-functions.hh"
+
+
+namespace Dune {
+namespace XT {
+namespace Functions {
+
+
+template <class GridFunctionType, DerivativeType derivative>
+class DerivativeGridFunction
+  : public GridFunctionInterface<typename internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::E,
+                                 internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::r,
+                                 internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::rC,
+                                 typename internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::R>
+{
+  static_assert(is_grid_function<GridFunctionType>::value, "");
+
+  using BaseType =
+      GridFunctionInterface<typename internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::E,
+                            internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::r,
+                            internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::rC,
+                            typename internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>::R>;
+
+  using Select = internal::DerivativeElementFunctionHelper<GridFunctionType, derivative>;
+
+  static const constexpr size_t r_ = GridFunctionType::r;
+  static const constexpr size_t rC_ = GridFunctionType::rC;
+
+public:
+  using BaseType::r;
+  using BaseType::rC;
+  using typename BaseType::E;
+  using typename BaseType::LocalFunctionType;
+  using typename BaseType::R;
+
+  DerivativeGridFunction(GridFunction<E, r_, rC_, R> grid_function, const std::string& nm = "")
+    : BaseType()
+    , grid_function_(grid_function)
+    , name_(nm.empty() ? "dune.xt.functions.derivativegridfunction" : nm)
+  {}
+
+  std::unique_ptr<LocalFunctionType> local_function() const override final
+  {
+    return std::make_unique<DerivativeElementFunction<typename GridFunctionType::LocalFunctionType, derivative>>(
+        grid_function_.local_function());
+  }
+
+  std::string name() const override final
+  {
+    return name_;
+  }
+
+private:
+  GridFunction<E, r_, rC_, R> grid_function_;
+  const std::string name_;
+}; // class DerivativeGridFunction
+
+
+template <class GridFunctionType>
+class DivergenceGridFunction : public DerivativeGridFunction<GridFunctionType, DerivativeType::divergence>
+{
+  using BaseType = DerivativeGridFunction<GridFunctionType, DerivativeType::divergence>;
+
+public:
+  template <class... Args>
+  explicit DivergenceGridFunction(Args&&... args)
+    : BaseType(std::forward<Args>(args)...)
+  {}
+}; // class DivergenceGridFunction
+
+
+template <class GridFunctionType>
+class GradientGridFunction : public DerivativeGridFunction<GridFunctionType, DerivativeType::gradient>
+{
+  using BaseType = DerivativeGridFunction<GridFunctionType, DerivativeType::gradient>;
+
+public:
+  template <class... Args>
+  explicit GradientGridFunction(Args&&... args)
+    : BaseType(std::forward<Args>(args)...)
+  {}
+}; // class GradientGridFunction
+
+
+} // namespace Functions
+} // namespace XT
+} // namespace Dune
+
+
+#endif // DUNE_XT_FUNCTIONS_DERIVED_HH
diff --git a/dune/xt/functions/derivatives.hh b/dune/xt/functions/derivatives.hh
index 497f8a207..7382304c3 100644
--- a/dune/xt/functions/derivatives.hh
+++ b/dune/xt/functions/derivatives.hh
@@ -13,7 +13,9 @@
 #define DUNE_XT_FUNCTIONS_DERIVATIVES_HH
 
 #include <dune/xt/functions/base/derivatives-of-element-functions.hh>
+#include <dune/xt/functions/base/derivatives-of-grid-functions.hh>
 #include <dune/xt/functions/interfaces/element-functions.hh>
+#include <dune/xt/functions/interfaces/grid-function.hh>
 
 namespace Dune {
 namespace XT {
@@ -22,18 +24,31 @@ namespace Functions {
 
 template <class E, class R>
 DivergenceElementFunction<ElementFunctionInterface<E, E::dimension, 1, R>>
-    divergence(ElementFunctionInterface<E, E::dimension, 1, R>& func)
+divergence(const ElementFunctionInterface<E, E::dimension, 1, R>& func)
 {
   return DivergenceElementFunction<ElementFunctionInterface<E, E::dimension, 1, R>>(func);
 }
 
+template <class E, class R>
+DivergenceGridFunction<GridFunctionInterface<E, E::dimension, 1, R>>
+divergence(const GridFunctionInterface<E, r, 1, R>& func)
+{
+  return DivergenceGridFunction<GridFunctionInterface<E, E::dimension, 1, R>>(func);
+}
+
 
 template <class E, class R>
-GradientElementFunction<ElementFunctionInterface<E, 1, 1, R>> gradient(ElementFunctionInterface<E, 1, 1, R>& func)
+GradientElementFunction<ElementFunctionInterface<E, 1, 1, R>> gradient(const ElementFunctionInterface<E, 1, 1, R>& func)
 {
   return GradientElementFunction<ElementFunctionInterface<E, 1, 1, R>>(func);
 }
 
+template <class E, class R>
+GradientGridFunction<GridFunctionInterface<E, 1, 1, R>> gradient(const GridFunctionInterface<E, 1, 1, R>& func)
+{
+  return GradientGridFunction<GridFunctionInterface<E, 1, 1, R>>(func);
+}
+
 
 } // namespace Functions
 } // namespace XT
-- 
GitLab