12#ifndef MFEM_FEM_KERNELS_HPP
13#define MFEM_FEM_KERNELS_HPP
34#if ((defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__)) || \
35 (defined(MFEM_USE_HIP) && defined(__HIP_DEVICE_COMPILE__)))
39template <
int VDIM,
int N>
42template <
int VDIM,
int DIM,
int N = 0>
48template <
int VDIM,
int N>
51template <
int VDIM,
int DIM,
int N>
55constexpr int SetMaxOf(
int n) {
return n; }
60template <
int VDIM,
int N>
63template <
int VDIM,
int DIM,
int N>
69template <
int VDIM,
int N>
72template <
int VDIM,
int DIM,
int N>
77constexpr int NextMultipleOf(
int n)
79 static_assert(N > 0 && (N & (N - 1)) == 0,
"N must be a power of 2");
80 return (n + (N - 1)) & ~(N - 1);
82constexpr int SetMaxOf(
int n) {
return NextMultipleOf<4>(n); }
86template <
int MQ1,
bool TRANSPOSE = false>
87inline MFEM_HOST_DEVICE
void LoadMatrix(
const int d1d,
const int q1d,
90 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
92 MFEM_FOREACH_THREAD_DIRECT(qx, x, q1d)
94 if constexpr (TRANSPOSE)
96 N[dy][qx] = M[qx * d1d + dy];
100 N[dy][qx] = M[dy * q1d + qx];
108template <
int VDIM,
int DIM,
int MQ1 = 0>
109inline MFEM_HOST_DEVICE
void LoadDofs2d(
const int e,
const int d1d,
const int c,
110 const DeviceTensor<4, const real_t> &X,
111 vd_regs2d_t<VDIM, DIM, MQ1> &Y)
113 for (
int d = 0; d <
DIM; d++)
115 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
117 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
119 Y[c][d][dy][dx] = X(dx, dy, c, e);
127template <
int VDIM,
int DIM,
int MQ1 = 0>
128inline MFEM_HOST_DEVICE
void LoadDofs2d(
const int e,
const int d1d,
129 const DeviceTensor<4, const real_t> &X,
130 vd_regs2d_t<VDIM, DIM, MQ1> &Y)
132 for (
int c = 0; c < VDIM; ++c) { LoadDofs2d(e, d1d, c, X, Y); }
136template <
int VDIM,
int MQ1 = 0>
137inline MFEM_HOST_DEVICE
void LoadDofs2d(
const int e,
const int d1d,
138 const DeviceTensor<4, const real_t> &X,
139 v_regs2d_t<VDIM, MQ1> &Y)
141 for (
int c = 0; c < VDIM; ++c)
143 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
145 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
147 Y[c][dy][dx] = X(dx, dy, c, e);
155template <
int MQ1 = 0>
156inline MFEM_HOST_DEVICE
void LoadDofs2d(
const int e,
const int d1d,
157 const DeviceTensor<3, const real_t> &X,
160 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
162 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
164 Y[dy][dx] = X(dx, dy, e);
171template <
int VDIM,
int DIM,
int MQ1 = 0>
172inline MFEM_HOST_DEVICE
void WriteDofs2d(
const int e,
const int d1d,
173 const int i,
const int j,
174 vd_regs2d_t<VDIM, DIM, MQ1> &X,
175 const DeviceTensor<4, real_t> &Y)
177 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
179 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
182 for (
int d = 0; d <
DIM; d++) { y += X(i, d, dy, dx); }
183 Y(dx, dy, j, e) += y;
190template <
int VDIM,
int DIM,
int MQ1 = 0>
191inline MFEM_HOST_DEVICE
void WriteDofs2d(
const int e,
const int d1d,
192 vd_regs2d_t<VDIM, DIM, MQ1> &X,
193 const DeviceTensor<4, real_t> &Y)
195 for (
int c = 0; c < VDIM; ++c) { WriteDofs2d(e, d1d, c, c, X, Y); }
199template <
int VDIM,
int MQ1 = 0>
200inline MFEM_HOST_DEVICE
void WriteDofs2d(
const int e,
const int d1d,
201 v_regs2d_t<VDIM, MQ1> &X,
202 const DeviceTensor<4, real_t> &Y)
204 for (
int c = 0; c < VDIM; ++c)
206 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
208 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
210 Y(dx, dy, c, e) += X(c, dy, dx);
218template <
int VDIM,
int DIM,
int MQ1>
219inline MFEM_HOST_DEVICE
void LoadDofs3d(
const int e,
const int d1d,
const int c,
220 const DeviceTensor<5, const real_t> &X,
221 vd_regs3d_t<VDIM, DIM, MQ1> &Y)
223 for (
int d = 0; d <
DIM; d++)
225 for (
int dz = 0; dz < d1d; ++dz)
227 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
229 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
231 Y[c][d][dz][dy][dx] = X(dx, dy, dz, c, e);
240template <
int VDIM,
int DIM,
int MQ1>
241inline MFEM_HOST_DEVICE
void LoadDofs3d(
const int e,
const int d1d,
242 const DeviceTensor<5, const real_t> &X,
243 vd_regs3d_t<VDIM, DIM, MQ1> &Y)
245 for (
int c = 0; c < VDIM; ++c) { LoadDofs3d(e, d1d, c, X, Y); }
249template <
int VDIM,
int MQ1>
250inline MFEM_HOST_DEVICE
void LoadDofs3d(
const int e,
const int d1d,
251 const DeviceTensor<5, const real_t> &X,
252 v_regs3d_t<VDIM, MQ1> &Y)
254 for (
int c = 0; c < VDIM; ++c)
256 for (
int dz = 0; dz < d1d; ++dz)
258 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
260 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
262 Y[c][dz][dy][dx] = X(dx,dy,dz,c,e);
272inline MFEM_HOST_DEVICE
void LoadDofs3d(
const int e,
const int d1d,
273 const DeviceTensor<4, const real_t> &X,
276 for (
int dz = 0; dz < d1d; ++dz)
278 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
280 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
282 Y[dz][dy][dx] = X(dx,dy,dz,e);
290template <
int VDIM,
int DIM,
int MQ1>
291inline MFEM_HOST_DEVICE
void WriteDofs3d(
const int e,
const int d1d,
292 const int i,
const int j,
293 vd_regs3d_t<VDIM, DIM, MQ1> &X,
294 const DeviceTensor<5, real_t> &Y)
296 for (
int dz = 0; dz < d1d; ++dz)
298 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
300 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
303 for (
int d = 0; d <
DIM; d++) { value += X(i, d, dz, dy, dx); }
304 Y(dx, dy, dz, j, e) += value;
312template <
int VDIM,
int DIM,
int MQ1>
313inline MFEM_HOST_DEVICE
void WriteDofs3d(
const int e,
const int d1d,
314 vd_regs3d_t<VDIM, DIM, MQ1> &X,
315 const DeviceTensor<5, real_t> &Y)
317 for (
int c = 0; c < VDIM; ++c) { WriteDofs3d(e, d1d, c, c, X, Y); }
321template <
int VDIM,
int MQ1>
322inline MFEM_HOST_DEVICE
void WriteDofs3d(
const int e,
const int d1d,
323 v_regs3d_t<VDIM, MQ1> &X,
324 const DeviceTensor<5, real_t> &Y)
326 for (
int c = 0; c < VDIM; ++c)
328 for (
int dz = 0; dz < d1d; ++dz)
330 MFEM_FOREACH_THREAD_DIRECT(dy, y, d1d)
332 MFEM_FOREACH_THREAD_DIRECT(dx, x, d1d)
334 Y(dx, dy, dz, c, e) += X(c, dz, dy, dx);
343template <
bool Transpose,
int MQ1>
344inline MFEM_HOST_DEVICE
void ContractX2d(
const int d1d,
const int q1d,
347 const s_regs2d_t<MQ1> &X,
350 MFEM_FOREACH_THREAD_DIRECT(y, y, d1d)
352 MFEM_FOREACH_THREAD_DIRECT(x, x, (
Transpose ? q1d : d1d))
354 smem[y][x] = X[y][x];
358 MFEM_FOREACH_THREAD_DIRECT(y, y, d1d)
360 MFEM_FOREACH_THREAD_DIRECT(x, x, (
Transpose ? d1d : q1d))
363 for (
int k = 0; k < (
Transpose ? q1d : d1d); ++k)
365 u += (
Transpose ? B[x][k] : B[k][x]) * smem[y][k];
374template <
bool Transpose,
int MQ1>
375inline MFEM_HOST_DEVICE
void ContractY2d(
const int d1d,
const int q1d,
378 const s_regs2d_t<MQ1> &X,
381 MFEM_FOREACH_THREAD_DIRECT(y, y, (
Transpose ? q1d : d1d))
383 MFEM_FOREACH_THREAD_DIRECT(x, x, q1d) { smem[y][x] = X[y][x]; }
386 MFEM_FOREACH_THREAD_DIRECT(y, y, (
Transpose ? d1d : q1d))
388 MFEM_FOREACH_THREAD_DIRECT(x, x, q1d)
391 for (
int k = 0; k < (
Transpose ? q1d : d1d); ++k)
393 u += (
Transpose ? B[y][k] : B[k][y]) * smem[k][x];
402template <
int MQ1 = 0>
403inline MFEM_HOST_DEVICE
void Copy2d(
const int q1d,
407 MFEM_FOREACH_THREAD_DIRECT(y, y, q1d)
409 MFEM_FOREACH_THREAD_DIRECT(x, x, q1d) { Y[y][x] = X[y][x]; }
415template <
bool Transpose,
int MQ1>
416inline MFEM_HOST_DEVICE
void Contract2d(
const int d1d,
const int q1d,
425 ContractX2d<false>(d1d, q1d, smem, Bx, X, Y);
426 ContractY2d<false>(d1d, q1d, smem, By, Y, X);
432 ContractY2d<true>(d1d, q1d, smem, By, Y, X);
433 ContractX2d<true>(d1d, q1d, smem, Bx, X, Y);
438template <
int MQ1,
bool Transpose = false>
439inline MFEM_HOST_DEVICE
void Eval2d(
const int d1d,
const int q1d,
445 Contract2d<Transpose, MQ1>(d1d, q1d, smem, B, B, X, Y);
449template <
int VDIM,
int MQ1,
bool Transpose = false>
450inline MFEM_HOST_DEVICE
void Eval2d(
const int d1d,
const int q1d,
453 v_regs2d_t<VDIM, MQ1> &X,
454 v_regs2d_t<VDIM, MQ1> &Y)
456 for (
int c = 0; c < VDIM; c++)
458 Eval2d<MQ1, Transpose>(d1d, q1d, smem, B, X[c], Y[c]);
463template <
int VDIM,
int MQ1>
464inline MFEM_HOST_DEVICE
void EvalTranspose2d(
const int d1d,
const int q1d,
467 v_regs2d_t<VDIM, MQ1> &X,
468 v_regs2d_t<VDIM, MQ1> &Y)
470 Eval2d<VDIM, MQ1, true>(d1d, q1d, smem, B, X, Y);
474template <
int VDIM,
int DIM,
int MQ1,
bool Transpose = false>
475inline MFEM_HOST_DEVICE
void Grad2d(
const int d1d,
const int q1d,
479 vd_regs2d_t<VDIM, DIM, MQ1> &X,
480 vd_regs2d_t<VDIM, DIM, MQ1> &Y,
484 for (
int d = 0; d <
DIM; d++)
486 const real_t (*Bx)[MQ1] = (d == 0) ? G : B;
487 const real_t (*By)[MQ1] = (d == 1) ? G : B;
488 Contract2d<Transpose>(d1d, q1d, smem, Bx, By, X[c][d], Y[c][d]);
494template <
int VDIM,
int DIM,
int MQ1,
bool Transpose = false>
495inline MFEM_HOST_DEVICE
void Grad2d(
const int d1d,
const int q1d,
499 vd_regs2d_t<VDIM, DIM, MQ1> &X,
500 vd_regs2d_t<VDIM, DIM, MQ1> &Y)
502 for (
int c = 0; c < VDIM; ++c)
504 Grad2d<VDIM, DIM, MQ1, Transpose>(d1d, q1d, smem, B, G, X, Y, c);
509template <
int VDIM,
int DIM,
int MQ1>
510inline MFEM_HOST_DEVICE
void GradTranspose2d(
const int d1d,
const int q1d,
514 vd_regs2d_t<VDIM, DIM, MQ1> &X,
515 vd_regs2d_t<VDIM, DIM, MQ1> &Y)
518 Grad2d<VDIM, DIM, MQ1, Transpose>(d1d, q1d, smem, B, G, X, Y);
522template <
int VDIM,
int DIM,
int MQ1>
523inline MFEM_HOST_DEVICE
void GradTranspose2d(
const int d1d,
const int q1d,
527 vd_regs2d_t<VDIM, DIM, MQ1> &X,
528 vd_regs2d_t<VDIM, DIM, MQ1> &Y,
532 Grad2d<VDIM, DIM, MQ1, Transpose>(d1d, q1d, smem, B, G, X, Y, c);
536template <
bool Transpose,
int MQ1>
537inline MFEM_HOST_DEVICE
void ContractX3d(
const int d1d,
const int q1d,
540 const s_regs3d_t<MQ1> &X,
543 for (
int z = 0; z < d1d; ++z)
545 MFEM_FOREACH_THREAD_DIRECT(y, y, d1d)
547 MFEM_FOREACH_THREAD_DIRECT(x, x, (
Transpose ? q1d : d1d))
549 smem[y][x] = X[z][y][x];
553 MFEM_FOREACH_THREAD_DIRECT(y, y, d1d)
555 MFEM_FOREACH_THREAD_DIRECT(x, x, (
Transpose ? d1d : q1d))
558 for (
int k = 0; k < (
Transpose ? q1d : d1d); ++k)
560 u += (
Transpose ? B[x][k] : B[k][x]) * smem[y][k];
570template <
bool Transpose,
int MQ1>
571inline MFEM_HOST_DEVICE
void ContractY3d(
const int d1d,
const int q1d,
574 const s_regs3d_t<MQ1> &X,
577 for (
int z = 0; z < d1d; ++z)
579 MFEM_FOREACH_THREAD_DIRECT(y, y, (
Transpose ? q1d : d1d))
581 MFEM_FOREACH_THREAD_DIRECT(x, x, q1d) { smem[y][x] = X[z][y][x]; }
584 MFEM_FOREACH_THREAD_DIRECT(y, y, (
Transpose ? d1d : q1d))
586 MFEM_FOREACH_THREAD_DIRECT(x, x, q1d)
589 for (
int k = 0; k < (
Transpose ? q1d : d1d); ++k)
591 u += (
Transpose ? B[y][k] : B[k][y]) * smem[k][x];
601template <
bool Transpose,
int MQ1>
602inline MFEM_HOST_DEVICE
void ContractZ3d(
const int d1d,
const int q1d,
604 const s_regs3d_t<MQ1> &X,
607 for (
int z = 0; z < (
Transpose ? d1d : q1d); ++z)
609 MFEM_FOREACH_THREAD_DIRECT(y, y, q1d)
611 MFEM_FOREACH_THREAD_DIRECT(x, x, q1d)
614 for (
int k = 0; k < (
Transpose ? q1d : d1d); ++k)
616 u += (
Transpose ? B[z][k] : B[k][z]) * X[k][y][x];
625template <
bool Transpose,
int MQ1>
626inline MFEM_HOST_DEVICE
void Contract3d(
const int d1d,
const int q1d,
636 ContractX3d<false>(d1d, q1d, smem, Bx, X, Y);
637 ContractY3d<false>(d1d, q1d, smem, By, Y, X);
638 ContractZ3d<false>(d1d, q1d, Bz, X, Y);
642 ContractZ3d<true>(d1d, q1d, Bz, X, Y);
643 ContractY3d<true>(d1d, q1d, smem, By, Y, X);
644 ContractX3d<true>(d1d, q1d, smem, Bx, X, Y);
649template <
int MQ1,
bool Transpose = false>
650inline MFEM_HOST_DEVICE
void Eval3d(
const int d1d,
const int q1d,
656 Contract3d<Transpose>(d1d, q1d, smem, B, B, B, X, Y);
660template <
int VDIM,
int MQ1,
bool Transpose = false>
661inline MFEM_HOST_DEVICE
void Eval3d(
const int d1d,
const int q1d,
664 v_regs3d_t<VDIM, MQ1> &X,
665 v_regs3d_t<VDIM, MQ1> &Y)
667 for (
int c = 0; c < VDIM; c++)
669 Eval3d<MQ1, Transpose>(d1d, q1d, smem, B, X[c], Y[c]);
674template <
int VDIM,
int MQ1>
675inline MFEM_HOST_DEVICE
void EvalTranspose3d(
const int d1d,
const int q1d,
678 v_regs3d_t<VDIM, MQ1> &X,
679 v_regs3d_t<VDIM, MQ1> &Y)
681 Eval3d<VDIM, MQ1, true>(d1d, q1d, smem, B, X, Y);
685template <
int VDIM,
int DIM,
int MQ1,
bool Transpose = false>
686inline MFEM_HOST_DEVICE
void Grad3d(
const int d1d,
const int q1d,
690 vd_regs3d_t<VDIM, DIM, MQ1> &X,
691 vd_regs3d_t<VDIM, DIM, MQ1> &Y,
694 for (
int d = 0; d <
DIM; d++)
696 const real_t (*Bx)[MQ1] = (d == 0) ? G : B;
697 const real_t (*By)[MQ1] = (d == 1) ? G : B;
698 const real_t (*Bz)[MQ1] = (d == 2) ? G : B;
699 Contract3d<Transpose>(d1d, q1d, smem, Bx, By, Bz, X[c][d], Y[c][d]);
704template <
int VDIM,
int DIM,
int MQ1,
bool Transpose = false>
705inline MFEM_HOST_DEVICE
void Grad3d(
const int d1d,
const int q1d,
709 vd_regs3d_t<VDIM, DIM, MQ1> &X,
710 vd_regs3d_t<VDIM, DIM, MQ1> &Y)
712 for (
int c = 0; c < VDIM; c++)
714 Grad3d<VDIM, DIM, MQ1, Transpose>(d1d, q1d, smem, B, G, X, Y, c);
719template <
int VDIM,
int DIM,
int MQ1>
720inline MFEM_HOST_DEVICE
void GradTranspose3d(
const int d1d,
const int q1d,
724 vd_regs3d_t<VDIM, DIM, MQ1> &X,
725 vd_regs3d_t<VDIM, DIM, MQ1> &Y)
727 Grad3d<VDIM, DIM, MQ1, true>(d1d, q1d, smem, B, G, X, Y);
731template <
int VDIM,
int DIM,
int MQ1>
732inline MFEM_HOST_DEVICE
void GradTranspose3d(
const int d1d,
const int q1d,
736 vd_regs3d_t<VDIM, DIM, MQ1> &X,
737 vd_regs3d_t<VDIM, DIM, MQ1> &Y,
740 Grad3d<VDIM, DIM, MQ1, true>(d1d, q1d, smem, B, G, X, Y, c);
744template<
int MD1,
int MQ1>
745MFEM_HOST_DEVICE
inline void LoadB(
const int D1D,
const int Q1D,
749 const int tidz = MFEM_THREAD_ID(z);
754 MFEM_FOREACH_THREAD(d,y,D1D)
756 MFEM_FOREACH_THREAD(q,x,Q1D)
766template<
int MD1,
int MQ1>
767MFEM_HOST_DEVICE
inline void LoadBt(
const int D1D,
const int Q1D,
771 const int tidz = MFEM_THREAD_ID(z);
776 MFEM_FOREACH_THREAD(d,y,D1D)
778 MFEM_FOREACH_THREAD(q,x,Q1D)
788template<
int MD1,
int MQ1>
789MFEM_HOST_DEVICE
inline void LoadBG(
const int D1D,
const int Q1D,
792 real_t (&sBG)[2][MQ1*MD1])
794 const int tidz = MFEM_THREAD_ID(z);
800 MFEM_FOREACH_THREAD(d,y,D1D)
802 MFEM_FOREACH_THREAD(q,x,Q1D)
813template<
int MD1,
int MQ1>
814MFEM_HOST_DEVICE
inline void LoadBGt(
const int D1D,
const int Q1D,
817 real_t (&sBG)[2][MQ1*MD1])
819 const int tidz = MFEM_THREAD_ID(z);
825 MFEM_FOREACH_THREAD(d,y,D1D)
827 MFEM_FOREACH_THREAD(q,x,Q1D)
838MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
839 const DeviceTensor<3, const real_t> &x,
842 MFEM_FOREACH_THREAD(dy,y,D1D)
844 MFEM_FOREACH_THREAD(dx,x,D1D)
846 DD(dx,dy) = x(dx,dy,e);
854template<
int MD1,
int NBZ>
855MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
856 const DeviceTensor<3, const real_t> &x,
857 real_t (&sX)[NBZ][MD1*MD1])
859 const int tidz = MFEM_THREAD_ID(z);
865MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
const int c,
866 const DeviceTensor<4, const real_t> &x,
869 MFEM_FOREACH_THREAD(dy,y,D1D)
871 MFEM_FOREACH_THREAD(dx,x,D1D)
873 DD(dx,dy) = x(dx,dy,c,e);
879template<
int MD1,
int NBZ>
880MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
const int c,
881 const DeviceTensor<4, const real_t> &x,
882 real_t (&sm)[NBZ][MD1*MD1])
884 const int tidz = MFEM_THREAD_ID(z);
890MFEM_HOST_DEVICE
inline void EvalX(
const int D1D,
const int Q1D,
895 MFEM_FOREACH_THREAD(dy,y,D1D)
897 MFEM_FOREACH_THREAD(qx,x,Q1D)
900 for (
int dx = 0; dx < D1D; ++dx)
902 u += B(dx,qx) * DD(dx,dy);
910template<
int MD1,
int MQ1,
int NBZ>
911MFEM_HOST_DEVICE
inline void EvalX(
const int D1D,
const int Q1D,
912 const real_t (&sB)[MQ1*MD1],
913 real_t (&sDD)[NBZ][MD1*MD1],
914 real_t (&sDQ)[NBZ][MD1*MQ1])
916 const int tidz = MFEM_THREAD_ID(z);
920 EvalX(D1D,Q1D,B,DD,DQ);
924MFEM_HOST_DEVICE
inline void EvalY(
const int D1D,
const int Q1D,
929 MFEM_FOREACH_THREAD(qy,y,Q1D)
931 MFEM_FOREACH_THREAD(qx,x,Q1D)
934 for (
int dy = 0; dy < D1D; ++dy)
936 u += DQ(dy,qx) * B(dy,qy);
944template<
int MD1,
int MQ1,
int NBZ>
945MFEM_HOST_DEVICE
inline void EvalY(
const int D1D,
const int Q1D,
946 const real_t (&sB)[MQ1*MD1],
947 real_t (&sDQ)[NBZ][MD1*MQ1],
948 real_t (&sQQ)[NBZ][MQ1*MQ1])
950 const int tidz = MFEM_THREAD_ID(z);
954 EvalY(D1D,Q1D,B,DQ,QQ);
958MFEM_HOST_DEVICE
inline void PullEval(
const int qx,
const int qy,
965template<
int MQ1,
int NBZ>
966MFEM_HOST_DEVICE
inline void PullEval(
const int Q1D,
967 const int qx,
const int qy,
968 real_t (&sQQ)[NBZ][MQ1*MQ1],
971 const int tidz = MFEM_THREAD_ID(z);
973 PullEval(qx,qy,QQ,P);
977template<
int MD1,
int NBZ>
978MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
979 const DeviceTensor<4, const real_t> &X,
980 real_t (&sX)[2][NBZ][MD1*MD1])
982 const int tidz = MFEM_THREAD_ID(z);
986 MFEM_FOREACH_THREAD(dy,y,D1D)
988 MFEM_FOREACH_THREAD(dx,x,D1D)
990 X0(dx,dy) = X(dx,dy,0,e);
991 X1(dx,dy) = X(dx,dy,1,e);
998template<
int MD1,
int MQ1,
int NBZ>
999MFEM_HOST_DEVICE
inline void EvalX(
const int D1D,
const int Q1D,
1000 const real_t (&sB)[MQ1*MD1],
1001 const real_t (&sX)[2][NBZ][MD1*MD1],
1002 real_t (&sDQ)[2][NBZ][MD1*MQ1])
1004 const int tidz = MFEM_THREAD_ID(z);
1011 MFEM_FOREACH_THREAD(dy,y,D1D)
1013 MFEM_FOREACH_THREAD(qx,x,Q1D)
1016 for (
int dx = 0; dx < D1D; ++dx)
1018 const real_t xx = X0(dx,dy);
1019 const real_t xy = X1(dx,dy);
1020 u[0] += B(dx,qx) * xx;
1021 u[1] += B(dx,qx) * xy;
1031template<
int MD1,
int MQ1,
int NBZ>
1032MFEM_HOST_DEVICE
inline void EvalY(
const int D1D,
const int Q1D,
1033 const real_t (&sB)[MQ1*MD1],
1034 const real_t (&sDQ)[2][NBZ][MD1*MQ1],
1035 real_t (&sQQ)[2][NBZ][MQ1*MQ1])
1037 const int tidz = MFEM_THREAD_ID(z);
1044 MFEM_FOREACH_THREAD(qy,y,Q1D)
1046 MFEM_FOREACH_THREAD(qx,x,Q1D)
1049 for (
int dy = 0; dy < D1D; ++dy)
1051 u[0] += DQ0(qx,dy) * B(dy,qy);
1052 u[1] += DQ1(qx,dy) * B(dy,qy);
1062template<
int MQ1,
int NBZ>
1063MFEM_HOST_DEVICE
inline void PullEval(
const int Q1D,
1064 const int qx,
const int qy,
1065 const real_t (&sQQ)[2][NBZ][MQ1*MQ1],
1068 const int tidz = MFEM_THREAD_ID(z);
1077template<
int MQ1,
int NBZ>
1078MFEM_HOST_DEVICE
inline void PushEval(
const int Q1D,
1079 const int qx,
const int qy,
1081 real_t (&sQQ)[2][NBZ][MQ1*MQ1])
1083 const int tidz = MFEM_THREAD_ID(z);
1092template<
int MD1,
int MQ1,
int NBZ>
1093MFEM_HOST_DEVICE
inline void EvalXt(
const int D1D,
const int Q1D,
1094 const real_t (&sB)[MQ1*MD1],
1095 const real_t (&sQQ)[2][NBZ][MQ1*MQ1],
1096 real_t (&sDQ)[2][NBZ][MD1*MQ1])
1098 const int tidz = MFEM_THREAD_ID(z);
1105 MFEM_FOREACH_THREAD(qy,y,Q1D)
1107 MFEM_FOREACH_THREAD(dx,x,D1D)
1110 for (
int qx = 0; qx < Q1D; ++qx)
1112 u[0] += QQ0(qx,qy) * Bt(qx,dx);
1113 u[1] += QQ1(qx,qy) * Bt(qx,dx);
1123template<
int MD1,
int MQ1,
int NBZ>
1124MFEM_HOST_DEVICE
inline void EvalYt(
const int D1D,
const int Q1D,
1125 const real_t (&sB)[MQ1*MD1],
1126 const real_t (&sDQ)[2][NBZ][MD1*MQ1],
1127 const DeviceTensor<4> &Y,
1130 const int tidz = MFEM_THREAD_ID(z);
1135 MFEM_FOREACH_THREAD(dy,y,D1D)
1137 MFEM_FOREACH_THREAD(dx,x,D1D)
1140 for (
int qy = 0; qy < Q1D; ++qy)
1142 u[0] += Bt(qy,dy) * DQ0(qy,dx);
1143 u[1] += Bt(qy,dy) * DQ1(qy,dx);
1145 Y(dx,dy,0,e) +=
u[0];
1146 Y(dx,dy,1,e) +=
u[1];
1153template<
int MD1,
int MQ1,
int NBZ>
1154MFEM_HOST_DEVICE
inline void GradX(
const int D1D,
const int Q1D,
1155 const real_t (&sBG)[2][MQ1*MD1],
1156 const real_t (&sX)[2][NBZ][MD1*MD1],
1157 real_t (&sDQ)[4][NBZ][MD1*MQ1])
1159 const int tidz = MFEM_THREAD_ID(z);
1169 MFEM_FOREACH_THREAD(dy,y,D1D)
1171 MFEM_FOREACH_THREAD(qx,x,Q1D)
1174 real_t v[2] = {0.0, 0.0};
1175 for (
int dx = 0; dx < D1D; ++dx)
1177 const real_t Bx = B(dx,qx);
1178 const real_t Gx = G(dx,qx);
1179 const real_t x0 = X0(dx,dy);
1180 const real_t x1 = X1(dx,dy);
1196template<
int MD1,
int MQ1,
int NBZ>
1197MFEM_HOST_DEVICE
inline void GradY(
const int D1D,
const int Q1D,
1198 const real_t (&sBG)[2][MQ1*MD1],
1199 const real_t (&sDQ)[4][NBZ][MD1*MQ1],
1200 real_t (&sQQ)[4][NBZ][MQ1*MQ1])
1202 const int tidz = MFEM_THREAD_ID(z);
1214 MFEM_FOREACH_THREAD(qy,y,Q1D)
1216 MFEM_FOREACH_THREAD(qx,x,Q1D)
1219 real_t v[2] = {0.0, 0.0};
1220 for (
int dy = 0; dy < D1D; ++dy)
1222 const real_t By = B(dy,qy);
1223 const real_t Gy = G(dy,qy);
1224 u[0] += X0G(qx,dy) * By;
1225 v[0] += X0B(qx,dy) * Gy;
1226 u[1] += X1G(qx,dy) * By;
1227 v[1] += X1B(qx,dy) * Gy;
1239template<
int MQ1,
int NBZ>
1240MFEM_HOST_DEVICE
inline void PullGrad(
const int Q1D,
1241 const int qx,
const int qy,
1242 const real_t (&sQQ)[4][NBZ][MQ1*MQ1],
1245 const int tidz = MFEM_THREAD_ID(z);
1251 Jpr[0] = X0GB(qx,qy);
1252 Jpr[1] = X1GB(qx,qy);
1253 Jpr[2] = X0BG(qx,qy);
1254 Jpr[3] = X1BG(qx,qy);
1258template<
int MQ1,
int NBZ>
1259MFEM_HOST_DEVICE
inline void PushGrad(
const int Q1D,
1260 const int qx,
const int qy,
1262 real_t (&sQQ)[4][NBZ][MQ1*MQ1])
1264 const int tidz = MFEM_THREAD_ID(z);
1277template<
int MD1,
int MQ1,
int NBZ>
1278MFEM_HOST_DEVICE
inline void GradYt(
const int D1D,
const int Q1D,
1279 const real_t (&sBG)[2][MQ1*MD1],
1280 const real_t (&GQ)[4][NBZ][MQ1*MQ1],
1281 real_t (&GD)[4][NBZ][MD1*MQ1])
1283 const int tidz = MFEM_THREAD_ID(z);
1295 MFEM_FOREACH_THREAD(qy,y,Q1D)
1297 MFEM_FOREACH_THREAD(dx,x,D1D)
1300 real_t v[2] = {0.0, 0.0};
1301 for (
int qx = 0; qx < Q1D; ++qx)
1303 u[0] += Gt(qx,dx) * QQx0(qx,qy);
1304 u[1] += Gt(qx,dx) * QQy0(qx,qy);
1305 v[0] += Bt(qx,dx) * QQx1(qx,qy);
1306 v[1] += Bt(qx,dx) * QQy1(qx,qy);
1318template<
int MD1,
int MQ1,
int NBZ>
1319MFEM_HOST_DEVICE
inline void GradXt(
const int D1D,
const int Q1D,
1320 const real_t (&sBG)[2][MQ1*MD1],
1321 const real_t (&GD)[4][NBZ][MD1*MQ1],
1322 const DeviceTensor<4> &Y,
1325 const int tidz = MFEM_THREAD_ID(z);
1333 MFEM_FOREACH_THREAD(dy,y,D1D)
1335 MFEM_FOREACH_THREAD(dx,x,D1D)
1338 real_t v[2] = {0.0, 0.0};
1339 for (
int qy = 0; qy < Q1D; ++qy)
1341 u[0] += DQxB(qy,dx) * Bt(qy,dy);
1342 u[1] += DQyB(qy,dx) * Bt(qy,dy);
1343 v[0] += DQxG(qy,dx) * Gt(qy,dy);
1344 v[1] += DQyG(qy,dx) * Gt(qy,dy);
1346 Y(dx,dy,0,e) +=
u[0] + v[0];
1347 Y(dx,dy,1,e) +=
u[1] + v[1];
1354MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
1355 const DeviceTensor<4, const real_t> &x,
1358 MFEM_FOREACH_THREAD(dz,z,D1D)
1360 MFEM_FOREACH_THREAD(dy,y,D1D)
1362 MFEM_FOREACH_THREAD(dx,x,D1D)
1364 X(dx,dy,dz) = x(dx,dy,dz,e);
1372MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
1373 const DeviceTensor<4, const real_t> &x,
1374 real_t (&sm)[MD1*MD1*MD1])
1381MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
const int c,
1382 const DeviceTensor<5, const real_t> &x,
1385 MFEM_FOREACH_THREAD(dz,z,D1D)
1387 MFEM_FOREACH_THREAD(dy,y,D1D)
1389 MFEM_FOREACH_THREAD(dx,x,D1D)
1391 X(dx,dy,dz) = x(dx,dy,dz,c,e);
1400MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
const int c,
1401 const DeviceTensor<5, const real_t> &x,
1402 real_t (&sm)[MD1*MD1*MD1])
1405 return LoadX<MD1>(e,D1D,c,x,X);
1409MFEM_HOST_DEVICE
inline void EvalX(
const int D1D,
const int Q1D,
1414 MFEM_FOREACH_THREAD(dz,z,D1D)
1416 MFEM_FOREACH_THREAD(dy,y,D1D)
1418 MFEM_FOREACH_THREAD(qx,x,Q1D)
1421 for (
int dx = 0; dx < D1D; ++dx)
1423 const real_t Bx = B(dx,qx);
1424 u += Bx * DDD(dx,dy,dz);
1433template<
int MD1,
int MQ1>
1434MFEM_HOST_DEVICE
inline void EvalX(
const int D1D,
const int Q1D,
1435 const real_t (&sB)[MQ1*MD1],
1436 const real_t (&sDDD)[MD1*MD1*MD1],
1437 real_t (&sDDQ)[MD1*MD1*MQ1])
1442 EvalX(D1D,Q1D,B,DDD,DDQ);
1446MFEM_HOST_DEVICE
inline void EvalY(
const int D1D,
const int Q1D,
1451 MFEM_FOREACH_THREAD(dz,z,D1D)
1453 MFEM_FOREACH_THREAD(qy,y,Q1D)
1455 MFEM_FOREACH_THREAD(qx,x,Q1D)
1458 for (
int dy = 0; dy < D1D; ++dy)
1460 const real_t By = B(dy,qy);
1461 u += DDQ(dz,dy,qx) * By;
1470template<
int MD1,
int MQ1>
1471MFEM_HOST_DEVICE
inline void EvalY(
const int D1D,
const int Q1D,
1472 const real_t (&sB)[MQ1*MD1],
1473 const real_t (&sDDQ)[MD1*MD1*MQ1],
1474 real_t (&sDQQ)[MD1*MQ1*MQ1])
1479 EvalY(D1D,Q1D,B,DDQ,DQQ);
1483MFEM_HOST_DEVICE
inline void EvalZ(
const int D1D,
const int Q1D,
1488 MFEM_FOREACH_THREAD(qz,z,Q1D)
1490 MFEM_FOREACH_THREAD(qy,y,Q1D)
1492 MFEM_FOREACH_THREAD(qx,x,Q1D)
1495 for (
int dz = 0; dz < D1D; ++dz)
1497 const real_t Bz = B(dz,qz);
1498 u += DQQ(dz,qy,qx) * Bz;
1507template<
int MD1,
int MQ1>
1508MFEM_HOST_DEVICE
inline void EvalZ(
const int D1D,
const int Q1D,
1509 const real_t (&sB)[MQ1*MD1],
1510 const real_t (&sDQQ)[MD1*MQ1*MQ1],
1511 real_t (&sQQQ)[MQ1*MQ1*MQ1])
1516 EvalZ(D1D,Q1D,B,DQQ,QQQ);
1520MFEM_HOST_DEVICE
inline void PullEval(
const int x,
const int y,
const int z,
1528MFEM_HOST_DEVICE
inline void PullEval(
const int Q1D,
1529 const int x,
const int y,
const int z,
1530 const real_t (&sQQQ)[MQ1*MQ1*MQ1],
1534 PullEval(x,y,z,QQQ,X);
1539MFEM_HOST_DEVICE
inline void LoadX(
const int e,
const int D1D,
1540 const DeviceTensor<5, const real_t> &X,
1541 real_t (*sm)[MD1*MD1*MD1])
1547 MFEM_FOREACH_THREAD(dz,z,D1D)
1549 MFEM_FOREACH_THREAD(dy,y,D1D)
1551 MFEM_FOREACH_THREAD(dx,x,D1D)
1553 Xx(dx,dy,dz) = X(dx,dy,dz,0,e);
1554 Xy(dx,dy,dz) = X(dx,dy,dz,1,e);
1555 Xz(dx,dy,dz) = X(dx,dy,dz,2,e);
1563template<
int MD1,
int MQ1>
1564MFEM_HOST_DEVICE
inline void EvalX(
const int D1D,
const int Q1D,
1565 const real_t (&sB)[MQ1*MD1],
1566 const real_t (&sDDD)[3][MD1*MD1*MD1],
1567 real_t (&sDDQ)[3][MD1*MD1*MQ1])
1577 MFEM_FOREACH_THREAD(dz,z,D1D)
1579 MFEM_FOREACH_THREAD(dy,y,D1D)
1581 MFEM_FOREACH_THREAD(qx,x,Q1D)
1583 real_t u[3] = {0.0, 0.0, 0.0};
1584 for (
int dx = 0; dx < D1D; ++dx)
1586 const real_t Bx = B(dx,qx);
1587 u[0] += Bx * Xx(dx,dy,dz);
1588 u[1] += Bx * Xy(dx,dy,dz);
1589 u[2] += Bx * Xz(dx,dy,dz);
1591 XxB(qx,dy,dz) =
u[0];
1592 XyB(qx,dy,dz) =
u[1];
1593 XzB(qx,dy,dz) =
u[2];
1601template<
int MD1,
int MQ1>
1602MFEM_HOST_DEVICE
inline void EvalY(
const int D1D,
const int Q1D,
1603 const real_t (&sB)[MQ1*MD1],
1604 const real_t (&sDDQ)[3][MD1*MD1*MQ1],
1605 real_t (&sDQQ)[3][MD1*MQ1*MQ1])
1615 MFEM_FOREACH_THREAD(dz,z,D1D)
1617 MFEM_FOREACH_THREAD(qy,y,Q1D)
1619 MFEM_FOREACH_THREAD(qx,x,Q1D)
1621 real_t u[3] = {0.0, 0.0, 0.0};
1622 for (
int dy = 0; dy < D1D; ++dy)
1624 const real_t By = B(dy,qy);
1625 u[0] += XxB(qx,dy,dz) * By;
1626 u[1] += XyB(qx,dy,dz) * By;
1627 u[2] += XzB(qx,dy,dz) * By;
1629 XxBB(qx,qy,dz) =
u[0];
1630 XyBB(qx,qy,dz) =
u[1];
1631 XzBB(qx,qy,dz) =
u[2];
1639template<
int MD1,
int MQ1>
1640MFEM_HOST_DEVICE
inline void EvalZ(
const int D1D,
const int Q1D,
1641 const real_t (&sB)[MQ1*MD1],
1642 const real_t (&sDQQ)[3][MD1*MQ1*MQ1],
1643 real_t (&sQQQ)[3][MQ1*MQ1*MQ1])
1653 MFEM_FOREACH_THREAD(qz,z,Q1D)
1655 MFEM_FOREACH_THREAD(qy,y,Q1D)
1657 MFEM_FOREACH_THREAD(qx,x,Q1D)
1659 real_t u[3] = {0.0, 0.0, 0.0};
1660 for (
int dz = 0; dz < D1D; ++dz)
1662 const real_t Bz = B(dz,qz);
1663 u[0] += XxBB(qx,qy,dz) * Bz;
1664 u[1] += XyBB(qx,qy,dz) * Bz;
1665 u[2] += XzBB(qx,qy,dz) * Bz;
1667 XxBBB(qx,qy,qz) =
u[0];
1668 XyBBB(qx,qy,qz) =
u[1];
1669 XzBBB(qx,qy,qz) =
u[2];
1678MFEM_HOST_DEVICE
inline void PullEval(
const int Q1D,
1679 const int x,
const int y,
const int z,
1680 const real_t (&sQQQ)[3][MQ1*MQ1*MQ1],
1687 X[0] = XxBBB(x,y,z);
1688 X[1] = XyBBB(x,y,z);
1689 X[2] = XzBBB(x,y,z);
1694MFEM_HOST_DEVICE
inline void PushEval(
const int Q1D,
1695 const int x,
const int y,
const int z,
1697 real_t (&sQQQ)[3][MQ1*MQ1*MQ1])
1703 XxBBB(x,y,z) = A[0];
1704 XyBBB(x,y,z) = A[1];
1705 XzBBB(x,y,z) = A[2];
1709template<
int MD1,
int MQ1>
1710MFEM_HOST_DEVICE
inline void EvalXt(
const int D1D,
const int Q1D,
1711 const real_t (&sB)[MQ1*MD1],
1712 const real_t (&sQQQ)[3][MQ1*MQ1*MQ1],
1713 real_t (&sDQQ)[3][MD1*MQ1*MQ1])
1723 MFEM_FOREACH_THREAD(qz,z,Q1D)
1725 MFEM_FOREACH_THREAD(qy,y,Q1D)
1727 MFEM_FOREACH_THREAD(dx,x,D1D)
1729 real_t u[3] = {0.0, 0.0, 0.0};
1730 for (
int qx = 0; qx < Q1D; ++qx)
1732 const real_t Btx = Bt(qx,dx);
1733 u[0] += XxBBB(qx,qy,qz) * Btx;
1734 u[1] += XyBBB(qx,qy,qz) * Btx;
1735 u[2] += XzBBB(qx,qy,qz) * Btx;
1737 XxBB(qz,qy,dx) =
u[0];
1738 XyBB(qz,qy,dx) =
u[1];
1739 XzBB(qz,qy,dx) =
u[2];
1747template<
int MD1,
int MQ1>
1748MFEM_HOST_DEVICE
inline void EvalYt(
const int D1D,
const int Q1D,
1749 const real_t (&sB)[MQ1*MD1],
1750 const real_t (&sDQQ)[3][MD1*MQ1*MQ1],
1751 real_t (&sDDQ)[3][MD1*MD1*MQ1])
1761 MFEM_FOREACH_THREAD(qz,z,Q1D)
1763 MFEM_FOREACH_THREAD(dy,y,D1D)
1765 MFEM_FOREACH_THREAD(dx,x,D1D)
1767 real_t u[3] = {0.0, 0.0, 0.0};
1768 for (
int qy = 0; qy < Q1D; ++qy)
1770 const real_t Bty = Bt(qy,dy);
1771 u[0] += XxBB(qz,qy,dx) * Bty;
1772 u[1] += XyBB(qz,qy,dx) * Bty;
1773 u[2] += XzBB(qz,qy,dx) * Bty;
1776 XxB(qz,dy,dx) =
u[0];
1777 XyB(qz,dy,dx) =
u[1];
1778 XzB(qz,dy,dx)=
u[2];
1786template<
int MD1,
int MQ1>
1787MFEM_HOST_DEVICE
inline void EvalZt(
const int D1D,
const int Q1D,
1788 const real_t (&sB)[MQ1*MD1],
1789 const real_t (&sDDQ)[3][MD1*MD1*MQ1],
1790 const DeviceTensor<5> &Y,
1798 MFEM_FOREACH_THREAD(dz,z,D1D)
1800 MFEM_FOREACH_THREAD(dy,y,D1D)
1802 MFEM_FOREACH_THREAD(dx,x,D1D)
1804 real_t u[3] = {0.0, 0.0, 0.0};
1805 for (
int qz = 0; qz < Q1D; ++qz)
1807 const real_t Btz = Bt(qz,dz);
1808 u[0] += XxB(qz,dy,dx) * Btz;
1809 u[1] += XyB(qz,dy,dx) * Btz;
1810 u[2] += XzB(qz,dy,dx) * Btz;
1812 Y(dx,dy,dz,0,e) +=
u[0];
1813 Y(dx,dy,dz,1,e) +=
u[1];
1814 Y(dx,dy,dz,2,e) +=
u[2];
1821template<
int MD1,
int MQ1>
1822MFEM_HOST_DEVICE
inline void GradX(
const int D1D,
const int Q1D,
1823 const real_t (*sBG)[MQ1*MD1],
1824 const real_t (*sDDD)[MD1*MD1*MD1],
1825 real_t (*sDDQ)[MD1*MD1*MQ1])
1839 MFEM_FOREACH_THREAD(dz,z,D1D)
1841 MFEM_FOREACH_THREAD(dy,y,D1D)
1843 MFEM_FOREACH_THREAD(qx,x,Q1D)
1845 real_t u[3] = {0.0, 0.0, 0.0};
1846 real_t v[3] = {0.0, 0.0, 0.0};
1847 for (
int dx = 0; dx < D1D; ++dx)
1849 const real_t xx = Xx(dx,dy,dz);
1850 const real_t xy = Xy(dx,dy,dz);
1851 const real_t xz = Xz(dx,dy,dz);
1852 const real_t Bx = B(dx,qx);
1853 const real_t Gx = G(dx,qx);
1862 XxB(qx,dy,dz) =
u[0];
1863 XyB(qx,dy,dz) =
u[1];
1864 XzB(qx,dy,dz) =
u[2];
1866 XxG(qx,dy,dz) = v[0];
1867 XyG(qx,dy,dz) = v[1];
1868 XzG(qx,dy,dz) = v[2];
1876template<
int MD1,
int MQ1>
1877MFEM_HOST_DEVICE
inline void GradY(
const int D1D,
const int Q1D,
1878 const real_t (*sBG)[MQ1*MD1],
1879 const real_t (*sDDQ)[MD1*MD1*MQ1],
1880 real_t (*sDQQ)[MD1*MQ1*MQ1])
1900 MFEM_FOREACH_THREAD(dz,z,D1D)
1902 MFEM_FOREACH_THREAD(qy,y,Q1D)
1904 MFEM_FOREACH_THREAD(qx,x,Q1D)
1906 real_t u[3] = {0.0, 0.0, 0.0};
1907 real_t v[3] = {0.0, 0.0, 0.0};
1908 real_t w[3] = {0.0, 0.0, 0.0};
1909 for (
int dy = 0; dy < D1D; ++dy)
1911 const real_t By = B(dy,qy);
1912 const real_t Gy = G(dy,qy);
1914 u[0] += XxB(qx,dy,dz) * By;
1915 u[1] += XyB(qx,dy,dz) * By;
1916 u[2] += XzB(qx,dy,dz) * By;
1918 v[0] += XxG(qx,dy,dz) * By;
1919 v[1] += XyG(qx,dy,dz) * By;
1920 v[2] += XzG(qx,dy,dz) * By;
1922 w[0] += XxB(qx,dy,dz) * Gy;
1923 w[1] += XyB(qx,dy,dz) * Gy;
1924 w[2] += XzB(qx,dy,dz) * Gy;
1926 XxBB(qx,qy,dz) =
u[0];
1927 XyBB(qx,qy,dz) =
u[1];
1928 XzBB(qx,qy,dz) =
u[2];
1930 XxBG(qx,qy,dz) = v[0];
1931 XyBG(qx,qy,dz) = v[1];
1932 XzBG(qx,qy,dz) = v[2];
1934 XxGB(qx,qy,dz) = w[0];
1935 XyGB(qx,qy,dz) = w[1];
1936 XzGB(qx,qy,dz) = w[2];
1944template<
int MD1,
int MQ1>
1945MFEM_HOST_DEVICE
inline void GradZ(
const int D1D,
const int Q1D,
1946 const real_t (*sBG)[MQ1*MD1],
1947 const real_t (*sDQQ)[MD1*MQ1*MQ1],
1948 real_t (*sQQQ)[MQ1*MQ1*MQ1])
1971 MFEM_FOREACH_THREAD(qz,z,Q1D)
1973 MFEM_FOREACH_THREAD(qy,y,Q1D)
1975 MFEM_FOREACH_THREAD(qx,x,Q1D)
1977 real_t u[3] = {0.0, 0.0, 0.0};
1978 real_t v[3] = {0.0, 0.0, 0.0};
1979 real_t w[3] = {0.0, 0.0, 0.0};
1980 for (
int dz = 0; dz < D1D; ++dz)
1982 const real_t Bz = B(dz,qz);
1983 const real_t Gz = G(dz,qz);
1985 u[0] += XxBG(qx,qy,dz) * Bz;
1986 u[1] += XyBG(qx,qy,dz) * Bz;
1987 u[2] += XzBG(qx,qy,dz) * Bz;
1989 v[0] += XxGB(qx,qy,dz) * Bz;
1990 v[1] += XyGB(qx,qy,dz) * Bz;
1991 v[2] += XzGB(qx,qy,dz) * Bz;
1993 w[0] += XxBB(qx,qy,dz) * Gz;
1994 w[1] += XyBB(qx,qy,dz) * Gz;
1995 w[2] += XzBB(qx,qy,dz) * Gz;
1997 XxBBG(qx,qy,qz) =
u[0];
1998 XyBBG(qx,qy,qz) =
u[1];
1999 XzBBG(qx,qy,qz) =
u[2];
2001 XxBGB(qx,qy,qz) = v[0];
2002 XyBGB(qx,qy,qz) = v[1];
2003 XzBGB(qx,qy,qz) = v[2];
2005 XxGBB(qx,qy,qz)= w[0];
2006 XyGBB(qx,qy,qz) = w[1];
2007 XzGBB(qx,qy,qz) = w[2];
2016MFEM_HOST_DEVICE
inline void PullGrad(
const int Q1D,
2017 const int x,
const int y,
const int z,
2018 const real_t (*sQQQ)[MQ1*MQ1*MQ1],
2031 Jpr[0] = XxBBG(x,y,z);
2032 Jpr[3] = XxBGB(x,y,z);
2033 Jpr[6] = XxGBB(x,y,z);
2034 Jpr[1] = XyBBG(x,y,z);
2035 Jpr[4] = XyBGB(x,y,z);
2036 Jpr[7] = XyGBB(x,y,z);
2037 Jpr[2] = XzBBG(x,y,z);
2038 Jpr[5] = XzBGB(x,y,z);
2039 Jpr[8] = XzGBB(x,y,z);
2044MFEM_HOST_DEVICE
inline void PushGrad(
const int Q1D,
2045 const int x,
const int y,
const int z,
2047 real_t (&sQQQ)[9][MQ1*MQ1*MQ1])
2059 XxBBG(x,y,z) = A[0];
2060 XxBGB(x,y,z) = A[1];
2061 XxGBB(x,y,z) = A[2];
2062 XyBBG(x,y,z) = A[3];
2063 XyBGB(x,y,z) = A[4];
2064 XyGBB(x,y,z) = A[5];
2065 XzBBG(x,y,z) = A[6];
2066 XzBGB(x,y,z) = A[7];
2067 XzGBB(x,y,z) = A[8];
2071template<
int MD1,
int MQ1>
2072MFEM_HOST_DEVICE
inline void GradZt(
const int D1D,
const int Q1D,
2073 const real_t (&sBG)[2][MQ1*MD1],
2074 const real_t (&sQQQ)[9][MQ1*MQ1*MQ1],
2075 real_t (&sDQQ)[9][MD1*MQ1*MQ1])
2099 MFEM_FOREACH_THREAD(qz,z,Q1D)
2101 MFEM_FOREACH_THREAD(qy,y,Q1D)
2103 MFEM_FOREACH_THREAD(dx,x,D1D)
2105 real_t u[3] = {0.0, 0.0, 0.0};
2106 real_t v[3] = {0.0, 0.0, 0.0};
2107 real_t w[3] = {0.0, 0.0, 0.0};
2108 for (
int qx = 0; qx < Q1D; ++qx)
2110 const real_t Btx = Bt(qx,dx);
2111 const real_t Gtx = Gt(qx,dx);
2113 u[0] += XxBBG(qx,qy,qz) * Gtx;
2114 v[0] += XxBGB(qx,qy,qz) * Btx;
2115 w[0] += XxGBB(qx,qy,qz) * Btx;
2117 u[1] += XyBBG(qx,qy,qz) * Gtx;
2118 v[1] += XyBGB(qx,qy,qz) * Btx;
2119 w[1] += XyGBB(qx,qy,qz) * Btx;
2121 u[2] += XzBBG(qx,qy,qz) * Gtx;
2122 v[2] += XzBGB(qx,qy,qz) * Btx;
2123 w[2] += XzGBB(qx,qy,qz) * Btx;
2125 XxBB(qz,qy,dx) =
u[0];
2126 XxBG(qz,qy,dx) = v[0];
2127 XxGB(qz,qy,dx) = w[0];
2129 XyBB(qz,qy,dx) =
u[1];
2130 XyBG(qz,qy,dx) = v[1];
2131 XyGB(qz,qy,dx) = w[1];
2133 XzBB(qz,qy,dx) =
u[2];
2134 XzBG(qz,qy,dx) = v[2];
2135 XzGB(qz,qy,dx) = w[2];
2143template<
int MD1,
int MQ1>
2144MFEM_HOST_DEVICE
inline void GradYt(
const int D1D,
const int Q1D,
2145 const real_t (&sBG)[2][MQ1*MD1],
2146 const real_t (&sDQQ)[9][MD1*MQ1*MQ1],
2147 real_t (&sDDQ)[9][MD1*MD1*MQ1])
2170 MFEM_FOREACH_THREAD(qz,z,Q1D)
2172 MFEM_FOREACH_THREAD(dy,y,D1D)
2174 MFEM_FOREACH_THREAD(dx,x,D1D)
2176 real_t u[3] = {0.0, 0.0, 0.0};
2177 real_t v[3] = {0.0, 0.0, 0.0};
2178 real_t w[3] = {0.0, 0.0, 0.0};
2179 for (
int qy = 0; qy < Q1D; ++qy)
2181 const real_t Bty = Bt(qy,dy);
2182 const real_t Gty = Gt(qy,dy);
2184 u[0] += XxBB(qz,qy,dx) * Bty;
2185 v[0] += XxBG(qz,qy,dx) * Gty;
2186 w[0] += XxGB(qz,qy,dx) * Bty;
2188 u[1] += XyBB(qz,qy,dx) * Bty;
2189 v[1] += XyBG(qz,qy,dx) * Gty;
2190 w[1] += XyGB(qz,qy,dx) * Bty;
2192 u[2] += XzBB(qz,qy,dx) * Bty;
2193 v[2] += XzBG(qz,qy,dx) * Gty;
2194 w[2] += XzGB(qz,qy,dx) * Bty;
2197 XxB(qz,dy,dx) =
u[0];
2198 XxC(qz,dy,dx) = v[0];
2199 XxG(qz,dy,dx) = w[0];
2201 XyB(qz,dy,dx) =
u[1];
2202 XyC(qz,dy,dx) = v[1];
2203 XyG(qz,dy,dx) = w[1];
2205 XzB(qz,dy,dx) =
u[2];
2206 XzC(qz,dy,dx) = v[2];
2207 XzG(qz,dy,dx) = w[2];
2215template<
int MD1,
int MQ1>
2216MFEM_HOST_DEVICE
inline void GradXt(
const int D1D,
const int Q1D,
2217 const real_t (&sBG)[2][MQ1*MD1],
2218 const real_t (&sDDQ)[9][MD1*MD1*MQ1],
2219 const DeviceTensor<5> &Y,
2234 MFEM_FOREACH_THREAD(dz,z,D1D)
2236 MFEM_FOREACH_THREAD(dy,y,D1D)
2238 MFEM_FOREACH_THREAD(dx,x,D1D)
2240 real_t u[3] = {0.0, 0.0, 0.0};
2241 real_t v[3] = {0.0, 0.0, 0.0};
2242 real_t w[3] = {0.0, 0.0, 0.0};
2243 for (
int qz = 0; qz < Q1D; ++qz)
2245 const real_t Btz = Bt(qz,dz);
2246 const real_t Gtz = Gt(qz,dz);
2248 u[0] += XxB(qz,dy,dx) * Btz;
2249 v[0] += XxC(qz,dy,dx) * Btz;
2250 w[0] += XxG(qz,dy,dx) * Gtz;
2252 u[1] += XyB(qz,dy,dx) * Btz;
2253 v[1] += XyC(qz,dy,dx)* Btz;
2254 w[1] += XyG(qz,dy,dx) * Gtz;
2256 u[2] += XzB(qz,dy,dx) * Btz;
2257 v[2] += XzC(qz,dy,dx) * Btz;
2258 w[2] += XzG(qz,dy,dx) * Gtz;
2260 Y(dx,dy,dz,0,e) +=
u[0] + v[0] + w[0];
2261 Y(dx,dy,dz,1,e) +=
u[1] + v[1] + w[1];
2262 Y(dx,dy,dz,2,e) +=
u[2] + v[2] + w[2];
DeviceTensor< 3, real_t > DeviceCube
real_t u(const Vector &xvec)
DeviceTensor< 3, const real_t > ConstDeviceCube
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
DeviceTensor< 2, const real_t > ConstDeviceMatrix
DeviceTensor< 2, real_t > DeviceMatrix
Implementation of the tensor class.