AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
FunctorGridFunction.hpp
1 #pragma once
2 
3 #include <tuple>
4 #include <type_traits>
5 
6 #include <dune/common/std/apply.hh>
7 
8 #include <amdis/Operations.hpp>
9 #include <amdis/common/ForEach.hpp>
10 #include <amdis/common/Logical.hpp>
11 #include <amdis/common/Order.hpp>
12 #include <amdis/gridfunctions/Derivative.hpp>
13 #include <amdis/gridfunctions/GridFunction.hpp>
14 
15 namespace AMDiS
16 {
17  namespace Impl
18  {
19  template <class T0, class... Ts>
20  struct DomainType
21  {
22  using type = typename T0::Domain;
23  };
24 
25  template <class T0, class... Ts>
26  struct EntitySetType
27  {
28  using type = typename T0::EntitySet;
29  };
30 
31  } // end namespace Impl
32 
33 
34 #ifndef DOXYGEN
35  template <class Signatur, class Functor, class... LocalFunctions>
37 #endif
38 
39  // implementation
40  template <class R, class D, class Functor, class... LocalFunctions>
41  class FunctorLocalFunction<R(D), Functor, LocalFunctions...>
42  {
43  public:
44  using Range = R;
45  using Domain = D;
46 
47  enum { hasDerivative = true };
48 
49  template <class LocalFct>
50  struct LocalFunctionWrapper
51  {
52  template <class GridFct>
53  LocalFunctionWrapper(GridFct const& gridFct)
54  : localFct_{localFunction(gridFct)}
55  {}
56 
57  LocalFct const& operator*() const { return localFct_; }
58  LocalFct & operator*() { return localFct_; }
59 
60  LocalFct localFct_;
61  };
62 
63  public:
65  template <class... GridFcts>
66  FunctorLocalFunction(Functor const& fct, GridFcts&&... gridFcts)
67  : fct_{fct}
68  , localFcts_{FWD(gridFcts)...}
69  {}
70 
72  template <class Element>
73  void bind(Element const& element)
74  {
75  Tools::for_each(localFcts_, [&](auto& localFct) {
76  (*localFct).bind(element);
77  });
78  }
79 
81  void unbind()
82  {
83  Tools::for_each(localFcts_, [&](auto& localFct) {
84  (*localFct).unbind();
85  });
86  }
87 
89  Range operator()(Domain const& x) const
90  {
91  return Tools::apply([&](auto&&... localFct) { return fct_((*localFct)(x)...); }, localFcts_);
92  }
93 
94  public:
96  Functor const& fct() const
97  {
98  return fct_;
99  }
100 
101  auto const& localFcts() const
102  {
103  return localFcts_;
104  }
105 
106  private:
107  Functor fct_;
108  std::tuple<LocalFunctionWrapper<LocalFunctions>...> localFcts_;
109  };
110 
111 
115 
121  template <class Sig, class F, class... LFs, class Type,
122  REQUIRES(Concepts::HasPartial<F>)>
123  auto derivativeOf(FunctorLocalFunction<Sig,F,LFs...> const& lf, Type const& type)
124  {
125  auto index_seq = std::index_sequence_for<LFs...>{};
126 
127  // d_i(f)[lgfs...] * lgfs_i
128  auto term_i = [&](auto const _i)
129  {
130  auto di_f = Tools::apply([&](auto const&... lgfs) {
131  return makeFunctorGridFunction(partial(lf.fct(), _i), (*lgfs)...);
132  }, lf.localFcts());
133 
134  using std::get;
135  auto const& lgfs_i = *get<VALUE(_i)>(lf.localFcts());
136  return makeFunctorGridFunction(Operation::Multiplies{}, di_f, derivativeOf(lgfs_i, type));
137  };
138 
139  // sum_i [ d_i(f)[lgfs...] * derivativeOf(lgfs_i)
140  auto gridFct = Tools::apply([&](auto const... _i)
141  {
142  return makeFunctorGridFunction(Operation::Plus{}, term_i(_i)...);
143  }, index_seq);
144 
145  return localFunction(gridFct);
146  }
147 
148 
152 
157  template <class Sig, class F, class... LFs,
158  REQUIRES(Concepts::HasFunctorOrder<F,sizeof...(LFs)>
159  && (Concepts::Polynomial<LFs> &&...))>
161  {
162  return Tools::apply([&lf](auto const&... lgfs) {
163  return order(lf.fct(), order(*lgfs)...);
164  }, lf.localFcts());
165  }
166 
167 
170 
184  template <class Functor, class... GridFunctions>
186  {
187  public:
189  using Range = decltype(std::declval<Functor>()(std::declval<typename GridFunctions::Range>()...));
190 
192  using Domain = typename Impl::DomainType<GridFunctions...>::type;
193 
195  using EntitySet = typename Impl::EntitySetType<GridFunctions...>::type;
196 
197  enum { hasDerivative = false };
198 
199  private:
200  template <class GridFct>
201  using LocalFct = TYPEOF( localFunction(std::declval<GridFct>()) );
202 
203  using RawRange = remove_cvref_t<Range>;
204  using LocalDomain = typename EntitySet::LocalCoordinate;
205 
206  public:
208 
210  template <class... GridFcts>
211  explicit FunctorGridFunction(Functor const& fct, GridFcts&&... gridFcts)
212  : fct_{fct}
213  , gridFcts_{FWD(gridFcts)...}
214  {}
215 
217  Range operator()(Domain const& x) const
218  {
219  return Tools::apply([&](auto&&... gridFct) { return fct_(gridFct(x)...); }, gridFcts_);
220  }
221 
223  EntitySet const& entitySet() const
224  {
225  return std::get<0>(gridFcts_).entitySet();
226  }
227 
228  LocalFunction makeLocalFunction() const
229  {
230  return Tools::apply([&](auto const&... gridFcts) { return LocalFunction{fct_, gridFcts...}; }, gridFcts_);
231  }
232 
233  private:
234  Functor fct_;
235  std::tuple<GridFunctions...> gridFcts_;
236  };
237 
238 
239  // Generator function for FunctorGridFunction expressions
240  template <class Functor, class... GridFcts>
241  auto makeFunctorGridFunction(Functor const& f, GridFcts const&... gridFcts)
242  {
243  static_assert((Concepts::GridFunction<GridFcts> &&...),
244  "All passed parameters must be GridFunctions.");
245  static_assert(Concepts::Callable<Functor, typename GridFcts::Range...>,
246  "Range types of grid functions are not compatible with the functor.");
247  return FunctorGridFunction<Functor, GridFcts...>{f, gridFcts...};
248  }
249 
250 
251 #ifndef DOXYGEN
252  // PreGridFunction related to FunctorGridFunction.
253  template <class Functor, class... PreGridFunctions>
255  {
257 
258  struct Creator
259  {
260  template <class GridView>
261  static auto create(Self const& self, GridView const& gridView)
262  {
263  return Tools::apply([&](auto const&... pgf) {
264  return makeFunctorGridFunction(self.fct_,
265  makeGridFunction(pgf, gridView)...);
266  }, self.preGridFcts_);
267  }
268  };
269 
270  template <class... PreGridFcts>
271  explicit FunctorPreGridFunction(Functor const& fct, PreGridFcts&&... pgfs)
272  : fct_{fct}
273  , preGridFcts_{FWD(pgfs)...}
274  {}
275 
276  private:
277  Functor fct_;
278  std::tuple<PreGridFunctions...> preGridFcts_;
279  };
280 
281  namespace Traits
282  {
283  template <class Functor, class... PreGridFcts>
284  struct IsPreGridFunction<FunctorPreGridFunction<Functor, PreGridFcts...>>
285  : std::true_type {};
286  }
287 #endif
288 
289 
292 
302  template <class Functor, class... PreGridFcts>
303  auto invokeAtQP(Functor const& f, PreGridFcts&&... gridFcts)
304  {
305  return FunctorPreGridFunction<Functor, TYPEOF(gridFcts)...>{f, FWD(gridFcts)...};
306  }
307 
308 } // end namespace AMDiS
FunctorLocalFunction(Functor const &fct, GridFcts &&... gridFcts)
Constructor. Stores copies of the functor and localFunction(gridfunction)s.
Definition: FunctorGridFunction.hpp:66
Definition: GridFunction.hpp:26
constexpr bool Functor
A Functor is a function F with signature Signature.
Definition: Concepts.hpp:134
Definition: FunctorGridFunction.hpp:36
auto invokeAtQP(Functor const &f, PreGridFcts &&... gridFcts)
Generator function for FunctorGridFunction.
Definition: FunctorGridFunction.hpp:303
Definition: FunctorGridFunction.hpp:254
typename Impl::DomainType< GridFunctions... >::type Domain
The argument type that can be applied to the grid-functions.
Definition: FunctorGridFunction.hpp:192
typename remove_cvref< T >::type remove_cvref_t
Helper alias template for remove_cvref.
Definition: TypeTraits.hpp:24
decltype(auto) makeGridFunction(PreGridFct const &preGridFct, GridView const &gridView)
Generator for Gridfunctions from Expressions (PreGridfunctions)
Definition: GridFunction.hpp:154
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
Functor const & fct() const
Return the stored functor.
Definition: FunctorGridFunction.hpp:96
Functor that represents A*B.
Definition: Arithmetic.hpp:100
Functor that represents A+B.
Definition: Arithmetic.hpp:19
auto order(F const &f) -> decltype(&F::operator(), f.order())
polynomial order of functions
Definition: Order.hpp:11
void unbind()
Calls unbind for all localFunctions.
Definition: FunctorGridFunction.hpp:81
A Gridfunction that applies a functor to the evaluated Gridfunctions.
Definition: FunctorGridFunction.hpp:185
auto derivativeOf(AnalyticLocalFunction< R(D), LC, F > const &lf, Type const &type)
Definition: AnalyticGridFunction.hpp:103
void bind(Element const &element)
Calls bind for all localFunctions.
Definition: FunctorGridFunction.hpp:73
FunctorGridFunction(Functor const &fct, GridFcts &&... gridFcts)
Constructor. Stores copies of the functor and gridfunctions.
Definition: FunctorGridFunction.hpp:211
Range operator()(Domain const &x) const
Applies the functor to the evaluated gridfunctions.
Definition: FunctorGridFunction.hpp:217
typename Impl::EntitySetType< GridFunctions... >::type EntitySet
The set of entities this grid-function binds to.
Definition: FunctorGridFunction.hpp:195
Range operator()(Domain const &x) const
Applies the functor fct_ to the evaluated localFunctions.
Definition: FunctorGridFunction.hpp:89
EntitySet const & entitySet() const
Return the stored EntitySet of the first GridFunction.
Definition: FunctorGridFunction.hpp:223
Definition: FunctorGridFunction.hpp:258
decltype(std::declval< Functor >()(std::declval< typename GridFunctions::Range >()...)) Range
The result type of the functor when applied to the grid-functions.
Definition: FunctorGridFunction.hpp:189