From 3670b93dc208b4efdf87add91099263d2ee6b32e Mon Sep 17 00:00:00 2001
From: Felix Schindler <felix.schindler@wwu.de>
Date: Sat, 14 Mar 2020 21:44:08 +0100
Subject: [PATCH] f func

---
 dune/gdt/functionals/l2.hh                    | 12 +--
 dune/gdt/functionals/vector-based.hh          | 21 ++++-
 .../local/assembler/functional-assemblers.hh  | 79 +++++++++++++++++++
 3 files changed, 102 insertions(+), 10 deletions(-)

diff --git a/dune/gdt/functionals/l2.hh b/dune/gdt/functionals/l2.hh
index f54c6cc23..c655a73b0 100644
--- a/dune/gdt/functionals/l2.hh
+++ b/dune/gdt/functionals/l2.hh
@@ -67,10 +67,8 @@ public:
                            const ElementFilterType& filter = ApplyOnAllElements())
     : BaseType(assembly_grid_view, source_spc, vec)
   {
-    this->append(LocalFunctionalType(local_binary_to_unary_element_integrand(inducing_function, LocalIntegrandType(1)),
-                                     over_integrate),
-                 param,
-                 filter);
+    this->append(
+        LocalFunctionalType(LocalIntegrandType(1).with_ansatz(inducing_function), over_integrate), param, filter);
   }
 
   L2VolumeVectorFunctional(AssemblyGridView assembly_grid_view,
@@ -81,10 +79,8 @@ public:
                            const ElementFilterType& filter = ApplyOnAllElements())
     : BaseType(assembly_grid_view, source_spc)
   {
-    this->append(LocalFunctionalType(local_binary_to_unary_element_integrand(inducing_function, LocalIntegrandType(1)),
-                                     over_integrate),
-                 param,
-                 filter);
+    this->append(
+        LocalFunctionalType(LocalIntegrandType(1).with_ansatz(inducing_function), over_integrate), param, filter);
   }
 }; // class L2VolumeVectorFunctional
 
diff --git a/dune/gdt/functionals/vector-based.hh b/dune/gdt/functionals/vector-based.hh
index e82925e9f..7c592ef56 100644
--- a/dune/gdt/functionals/vector-based.hh
+++ b/dune/gdt/functionals/vector-based.hh
@@ -160,10 +160,11 @@ public:
   using typename FunctionalBaseType::SourceVectorType;
 
   using typename WalkerBaseType::ElementType;
+  using typename WalkerBaseType::IntersectionType;
   using ElementFilterType = XT::Grid::ElementFilter<AssemblyGridViewType>;
   using IntersectionFilterType = XT::Grid::IntersectionFilter<AssemblyGridViewType>;
   using ApplyOnAllElements = XT::Grid::ApplyOn::AllElements<AssemblyGridViewType>;
