Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
subroutines.h
Go to the documentation of this file.
1#pragma once
3#include "dg/backend/config.h"
4
5namespace dg{
11{
12 template<class T>
13 DG_DEVICE T operator()(T x)const{return x;}
14};
15
16
19
21struct equals
22{
23 template< class T1, class T2>
24DG_DEVICE void operator()( T1 x, T2& y) const
25 {
26 y = x;
27 }
28};
31{
32 template< class T1, class T2>
33DG_DEVICE void operator()( T1 x, T2& y) const
34 {
35 y += x;
36 }
37};
40{
41 template< class T1, class T2>
42DG_DEVICE void operator()( T1 x, T2& y) const
43 {
44 y -= x;
45 }
46};
49{
50 template< class T1, class T2>
51DG_DEVICE void operator()( T1 x, T2& y) const
52 {
53 y *= x;
54 }
55};
58{
59 template< class T1, class T2>
60DG_DEVICE void operator()( T1 x, T2& y) const
61 {
62 y /= x;
63 }
64};
66
69
70
72struct Sum
73{
75 template< class T1, class ...Ts>
76DG_DEVICE auto operator()( T1 x, Ts... rest) const
77 {
78 // unfortunately the fold expression ( x + ... + rest)
79 // does currently not guarantee the order of execution
80 // so we need to wait for DR 2611 to be implemented in g++ to use it
81 return sum( x, rest ...);
82 }
83 private:
84 template< class T1, class ...Ts>
85DG_DEVICE auto sum( T1 x, Ts... rest) const
86 {
87 return x + sum( rest...);
88 }
89
90 template<class T1>
91DG_DEVICE auto sum( T1 x1) const
92 {
93 return x1;
94 }
95};
96
97
99struct Product
100{
102 template< class T1, class ...Ts>
103DG_DEVICE auto operator()( T1 x, Ts... rest) const
104 {
105 // manual implement ( x * ... * rest) until DR 2611 is resolved
106 return prod(x, rest...);
107 }
108 private:
109 template< class T1, class ...Ts>
110DG_DEVICE auto prod( T1 x, Ts... rest) const
111 {
112 return x * prod( rest...);
113 }
114
115 template<class T1>
116DG_DEVICE auto prod( T1 x1) const
117 {
118 return x1;
119 }
120};
121
124{
126 template< class T1, class T2, class ...Ts>
127DG_DEVICE auto operator()( T1 a, T2 x, Ts... rest) const
128 {
129 return sum( a, x, rest...);
130 }
131 private:
132 template<class T1, class T2, class ...Ts>
133DG_DEVICE auto sum( T1 alpha, T2 x, Ts... rest) const
134 {
135 return DG_FMA( alpha, x, sum(rest...));
136 }
137
138 template< class T1, class T2>
139DG_DEVICE auto sum( T1 alpha, T2 x) const
140 {
141 return alpha*x;
142 }
143};
146{
148 template< class T0, class T1, class T2, class ...Ts>
149DG_DEVICE auto operator()( T0 a, T1 x1, T2 y1, Ts... rest) const
150 {
151 return sum( a, x1, y1, rest...);
152 }
153 private:
154 template<class T0, class T1, class T2, class ...Ts>
155DG_DEVICE auto sum( T0 alpha, T1 x, T2 y, Ts... rest) const
156 {
157 return DG_FMA( alpha*x, y, sum(rest...));
158 }
159
160 template<class T0, class T1, class T2>
161DG_DEVICE auto sum( T0 alpha, T1 x, T2 y) const
162 {
163 return (alpha*x)*y;
164 }
165};
166
168
171
174{
176 template< class T1, class ...Ts>
177DG_DEVICE void operator()( T1& y, T1& yt, T1 b, T1 bt, Ts... rest) const
178 {
179 y = b*y;
180 yt = bt*yt;
181 sum( y, yt, rest...);
182 }
183 private:
184 template< class T1, class ...Ts>
185DG_DEVICE void sum( T1& y_1, T1& yt_1, T1 b, T1 bt, T1 k, Ts... rest) const
186 {
187 y_1 = DG_FMA( b, k, y_1);
188 yt_1 = DG_FMA( bt, k, yt_1);
189 sum( y_1, yt_1, rest...);
190 }
191
192 template< class T1>
193DG_DEVICE void sum( T1& y_1, T1& yt_1, T1 b, T1 bt, T1 k) const
194 {
195 y_1 = DG_FMA( b, k, y_1);
196 yt_1 = DG_FMA( bt, k, yt_1);
197 }
198};
199
201
202//The only reason the following classes exist is that nvcc does not allow
203//device lambdas or local classes inside host functions
205
207template<class BinarySub, class Functor>
208struct Evaluate
209{
210 Evaluate( BinarySub sub, Functor g): m_f( sub), m_g( g) {}
211#ifdef __CUDACC__
212// cuda compiler spits out a lot of warnings if
213// e.g. dg::transform is used on host vectors with host function
214// hd_warning_disable is unfortunately undocumented, but let's try
215// If it ever causes trouble we can remove it again
216// it just suppresses compiler warnings:
217// https://stackoverflow.com/questions/55481202/how-to-disable-cuda-host-device-warning-for-just-one-function
218#pragma hd_warning_disable
219#endif
220 template< class T, class... Ts>
221DG_DEVICE void operator() ( T& y, Ts... xs){
222 m_f(m_g(xs...), y);
223 }
224 private:
225 BinarySub m_f;
226 Functor m_g;
227};
228
229
231template<class T>
232struct Scal
233{
234 Scal( T a): m_a(a){}
235 template<class T1>
237 void operator()( T1& y)const{
238 y *= m_a;
239 }
240 private:
241 T m_a;
242};
243
245template<class T>
246struct Plus
247{
248 Plus( T a): m_a(a){}
249 template<class T1>
251 void operator()( T1& y) const{
252 y += m_a;
253 }
254 private:
255 T m_a;
256};
257
260template<class T0, class T1>
261struct Axpby
262{
263 Axpby( T0 a, T1 b): m_a(a), m_b(b){}
264 template<class T2, class T3>
266 void operator()( T2 x, T3& y)const {
267 y *= m_b;
268 y = DG_FMA( m_a, x, y);
269 }
270 private:
271 T0 m_a;
272 T1 m_b;
273};
276template<class T0, class T1>
277struct AxyPby
278{
279 AxyPby( T0 a, T1 b): m_a(a), m_b(b){}
280 template<class T2, class T3>
282 void operator()( T2 x, T3& y)const {
283 y *= m_b;
284 y = DG_FMA( m_a*x, y, y);
285 }
286 private:
287 T0 m_a;
288 T1 m_b;
289};
290
292template<class T0, class T1, class T2>
293struct Axpbypgz
294{
295 Axpbypgz( T0 a, T1 b, T2 g): m_a(a), m_b(b), m_g(g){}
296 template<class T3, class T4, class T5>
298 void operator()( T3 x, T4 y, T5& z)const{
299 z *= m_g;
300 z = DG_FMA( m_a, x, z);
301 z = DG_FMA( m_b, y, z);
302 }
303 private:
304 T0 m_a;
305 T1 m_b;
306 T2 m_g;
307};
308
310template<class T0, class T1>
311struct PointwiseDot
312{
313 PointwiseDot( T0 a, T1 b): m_a(a), m_b(b) {}
314 template<class T3, class T4, class T5>
316DG_DEVICE void operator()( T3 x, T4 y, T5& z)const{
317 z *= m_b;
318 z = DG_FMA( m_a*x, y, z);
319 }
321 template<class T3, class T4, class T5, class T6>
323 void operator()( T3 x1, T4 x2, T5 x3, T6& y)const{
324 y *= m_b;
325 y = DG_FMA( m_a*x1, x2*x3, y);
326 }
327 private:
328 T0 m_a;
329 T1 m_b;
330};
332template<class T0, class T1, class T2>
333struct PointwiseDot2
334{
335 PointwiseDot2( T0 a, T1 b, T2 g): m_a(a), m_b(b), m_g(g) {}
337 template<class T3, class T4, class T5, class T6, class T7>
339 void operator()( T3 x1, T4 y1, T5 x2, T6 y2, T7& z)const{
340 z *= m_g;
341 z = DG_FMA( m_a*x1, y1, z);
342 z = DG_FMA( m_b*x2, y2, z);
343 }
344 private:
345 T0 m_a;
346 T1 m_b;
347 T2 m_g;
348};
349
351struct divides
352{
353 template< class T1, class T2>
354DG_DEVICE auto operator()( T1 x1, T2 x2) const
355 {
356 return x1/x2;
357 }
358};
359
361template<class T0, class T1>
362struct PointwiseDivide
363{
364 PointwiseDivide( T0 a, T1 b): m_a(a), m_b(b){}
366 template<class T3, class T4>
368 void operator()( T3 y, T4& z)const{
369 z *= m_b;
370 z = DG_FMA( m_a, z/y, z);
371 }
372 template<class T3, class T4, class T5>
374 void operator()( T3 x, T4 y, T5& z)const{
375 z *= m_b;
376 z = DG_FMA( m_a, x/y, z);
377 }
378 private:
379 T0 m_a;
380 T1 m_b;
381};
382namespace detail
383{
384template<class F, class G>
385struct Compose
386{
387 Compose( F f, G g):m_f(f), m_g(g){}
388 template<class ...Xs>
389 auto operator() ( Xs&& ... xs){
390 return m_f(m_g(std::forward<Xs>(xs)...));
391 }
392 template<class ...Xs>
393 auto operator() ( Xs&& ... xs) const {
394 return m_f(m_g(std::forward<Xs>(xs)...));
395 }
396 private:
397 F m_f;
398 G m_g;
399};
400}//namespace detail
402
405
425template <class UnaryOp, class Functor>
426auto compose( UnaryOp f, Functor g) {
427 return detail::Compose<UnaryOp,Functor>( f, g);
428 //a C++-14 way of generating a generic lambda with a parameter pack. Taken from:
429 //https://stackoverflow.com/questions/19071268/function-composition-in-c-c11
430 //return [f,g](auto&&... xs){ return f(g(std::forward<decltype(xs)>(xs)...));};
431}
437template <class UnaryOp, typename... Functors>
438auto compose(UnaryOp f0, Functors... fs) {
439 return compose( f0 , compose(fs...));
440}
442
443}//namespace dg
Some utility functions for the dg::evaluate routines.
auto compose(UnaryOp f, Functor g)
Create Composition functor .
Definition subroutines.h:426
@ z
z direction
@ y
y direction
@ x
x direction
#define DG_DEVICE
Expands to __host__ __device__ if compiled with nvcc else is empty.
Definition dg_doc.h:378
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Definition subroutines.h:174
DG_DEVICE void operator()(T1 &y, T1 &yt, T1 b, T1 bt, Ts... rest) const
Definition subroutines.h:177
Definition subroutines.h:11
DG_DEVICE T operator()(T x) const
Definition subroutines.h:13
Definition subroutines.h:124
DG_DEVICE auto operator()(T1 a, T2 x, Ts... rest) const
Definition subroutines.h:127
Definition subroutines.h:100
DG_DEVICE auto operator()(T1 x, Ts... rest) const
Definition subroutines.h:103
Definition subroutines.h:73
DG_DEVICE auto operator()(T1 x, Ts... rest) const
Definition subroutines.h:76
Definition subroutines.h:146
DG_DEVICE auto operator()(T0 a, T1 x1, T2 y1, Ts... rest) const
Definition subroutines.h:149
Definition subroutines.h:58
DG_DEVICE void operator()(T1 x, T2 &y) const
Definition subroutines.h:60
Definition subroutines.h:22
DG_DEVICE void operator()(T1 x, T2 &y) const
Definition subroutines.h:24
Definition subroutines.h:40
DG_DEVICE void operator()(T1 x, T2 &y) const
Definition subroutines.h:42
Definition subroutines.h:31
DG_DEVICE void operator()(T1 x, T2 &y) const
Definition subroutines.h:33
Definition subroutines.h:49
DG_DEVICE void operator()(T1 x, T2 &y) const
Definition subroutines.h:51