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 T3 tmp = y;
284 y *= m_b;
285 y = DG_FMA( m_a*x, tmp, y);
286 }
287 private:
288 T0 m_a;
289 T1 m_b;
290};
291
293template<class T0, class T1, class T2>
294struct Axpbypgz
295{
296 Axpbypgz( T0 a, T1 b, T2 g): m_a(a), m_b(b), m_g(g){}
297 template<class T3, class T4, class T5>
299 void operator()( T3 x, T4 y, T5& z)const{
300 z *= m_g;
301 z = DG_FMA( m_a, x, z);
302 z = DG_FMA( m_b, y, z);
303 }
304 private:
305 T0 m_a;
306 T1 m_b;
307 T2 m_g;
308};
309
311template<class T0, class T1>
312struct PointwiseDot
313{
314 PointwiseDot( T0 a, T1 b): m_a(a), m_b(b) {}
315 template<class T3, class T4, class T5>
317DG_DEVICE void operator()( T3 x, T4 y, T5& z)const{
318 z *= m_b;
319 z = DG_FMA( m_a*x, y, z);
320 }
322 template<class T3, class T4, class T5, class T6>
324 void operator()( T3 x1, T4 x2, T5 x3, T6& y)const{
325 y *= m_b;
326 y = DG_FMA( m_a*x1, x2*x3, y);
327 }
328 private:
329 T0 m_a;
330 T1 m_b;
331};
333template<class T0, class T1, class T2>
334struct PointwiseDot2
335{
336 PointwiseDot2( T0 a, T1 b, T2 g): m_a(a), m_b(b), m_g(g) {}
338 template<class T3, class T4, class T5, class T6, class T7>
340 void operator()( T3 x1, T4 y1, T5 x2, T6 y2, T7& z)const{
341 z *= m_g;
342 z = DG_FMA( m_a*x1, y1, z);
343 z = DG_FMA( m_b*x2, y2, z);
344 }
345 private:
346 T0 m_a;
347 T1 m_b;
348 T2 m_g;
349};
350
352struct divides
353{
354 template< class T1, class T2>
355DG_DEVICE auto operator()( T1 x1, T2 x2) const
356 {
357 return x1/x2;
358 }
359};
360
362template<class T0, class T1>
363struct PointwiseDivide
364{
365 PointwiseDivide( T0 a, T1 b): m_a(a), m_b(b){}
367 template<class T3, class T4>
369 void operator()( T3 y, T4& z)const{
370 T4 tmp = z;
371 z *= m_b;
372 z = DG_FMA( m_a, tmp/y, z);
373 }
374 template<class T3, class T4, class T5>
376 void operator()( T3 x, T4 y, T5& z)const{
377 z *= m_b;
378 z = DG_FMA( m_a, x/y, z);
379 }
380 private:
381 T0 m_a;
382 T1 m_b;
383};
384namespace detail
385{
386template<class F, class G>
387struct Compose
388{
389 Compose( F f, G g):m_f(f), m_g(g){}
390 template<class ...Xs>
391 auto operator() ( Xs&& ... xs){
392 return m_f(m_g(std::forward<Xs>(xs)...));
393 }
394 template<class ...Xs>
395 auto operator() ( Xs&& ... xs) const {
396 return m_f(m_g(std::forward<Xs>(xs)...));
397 }
398 private:
399 F m_f;
400 G m_g;
401};
402}//namespace detail
404
407
427template <class UnaryOp, class Functor>
428auto compose( UnaryOp f, Functor g) {
429 return detail::Compose<UnaryOp,Functor>( f, g);
430 //a C++-14 way of generating a generic lambda with a parameter pack. Taken from:
431 //https://stackoverflow.com/questions/19071268/function-composition-in-c-c11
432 //return [f,g](auto&&... xs){ return f(g(std::forward<decltype(xs)>(xs)...));};
433}
439template <class UnaryOp, typename... Functors>
440auto compose(UnaryOp f0, Functors... fs) {
441 return compose( f0 , compose(fs...));
442}
444
445}//namespace dg
Some utility functions for the dg::evaluate routines.
auto compose(UnaryOp f, Functor g)
Create Composition functor .
Definition subroutines.h:428
@ 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
const double alpha
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