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
14namespace 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
197 = ComposerLocalFunction<Range(LocalDomain), Element, Functor, LocalFct<GridFunctions>...>;
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>
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
LocalFunction makeLocalFunction() const
Create the localFunction by composition of the inner localFunctions.
Definition: ComposerGridFunction.hpp:221
Range operator()(Domain const &x) const
Applies the functor to the evaluated gridfunctions.
Definition: ComposerGridFunction.hpp:208
EntitySet const & entitySet() const
Return the stored EntitySet of the first GridFunction.
Definition: ComposerGridFunction.hpp:215
ComposerGridFunction(EntitySet const &entitySet, Functor const &fct, GridFcts &&... gridFcts)
Constructor. Stores copies of the functor and gridfunctions.
Definition: ComposerGridFunction.hpp:201
A Gridfunction that applies a functor to the evaluated Gridfunctions.
Definition: ComposerGridFunction.hpp:176
bool bound() const
Check whether the LocalFunction is bound to an element.
Definition: ComposerGridFunction.hpp:54
Range operator()(Domain const &x) const
Applies the functor fct_ to the evaluated localFunctions.
Definition: ComposerGridFunction.hpp:60
ComposerLocalFunction(Functor const &fct, LocalFcts &&... localFcts)
Constructor. Stores copies of the functor and localFunction(gridfunction)s.
Definition: ComposerGridFunction.hpp:35
Functor const & fct() const
Return the stored functor.
Definition: ComposerGridFunction.hpp:75
void bind(Element const &element)
Calls bind for all localFunctions.
Definition: ComposerGridFunction.hpp:41
Element const & localContext() const
Get the element this localfunction (and all inner localfunctions) are bound to.
Definition: ComposerGridFunction.hpp:67
void unbind()
Calls unbind for all localFunctions.
Definition: ComposerGridFunction.hpp:47
Definition: ComposerGridFunction.hpp:18
constexpr bool Functor
A Functor is a function F with signature Signature.
Definition: Concepts.hpp:133
constexpr bool Callable
A Collable is a function F that can be called with arguments of type Args....
Definition: Concepts.hpp:120
auto invokeAtQP(Functor const &f, PreGridFcts &&... gridFcts)
Generator function for ComposerGridFunction.
Definition: ComposerGridFunction.hpp:305
decltype(auto) makeGridFunction(PreGridFct const &preGridFct, GridView const &gridView)
Generator for Gridfunctions from Expressions (PreGridfunctions)
Definition: GridFunction.hpp:168
Definition: ComposerGridFunction.hpp:261
Definition: ComposerGridFunction.hpp:257
Definition: GridFunction.hpp:27