-  using ApplyOnAllIntersection = XT::Grid::ApplyOn::AllIntersections<AssemblyGridViewType>;
+  using ApplyOnAllIntersections = XT::Grid::ApplyOn::AllIntersections<AssemblyGridViewType>;
 
   /**
    * \name Ctors which accept an existing vector into which to assemble.
@@ -232,7 +233,23 @@ public:
         local_functional, param, XT::Grid::ApplyOn::GenericFilteredElements<AssemblyGridViewType>(filter_lambda));
   }
 
-  // similar append for LocalIntersectionFunctionalInterface ...
+  ThisType& append(const LocalIntersectionFunctionalInterface<IntersectionType, r, rC, F, DofFieldType>& local_functional,
+                   const XT::Common::Parameter& param = {},
+                   const IntersectionFilterType& filter = ApplyOnAllIntersections())
+  {
+    LocalIntersectionFunctionalAssembler<V, AssemblyGridViewType, r, rC, F, GV> tmp(
+        this->source_space(), local_functional, VectorStorage::access(), param);
+    this->append(tmp, filter);
+    return *this;
+  }
+
+  ThisType& append(const LocalIntersectionFunctionalInterface<IntersectionType, r, rC, F, DofFieldType>& local_functional,
+                   const XT::Common::Parameter& param,
+                   std::function<bool(const AssemblyGridViewType&, const IntersectionType&)> filter_lambda)
+  {
+    return append(
+        local_functional, param, XT::Grid::ApplyOn::GenericFilteredIntersections<AssemblyGridViewType>(filter_lambda));
+  }
 
   void assemble(const bool use_tbb = false) override final
   {
diff --git a/dune/gdt/local/assembler/functional-assemblers.hh b/dune/gdt/local/assembler/functional-assemblers.hh
index 56eadff3b..16ad8d44f 100644
--- a/dune/gdt/local/assembler/functional-assemblers.hh
+++ b/dune/gdt/local/assembler/functional-assemblers.hh
@@ -96,6 +96,85 @@ private:
 }; // class LocalElementFunctionalAssembler
 
 
+template <class Vector, class GridView, size_t r, size_t rC, class R = double, class SpaceGridView = GridView>
+class LocalIntersectionFunctionalAssembler : public XT::Grid::IntersectionFunctor<GridView>
+{
+  static_assert(XT::LA::is_vector<Vector>::value, "");
+  static_assert(XT::Grid::is_view<GridView>::value, "");
+  static_assert(XT::Grid::is_view<SpaceGridView>::value, "");
+
+  using ThisType = LocalIntersectionFunctionalAssembler<Vector, GridView, r, rC, R, SpaceGridView>;
+  using BaseType = XT::Grid::IntersectionFunctor<GridView>;
+
+public:
+  using typename BaseType::ElementType;
+  using typename BaseType::IntersectionType;
+  using VectorType = Vector;
+  using FieldType = typename VectorType::ScalarType;
+  using SpaceType = SpaceInterface<SpaceGridView, r, rC, R>;
+  using LocalFunctionalType = LocalIntersectionFunctionalInterface<IntersectionType, r, rC, R, FieldType>;
+
+  LocalIntersectionFunctionalAssembler(const SpaceType& space,
+                                       const LocalFunctionalType& local_functional,
+                                       VectorType& global_vector,
+                                       const XT::Common::Parameter& param = {})
+    : space_(space)
+    , local_functional_(local_functional.copy())
+    , global_vector_(global_vector)
+    , param_(param)
+    , local_vector_(space_.mapper().max_local_size())
+    , global_indices_(space_.mapper().max_local_size())
+    , basis_(space_.basis().localize())
+  {
+    DUNE_THROW_IF(global_vector_.size() != space_.mapper().size(),
+                  XT::Common::Exceptions::shapes_do_not_match,
+                  "global_vector.size() = " << global_vector_.size() << "\n  "
+                                            << "space.mapper().size()" << space_.mapper().size());
+  }
+
+  LocalIntersectionFunctionalAssembler(const ThisType& other)
+    : BaseType()
+    , space_(other.space_)
+    , local_functional_(other.local_functional_->copy())
+    , global_vector_(other.global_vector_)
+    , param_(other.param_)
+    , local_vector_(other.local_vector_)
+    , global_indices_(other.global_indices_)
+    , basis_(space_.basis().localize())
+  {}
+
+  LocalIntersectionFunctionalAssembler(ThisType&& source) = default;
+
+  BaseType* copy() override final
+  {
+    return new ThisType(*this);
+  }
+
+  void apply_local(const IntersectionType& intersection,
+                   const ElementType& inside_element,
+                   const ElementType& outside_element) override final
+  {
+    const auto& element = local_functional_->inside() ? inside_element : outside_element;
+    // apply functional
+    basis_->bind(element);
+    local_functional_->apply(intersection, *basis_, local_vector_, param_);
+    // copy local vector to global
+    space_.mapper().global_indices(element, global_indices_);
+    for (size_t jj = 0; jj < basis_->size(param_); ++jj)
+      global_vector_.add_to_entry(global_indices_[jj], local_vector_[jj]);
+  }
+
+private:
+  const SpaceType& space_;
+  std::unique_ptr<LocalFunctionalType> local_functional_;
+  VectorType& global_vector_;
+  XT::Common::Parameter param_;
+  DynamicVector<FieldType> local_vector_;
+  DynamicVector<size_t> global_indices_;
+  mutable std::unique_ptr<typename SpaceType::GlobalBasisType::LocalizedType> basis_;
+}; // class LocalIntersectionFunctionalAssembler
+
+
 } // namespace GDT
 } // namespace Dune
 
-- 
GitLab