12#ifndef MFEM_BILININTEG_CONVECTION_KERNELS_HPP
13#define MFEM_BILININTEG_CONVECTION_KERNELS_HPP
26template <
int T_D1D = 0,
int T_Q1D = 0>
27void PAConvectionApply2D(
const int ne,
const Array<real_t> &
b,
28 const Array<real_t> &g,
const Array<real_t> &bt,
29 const Array<real_t> >,
const Vector &op_,
30 const Vector &x_, Vector &y_,
const int d1d = 0,
34 const int D1D = T_D1D ? T_D1D : d1d;
35 const int Q1D = T_Q1D ? T_Q1D : q1d;
38 auto B =
Reshape(
b.Read(), Q1D, D1D);
39 auto G =
Reshape(g.Read(), Q1D, D1D);
40 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
41 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
42 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
43 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
46 const int D1D = T_D1D ? T_D1D : d1d;
47 const int Q1D = T_Q1D ? T_Q1D : q1d;
49 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
50 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
53 for (
int dy = 0; dy < D1D; ++dy)
55 for (
int dx = 0; dx < D1D; ++dx)
57 u[dy][dx] = x(dx,dy,e);
60 real_t Bu[max_D1D][max_Q1D];
61 real_t Gu[max_D1D][max_Q1D];
62 for (
int dy = 0; dy < D1D; ++dy)
64 for (
int qx = 0; qx < Q1D; ++qx)
68 for (
int dx = 0; dx < D1D; ++dx)
70 const real_t bx = B(qx,dx);
71 const real_t gx = G(qx,dx);
78 real_t GBu[max_Q1D][max_Q1D];
79 real_t BGu[max_Q1D][max_Q1D];
80 for (
int qx = 0; qx < Q1D; ++qx)
82 for (
int qy = 0; qy < Q1D; ++qy)
86 for (
int dy = 0; dy < D1D; ++dy)
88 const real_t bx = B(qy,dy);
89 const real_t gx = G(qy,dy);
90 GBu[qy][qx] += gx * Bu[dy][qx];
91 BGu[qy][qx] += bx * Gu[dy][qx];
96 real_t DGu[max_Q1D][max_Q1D];
97 for (
int qy = 0; qy < Q1D; ++qy)
99 for (
int qx = 0; qx < Q1D; ++qx)
101 const real_t O1 = op(qx,qy,0,e);
102 const real_t O2 = op(qx,qy,1,e);
104 const real_t gradX = BGu[qy][qx];
105 const real_t gradY = GBu[qy][qx];
107 DGu[qy][qx] = (O1 * gradX) + (O2 * gradY);
110 real_t BDGu[max_D1D][max_Q1D];
111 for (
int qx = 0; qx < Q1D; ++qx)
113 for (
int dy = 0; dy < D1D; ++dy)
116 for (
int qy = 0; qy < Q1D; ++qy)
118 const real_t w = Bt(dy,qy);
119 BDGu[dy][qx] += w * DGu[qy][qx];
123 for (
int dx = 0; dx < D1D; ++dx)
125 for (
int dy = 0; dy < D1D; ++dy)
128 for (
int qx = 0; qx < Q1D; ++qx)
130 const real_t w = Bt(dx,qx);
131 BBDGu += w * BDGu[dy][qx];
140template <
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
141void SmemPAConvectionApply2D(
const int ne,
const Array<real_t> &
b,
142 const Array<real_t> &g,
const Array<real_t> &bt,
143 const Array<real_t> >,
const Vector &op_,
144 const Vector &x_, Vector &y_,
const int d1d = 0,
148 const int D1D = T_D1D ? T_D1D : d1d;
149 const int Q1D = T_Q1D ? T_Q1D : q1d;
150 constexpr int NBZ = T_NBZ ? T_NBZ : 1;
153 auto B =
Reshape(
b.Read(), Q1D, D1D);
154 auto G =
Reshape(g.Read(), Q1D, D1D);
155 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
156 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
157 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
158 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
161 const int tidz = MFEM_THREAD_ID(z);
162 const int D1D = T_D1D ? T_D1D : d1d;
163 const int Q1D = T_Q1D ? T_Q1D : q1d;
165 constexpr int NBZ = T_NBZ ? T_NBZ : 1;
166 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
167 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
169 MFEM_SHARED
real_t u[NBZ][max_D1D][max_D1D];
170 MFEM_FOREACH_THREAD(dy,y,D1D)
172 MFEM_FOREACH_THREAD(dx,x,D1D)
175 u[tidz][dy][dx] = x(dx,dy,e);
179 MFEM_SHARED
real_t Bu[NBZ][max_D1D][max_Q1D];
180 MFEM_SHARED
real_t Gu[NBZ][max_D1D][max_Q1D];
181 MFEM_FOREACH_THREAD(dy,y,D1D)
183 MFEM_FOREACH_THREAD(qx,x,Q1D)
185 Bu[tidz][dy][qx] = 0.0;
186 Gu[tidz][dy][qx] = 0.0;
187 for (
int dx = 0; dx < D1D; ++dx)
189 const real_t bx = B(qx,dx);
190 const real_t gx = G(qx,dx);
191 const real_t x =
u[tidz][dy][dx];
192 Bu[tidz][dy][qx] += bx * x;
193 Gu[tidz][dy][qx] += gx * x;
198 MFEM_SHARED
real_t GBu[NBZ][max_Q1D][max_Q1D];
199 MFEM_SHARED
real_t BGu[NBZ][max_Q1D][max_Q1D];
200 MFEM_FOREACH_THREAD(qx,x,Q1D)
202 MFEM_FOREACH_THREAD(qy,y,Q1D)
204 GBu[tidz][qy][qx] = 0.0;
205 BGu[tidz][qy][qx] = 0.0;
206 for (
int dy = 0; dy < D1D; ++dy)
208 const real_t bx = B(qy,dy);
209 const real_t gx = G(qy,dy);
210 GBu[tidz][qy][qx] += gx * Bu[tidz][dy][qx];
211 BGu[tidz][qy][qx] += bx * Gu[tidz][dy][qx];
217 MFEM_SHARED
real_t DGu[NBZ][max_Q1D][max_Q1D];
218 MFEM_FOREACH_THREAD(qy,y,Q1D)
220 MFEM_FOREACH_THREAD(qx,x,Q1D)
222 const real_t O1 = op(qx,qy,0,e);
223 const real_t O2 = op(qx,qy,1,e);
225 const real_t gradX = BGu[tidz][qy][qx];
226 const real_t gradY = GBu[tidz][qy][qx];
228 DGu[tidz][qy][qx] = (O1 * gradX) + (O2 * gradY);
232 MFEM_SHARED
real_t BDGu[NBZ][max_D1D][max_Q1D];
233 MFEM_FOREACH_THREAD(qx,x,Q1D)
235 MFEM_FOREACH_THREAD(dy,y,D1D)
237 BDGu[tidz][dy][qx] = 0.0;
238 for (
int qy = 0; qy < Q1D; ++qy)
240 const real_t w = Bt(dy,qy);
241 BDGu[tidz][dy][qx] += w * DGu[tidz][qy][qx];
246 MFEM_FOREACH_THREAD(dx,x,D1D)
248 MFEM_FOREACH_THREAD(dy,y,D1D)
251 for (
int qx = 0; qx < Q1D; ++qx)
253 const real_t w = Bt(dx,qx);
254 BBDGu += w * BDGu[tidz][dy][qx];
263template <
int T_D1D = 0,
int T_Q1D = 0>
264void PAConvectionApply3D(
const int ne,
const Array<real_t> &
b,
265 const Array<real_t> &g,
const Array<real_t> &bt,
266 const Array<real_t> >,
const Vector &op_,
267 const Vector &x_, Vector &y_,
const int d1d = 0,
271 const int D1D = T_D1D ? T_D1D : d1d;
272 const int Q1D = T_Q1D ? T_Q1D : q1d;
275 auto B =
Reshape(
b.Read(), Q1D, D1D);
276 auto G =
Reshape(g.Read(), Q1D, D1D);
277 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
278 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
279 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
280 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
283 const int D1D = T_D1D ? T_D1D : d1d;
284 const int Q1D = T_Q1D ? T_Q1D : q1d;
286 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
287 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
289 real_t u[max_D1D][max_D1D][max_D1D];
290 for (
int dz = 0; dz < D1D; ++dz)
292 for (
int dy = 0; dy < D1D; ++dy)
294 for (
int dx = 0; dx < D1D; ++dx)
296 u[dz][dy][dx] = x(dx,dy,dz,e);
300 real_t Bu[max_D1D][max_D1D][max_Q1D];
301 real_t Gu[max_D1D][max_D1D][max_Q1D];
302 for (
int dz = 0; dz < D1D; ++dz)
304 for (
int dy = 0; dy < D1D; ++dy)
306 for (
int qx = 0; qx < Q1D; ++qx)
308 Bu[dz][dy][qx] = 0.0;
309 Gu[dz][dy][qx] = 0.0;
310 for (
int dx = 0; dx < D1D; ++dx)
312 const real_t bx = B(qx,dx);
313 const real_t gx = G(qx,dx);
314 const real_t x =
u[dz][dy][dx];
315 Bu[dz][dy][qx] += bx * x;
316 Gu[dz][dy][qx] += gx * x;
321 real_t BBu[max_D1D][max_Q1D][max_Q1D];
322 real_t GBu[max_D1D][max_Q1D][max_Q1D];
323 real_t BGu[max_D1D][max_Q1D][max_Q1D];
324 for (
int dz = 0; dz < D1D; ++dz)
326 for (
int qx = 0; qx < Q1D; ++qx)
328 for (
int qy = 0; qy < Q1D; ++qy)
330 BBu[dz][qy][qx] = 0.0;
331 GBu[dz][qy][qx] = 0.0;
332 BGu[dz][qy][qx] = 0.0;
333 for (
int dy = 0; dy < D1D; ++dy)
335 const real_t bx = B(qy,dy);
336 const real_t gx = G(qy,dy);
337 BBu[dz][qy][qx] += bx * Bu[dz][dy][qx];
338 GBu[dz][qy][qx] += gx * Bu[dz][dy][qx];
339 BGu[dz][qy][qx] += bx * Gu[dz][dy][qx];
344 real_t GBBu[max_Q1D][max_Q1D][max_Q1D];
345 real_t BGBu[max_Q1D][max_Q1D][max_Q1D];
346 real_t BBGu[max_Q1D][max_Q1D][max_Q1D];
347 for (
int qx = 0; qx < Q1D; ++qx)
349 for (
int qy = 0; qy < Q1D; ++qy)
351 for (
int qz = 0; qz < Q1D; ++qz)
353 GBBu[qz][qy][qx] = 0.0;
354 BGBu[qz][qy][qx] = 0.0;
355 BBGu[qz][qy][qx] = 0.0;
356 for (
int dz = 0; dz < D1D; ++dz)
358 const real_t bx = B(qz,dz);
359 const real_t gx = G(qz,dz);
360 GBBu[qz][qy][qx] += gx * BBu[dz][qy][qx];
361 BGBu[qz][qy][qx] += bx * GBu[dz][qy][qx];
362 BBGu[qz][qy][qx] += bx * BGu[dz][qy][qx];
368 real_t DGu[max_Q1D][max_Q1D][max_Q1D];
369 for (
int qz = 0; qz < Q1D; ++qz)
371 for (
int qy = 0; qy < Q1D; ++qy)
373 for (
int qx = 0; qx < Q1D; ++qx)
375 const real_t O1 = op(qx,qy,qz,0,e);
376 const real_t O2 = op(qx,qy,qz,1,e);
377 const real_t O3 = op(qx,qy,qz,2,e);
379 const real_t gradX = BBGu[qz][qy][qx];
380 const real_t gradY = BGBu[qz][qy][qx];
381 const real_t gradZ = GBBu[qz][qy][qx];
383 DGu[qz][qy][qx] = (O1 * gradX) + (O2 * gradY) + (O3 * gradZ);
387 real_t BDGu[max_D1D][max_Q1D][max_Q1D];
388 for (
int qx = 0; qx < Q1D; ++qx)
390 for (
int qy = 0; qy < Q1D; ++qy)
392 for (
int dz = 0; dz < D1D; ++dz)
394 BDGu[dz][qy][qx] = 0.0;
395 for (
int qz = 0; qz < Q1D; ++qz)
397 const real_t w = Bt(dz,qz);
398 BDGu[dz][qy][qx] += w * DGu[qz][qy][qx];
403 real_t BBDGu[max_D1D][max_D1D][max_Q1D];
404 for (
int dz = 0; dz < D1D; ++dz)
406 for (
int qx = 0; qx < Q1D; ++qx)
408 for (
int dy = 0; dy < D1D; ++dy)
410 BBDGu[dz][dy][qx] = 0.0;
411 for (
int qy = 0; qy < Q1D; ++qy)
413 const real_t w = Bt(dy,qy);
414 BBDGu[dz][dy][qx] += w * BDGu[dz][qy][qx];
419 for (
int dz = 0; dz < D1D; ++dz)
421 for (
int dy = 0; dy < D1D; ++dy)
423 for (
int dx = 0; dx < D1D; ++dx)
426 for (
int qx = 0; qx < Q1D; ++qx)
428 const real_t w = Bt(dx,qx);
429 BBBDGu += w * BBDGu[dz][dy][qx];
431 y(dx,dy,dz,e) += BBBDGu;
439template <
int T_D1D = 0,
int T_Q1D = 0>
440void SmemPAConvectionApply3D(
const int ne,
const Array<real_t> &
b,
441 const Array<real_t> &g,
const Array<real_t> &bt,
442 const Array<real_t> >,
const Vector &op_,
443 const Vector &x_, Vector &y_,
const int d1d = 0,
447 const int D1D = T_D1D ? T_D1D : d1d;
448 const int Q1D = T_Q1D ? T_Q1D : q1d;
451 auto B =
Reshape(
b.Read(), Q1D, D1D);
452 auto G =
Reshape(g.Read(), Q1D, D1D);
453 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
454 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
455 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
456 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
459 const int D1D = T_D1D ? T_D1D : d1d;
460 const int Q1D = T_Q1D ? T_Q1D : q1d;
462 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
463 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
464 constexpr int max_DQ = (max_Q1D > max_D1D) ? max_Q1D : max_D1D;
465 MFEM_SHARED
real_t sm0[max_DQ*max_DQ*max_DQ];
466 MFEM_SHARED
real_t sm1[max_DQ*max_DQ*max_DQ];
467 MFEM_SHARED
real_t sm2[max_DQ*max_DQ*max_DQ];
468 MFEM_SHARED
real_t sm3[max_DQ*max_DQ*max_DQ];
469 MFEM_SHARED
real_t sm4[max_DQ*max_DQ*max_DQ];
470 MFEM_SHARED
real_t sm5[max_DQ*max_DQ*max_DQ];
472 real_t (*
u)[max_D1D][max_D1D] = (
real_t (*)[max_D1D][max_D1D]) sm0;
473 MFEM_FOREACH_THREAD(dz,z,D1D)
475 MFEM_FOREACH_THREAD(dy,y,D1D)
477 MFEM_FOREACH_THREAD(dx,x,D1D)
479 u[dz][dy][dx] = x(dx,dy,dz,e);
484 real_t (*Bu)[max_D1D][max_Q1D] = (
real_t (*)[max_D1D][max_Q1D])sm1;
485 real_t (*Gu)[max_D1D][max_Q1D] = (
real_t (*)[max_D1D][max_Q1D])sm2;
486 MFEM_FOREACH_THREAD(dz,z,D1D)
488 MFEM_FOREACH_THREAD(dy,y,D1D)
490 MFEM_FOREACH_THREAD(qx,x,Q1D)
494 for (
int dx = 0; dx < D1D; ++dx)
496 const real_t bx = B(qx,dx);
497 const real_t gx = G(qx,dx);
498 const real_t x =
u[dz][dy][dx];
502 Bu[dz][dy][qx] = Bu_;
503 Gu[dz][dy][qx] = Gu_;
508 real_t (*BBu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm3;
509 real_t (*GBu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm4;
510 real_t (*BGu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm5;
511 MFEM_FOREACH_THREAD(dz,z,D1D)
513 MFEM_FOREACH_THREAD(qx,x,Q1D)
515 MFEM_FOREACH_THREAD(qy,y,Q1D)
520 for (
int dy = 0; dy < D1D; ++dy)
522 const real_t bx = B(qy,dy);
523 const real_t gx = G(qy,dy);
524 BBu_ += bx * Bu[dz][dy][qx];
525 GBu_ += gx * Bu[dz][dy][qx];
526 BGu_ += bx * Gu[dz][dy][qx];
528 BBu[dz][qy][qx] = BBu_;
529 GBu[dz][qy][qx] = GBu_;
530 BGu[dz][qy][qx] = BGu_;
535 real_t (*GBBu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm0;
536 real_t (*BGBu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm1;
537 real_t (*BBGu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm2;
538 MFEM_FOREACH_THREAD(qx,x,Q1D)
540 MFEM_FOREACH_THREAD(qy,y,Q1D)
542 MFEM_FOREACH_THREAD(qz,z,Q1D)
547 for (
int dz = 0; dz < D1D; ++dz)
549 const real_t bx = B(qz,dz);
550 const real_t gx = G(qz,dz);
551 GBBu_ += gx * BBu[dz][qy][qx];
552 BGBu_ += bx * GBu[dz][qy][qx];
553 BBGu_ += bx * BGu[dz][qy][qx];
555 GBBu[qz][qy][qx] = GBBu_;
556 BGBu[qz][qy][qx] = BGBu_;
557 BBGu[qz][qy][qx] = BBGu_;
562 real_t (*DGu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm3;
563 MFEM_FOREACH_THREAD(qz,z,Q1D)
565 MFEM_FOREACH_THREAD(qy,y,Q1D)
567 MFEM_FOREACH_THREAD(qx,x,Q1D)
569 const real_t O1 = op(qx,qy,qz,0,e);
570 const real_t O2 = op(qx,qy,qz,1,e);
571 const real_t O3 = op(qx,qy,qz,2,e);
573 const real_t gradX = BBGu[qz][qy][qx];
574 const real_t gradY = BGBu[qz][qy][qx];
575 const real_t gradZ = GBBu[qz][qy][qx];
577 DGu[qz][qy][qx] = (O1 * gradX) + (O2 * gradY) + (O3 * gradZ);
582 real_t (*BDGu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm4;
583 MFEM_FOREACH_THREAD(qx,x,Q1D)
585 MFEM_FOREACH_THREAD(qy,y,Q1D)
587 MFEM_FOREACH_THREAD(dz,z,D1D)
590 for (
int qz = 0; qz < Q1D; ++qz)
592 const real_t w = Bt(dz,qz);
593 BDGu_ += w * DGu[qz][qy][qx];
595 BDGu[dz][qy][qx] = BDGu_;
600 real_t (*BBDGu)[max_D1D][max_Q1D] = (
real_t (*)[max_D1D][max_Q1D])sm5;
601 MFEM_FOREACH_THREAD(dz,z,D1D)
603 MFEM_FOREACH_THREAD(qx,x,Q1D)
605 MFEM_FOREACH_THREAD(dy,y,D1D)
608 for (
int qy = 0; qy < Q1D; ++qy)
610 const real_t w = Bt(dy,qy);
611 BBDGu_ += w * BDGu[dz][qy][qx];
613 BBDGu[dz][dy][qx] = BBDGu_;
618 MFEM_FOREACH_THREAD(dz,z,D1D)
620 MFEM_FOREACH_THREAD(dy,y,D1D)
622 MFEM_FOREACH_THREAD(dx,x,D1D)
625 for (
int qx = 0; qx < Q1D; ++qx)
627 const real_t w = Bt(dx,qx);
628 BBBDGu += w * BBDGu[dz][dy][qx];
630 y(dx,dy,dz,e) += BBBDGu;
638template <
int T_D1D = 0,
int T_Q1D = 0>
639void PAConvectionApplyT2D(
const int ne,
const Array<real_t> &
b,
640 const Array<real_t> &g,
const Array<real_t> &bt,
641 const Array<real_t> >,
const Vector &op_,
642 const Vector &x_, Vector &y_,
const int d1d = 0,
646 const int D1D = T_D1D ? T_D1D : d1d;
647 const int Q1D = T_Q1D ? T_Q1D : q1d;
650 auto B =
Reshape(
b.Read(), Q1D, D1D);
651 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
652 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
653 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
654 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
655 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
658 const int D1D = T_D1D ? T_D1D : d1d;
659 const int Q1D = T_Q1D ? T_Q1D : q1d;
661 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
662 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
665 for (
int dy = 0; dy < D1D; ++dy)
667 for (
int dx = 0; dx < D1D; ++dx)
669 u[dy][dx] = x(dx,dy,e);
672 real_t Bu[max_D1D][max_Q1D];
673 for (
int dy = 0; dy < D1D; ++dy)
675 for (
int qx = 0; qx < Q1D; ++qx)
678 for (
int dx = 0; dx < D1D; ++dx)
680 const real_t bx = B(qx,dx);
682 Bu[dy][qx] += bx * x;
686 real_t BBu[max_Q1D][max_Q1D];
687 for (
int qx = 0; qx < Q1D; ++qx)
689 for (
int qy = 0; qy < Q1D; ++qy)
692 for (
int dy = 0; dy < D1D; ++dy)
694 const real_t bx = B(qy,dy);
695 BBu[qy][qx] += bx * Bu[dy][qx];
700 real_t DBu[max_Q1D][max_Q1D][2];
701 for (
int qy = 0; qy < Q1D; ++qy)
703 for (
int qx = 0; qx < Q1D; ++qx)
705 const real_t O1 = op(qx,qy,0,e);
706 const real_t O2 = op(qx,qy,1,e);
708 const real_t X = BBu[qy][qx];
710 DBu[qy][qx][0] = O1 * X;
711 DBu[qy][qx][1] = O2 * X;
714 real_t GDBu[max_D1D][max_Q1D][2];
715 for (
int qx = 0; qx < Q1D; ++qx)
717 for (
int dy = 0; dy < D1D; ++dy)
719 GDBu[dy][qx][0] = 0.0;
720 GDBu[dy][qx][1] = 0.0;
721 for (
int qy = 0; qy < Q1D; ++qy)
723 const real_t by = Bt(dy,qy);
724 const real_t gy = Gt(dy,qy);
725 GDBu[dy][qx][0] += by * DBu[qy][qx][0];
726 GDBu[dy][qx][1] += gy * DBu[qy][qx][1];
730 for (
int dx = 0; dx < D1D; ++dx)
732 for (
int dy = 0; dy < D1D; ++dy)
735 for (
int qx = 0; qx < Q1D; ++qx)
737 const real_t bx = Bt(dx,qx);
738 const real_t gx = Gt(dx,qx);
739 res += gx * GDBu[dy][qx][0] + bx * GDBu[dy][qx][1];
748template <
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
749void SmemPAConvectionApplyT2D(
const int ne,
const Array<real_t> &
b,
750 const Array<real_t> &g,
const Array<real_t> &bt,
751 const Array<real_t> >,
const Vector &op_,
752 const Vector &x_, Vector &y_,
const int d1d = 0,
756 const int D1D = T_D1D ? T_D1D : d1d;
757 const int Q1D = T_Q1D ? T_Q1D : q1d;
758 constexpr int NBZ = T_NBZ ? T_NBZ : 1;
761 auto B =
Reshape(
b.Read(), Q1D, D1D);
762 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
763 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
764 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
765 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
766 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
769 const int tidz = MFEM_THREAD_ID(z);
770 const int D1D = T_D1D ? T_D1D : d1d;
771 const int Q1D = T_Q1D ? T_Q1D : q1d;
773 constexpr int NBZ = T_NBZ ? T_NBZ : 1;
774 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
775 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
776 MFEM_SHARED
real_t u[NBZ][max_D1D][max_D1D];
777 MFEM_FOREACH_THREAD(dy,y,D1D)
779 MFEM_FOREACH_THREAD(dx,x,D1D)
782 u[tidz][dy][dx] = x(dx,dy,e);
786 MFEM_SHARED
real_t Bu[NBZ][max_D1D][max_Q1D];
787 MFEM_FOREACH_THREAD(dy,y,D1D)
789 MFEM_FOREACH_THREAD(qx,x,Q1D)
791 Bu[tidz][dy][qx] = 0.0;
792 for (
int dx = 0; dx < D1D; ++dx)
794 const real_t bx = B(qx,dx);
795 const real_t x =
u[tidz][dy][dx];
796 Bu[tidz][dy][qx] += bx * x;
801 MFEM_SHARED
real_t BBu[NBZ][max_Q1D][max_Q1D];
802 MFEM_FOREACH_THREAD(qx,x,Q1D)
804 MFEM_FOREACH_THREAD(qy,y,Q1D)
806 BBu[tidz][qy][qx] = 0.0;
807 for (
int dy = 0; dy < D1D; ++dy)
809 const real_t bx = B(qy,dy);
810 BBu[tidz][qy][qx] += bx * Bu[tidz][dy][qx];
816 MFEM_SHARED
real_t DBu[NBZ][max_Q1D][max_Q1D][2];
817 MFEM_FOREACH_THREAD(qy,y,Q1D)
819 MFEM_FOREACH_THREAD(qx,x,Q1D)
821 const real_t O1 = op(qx,qy,0,e);
822 const real_t O2 = op(qx,qy,1,e);
824 const real_t X = BBu[tidz][qy][qx];
826 DBu[tidz][qy][qx][0] = O1 * X;
827 DBu[tidz][qy][qx][1] = O2 * X;
831 MFEM_SHARED
real_t GDBu[NBZ][max_D1D][max_Q1D][2];
832 MFEM_FOREACH_THREAD(qx,x,Q1D)
834 MFEM_FOREACH_THREAD(dy,y,D1D)
836 GDBu[tidz][dy][qx][0] = 0.0;
837 GDBu[tidz][dy][qx][1] = 0.0;
838 for (
int qy = 0; qy < Q1D; ++qy)
840 const real_t by = Bt(dy,qy);
841 const real_t gy = Gt(dy,qy);
842 GDBu[tidz][dy][qx][0] += by * DBu[tidz][qy][qx][0];
843 GDBu[tidz][dy][qx][1] += gy * DBu[tidz][qy][qx][1];
848 MFEM_FOREACH_THREAD(dx,x,D1D)
850 MFEM_FOREACH_THREAD(dy,y,D1D)
853 for (
int qx = 0; qx < Q1D; ++qx)
855 const real_t bx = Bt(dx,qx);
856 const real_t gx = Gt(dx,qx);
857 res += gx * GDBu[tidz][dy][qx][0] + bx * GDBu[tidz][dy][qx][1];
866template <
int T_D1D = 0,
int T_Q1D = 0>
867void PAConvectionApplyT3D(
const int ne,
const Array<real_t> &
b,
868 const Array<real_t> &g,
const Array<real_t> &bt,
869 const Array<real_t> >,
const Vector &op_,
870 const Vector &x_, Vector &y_,
const int d1d = 0,
874 const int D1D = T_D1D ? T_D1D : d1d;
875 const int Q1D = T_Q1D ? T_Q1D : q1d;
878 auto B =
Reshape(
b.Read(), Q1D, D1D);
879 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
880 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
881 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
882 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
883 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
886 const int D1D = T_D1D ? T_D1D : d1d;
887 const int Q1D = T_Q1D ? T_Q1D : q1d;
889 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
890 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
892 real_t u[max_D1D][max_D1D][max_D1D];
893 for (
int dz = 0; dz < D1D; ++dz)
895 for (
int dy = 0; dy < D1D; ++dy)
897 for (
int dx = 0; dx < D1D; ++dx)
899 u[dz][dy][dx] = x(dx,dy,dz,e);
903 real_t Bu[max_D1D][max_D1D][max_Q1D];
904 for (
int dz = 0; dz < D1D; ++dz)
906 for (
int dy = 0; dy < D1D; ++dy)
908 for (
int qx = 0; qx < Q1D; ++qx)
910 Bu[dz][dy][qx] = 0.0;
911 for (
int dx = 0; dx < D1D; ++dx)
913 const real_t bx = B(qx,dx);
914 const real_t x =
u[dz][dy][dx];
915 Bu[dz][dy][qx] += bx * x;
920 real_t BBu[max_D1D][max_Q1D][max_Q1D];
921 for (
int dz = 0; dz < D1D; ++dz)
923 for (
int qx = 0; qx < Q1D; ++qx)
925 for (
int qy = 0; qy < Q1D; ++qy)
927 BBu[dz][qy][qx] = 0.0;
928 for (
int dy = 0; dy < D1D; ++dy)
930 const real_t bx = B(qy,dy);
931 BBu[dz][qy][qx] += bx * Bu[dz][dy][qx];
936 real_t BBBu[max_Q1D][max_Q1D][max_Q1D];
937 for (
int qx = 0; qx < Q1D; ++qx)
939 for (
int qy = 0; qy < Q1D; ++qy)
941 for (
int qz = 0; qz < Q1D; ++qz)
943 BBBu[qz][qy][qx] = 0.0;
944 for (
int dz = 0; dz < D1D; ++dz)
946 const real_t bx = B(qz,dz);
947 BBBu[qz][qy][qx] += bx * BBu[dz][qy][qx];
953 real_t DBu[max_Q1D][max_Q1D][max_Q1D][3];
954 for (
int qz = 0; qz < Q1D; ++qz)
956 for (
int qy = 0; qy < Q1D; ++qy)
958 for (
int qx = 0; qx < Q1D; ++qx)
960 const real_t O1 = op(qx,qy,qz,0,e);
961 const real_t O2 = op(qx,qy,qz,1,e);
962 const real_t O3 = op(qx,qy,qz,2,e);
964 const real_t X = BBBu[qz][qy][qx];
966 DBu[qz][qy][qx][0] = O1 * X;
967 DBu[qz][qy][qx][1] = O2 * X;
968 DBu[qz][qy][qx][2] = O3 * X;
972 real_t GDBu[max_D1D][max_Q1D][max_Q1D][3];
973 for (
int qx = 0; qx < Q1D; ++qx)
975 for (
int qy = 0; qy < Q1D; ++qy)
977 for (
int dz = 0; dz < D1D; ++dz)
979 GDBu[dz][qy][qx][0] = 0.0;
980 GDBu[dz][qy][qx][1] = 0.0;
981 GDBu[dz][qy][qx][2] = 0.0;
982 for (
int qz = 0; qz < Q1D; ++qz)
984 const real_t bz = Bt(dz,qz);
985 const real_t gz = Gt(dz,qz);
986 GDBu[dz][qy][qx][0] += bz * DBu[qz][qy][qx][0];
987 GDBu[dz][qy][qx][1] += bz * DBu[qz][qy][qx][1];
988 GDBu[dz][qy][qx][2] += gz * DBu[qz][qy][qx][2];
993 real_t GGDBu[max_D1D][max_D1D][max_Q1D][3];
994 for (
int dz = 0; dz < D1D; ++dz)
996 for (
int qx = 0; qx < Q1D; ++qx)
998 for (
int dy = 0; dy < D1D; ++dy)
1000 GGDBu[dz][dy][qx][0] = 0.0;
1001 GGDBu[dz][dy][qx][1] = 0.0;
1002 GGDBu[dz][dy][qx][2] = 0.0;
1003 for (
int qy = 0; qy < Q1D; ++qy)
1005 const real_t by = Bt(dy,qy);
1006 const real_t gy = Gt(dy,qy);
1007 GGDBu[dz][dy][qx][0] += by * GDBu[dz][qy][qx][0];
1008 GGDBu[dz][dy][qx][1] += gy * GDBu[dz][qy][qx][1];
1009 GGDBu[dz][dy][qx][2] += by * GDBu[dz][qy][qx][2];
1014 for (
int dz = 0; dz < D1D; ++dz)
1016 for (
int dy = 0; dy < D1D; ++dy)
1018 for (
int dx = 0; dx < D1D; ++dx)
1021 for (
int qx = 0; qx < Q1D; ++qx)
1023 const real_t bx = Bt(dx,qx);
1024 const real_t gx = Gt(dx,qx);
1025 res += gx * GGDBu[dz][dy][qx][0];
1026 res += bx * GGDBu[dz][dy][qx][1];
1027 res += bx * GGDBu[dz][dy][qx][2];
1029 y(dx,dy,dz,e) += res;
1037template <
int T_D1D = 0,
int T_Q1D = 0>
1038void SmemPAConvectionApplyT3D(
const int ne,
const Array<real_t> &
b,
1039 const Array<real_t> &g,
const Array<real_t> &bt,
1040 const Array<real_t> >,
const Vector &op_,
1041 const Vector &x_, Vector &y_,
const int d1d = 0,
1045 const int D1D = T_D1D ? T_D1D : d1d;
1046 const int Q1D = T_Q1D ? T_Q1D : q1d;
1049 auto B =
Reshape(
b.Read(), Q1D, D1D);
1050 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
1051 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
1052 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
1053 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
1054 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
1057 const int D1D = T_D1D ? T_D1D : d1d;
1058 const int Q1D = T_Q1D ? T_Q1D : q1d;
1060 constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
1061 constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
1062 constexpr int max_DQ = (max_Q1D > max_D1D) ? max_Q1D : max_D1D;
1063 MFEM_SHARED
real_t sm0[3*max_DQ*max_DQ*max_DQ];
1064 MFEM_SHARED
real_t sm1[3*max_DQ*max_DQ*max_DQ];
1066 real_t (*
u)[max_D1D][max_D1D] = (
real_t (*)[max_D1D][max_D1D]) sm0;
1067 MFEM_FOREACH_THREAD(dz,z,D1D)
1069 MFEM_FOREACH_THREAD(dy,y,D1D)
1071 MFEM_FOREACH_THREAD(dx,x,D1D)
1073 u[dz][dy][dx] = x(dx,dy,dz,e);
1078 real_t (*Bu)[max_D1D][max_Q1D] = (
real_t (*)[max_D1D][max_Q1D])sm1;
1079 MFEM_FOREACH_THREAD(dz,z,D1D)
1081 MFEM_FOREACH_THREAD(dy,y,D1D)
1083 MFEM_FOREACH_THREAD(qx,x,Q1D)
1086 for (
int dx = 0; dx < D1D; ++dx)
1088 const real_t bx = B(qx,dx);
1089 const real_t x =
u[dz][dy][dx];
1092 Bu[dz][dy][qx] = Bu_;
1097 real_t (*BBu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm0;
1098 MFEM_FOREACH_THREAD(dz,z,D1D)
1100 MFEM_FOREACH_THREAD(qx,x,Q1D)
1102 MFEM_FOREACH_THREAD(qy,y,Q1D)
1105 for (
int dy = 0; dy < D1D; ++dy)
1107 const real_t bx = B(qy,dy);
1108 BBu_ += bx * Bu[dz][dy][qx];
1110 BBu[dz][qy][qx] = BBu_;
1115 real_t (*BBBu)[max_Q1D][max_Q1D] = (
real_t (*)[max_Q1D][max_Q1D])sm1;
1116 MFEM_FOREACH_THREAD(qx,x,Q1D)
1118 MFEM_FOREACH_THREAD(qy,y,Q1D)
1120 MFEM_FOREACH_THREAD(qz,z,Q1D)
1123 for (
int dz = 0; dz < D1D; ++dz)
1125 const real_t bx = B(qz,dz);
1126 BBBu_ += bx * BBu[dz][qy][qx];
1128 BBBu[qz][qy][qx] = BBBu_;
1133 real_t (*DBu)[max_Q1D][max_Q1D][3] = (
real_t (*)[max_Q1D][max_Q1D][3])sm0;
1134 MFEM_FOREACH_THREAD(qz,z,Q1D)
1136 MFEM_FOREACH_THREAD(qy,y,Q1D)
1138 MFEM_FOREACH_THREAD(qx,x,Q1D)
1140 const real_t O1 = op(qx,qy,qz,0,e);
1141 const real_t O2 = op(qx,qy,qz,1,e);
1142 const real_t O3 = op(qx,qy,qz,2,e);
1144 const real_t X = BBBu[qz][qy][qx];
1146 DBu[qz][qy][qx][0] = O1 * X;
1147 DBu[qz][qy][qx][1] = O2 * X;
1148 DBu[qz][qy][qx][2] = O3 * X;
1153 real_t (*GDBu)[max_Q1D][max_Q1D][3] = (
real_t (*)[max_Q1D][max_Q1D][3])sm1;
1154 MFEM_FOREACH_THREAD(qx,x,Q1D)
1156 MFEM_FOREACH_THREAD(qy,y,Q1D)
1158 MFEM_FOREACH_THREAD(dz,z,D1D)
1163 for (
int qz = 0; qz < Q1D; ++qz)
1165 const real_t bz = Bt(dz,qz);
1166 const real_t gz = Gt(dz,qz);
1167 GDBu0 += bz * DBu[qz][qy][qx][0];
1168 GDBu1 += bz * DBu[qz][qy][qx][1];
1169 GDBu2 += gz * DBu[qz][qy][qx][2];
1171 GDBu[dz][qy][qx][0] = GDBu0;
1172 GDBu[dz][qy][qx][1] = GDBu1;
1173 GDBu[dz][qy][qx][2] = GDBu2;
1178 real_t (*GGDBu)[max_D1D][max_Q1D][3] = (
real_t (*)[max_D1D][max_Q1D][3])sm0;
1179 MFEM_FOREACH_THREAD(dz,z,D1D)
1181 MFEM_FOREACH_THREAD(qx,x,Q1D)
1183 MFEM_FOREACH_THREAD(dy,y,D1D)
1188 for (
int qy = 0; qy < Q1D; ++qy)
1190 const real_t by = Bt(dy,qy);
1191 const real_t gy = Gt(dy,qy);
1192 GGDBu0 += by * GDBu[dz][qy][qx][0];
1193 GGDBu1 += gy * GDBu[dz][qy][qx][1];
1194 GGDBu2 += by * GDBu[dz][qy][qx][2];
1196 GGDBu[dz][dy][qx][0] = GGDBu0;
1197 GGDBu[dz][dy][qx][1] = GGDBu1;
1198 GGDBu[dz][dy][qx][2] = GGDBu2;
1203 MFEM_FOREACH_THREAD(dz,z,D1D)
1205 MFEM_FOREACH_THREAD(dy,y,D1D)
1207 MFEM_FOREACH_THREAD(dx,x,D1D)
1210 for (
int qx = 0; qx < Q1D; ++qx)
1212 const real_t bx = Bt(dx,qx);
1213 const real_t gx = Gt(dx,qx);
1214 res += gx * GGDBu[dz][dy][qx][0];
1215 res += bx * GGDBu[dz][dy][qx][1];
1216 res += bx * GGDBu[dz][dy][qx][2];
1218 y(dx,dy,dz,e) += res;
1227constexpr int ipow(
int x,
int p) {
return p == 0 ? 1 : x*ipow(x,
p-1); }
1228constexpr int D(
int D1D) {
return (11 - D1D) / 2; }
1229constexpr int NBZ(
int D1D)
1231 return ipow(2, D(D1D) >= 0 ? D(D1D) : 0);
1235template <
int DIM,
int T_D1D,
int T_Q1D>
1237ConvectionIntegrator::ApplyPAKernels::Kernel()
1239 if constexpr (
DIM == 2)
1241 constexpr int T_NBZ = convection::NBZ(T_D1D);
1242 return SmemPAConvectionApply2D<T_D1D, T_Q1D, T_NBZ>;
1244 else if constexpr (
DIM == 3)
1246 return SmemPAConvectionApply3D<T_D1D, T_Q1D>;
1251template <
int DIM,
int T_D1D,
int T_Q1D>
1253ConvectionIntegrator::ApplyPATKernels::Kernel()
1255 if constexpr (
DIM == 2)
1257 constexpr int T_NBZ = convection::NBZ(T_D1D);
1258 return SmemPAConvectionApplyT2D<T_D1D, T_Q1D, T_NBZ>;
1260 else if constexpr (
DIM == 3)
1262 return SmemPAConvectionApplyT3D<T_D1D, T_Q1D>;
void(*)(const int, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplyKernelType
arguments: NE, B, G, Bt, Gt, pa_data, x, y, D1D, Q1D
real_t u(const Vector &xvec)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void forall_2D_batch(int N, int X, int Y, int BZ, lambda &&body)
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
void forall(int N, lambda &&body)
real_t p(const Vector &x, real_t t)
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.