AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
ComposerGridFunction.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/common/TypeTraits.hpp>
13 #include <amdis/gridfunctions/Derivative.hpp>
14 #include <amdis/gridfunctions/GridFunction.hpp>
15 
16 namespace AMDiS
17 {
18 #ifndef DOXYGEN
19  template <class Signatur, class Element, class Functor, class... LocalFunctions>
21 #endif
22 
23  // implementation
24  template <class R, class D, class E, class Functor, class... LocalFunctions>
25  class ComposerLocalFunction<R(D), E, Functor, LocalFunctions...>
26  {
27  public:
28  using Range = R;
29  using Domain = D;
30  using Element = E;
31 
32  enum { hasDerivative = true };
33 
34  public:
36  template <class... LocalFcts>
37  ComposerLocalFunction(Functor const& fct, LocalFcts&&... localFcts)
38  : fct_{fct}
39  , localFcts_{FWD(localFcts)...}
40  {}
41 
43  void bind(Element const& element)
44  {
45  std::apply([&](auto&... lf) { (lf.bind(element),...); },
46  localFcts_);
47  }
48 
50  void unbind()
51  {
52  std::apply([](auto&... lf) { (lf.unbind(),...); },
53  localFcts_);
54  }
55 
57  Range operator()(Domain const& x) const
58  {
59  return std::apply([&](auto const&... lf) { return fct_(lf(x)...); },
60  localFcts_);
61  }
62 
64  Element const& localContext() const
65  {
66  return std::get<0>(localFcts_).localContext();
67  }
68 
69 
70  public:
72  Functor const& fct() const
73  {
74  return fct_;
75  }
76 
77  auto const& localFunctions() const
78  {
79  return localFcts_;
80  }
81 
82  private:
83  Functor fct_;
84  std::tuple<LocalFunctions...> localFcts_;
85  };
86 
87  template <class Element, class Functor, class... LocalFunctions>
88  auto makeComposerLocalFunction(Functor const& f, LocalFunctions const&... lf)
89  {
90  using D = typename Element::Geometry::LocalCoordinate;
91  using R = TYPEOF(f(lf(std::declval<D>())...));
92  return ComposerLocalFunction<R(D), Element, Functor, LocalFunctions...>{f, lf...};
93  }
94 
95 
96 
100 
106  template <class Sig, class E, class F, class... LFs, class Type,
107  REQUIRES(Concepts::HasPartial<F>)>
108  auto derivativeOf(ComposerLocalFunction<Sig,E,F,LFs...> const& composed, Type const& type)
109  {
110  // d_i(f)[lgfs...] * lgfs_i
111  auto term_i = [&](auto ii)
112  {
113  auto di_f = std::apply([&](auto const&... lf) {
114  return makeComposerLocalFunction<E>(partial(composed.fct(), ii), lf...);
115  }, composed.localFunctions());
116 
117  auto const& lf_i = std::get<ii>(composed.localFunctions());
118  return makeComposerLocalFunction<E>(Operation::Multiplies{}, di_f, derivativeOf(lf_i, type));
119  };
120 
121  // sum_i [ d_i(f)[lgfs...] * derivativeOf(lgfs_i)
122  auto localFct = Ranges::applyIndices<sizeof...(LFs)>([&](auto... ii)
123  {
124  return makeComposerLocalFunction<E>(Operation::Plus{}, term_i(ii)...);
125  });
126 
127  return localFct;
128  }
129 
130 
134 
139  template <class Sig, class E, class F, class... LFs,
140  REQUIRES(Concepts::HasFunctorOrder<F,sizeof...(LFs)>
141  && (Concepts::Polynomial<LFs> &&...))>
142  int order(ComposerLocalFunction<Sig,E,F,LFs...> const& composed)
143  {
144  return Ranges::apply([&](auto const&... lf) {
145  return order(composed.fct(), order(lf)...);
146  }, composed.localFunctions());
147  }
148 
149 
152 
168  template <class Sig, class EntitySet, class Functor, class... GridFunctions>
170 
171  template <class R, class D, class ES, class Functor, class... GridFunctions>
172  class ComposerGridFunction<R(D), ES, Functor, GridFunctions...>
173  {
174  public:
175  using Range = R;
176  using Domain = D;
177  using EntitySet = ES;
178 
179  enum { hasDerivative = false };
180 
181  private:
182  template <class GridFct>
183  using LocalFct = TYPEOF( localFunction(underlying(std::declval<GridFct const&>())) );
184 
185  using LocalDomain = typename EntitySet::LocalCoordinate;
186  using Element = typename EntitySet::Element;
187 
188  public:
189  using LocalFunction
191 
193  template <class... GridFcts>
194  ComposerGridFunction(EntitySet const& entitySet, Functor const& fct, GridFcts&&... gridFcts)
195  : entitySet_{entitySet}
196  , fct_{fct}
197  , gridFcts_{FWD(gridFcts)...}
198  {}
199 
201  Range operator()(Domain const& x) const
202  {
203  return std::apply([&](auto const&... gf) { return fct_(underlying(gf)(x)...); },
204  gridFcts_);
205  }
206 
208  EntitySet const& entitySet() const
209  {
210  return entitySet_;
211  }
212 
215  {
216  return std::apply([&](auto const&... gf) { return LocalFunction{fct_, localFunction(underlying(gf))...}; },
217  gridFcts_);
218  }
219 
220  private:
221  EntitySet entitySet_;
222  Functor fct_;
223  std::tuple<GridFunctions...> gridFcts_;
224  };
225 
226 
227  // Generator function for ComposerGridFunction expressions
228  template <class Functor, class GridView, class... GridFcts>
229  auto makeComposerGridFunction(Functor const& f, GridView const& gridView,
230  GridFcts const&... gridFcts)
231  {
232  static_assert((Concepts::GridFunction<GridFcts> && ...),
233  "All passed parameters must be GridFunctions.");
234  static_assert(Concepts::Callable<Functor, typename GridFcts::Range...>,
235  "Range types of grid functions are not compatible with the functor.");
236 
237  using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;
238  using Domain = typename EntitySet::GlobalCoordinate;
239  using Range = TYPEOF(f(underlying(gridFcts)(std::declval<Domain>())...));
240 
241  using FGF = ComposerGridFunction<Range(Domain), EntitySet, Functor, GridFcts...>;
242  return FGF{EntitySet{gridView},f, gridFcts...};
243  }
244 
245 
246 #ifndef DOXYGEN
247  // PreGridFunction related to ComposerGridFunction.
248  template <class Functor, class... PreGridFunctions>
250  {
252 
253  struct Creator
254  {
255  template <class GridView>
256  static auto create(Self const& self, GridView const& gridView)
257  {
258  return std::apply([&](auto const&... pgf) {
259  return makeComposerGridFunction(self.fct_, gridView,
260  makeGridFunction(pgf, gridView)...);
261  }, self.preGridFcts_);
262  }
263  };
264 
265  template <class... PreGridFcts>
266  explicit ComposerPreGridFunction(Functor const& fct, PreGridFcts&&... pgfs)
267  : fct_{fct}
268  , preGridFcts_{FWD(pgfs)...}
269  {}
270 
271  private:
272  Functor fct_;
273  std::tuple<PreGridFunctions...> preGridFcts_;
274  };
275 
276  namespace Traits
277  {
278  template <class Functor, class... PreGridFcts>
279  struct IsPreGridFunction<ComposerPreGridFunction<Functor, PreGridFcts...>>
280  : std::true_type {};
281  }
282 #endif
283 
284 
287 
297  template <class Functor, class... PreGridFcts>
298  auto invokeAtQP(Functor const& f, PreGridFcts&&... gridFcts)
299  {
300  return ComposerPreGridFunction<Functor, TYPEOF(gridFcts)...>{f, FWD(gridFcts)...};
301  }
302 
303 } // end namespace AMDiS
A Gridfunction that applies a functor to the evaluated Gridfunctions.
Definition: ComposerGridFunction.hpp:169
Definition: GridFunction.hpp:26
Functor const & fct() const
Return the stored functor.
Definition: ComposerGridFunction.hpp:72
constexpr bool Functor
A Functor is a function F with signature Signature.
Definition: Concepts.hpp:134
auto invokeAtQP(Functor const &f, PreGridFcts &&... gridFcts)
Generator function for ComposerGridFunction.
Definition: ComposerGridFunction.hpp:298
Range operator()(Domain const &x) const
Applies the functor to the evaluated gridfunctions.
Definition: ComposerGridFunction.hpp:201
decltype(auto) makeGridFunction(PreGridFct const &preGridFct, GridView const &gridView)
Generator for Gridfunctions from Expressions (PreGridfunctions)
Definition: GridFunction.hpp:168
Definition: AdaptBase.hpp:6
void bind(Element const &element)
Calls bind for all localFunctions.
Definition: ComposerGridFunction.hpp:43
Functor that represents A*B.
Definition: Arithmetic.hpp:100
Functor that represents A+B.
Definition: Arithmetic.hpp:19
Definition: ComposerGridFunction.hpp:253
ComposerGridFunction(EntitySet const &entitySet, Functor const &fct, GridFcts &&... gridFcts)
Constructor. Stores copies of the functor and gridfunctions.
Definition: ComposerGridFunction.hpp:194
Definition: ComposerGridFunction.hpp:249
LocalFunction makeLocalFunction() const
Create the localFunction by composition of the inner localFunctions.
Definition: ComposerGridFunction.hpp:214
Element const & localContext() const
Get the element this localfunction (and all inner localfunctions) are bound to.
Definition: ComposerGridFunction.hpp:64
EntitySet const & entitySet() const
Return the stored EntitySet of the first GridFunction.
Definition: ComposerGridFunction.hpp:208
Definition: ComposerGridFunction.hpp:20
ComposerLocalFunction(Functor const &fct, LocalFcts &&... localFcts)
Constructor. Stores copies of the functor and localFunction(gridfunction)s.
Definition: ComposerGridFunction.hpp:37
void unbind()
Calls unbind for all localFunctions.
Definition: ComposerGridFunction.hpp:50
Range operator()(Domain const &x) const
Applies the functor fct_ to the evaluated localFunctions.
Definition: ComposerGridFunction.hpp:57