39template <
bool ACCUMULATE = true>
40MFEM_HOST_DEVICE
inline
41void PAMassApplyTriangle_Element(
const int e,
55 const int D1D = d1d, Q1D = q1d;
56 constexpr int max_D1D = DofQuadLimits::MAX_D1D_SIMPLEX;
57 constexpr int max_Q1D = DofQuadLimits::MAX_Q1D_SIMPLEX;
59 const auto lex_map = DeviceTensor<2,const int>(lex_map_, D1D, D1D);
71 for (
int idx = 0; idx < BASIS_DIM; idx++)
81 real_t C2[max_Q1D * max_Q1D];
82 real_t C1[max_D1D * max_Q1D];
84 for (
int i1 = 0; i1 < Q1D; i1++)
86 for (
int i2 = 0; i2 < Q1D; i2++)
88 const int q = i2 + Q1D*i1;
91 for (
int a1 = 0; a1 < D1D; a1++)
93 const int q = a1 + D1D*i1;
100 for (
int i2 = 0; i2 < Q1D; i2++)
102 for (
int a1 = 0; a1 < D1D; a1++)
104 const int a1i2 = a1 + D1D*i2;
105 for (
int a2 = 0; a2 < D1D-a1; a2++)
107 const int idx = lex_map(a2, a1);
108 C1[a1i2] += X(idx, e) * Ba2(a2, a1, i2);
118 for (
int i1 = 0; i1 < Q1D; i1++)
120 for (
int a1 = 0; a1 < D1D; a1++)
122 const real_t Bai = Ba1(a1, i1);
123 for (
int i2 = 0; i2 < Q1D; i2++)
125 C2[i2 + Q1D*i1] += C1[a1 + D1D*i2] * Bai;
129 for (
int i1 = 0; i1 < Q1D; i1++)
131 for (
int i2 = 0; i2 < Q1D; i2++)
133 C2[i2 + Q1D*i1] *= D(i1, i2, e);
140 for (
int i2 = 0; i2 < Q1D; i2++)
142 for (
int a1 = 0; a1 < D1D; a1++)
144 C1[a1 + D1D*i2] = 0.0;
147 for (
int i1 = 0; i1 < Q1D; i1++)
149 for (
int a1 = 0; a1 < D1D; a1++)
151 const real_t Bai = Ba1t(i1, a1);
152 for (
int i2 = 0; i2 < Q1D; i2++)
154 C1[i2 + Q1D*a1] += C2[i2 + Q1D*i1] * Bai;
161 for (
int a1 = 0; a1 < D1D; a1++)
163 for (
int i2 = 0; i2 < Q1D; i2++)
165 const int a1i2 = i2 + Q1D*a1;
166 for (
int a2 = 0; a2 < D1D-a1; a2++)
168 const int idx = lex_map(a2, a1);
169 Y(idx,e) += C1[a1i2] * Ba2t(i2, a1, a2);
176template<
int T_D1D = 0,
int T_Q1D = 0>
177inline void PAMassApplyTriangle(
const int NE,
178 const Array<int> &lex_map_,
183 const Array<real_t> &ba1_,
184 const Array<real_t> &ba2_,
185 const Array<real_t> &,
186 const Array<real_t> &ba1t_,
187 const Array<real_t> &ba2t_,
188 const Array<real_t> &,
195 const int D1D = T_D1D ? T_D1D : d1d;
196 const int Q1D = T_Q1D ? T_Q1D : q1d;
197 const int BASIS_DIM = D1D * (D1D + 1) / 2;
202 const auto lex_map = lex_map_.Read();
203 const auto Ba1 = ba1_.Read();
204 const auto Ba2 = ba2_.Read();
205 const auto Ba1t = ba1t_.Read();
206 const auto Ba2t = ba2t_.Read();
207 const auto D = d_.Read();
208 const auto X = x_.Read();
209 auto Y = y_.ReadWrite();
213 internal::PAMassApplyTriangle_Element(e, NE, BASIS_DIM,
214 lex_map, Ba1, Ba2, Ba1t, Ba2t, D,
220template<
int T_D1D,
int T_Q1D,
bool ACCUMULATE = true>
221MFEM_HOST_DEVICE
inline
222void SmemPAMassApplyTriangle_Element(
const int e,
235 const int D1D = T_D1D ? T_D1D : d1d;
236 const int Q1D = T_Q1D ? T_Q1D : q1d;
238 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D_SIMPLEX;
239 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D_SIMPLEX;
240 constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
241 constexpr int BASIS_DIM = MD1 * (MD1+1) / 2;
243 const auto map = DeviceTensor<2,const int>(lex_map_, D1D, D1D);
252 MFEM_SHARED
real_t B[2][MQ1*MD1*MD1];
253 auto Ba1 = (
real_t (*)[MD1]) (B+0);
254 auto Ba2 = (
real_t (*)[MD1][MD1]) (B+1);
255 auto Ba1t = (
real_t (*)[MQ1]) (B+0);
256 auto Ba2t = (
real_t (*)[MD1][MQ1]) (B+1);
257 MFEM_SHARED
real_t Xz[BASIS_DIM];
258 MFEM_SHARED
real_t sm0[MDQ*MDQ], sm1[MDQ*MDQ];
259 auto X = (
real_t (*)) (Xz);
260 auto DQ = (
real_t (*)[MD1]) (sm1);
261 auto QQ = (
real_t (*)[MQ1]) (sm0);
262 auto QD = (
real_t (*)[MQ1]) (sm1);
263 MFEM_SHARED
int s_lex[MD1*MD1];
264 auto lex_map = (int (*)[MD1])(s_lex);
267 MFEM_FOREACH_THREAD_DIRECT(a1,y,D1D)
269 MFEM_FOREACH_THREAD_DIRECT(a2,x,D1D-a1)
271 const int idx = map(a2,a1);
272 lex_map[a1][a2] = idx;
277 MFEM_FOREACH_THREAD_DIRECT(a1,y,D1D)
279 MFEM_FOREACH_THREAD_DIRECT(i1,x,Q1D)
281 Ba1[i1][a1] = ba1(a1,i1);
282 for (
int a2 = 0; a2 < D1D-a1; ++a2)
284 Ba2[i1][a1][a2] = ba2(a2,a1,i1);
291 MFEM_FOREACH_THREAD_DIRECT(i2,y,Q1D)
293 MFEM_FOREACH_THREAD_DIRECT(a1,x,D1D)
296 for (
int a2 = 0; a2 < D1D-a1; ++a2)
298 int idx = lex_map[a1][a2];
299 u += X[idx] * Ba2[i2][a1][a2];
311 MFEM_FOREACH_THREAD_DIRECT(i1,y,Q1D)
313 MFEM_FOREACH_THREAD_DIRECT(i2,x,Q1D)
316 for (
int a1 = 0; a1 < D1D; ++a1)
318 u += DQ[i2][a1] * Ba1[i1][a1];
320 QQ[i1][i2] =
u * D(i1, i2, e);
324 MFEM_FOREACH_THREAD_DIRECT(a1,y,D1D)
326 MFEM_FOREACH_THREAD_DIRECT(i1,x,Q1D)
328 Ba1t[a1][i1] = ba1t(i1,a1);
329 for (
int a2 = 0; a2 < D1D-a1; ++a2)
331 Ba2t[a2][a1][i1] = ba2t(i1,a1,a2);
339 MFEM_FOREACH_THREAD_DIRECT(i2,y,Q1D)
341 MFEM_FOREACH_THREAD_DIRECT(a1,x,D1D)
344 for (
int i1 = 0; i1 < Q1D; ++i1)
346 u += QQ[i1][i2] * Ba1t[a1][i1];
355 MFEM_FOREACH_THREAD_DIRECT(a1,y,D1D)
357 MFEM_FOREACH_THREAD_DIRECT(a2,x,D1D-a1)
360 for (
int i2 = 0; i2 < Q1D; ++i2)
362 u += QD[a1][i2] * Ba2t[a2][a1][i2];
364 int idx = lex_map[a1][a2];
378template<
int T_D1D = 0,
int T_Q1D = 0>
379inline void SmemPAMassApplyTriangle(
const int NE,
380 const Array<int> &lex_map_,
385 const Array<real_t> &ba1_,
386 const Array<real_t> &ba2_,
387 const Array<real_t> &,
388 const Array<real_t> &ba1t_,
389 const Array<real_t> &ba2t_,
390 const Array<real_t> &,
397 const int D1D = T_D1D ? T_D1D : d1d;
398 const int Q1D = T_Q1D ? T_Q1D : q1d;
402 MFEM_VERIFY(D1D <= max_d1d,
"");
403 MFEM_VERIFY(Q1D <= max_q1d,
"");
405 const auto lex_map = lex_map_.Read();
406 const auto Ba1 = ba1_.Read(), Ba2 = ba2_.Read();
407 const auto Ba1t = ba1t_.Read(), Ba2t = ba2t_.Read();
408 const auto D = d_.Read();
409 const auto X = x_.Read();
410 auto Y = y_.ReadWrite();
412 const int T1D = (Q1D > D1D) ? Q1D : D1D;
413 constexpr int T_T1D = (T_Q1D > T_D1D) ? T_Q1D : T_D1D;
417 internal::SmemPAMassApplyTriangle_Element<T_D1D, T_Q1D>
418 (e, NE, lex_map, Ba1, Ba2, Ba1t, Ba2t, D, X, Y, d1d, q1d);
433template <
bool ACCUMULATE = true>
434MFEM_HOST_DEVICE
inline
435void PAMassApplyTetrahedron_Element(
const int e,
438 const int BASIS_DIM2D,
439 const int *forward_map2d,
441 const int *forward_map3d,
455 const int D1D = d1d, Q1D = q1d;
463 const auto D = DeviceTensor<4,const real_t>(d_, Q1D, Q1D, Q1D, NE);
469 for (
int idx = 0; idx < BASIS_DIM; idx++)
481 constexpr int max_D1D = DofQuadLimits::MAX_D1D_SIMPLEX;
482 constexpr int max_Q1D = DofQuadLimits::MAX_Q1D_SIMPLEX;
483 constexpr int BASIS_DIM2D_ = max_D1D * (max_D1D) / 2;
485 real_t C3[max_Q1D][max_Q1D][max_Q1D];
486 for (
int i3 = 0; i3 < Q1D; i3++)
488 for (
int i2 = 0; i2 < Q1D; i2++)
490 for (
int i1 = 0; i1 < Q1D; i1++)
492 C3[i3][i2][i1] = 0.0;
497 for (
int a1 = 0; a1 < D1D; a1++)
499 real_t C2[max_Q1D][max_Q1D];
500 for (
int i3 = 0; i3 < Q1D; i3++)
502 for (
int i2 = 0; i2 < Q1D; i2++)
508 for (
int a2 = 0; a2 < D1D-a1; a2++)
511 for (
int i3 = 0; i3 < Q1D; i3++)
516 for (
int a3 = 0; a3 < D1D-a1-a2; a3++)
518 const int a = forward_map3d[a3 + D1D*(a2 + D1D*a1)];
520 for (
int i3 = 0; i3 < Q1D; i3++)
522 C1[i3] += s * Ba3t(i3,
a);
526 const int a_2d = forward_map2d[a2 + D1D*a1];
527 for (
int i3 = 0; i3 < Q1D; i3++)
530 for (
int i2 = 0; i2 < Q1D; i2++)
532 C2[i3][i2] += Ba2t(i2,a_2d) * s;
537 for (
int i3 = 0; i3 < Q1D; i3++)
539 for (
int i2 = 0; i2 < Q1D; i2++)
541 const real_t s = C2[i3][i2];
542 for (
int i1 = 0; i1 < Q1D; i1++)
544 C3[i3][i2][i1] += Ba1t(i1,a1) * s;
550 for (
int i3 = 0; i3 < Q1D; i3++)
552 for (
int i2 = 0; i2 < Q1D; i2++)
554 for (
int i1 = 0; i1 < Q1D; i1++)
556 C3[i3][i2][i1] *= D(i1,i2,i3,e);
561 for (
int i3 = 0; i3 < Q1D; i3++)
564 for (
int a = 0;
a < BASIS_DIM2D;
a++)
569 for (
int i2 = 0; i2 < Q1D; i2++)
572 for (
int a1 = 0; a1 < D1D; a1++)
577 for (
int i1 = 0; i1 < Q1D; i1++)
579 const real_t s = C3[i3][i2][i1];
580 for (
int a1 = 0; a1 < D1D; a1++)
582 F1[a1] += Ba1(a1,i1) * s;
586 for (
int a1 = 0; a1 < D1D; a1++)
589 for (
int a2 = 0; a2 < D1D-a1; a2++)
591 const int a_2d = forward_map2d[a2 + D1D*a1];
592 F2[a_2d] += Ba2(a_2d,i2) * s;
597 for (
int a1 = 0; a1 < D1D; a1++)
599 for (
int a2 = 0; a2 < D1D-a1; a2++)
601 const int a_2d = forward_map2d[a2 + D1D*a1];
602 const real_t s = F2[a_2d];
603 for (
int a3 = 0; a3 < D1D-a1-a2; a3++)
605 const int a = forward_map3d[a3 + D1D*(a2 + D1D*a1)];
606 Y(
a,e) += Ba3(
a,i3) * s;
614template<
int T_D1D = 0,
int T_Q1D = 0>
615inline void PAMassApplyTetrahedron(
const int NE,
617 const Array<int> &forward_map2d_,
618 const Array<int> &inverse_map2d_,
619 const Array<int> &forward_map3d_,
620 const Array<int> &inverse_map3d_,
621 const Array<real_t> &ba1_,
622 const Array<real_t> &ba2_,
623 const Array<real_t> &ba3_,
624 const Array<real_t> &ba1t_,
625 const Array<real_t> &ba2t_,
626 const Array<real_t> &ba3t_,
633 const int D1D = T_D1D ? T_D1D : d1d;
634 const int Q1D = T_Q1D ? T_Q1D : q1d;
635 const int BASIS_DIM = D1D * (D1D + 1) * (D1D + 2) / 6;
636 const int BASIS_DIM2D = D1D * (D1D + 1) / 2;
641 const auto forward_map2d = forward_map2d_.Read();
642 const auto inverse_map2d = inverse_map2d_.Read();
643 const auto forward_map3d = forward_map3d_.Read();
644 const auto inverse_map3d = inverse_map3d_.Read();
645 const auto Ba1 = ba1_.Read();
646 const auto Ba2 = ba2_.Read();
647 const auto Ba3 = ba3_.Read();
648 const auto Ba1t = ba1t_.Read();
649 const auto Ba2t = ba2t_.Read();
650 const auto Ba3t = ba3t_.Read();
651 const auto D = d_.Read();
652 const auto X = x_.Read();
653 auto Y = y_.ReadWrite();
657 internal::PAMassApplyTetrahedron_Element(e, NE, BASIS_DIM, BASIS_DIM2D,
658 forward_map2d, inverse_map2d,
659 forward_map3d, inverse_map3d,
660 Ba1, Ba2, Ba3, Ba1t, Ba2t, Ba3t,
666template<
int T_D1D,
int T_Q1D,
bool ACCUMULATE = true>
667MFEM_HOST_DEVICE
inline
668void SmemPAMassApplyTetrahedron_Element(
const int e,
671 const int BASIS_DIM2D,
673 const int *forward_map2d_,
674 const int *inverse_map2d_,
675 const int *forward_map3d_,
689 constexpr int D1D = T_D1D ? T_D1D : d1d;
690 constexpr int Q1D = T_Q1D ? T_Q1D : q1d;
692 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D_SIMPLEX;
693 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D_SIMPLEX;
694 constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
695 constexpr int BASIS_DIM2D_ = MD1 * (MD1 + 1) / 2;
696 constexpr int BASIS_DIM_ = MD1 * (MD1 + 1) * (MD1 + 2) / 6;
704 const auto d = DeviceTensor<4,const real_t>(d_, Q1D, Q1D, Q1D, NE);
708 const auto forward_map3d__ =
709 DeviceTensor<3,const int>(forward_map3d_, D1D, D1D, D1D);
710 const auto forward_map2d__ =
711 DeviceTensor<2,const int>(forward_map2d_, D1D, D1D);
712 const auto inverse_map2d__ =
713 DeviceTensor<2,const int>(inverse_map2d_, 2, BASIS_DIM2D);
715 MFEM_SHARED
real_t sDQ[BASIS_DIM_*MQ1];
716 auto Ba1 = (
real_t (*)[MD1]) sDQ;
717 auto Ba1t = (
real_t (*)[MQ1]) sDQ;
718 auto Ba2 = (
real_t (*)[BASIS_DIM2D_]) sDQ;
719 auto Ba2t = (
real_t (*)[MQ1]) sDQ;
720 auto Ba3 = (
real_t (*)[BASIS_DIM_]) sDQ;
721 auto Ba3t = (
real_t (*)[MQ1]) sDQ;
722 MFEM_SHARED
real_t sm0[MDQ*MDQ*MDQ];
723 MFEM_SHARED
real_t sm1[MDQ*MDQ*MDQ];
724 auto X = (
real_t (*)) sm0;
725 auto C1 = (
real_t (*)[MQ1]) sm1;
726 auto C2 = (
real_t (*)[MQ1][MQ1]) sm0;
727 auto C3 = (
real_t (*)[MQ1][MQ1]) sm1;
728 auto F1 = (
real_t (*)[MQ1][MD1]) sm0;
729 auto F2 = (
real_t (*)[MQ1]) sm1;
730 MFEM_SHARED
int s3D[MD1*MD1*MD1];
731 MFEM_SHARED
int s2D[MD1*MD1];
732 auto forward_map3d = (int (*)[MD1][MD1]) s3D;
733 auto forward_map2d = (int (*)[MD1]) s2D;
734 MFEM_SHARED
int s2D_inv[BASIS_DIM2D_*2];
735 auto inverse_map2d = (int (*)[2]) s2D_inv;
737 MFEM_FOREACH_THREAD_DIRECT(a_2d,y,BASIS_DIM2D)
739 inverse_map2d[a_2d][0] = inverse_map2d__(0,a_2d);
740 inverse_map2d[a_2d][1] = inverse_map2d__(1,a_2d);
741 const int a1 = inverse_map2d[a_2d][0];
742 const int a2 = inverse_map2d[a_2d][1];
743 const int a_2d_ = forward_map2d__(a2, a1);
744 forward_map2d[a1][a2] = a_2d_;
745 MFEM_FOREACH_THREAD_DIRECT(i3,x,Q1D)
748 for (
int a3 = 0; a3 < D1D-a1-a2; ++a3)
750 const int a = forward_map3d__(a3, a2, a1);
751 forward_map3d[a1][a2][a3] =
a;
753 Ba3[i3][
a] = ba3(
a,i3);
758 MFEM_FOREACH_THREAD_DIRECT(a_2d,y,BASIS_DIM2D)
760 const int a1 = inverse_map2d[a_2d][0];
761 const int a2 = inverse_map2d[a_2d][1];
762 MFEM_FOREACH_THREAD_DIRECT(i3,x,Q1D)
766 for (
int a3 = 0; a3 < D1D-a1-a2; ++a3)
768 const int a = forward_map3d[a1][a2][a3];
769 u += X[
a] * Ba3[i3][
a];
775 MFEM_FOREACH_THREAD_DIRECT(a_2d,y,BASIS_DIM2D)
777 MFEM_FOREACH_THREAD_DIRECT(i2,x,Q1D)
779 Ba2[i2][a_2d] = ba2(a_2d,i2);
783 MFEM_FOREACH_THREAD_DIRECT(a1i2,y,Q1D*D1D)
785 const int i2 = a1i2 % Q1D;
786 const int a1 = (int) a1i2 / Q1D;
787 MFEM_FOREACH_THREAD_DIRECT(i3,x,Q1D)
791 for (
int a2 = 0; a2 < D1D-a1; a2++)
793 const int a_2d = forward_map2d[a1][a2];
794 u += C1[a_2d][i3] * Ba2[i2][a_2d];
800 MFEM_FOREACH_THREAD_DIRECT(a1i1,y,Q1D*D1D)
802 const int i1 = a1i1 % Q1D;
803 const int a1 = (int) a1i1 / Q1D;
804 Ba1[i1][a1] = ba1(a1,i1);
807 MFEM_FOREACH_THREAD_DIRECT(i2i3,y,Q1D*Q1D)
809 const int i3 = i2i3 % Q1D;
810 const int i2 = (int) i2i3 / Q1D;
811 MFEM_FOREACH_THREAD_DIRECT(i1,x,Q1D)
815 for (
int a1 = 0; a1 < D1D; a1++)
817 u += C2[a1][i2][i3] * Ba1[i1][a1];
819 C3[i2][i3][i1] =
u * d(i1,i2,i3,e);
823 MFEM_FOREACH_THREAD_DIRECT(a1i1,y,Q1D*D1D)
825 const int i1 = a1i1 % Q1D;
826 const int a1 = (int) a1i1 / Q1D;
827 Ba1t[a1][i1] = ba1t(i1,a1);
830 MFEM_FOREACH_THREAD_DIRECT(i2i3,y,Q1D*Q1D)
832 const int i3 = i2i3 % Q1D;
833 const int i2 = (int) i2i3 / Q1D;
834 MFEM_FOREACH_THREAD_DIRECT(a1,x,D1D)
838 for (
int i1 = 0; i1 < Q1D; i1++)
840 u += C3[i2][i3][i1] * Ba1t[a1][i1];
846 MFEM_FOREACH_THREAD_DIRECT(a_2d,y,BASIS_DIM2D)
848 MFEM_FOREACH_THREAD_DIRECT(i2,x,Q1D)
850 Ba2t[a_2d][i2] = ba2t(i2,a_2d);
854 MFEM_FOREACH_THREAD_DIRECT(a_2d,y,BASIS_DIM2D)
856 const int a1 = inverse_map2d[a_2d][0];
857 MFEM_FOREACH_THREAD_DIRECT(i3,x,Q1D)
861 for (
int i2 = 0; i2 < Q1D; i2++)
863 u += F1[i2][i3][a1] * Ba2t[a_2d][i2];
869 MFEM_FOREACH_THREAD_DIRECT(a_2d,y,BASIS_DIM2D)
871 const int a1 = inverse_map2d[a_2d][0];
872 const int a2 = inverse_map2d[a_2d][1];
873 MFEM_FOREACH_THREAD_DIRECT(i3,x,Q1D)
876 for (
int a3 = 0; a3 < D1D-a1-a2; ++a3)
878 const int a = forward_map3d[a1][a2][a3];
879 Ba3t[
a][i3] = ba3t(i3,
a);
884 MFEM_FOREACH_THREAD_DIRECT(a_2d,y,BASIS_DIM2D)
886 const int a1 = inverse_map2d[a_2d][0];
887 const int a2 = inverse_map2d[a_2d][1];
888 MFEM_FOREACH_THREAD_DIRECT(a3,x,D1D-a1-a2)
891 const int a = forward_map3d[a1][a2][a3];
893 for (
int i3 = 0; i3 < Q1D; i3++)
895 u += F2[a_2d][i3] * Ba3t[
a][i3];
911template<
int T_D1D = 0,
int T_Q1D = 0>
912inline void SmemPAMassApplyTetrahedron(
const int NE,
914 const Array<int> &forward_map2d_,
915 const Array<int> &inverse_map2d_,
916 const Array<int> &forward_map3d_,
918 const Array<real_t> &ba1_,
919 const Array<real_t> &ba2_,
920 const Array<real_t> &ba3_,
921 const Array<real_t> &ba1t_,
922 const Array<real_t> &ba2t_,
923 const Array<real_t> &ba3t_,
930 const int D1D = T_D1D ? T_D1D : d1d;
931 const int Q1D = T_Q1D ? T_Q1D : q1d;
932 const int BASIS_DIM = D1D * (D1D + 1) * (D1D + 2) / 6;
933 const int BASIS_DIM2D = D1D * (D1D + 1) / 2;
935 constexpr int max_q1d =
937 constexpr int max_d1d =
939 MFEM_VERIFY(D1D <= max_d1d,
"");
940 MFEM_VERIFY(Q1D <= max_q1d,
"");
942 const auto forward_map2d = forward_map2d_.Read();
943 const auto inverse_map2d = inverse_map2d_.Read();
944 const auto forward_map3d = forward_map3d_.Read();
945 const auto Ba1 = ba1_.Read();
946 const auto Ba2 = ba2_.Read();
947 const auto Ba3 = ba3_.Read();
948 const auto Ba1t = ba1t_.Read();
949 const auto Ba2t = ba2t_.Read();
950 const auto Ba3t = ba3t_.Read();
951 const auto D = d_.Read();
952 const auto X = x_.Read();
953 auto Y = y_.ReadWrite();
955 const int T1D = (Q1D > D1D) ? Q1D : D1D;
956 constexpr int T_T1D = (T_Q1D > T_D1D) ? T_Q1D : T_D1D;
959 [=] MFEM_HOST_DEVICE (
int e)
961 internal::SmemPAMassApplyTetrahedron_Element<T_D1D, T_Q1D>
962 (e, NE, BASIS_DIM, BASIS_DIM2D,
963 forward_map2d, inverse_map2d, forward_map3d,
964 Ba1, Ba2, Ba3, Ba1t, Ba2t, Ba3t, D, X, Y,
971template<
int DIM,
int T_D1D,
int T_Q1D>
973MassIntegrator::ApplySimplexPAKernels::Kernel()
975 if constexpr (
DIM == 2)
977 return internal::SmemPAMassApplyTriangle<T_D1D,T_Q1D>;
979 else if constexpr (
DIM == 3)
981 return internal::SmemPAMassApplyTetrahedron<T_D1D, T_Q1D>;
983 else { MFEM_ABORT(
""); }
988MassIntegrator::ApplySimplexPAKernels::Fallback(
int dim,
int,
int)
992 return internal::PAMassApplyTriangle;
996 return internal::PAMassApplyTetrahedron;
998 else { MFEM_ABORT(
""); }
void(*)(const int, const Array< int > &, const Array< int > &, const Array< int > &, const Array< int > &, const Array< int > &, const Array< real_t > &, const Array< real_t > &, 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) ApplySimplexKernelType
real_t u(const Vector &xvec)
DeviceTensor< 3, const real_t > ConstDeviceCube
void forall_2D(int N, int X, int Y, lambda &&body)
DeviceTensor< 2, const real_t > ConstDeviceMatrix
void forall(int N, lambda &&body)
DeviceTensor< 2, real_t > DeviceMatrix
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.
int MAX_D1D_SIMPLEX
Maximum number of 1D nodal points for simplices.
int MAX_Q1D_SIMPLEX
Maximum number of 1D quadrature points for simplices.