AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
ComposerGridFunction.hpp
1 #pragma once
2 
3 #include <tuple>
4 #include <type_traits>
5 
6 #include <amdis/Operations.hpp>
7 #include <amdis/common/ForEach.hpp>
8 #include <amdis/common/Logical.hpp>
9 #include <amdis/common/Order.hpp>
10 #include <amdis/common/TypeTraits.hpp>
11 #include <amdis/gridfunctions/Derivative.hpp>
12 #include <amdis/gridfunctions/GridFunction.hpp>
13 
14 namespace AMDiS
15 {
16 #ifndef DOXYGEN
17  template <class Signatur, class Element, class Functor, class... LocalFunctions>
19 #endif
20 
21  // implementation
22  template <class R, class D, class E, class Functor, class... LocalFunctions>
23  class ComposerLocalFunction<R(D), E, Functor, LocalFunctions...>
24  {
25  public:
26  using Range = R;
27  using Domain = D;
28  using Element = E;
29 
30  enum { hasDerivative = true };
31 
32  public:
34  template <class... LocalFcts>
35  ComposerLocalFunction(Functor const& fct, LocalFcts&&... localFcts)
36  : fct_{fct}
37  , localFcts_{FWD(localFcts)...}
38  {}
39 
41  void bind(Element const& element)
42  {
43  std::apply([&](auto &...lf) { (lf.bind(element), ...); }, localFcts_);
44  }
45 
47  void unbind()
48  {
49  std::apply([](auto&... lf) { (lf.unbind(),...); },
50  localFcts_);
51  }
52 
54  bool bound() const
55  {
56  return std::get<0>(localFcts_).bound();
57  }
58 
60  Range operator()(Domain const& x) const
61  {
62  return std::apply([&](auto const&... lf) { return fct_(lf(x)...); },
63  localFcts_);
64  }
65 
67  Element const& localContext() const
68  {
69  return std::get<0>(localFcts_).localContext();
70  }
71 
72 
73  public:
75  Functor const& fct() const
76  {
77  return fct_;
78  }
79 
80  auto const& localFunctions() const
81  {
82  return localFcts_;
83  }
84 
85  private:
86  Functor fct_;
87  std::tuple<LocalFunctions...> localFcts_;
88  };
89 
90  template <class Element, class Functor, class... LocalFunctions>
91  auto makeComposerLocalFunction(Functor const& f, LocalFunctions const&... lf)
92  {
93  using D = typename Element::Geometry::LocalCoordinate;
94  using R = TYPEOF(f(lf(std::declval<D>())...));
95  return ComposerLocalFunction<R(D), Element, Functor, LocalFunctions...>{f, lf...};
96  }
97 
98 
99 
103 
109  template <class Sig, class E, class F, class... LFs, class Type,
110  REQUIRES(Concepts::HasPartial<F>)>
111  auto derivativeOf(ComposerLocalFunction<Sig,E,F,LFs...> const& composed, Type const& type)
112  {
113  // d_i(f)[lgfs...] * lgfs_i
114  auto term_i = [&](auto ii)
115  {
116  auto di_f = std::apply([&](auto const&... lf) {
117  return makeComposerLocalFunction<E>(partial(composed.fct(), ii), lf...);
118  }, composed.localFunctions());
119 
120  auto const& lf_i = std::get<ii>(composed.localFunctions());
121  auto df
122  = makeComposerLocalFunction<E>(Operation::Multiplies{}, di_f, derivativeOf(lf_i, type));
123  if (composed.bound())
124  df.bind(composed.localContext());
125  return df;
126  };
127 
128  // sum_i [ d_i(f)[lgfs...] * derivativeOf(lgfs_i)
129  auto localFct = Ranges::applyIndices<sizeof...(LFs)>([&](auto... ii)
130  {
131  return makeComposerLocalFunction<E>(Operation::Plus{}, term_i(ii)...);
132  });
133 
134  return localFct;
135  }
136 
137 
141 
146  template <class Sig, class E, class F, class... LFs,
147  REQUIRES(Concepts::HasFunctorOrder<F,sizeof...(LFs)>
148  && (Concepts::Polynomial<LFs> &&...))>
149  int order(ComposerLocalFunction<Sig,E,F,LFs...> const& composed)
150  {
151  return Ranges::apply([&](auto const&... lf) {
152  return order(composed.fct(), order(lf)...);
153  }, composed.localFunctions());
154  }
155 
156 
159 
175  template <class Sig, class EntitySet, class Functor, class... GridFunctions>
177 
178  template <class R, class D, class ES, class Functor, class... GridFunctions>
179  class ComposerGridFunction<R(D), ES, Functor, GridFunctions...>
180  {
181  public:
182  using Range = R;
183  using Domain = D;
184  using EntitySet = ES;
185 
186  enum { hasDerivative = false };
187 
188  private:
189  template <class GridFct>
190  using LocalFct = TYPEOF( localFunction(underlying(std::declval<GridFct const&>())) );
191 
192  using LocalDomain = typename EntitySet::LocalCoordinate;
193  using Element = typename EntitySet::Element;
194 
195  public:
196  using LocalFunction
198 
200  template <class... GridFcts>
201  ComposerGridFunction(EntitySet const& entitySet, Functor const& fct, GridFcts&&... gridFcts)
202  : entitySet_{entitySet}
203  , fct_{fct}
204  , gridFcts_{FWD(gridFcts)...}
205  {}
206 
208  Range operator()(Domain const& x) const
209  {
210  return std::apply([&](auto const&... gf) { return fct_(underlying(gf)(x)...); },
211  gridFcts_);
212  }
213 
215  EntitySet const& entitySet() const
216  {
217  return entitySet_;
218  }
219 
222  {
223  return std::apply([&](auto const&... gf) { return LocalFunction{fct_, localFunction(underlying(gf))...}; },
224  gridFcts_);
225  }
226 
227  private:
228  EntitySet entitySet_;
229  Functor fct_;
230  std::tuple<GridFunctions...> gridFcts_;
231  };
232 
233 
234  // Generator function for ComposerGridFunction expressions
235  template <class Functor, class GridView, class... GridFcts>
236  auto makeComposerGridFunction(Functor const& f, GridView const& gridView,
237  GridFcts const&... gridFcts)
238  {
239  static_assert((Concepts::GridFunction<GridFcts> && ...),
240  "All passed parameters must be GridFunctions.");
241  static_assert(Concepts::Callable<Functor, typename GridFcts::Range...>,
242  "Range types of grid functions are not compatible with the functor.");
243 
244  using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;
245  using Domain = typename EntitySet::GlobalCoordinate;
246  using Range = TYPEOF(f(underlying(gridFcts)(std::declval<Domain>())...));
247 
248  using FGF = ComposerGridFunction<Range(Domain), EntitySet, Functor, GridFcts...>;
249  return FGF{EntitySet{gridView},f, gridFcts...};
250  }
251 
252 
253 #ifndef DOXYGEN
254  // PreGridFunction related to ComposerGridFunction.
255  template <class Functor, class... PreGridFunctions>
257  {
259 
260  struct Creator
261  {
262  template <class GridView>
263  static auto create(Self const& self, GridView const& gridView)
264  {
265  return std::apply([&](auto const&... pgf) {
266  return makeComposerGridFunction(self.fct_, gridView,
267  makeGridFunction(pgf, gridView)...);
268  }, self.preGridFcts_);
269  }
270  };
271 
272  template <class... PreGridFcts>
273  explicit ComposerPreGridFunction(Functor const& fct, PreGridFcts&&... pgfs)
274  : fct_{fct}
275  , preGridFcts_{FWD(pgfs)...}
276  {}
277 
278  private:
279  Functor fct_;
280  std::tuple<PreGridFunctions...> preGridFcts_;
281  };
282 
283  namespace Traits
284  {
285  template <class Functor, class... PreGridFcts>
286  struct IsPreGridFunction<ComposerPreGridFunction<Functor, PreGridFcts...>>
287  : std::true_type {};
288  }
289 #endif
290 
291 
294 
304  template <class Functor, class... PreGridFcts>
305  auto invokeAtQP(Functor const& f, PreGridFcts&&... gridFcts)
306  {
307  return ComposerPreGridFunction<Functor, TYPEOF(gridFcts)...>{f, FWD(gridFcts)...};
308  }
309 
310 } // end namespace AMDiS
A Gridfunction that applies a functor to the evaluated Gridfunctions.
Definition: ComposerGridFunction.hpp:176
Definition: GridFunction.hpp:26
Functor const & fct() const
Return the stored functor.
Definition: ComposerGridFunction.hpp:75
constexpr bool Functor
A Functor is a function F with signature Signature.
Definition: Concepts.hpp:133
auto invokeAtQP(Functor const &f, PreGridFcts &&... gridFcts)
Generator function for ComposerGridFunction.
Definition: ComposerGridFunction.hpp:305
Range operator()(Domain const &x) const
Applies the functor to the evaluated gridfunctions.
Definition: ComposerGridFunction.hpp:208
bool bound() const
Check whether the LocalFunction is bound to an element.
Definition: ComposerGridFunction.hpp:54
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:41
Functor that represents A*B.
Definition: Arithmetic.hpp:100
Functor that represents A+B.
Definition: Arithmetic.hpp:19
Definition: ComposerGridFunction.hpp:260
ComposerGridFunction(EntitySet const &entitySet, Functor const &fct, GridFcts &&... gridFcts)
Constructor. Stores copies of the functor and gridfunctions.
Definition: ComposerGridFunction.hpp:201
Definition: ComposerGridFunction.hpp:256
LocalFunction makeLocalFunction() const
Create the localFunction by composition of the inner localFunctions.
Definition: ComposerGridFunction.hpp:221
Element const & localContext() const
Get the element this localfunction (and all inner localfunctions) are bound to.
Definition: ComposerGridFunction.hpp:67
EntitySet const & entitySet() const
Return the stored EntitySet of the first GridFunction.
Definition: ComposerGridFunction.hpp:215
Definition: ComposerGridFunction.hpp:18
ComposerLocalFunction(Functor const &fct, LocalFcts &&... localFcts)
Constructor. Stores copies of the functor and localFunction(gridfunction)s.
Definition: ComposerGridFunction.hpp:35
void unbind()
Calls unbind for all localFunctions.
Definition: ComposerGridFunction.hpp:47
Range operator()(Domain const &x) const
Applies the functor fct_ to the evaluated localFunctions.
Definition: ComposerGridFunction.hpp:60