From 5a169a85c68ae6bfb6e78316fa7916936b711a01 Mon Sep 17 00:00:00 2001
From: "Praetorius, Simon" <simon.praetorius@tu-dresden.de>
Date: Thu, 22 Aug 2019 08:46:09 +0200
Subject: [PATCH] added helper utility to wrap Dune::FunctionFromCallable
 constructors

---
 src/amdis/DataTransfer.inc.hpp               | 13 ++++----
 src/amdis/PeriodicBC.inc.hpp                 |  5 ++--
 src/amdis/functions/CMakeLists.txt           |  1 +
 src/amdis/functions/FunctionFromCallable.hpp | 31 ++++++++++++++++++++
 4 files changed, 39 insertions(+), 11 deletions(-)
 create mode 100644 src/amdis/functions/FunctionFromCallable.hpp

diff --git a/src/amdis/DataTransfer.inc.hpp b/src/amdis/DataTransfer.inc.hpp
index c5a8a177..537f1ee7 100644
--- a/src/amdis/DataTransfer.inc.hpp
+++ b/src/amdis/DataTransfer.inc.hpp
@@ -17,10 +17,9 @@
 #include <dune/grid/common/geometry.hh>
 #include <dune/grid/common/rangegenerators.hh>
 
-#include <dune/functions/common/functionfromcallable.hh>
-
 #include <amdis/Output.hpp>
 #include <amdis/common/ConcurrentCache.hpp>
+#include <amdis/functions/FunctionFromCallable.hpp>
 #include <amdis/typetree/Traversal.hpp>
 
 namespace AMDiS {
@@ -373,9 +372,8 @@ bool NodeDataTransfer<N,C,B>::
     return fatherDOFsTemp_[currentDOF++];
   };
 
-  using FFC
-    = Dune::Functions::FunctionFromCallable<LIRangeType(LIDomainType), decltype(evalLeaf)>;
-  fatherFE.localInterpolation().interpolate(FFC(evalLeaf), fatherDOFs);
+  auto evalLeafFct = functionFromCallable<LIRangeType(LIDomainType)>(evalLeaf);
+  fatherFE.localInterpolation().interpolate(evalLeafFct, fatherDOFs);
 
   // Return true if all father DOFs have been evaluated
   return std::accumulate(finishedDOFs_.begin(), finishedDOFs_.end(), true,
@@ -413,9 +411,8 @@ void NodeDataTransfer<N,C,B>::
 
   auto const& childFE = childNode.finiteElement();
   thread_local std::vector<T> childDOFs;
-  using FFC = Dune::Functions
-    ::FunctionFromCallable<LIRangeType(LIDomainType), decltype(evalFather)>;
-  childFE.localInterpolation().interpolate(FFC(evalFather), childDOFs);
+  auto evalFatherFct = functionFromCallable<LIRangeType(LIDomainType)>(evalFather);
+  childFE.localInterpolation().interpolate(evalFatherFct, childDOFs);
 
   for (std::size_t i = 0; i < childDOFs.size(); ++i)
     (*coeff_)[lv_->index(childNode.localIndex(i))] = childDOFs[i];
diff --git a/src/amdis/PeriodicBC.inc.hpp b/src/amdis/PeriodicBC.inc.hpp
index b8901f9f..e60a5e85 100644
--- a/src/amdis/PeriodicBC.inc.hpp
+++ b/src/amdis/PeriodicBC.inc.hpp
@@ -211,9 +211,8 @@ coords(Node const& tree, std::vector<std::size_t> const& localIndices) const
 
     std::array<std::vector<typename RangeType::field_type>, D::dimension> coeffs;
     for (int d = 0; d < D::dimension; ++d) {
-      auto evalCoord = [&](DomainType const& local) -> RangeType { return geometry.global(local)[d]; };
-      using FFC = Dune::Functions::FunctionFromCallable<RangeType(DomainType), decltype(evalCoord)>;
-      localInterpol.interpolate(FFC(evalCoord), coeffs[d]);
+      auto evalCoord = functionFromCallable<RangeType(DomainType)>([&](DomainType const& local) -> RangeType { return geometry.global(local)[d]; });
+      localInterpol.interpolate(evalCoord, coeffs[d]);
     }
 
     for (std::size_t j = 0; j < localIndices.size(); ++j) {
diff --git a/src/amdis/functions/CMakeLists.txt b/src/amdis/functions/CMakeLists.txt
index 3d89bca7..837a5f64 100644
--- a/src/amdis/functions/CMakeLists.txt
+++ b/src/amdis/functions/CMakeLists.txt
@@ -1,6 +1,7 @@
 #install headers
 
 install(FILES
+    FunctionFromCallable.hpp
     GlobalIdSet.hpp
     HierarchicNodeToRangeMap.hpp
     Interpolate.hpp
diff --git a/src/amdis/functions/FunctionFromCallable.hpp b/src/amdis/functions/FunctionFromCallable.hpp
new file mode 100644
index 00000000..e6fe5da3
--- /dev/null
+++ b/src/amdis/functions/FunctionFromCallable.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <dune/common/typeutilities.hh>
+#include <dune/functions/common/functionfromcallable.hh>
+
+namespace AMDiS
+{
+  namespace Impl
+  {
+    template <class Traits, class F,
+      class Range = typename Traits::RangeType,
+      class Domain = typename Traits::DomainType>
+    auto functionFromCallableImpl(F const& f, Dune::PriorityTag<2>)
+    {
+      return Dune::Functions::FunctionFromCallable<Range(Domain), F>(f);
+    }
+
+    template <class Signature, class F>
+    auto functionFromCallableImpl(F const& f, Dune::PriorityTag<1>)
+    {
+      return Dune::Functions::FunctionFromCallable<Signature, F>(f);
+    }
+  }
+
+  template <class SigTraits, class F>
+  auto functionFromCallable(F const& f)
+  {
+    return Impl::functionFromCallableImpl<SigTraits>(f, Dune::PriorityTag<10>{});
+  }
+
+} // end namespace AMDiS
-- 
GitLab