12 #ifndef MFEM_TEMPLATE_EVALUATOR
13 #define MFEM_TEMPLATE_EVALUATOR
15 #include "../config/tconfig.hpp"
16 #include "../linalg/ttensor.hpp"
17 #include "../general/error.hpp"
28 template <
class FE,
class IR,
bool TP,
typename real_t>
32 template <
class FE,
class IR,
typename real_t>
36 static const int DOF = FE::dofs;
37 static const int NIP = IR::qpts;
49 fe.CalcShapes(IR::GetIntRule(), B.data, G.data);
50 TAssign<AssignOp::Set>(Bt.layout, Bt, B.layout.transpose_12(), B);
51 TAssign<AssignOp::Set>(Gt.layout.merge_23(), Gt,
52 G.layout.merge_12().transpose_12(), G);
59 template <
typename dof_layout_t,
typename dof_data_t,
60 typename qpt_layout_t,
typename qpt_data_t>
62 void Calc(
const dof_layout_t &dof_layout,
const dof_data_t &dof_data,
63 const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data)
const
65 MFEM_STATIC_ASSERT(dof_layout_t::rank == 2 &&
66 dof_layout_t::dim_1 == DOF,
67 "invalid dof_layout_t.");
68 MFEM_STATIC_ASSERT(qpt_layout_t::rank == 2 &&
69 qpt_layout_t::dim_1 == NIP,
70 "invalid qpt_layout_t.");
71 MFEM_STATIC_ASSERT(dof_layout_t::dim_2 == qpt_layout_t::dim_2,
72 "incompatible dof- and qpt- layouts.");
74 Mult_AB<false>(B.layout, B,
76 qpt_layout, qpt_data);
82 typename qpt_layout_t,
typename qpt_data_t,
83 typename dof_layout_t,
typename dof_data_t>
85 void CalcT(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
86 const dof_layout_t &dof_layout, dof_data_t &dof_data)
const
88 MFEM_STATIC_ASSERT(dof_layout_t::rank == 2 &&
89 dof_layout_t::dim_1 == DOF,
90 "invalid dof_layout_t.");
91 MFEM_STATIC_ASSERT(qpt_layout_t::rank == 2 &&
92 qpt_layout_t::dim_1 == NIP,
93 "invalid qpt_layout_t.");
94 MFEM_STATIC_ASSERT(dof_layout_t::dim_2 == qpt_layout_t::dim_2,
95 "incompatible dof- and qpt- layouts.");
97 Mult_AB<Add>(Bt.layout, Bt,
99 dof_layout, dof_data);
104 template <
typename dof_layout_t,
typename dof_data_t,
105 typename grad_layout_t,
typename grad_data_t>
108 const dof_data_t &dof_data,
109 const grad_layout_t &grad_layout,
110 grad_data_t &grad_data)
const
112 MFEM_STATIC_ASSERT(dof_layout_t::rank == 2 &&
113 dof_layout_t::dim_1 == DOF,
114 "invalid dof_layout_t.");
115 MFEM_STATIC_ASSERT(grad_layout_t::rank == 3 &&
116 grad_layout_t::dim_1 == NIP &&
117 grad_layout_t::dim_2 == DIM,
118 "invalid grad_layout_t.");
119 MFEM_STATIC_ASSERT(dof_layout_t::dim_2 == grad_layout_t::dim_3,
120 "incompatible dof- and grad- layouts.");
122 Mult_AB<false>(G.layout.merge_12(), G,
123 dof_layout, dof_data,
124 grad_layout.merge_12(), grad_data);
130 typename grad_layout_t,
typename grad_data_t,
131 typename dof_layout_t,
typename dof_data_t>
134 const grad_data_t &grad_data,
135 const dof_layout_t &dof_layout,
136 dof_data_t &dof_data)
const
138 MFEM_STATIC_ASSERT(dof_layout_t::rank == 2 &&
139 dof_layout_t::dim_1 == DOF,
140 "invalid dof_layout_t.");
141 MFEM_STATIC_ASSERT(grad_layout_t::rank == 3 &&
142 grad_layout_t::dim_1 == NIP &&
143 grad_layout_t::dim_2 == DIM,
144 "invalid grad_layout_t.");
145 MFEM_STATIC_ASSERT(dof_layout_t::dim_2 == grad_layout_t::dim_3,
146 "incompatible dof- and grad- layouts.");
148 Mult_AB<Add>(Gt.layout.merge_23(), Gt,
149 grad_layout.merge_12(), grad_data,
150 dof_layout, dof_data);
155 template <
typename qpt_layout_t,
typename qpt_data_t,
156 typename M_layout_t,
typename M_data_t>
158 void Assemble(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
159 const M_layout_t &M_layout, M_data_t &M_data)
const
164 TensorAssemble<false>(
166 qpt_layout.template split_1<1,NIP>(), qpt_data,
167 M_layout.template split_1<DOF,1>(), M_data);
169 TensorAssemble<false>(
170 Bt.layout, Bt, B.layout, B,
171 qpt_layout.template split_1<1,NIP>(), qpt_data,
172 M_layout.template split_1<DOF,1>(), M_data);
179 template <
typename qpt_layout_t,
typename qpt_data_t,
180 typename D_layout_t,
typename D_data_t>
183 const qpt_data_t &qpt_data,
184 const D_layout_t &D_layout,
185 D_data_t &D_data)
const
187 const int NC = qpt_layout_t::dim_4;
189 for (
int k = 0; k < NC; k++)
193 for (
int j = 0; j < NIP; j++)
195 Mult_AB<false>(qpt_layout.ind14(j,k), qpt_data,
201 Mult_2_1<false>(Gt.layout.merge_23(), Gt,
207 template <
int Dim,
int DOF,
int NIP,
typename real_t>
211 template <
int DOF,
int NIP,
typename real_t>
215 static const int TDOF = DOF;
225 template <
typename dof_layout_t,
typename dof_data_t,
226 typename qpt_layout_t,
typename qpt_data_t>
228 void Calc(
const dof_layout_t &dof_layout,
const dof_data_t &dof_data,
229 const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data)
const
231 Mult_AB<false>(B_1d.layout, B_1d,
232 dof_layout, dof_data,
233 qpt_layout, qpt_data);
239 typename qpt_layout_t,
typename qpt_data_t,
240 typename dof_layout_t,
typename dof_data_t>
242 void CalcT(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
243 const dof_layout_t &dof_layout, dof_data_t &dof_data)
const
245 Mult_AB<Add>(Bt_1d.layout, Bt_1d,
246 qpt_layout, qpt_data,
247 dof_layout, dof_data);
252 template <
typename dof_layout_t,
typename dof_data_t,
253 typename grad_layout_t,
typename grad_data_t>
256 const dof_data_t &dof_data,
257 const grad_layout_t &grad_layout,
258 grad_data_t &grad_data)
const
261 Mult_AB<false>(G_1d.layout, G_1d,
262 dof_layout, dof_data,
263 grad_layout.merge_12(), grad_data);
269 typename grad_layout_t,
typename grad_data_t,
270 typename dof_layout_t,
typename dof_data_t>
273 const grad_data_t &grad_data,
274 const dof_layout_t &dof_layout,
275 dof_data_t &dof_data)
const
279 Mult_AB<Add>(Gt_1d.layout, Gt_1d,
280 grad_layout.merge_12(), grad_data,
281 dof_layout, dof_data);
286 template <
typename qpt_layout_t,
typename qpt_data_t,
287 typename M_layout_t,
typename M_data_t>
289 void Assemble(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
290 const M_layout_t &M_layout, M_data_t &M_data)
const
295 TensorAssemble<false>(
297 qpt_layout.template split_1<1,NIP>(), qpt_data,
298 M_layout.template split_1<DOF,1>(), M_data);
300 TensorAssemble<false>(
301 Bt_1d.layout, Bt_1d, B_1d.layout, B_1d,
302 qpt_layout.template split_1<1,NIP>(), qpt_data,
303 M_layout.template split_1<DOF,1>(), M_data);
310 template <
typename qpt_layout_t,
typename qpt_data_t,
311 typename D_layout_t,
typename D_data_t>
314 const qpt_data_t &qpt_data,
315 const D_layout_t &D_layout,
316 D_data_t &D_data)
const
321 TensorAssemble<false>(
323 qpt_layout.merge_12().merge_23().template split_1<1,NIP>(), qpt_data,
324 D_layout.template split_1<DOF,1>(), D_data);
326 TensorAssemble<false>(
327 Gt_1d.layout, Gt_1d, G_1d.layout, G_1d,
328 qpt_layout.merge_12().merge_23().template split_1<1,NIP>(), qpt_data,
329 D_layout.template split_1<DOF,1>(), D_data);
335 template <
int DOF,
int NIP,
typename real_t>
343 static const int TDOF = DOF*DOF;
344 static const int TNIP = NIP*NIP;
348 template <
bool Dx,
bool Dy,
349 typename dof_layout_t,
typename dof_data_t,
350 typename qpt_layout_t,
typename qpt_data_t>
352 void Calc(
const dof_layout_t &dof_layout,
const dof_data_t &dof_data,
353 const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data)
const
355 const int NC = dof_layout_t::dim_2;
360 Mult_2_1<false>(B_1d.layout, Dx ? G_1d : B_1d,
361 dof_layout.
template split_1<DOF,DOF>(), dof_data,
364 Mult_1_2<false>(Bt_1d.layout, Dy ? Gt_1d : Bt_1d,
366 qpt_layout.template split_1<NIP,NIP>(), qpt_data);
371 template <
typename dof_layout_t,
typename dof_data_t,
372 typename qpt_layout_t,
typename qpt_data_t>
374 void Calc(
const dof_layout_t &dof_layout,
const dof_data_t &dof_data,
375 const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data)
const
377 Calc<false,false>(dof_layout, dof_data, qpt_layout, qpt_data);
380 template <
bool Dx,
bool Dy,
bool Add,
381 typename qpt_layout_t,
typename qpt_data_t,
382 typename dof_layout_t,
typename dof_data_t>
384 void CalcT(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
385 const dof_layout_t &dof_layout, dof_data_t &dof_data)
const
387 const int NC = dof_layout_t::dim_2;
392 Mult_1_2<false>(B_1d.layout, Dy ? G_1d : B_1d,
393 qpt_layout.template split_1<NIP,NIP>(), qpt_data,
396 Mult_2_1<Add>(Bt_1d.layout, Dx ? Gt_1d : Bt_1d,
398 dof_layout.template split_1<DOF,DOF>(), dof_data);
404 typename qpt_layout_t,
typename qpt_data_t,
405 typename dof_layout_t,
typename dof_data_t>
407 void CalcT(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
408 const dof_layout_t &dof_layout, dof_data_t &dof_data)
const
410 CalcT<false,false,Add>(qpt_layout, qpt_data, dof_layout, dof_data);
415 template <
typename dof_layout_t,
typename dof_data_t,
416 typename grad_layout_t,
typename grad_data_t>
419 const dof_data_t &dof_data,
420 const grad_layout_t &grad_layout,
421 grad_data_t &grad_data)
const
423 Calc<true,false>(dof_layout, dof_data,
424 grad_layout.ind2(0), grad_data);
425 Calc<false,true>(dof_layout, dof_data,
426 grad_layout.ind2(1), grad_data);
433 typename grad_layout_t,
typename grad_data_t,
434 typename dof_layout_t,
typename dof_data_t>
437 const grad_data_t &grad_data,
438 const dof_layout_t &dof_layout,
439 dof_data_t &dof_data)
const
441 CalcT<true,false, Add>(grad_layout.ind2(0), grad_data,
442 dof_layout, dof_data);
443 CalcT<false,true,true>(grad_layout.ind2(1), grad_data,
444 dof_layout, dof_data);
449 template <
typename qpt_layout_t,
typename qpt_data_t,
450 typename M_layout_t,
typename M_data_t>
452 void Assemble(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
453 const M_layout_t &M_layout, M_data_t &M_data)
const
455 const int NC = qpt_layout_t::dim_2;
462 TensorAssemble<false>(
464 qpt_layout.template split_1<NIP,NIP>(), qpt_data,
467 TensorAssemble<false>(
470 M_layout.merge_23().template split_12<DOF,DOF,DOF,DOF*NC>(), M_data);
474 TensorAssemble<false>(
475 Bt_1d.layout, Bt_1d, B_1d.layout, B_1d,
476 qpt_layout.template split_1<NIP,NIP>(), qpt_data,
479 TensorAssemble<false>(
480 Bt_1d.layout, Bt_1d, B_1d.layout, B_1d,
482 M_layout.merge_23().template split_12<DOF,DOF,DOF,DOF*NC>(), M_data);
487 for (
int k = 0; k < NC; k++)
490 TensorProduct<AssignOp::Set>(
491 qpt_layout.ind2(k).template split_1<NIP,NIP>().
492 template split_1<1,NIP>(), qpt_data,
493 B_1d.layout, B_1d, F3.
layout.template split_1<1,NIP>(), F3);
495 TensorProduct<AssignOp::Set>(
498 Mult_1_2<false>(B_1d.layout, B_1d,
502 Mult_2_1<false>(Bt_1d.layout, Bt_1d,
504 M_layout.ind3(k).template split_1<DOF,DOF>(),
510 template <
int D1,
int D2,
bool Add,
511 typename qpt_layout_t,
typename qpt_data_t,
512 typename D_layout_t,
typename D_data_t>
515 const qpt_data_t &qpt_data,
516 const D_layout_t &D_layout,
517 D_data_t &D_data)
const
519 const int NC = qpt_layout_t::dim_2;
525 TensorAssemble<false>(
526 Bt_1d.layout, D1 == 0 ? Bt_1d : Gt_1d,
527 B_1d.layout, D2 == 0 ? B_1d : G_1d,
528 qpt_layout.template split_1<NIP,NIP>(), qpt_data,
532 Bt_1d.layout, D1 == 1 ? Bt_1d : Gt_1d,
533 B_1d.layout, D2 == 1 ? B_1d : G_1d,
535 D_layout.merge_23().template split_12<DOF,DOF,DOF,DOF*NC>(), D_data);
541 template <
typename qpt_layout_t,
typename qpt_data_t,
542 typename D_layout_t,
typename D_data_t>
545 const qpt_data_t &qpt_data,
546 const D_layout_t &D_layout,
547 D_data_t &D_data)
const
550 Assemble<0,0,false>(qpt_layout.ind23(0,0), qpt_data, D_layout, D_data);
551 Assemble<1,0,true >(qpt_layout.ind23(1,0), qpt_data, D_layout, D_data);
552 Assemble<0,1,true >(qpt_layout.ind23(0,1), qpt_data, D_layout, D_data);
553 Assemble<1,1,true >(qpt_layout.ind23(1,1), qpt_data, D_layout, D_data);
555 const int NC = qpt_layout_t::dim_4;
560 for (
int k = 0; k < NC; k++)
562 for (
int d1 = 0; d1 < 2; d1++)
567 TensorProduct<Set>(qpt_layout.ind23(d1,0).ind2(k).
568 template split_1<NIP,NIP>().
569 template split_1<1,NIP>(), qpt_data,
571 F3.
layout.template split_1<1,NIP>(), F3);
573 TensorProduct<Set>(F3.
layout, F3,
577 TensorProduct<Set>(qpt_layout.ind23(d1,1).ind2(k).
578 template split_1<NIP,NIP>().
579 template split_1<1,NIP>(), qpt_data,
581 F3.
layout.template split_1<1,NIP>(), F3);
583 TensorProduct<Add>(F3.
layout, F3,
587 Mult_1_2<false>(B_1d.layout, d1 == 0 ? B_1d : G_1d,
592 Mult_2_1<false>(Bt_1d.layout, Gt_1d,
594 D_layout.ind3(k).template split_1<DOF,DOF>(),
599 Mult_2_1<true>(Bt_1d.layout, Bt_1d,
601 D_layout.ind3(k).template split_1<DOF,DOF>(),
611 template <
int DOF,
int NIP,
typename real_t>
619 static const int TDOF = DOF*DOF*DOF;
620 static const int TNIP = NIP*NIP*NIP;
624 template <
bool Dx,
bool Dy,
bool Dz,
625 typename dof_layout_t,
typename dof_data_t,
626 typename qpt_layout_t,
typename qpt_data_t>
628 void Calc(
const dof_layout_t &dof_layout,
const dof_data_t &dof_data,
629 const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data)
const
631 const int NC = dof_layout_t::dim_2;
636 Mult_2_1<false>(B_1d.
layout, Dx ? G_1d : B_1d,
637 dof_layout.template split_1<DOF,DOF*DOF>(), dof_data,
640 Mult_1_2<false>(Bt_1d.
layout, Dy ? Gt_1d : Bt_1d,
644 Mult_1_2<false>(Bt_1d.
layout, Dz ? Gt_1d : Bt_1d,
646 qpt_layout.template split_1<NIP*NIP,NIP>(), qpt_data);
651 template <
typename dof_layout_t,
typename dof_data_t,
652 typename qpt_layout_t,
typename qpt_data_t>
654 void Calc(
const dof_layout_t &dof_layout,
const dof_data_t &dof_data,
655 const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data)
const
657 Calc<false,false,false>(dof_layout, dof_data, qpt_layout, qpt_data);
660 template <
bool Dx,
bool Dy,
bool Dz,
bool Add,
661 typename qpt_layout_t,
typename qpt_data_t,
662 typename dof_layout_t,
typename dof_data_t>
664 void CalcT(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
665 const dof_layout_t &dof_layout, dof_data_t &dof_data)
const
667 const int NC = dof_layout_t::dim_2;
672 Mult_1_2<false>(B_1d.
layout, Dz ? G_1d : B_1d,
673 qpt_layout.template split_1<NIP*NIP,NIP>(), qpt_data,
676 Mult_1_2<false>(B_1d.
layout, Dy ? G_1d : B_1d,
680 Mult_2_1<Add>(Bt_1d.
layout, Dx ? Gt_1d : Bt_1d,
682 dof_layout.template split_1<DOF,DOF*DOF>(), dof_data);
688 typename qpt_layout_t,
typename qpt_data_t,
689 typename dof_layout_t,
typename dof_data_t>
691 void CalcT(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
692 const dof_layout_t &dof_layout, dof_data_t &dof_data)
const
694 CalcT<false,false,false,Add>(qpt_layout, qpt_data, dof_layout, dof_data);
699 template <
typename dof_layout_t,
typename dof_data_t,
700 typename grad_layout_t,
typename grad_data_t>
703 const dof_data_t &dof_data,
704 const grad_layout_t &grad_layout,
705 grad_data_t &grad_data)
const
707 Calc<true,false,false>(dof_layout, dof_data,
708 grad_layout.ind2(0), grad_data);
709 Calc<false,true,false>(dof_layout, dof_data,
710 grad_layout.ind2(1), grad_data);
711 Calc<false,false,true>(dof_layout, dof_data,
712 grad_layout.ind2(2), grad_data);
721 typename grad_layout_t,
typename grad_data_t,
722 typename dof_layout_t,
typename dof_data_t>
725 const grad_data_t &grad_data,
726 const dof_layout_t &dof_layout,
727 dof_data_t &dof_data)
const
729 CalcT<true,false,false, Add>(grad_layout.ind2(0), grad_data,
730 dof_layout, dof_data);
731 CalcT<false,true,false,true>(grad_layout.ind2(1), grad_data,
732 dof_layout, dof_data);
733 CalcT<false,false,true,true>(grad_layout.ind2(2), grad_data,
734 dof_layout, dof_data);
739 template <
typename qpt_layout_t,
typename qpt_data_t,
740 typename M_layout_t,
typename M_data_t>
742 void Assemble(
const qpt_layout_t &qpt_layout,
const qpt_data_t &qpt_data,
743 const M_layout_t &M_layout, M_data_t &M_data)
const
745 const int NC = qpt_layout_t::dim_2;
753 TensorAssemble<false>(
755 qpt_layout.template split_1<NIP*NIP,NIP>(), qpt_data,
758 TensorAssemble<false>(
763 TensorAssemble<false>(
766 M_layout.merge_23().template split_12<DOF,DOF*DOF,DOF,DOF*DOF*NC>(),
770 TensorAssemble<false>(
772 qpt_layout.template split_1<NIP*NIP,NIP>(), qpt_data,
775 TensorAssemble<false>(
777 TTensor3<DOF*NIP,NIP,DOF*NC>::layout, A1,
780 TensorAssemble<false>(
782 TTensor3<DOF*DOF,NIP,DOF*DOF*NC>::layout, A2,
783 M_layout.merge_23().template split_12<DOF,DOF*DOF,DOF,DOF*DOF*NC>(),
788 template <
int D1,
int D2,
bool Add,
789 typename qpt_layout_t,
typename qpt_data_t,
790 typename D_layout_t,
typename D_data_t>
793 const qpt_data_t &qpt_data,
794 const D_layout_t &D_layout,
795 D_data_t &D_data)
const
797 const int NC = qpt_layout_t::dim_2;
804 TensorAssemble<false>(
805 Bt_1d.
layout, D1 != 2 ? Bt_1d : Gt_1d,
806 B_1d.
layout, D2 != 2 ? B_1d : G_1d,
807 qpt_layout.template split_1<NIP*NIP,NIP>(), qpt_data,
810 TensorAssemble<false>(
811 Bt_1d.
layout, D1 != 1 ? Bt_1d : Gt_1d,
812 B_1d.
layout, D2 != 1 ? B_1d : G_1d,
817 Bt_1d.
layout, D1 != 0 ? Bt_1d : Gt_1d,
818 B_1d.
layout, D2 != 0 ? B_1d : G_1d,
820 D_layout.merge_23().template split_12<DOF,DOF*DOF,DOF,DOF*DOF*NC>(),
825 template <
typename qpt_layout_t,
typename qpt_data_t,
826 typename D_layout_t,
typename D_data_t>
829 const qpt_layout_t &qpt_layout,
830 const qpt_data_t &qpt_data,
831 const D_layout_t &D_layout,
832 D_data_t &D_data)
const
834 const int NC = qpt_layout_t::dim_2;
841 TensorAssemble<false>(
842 Bt_1d.
layout, D1 != 2 ? Bt_1d : Gt_1d,
843 B_1d.
layout, D2 != 2 ? B_1d : G_1d,
844 qpt_layout.template split_1<NIP*NIP,NIP>(), qpt_data,
847 TensorAssemble<false>(
848 Bt_1d.
layout, D1 != 1 ? Bt_1d : Gt_1d,
849 B_1d.
layout, D2 != 1 ? B_1d : G_1d,
853 TensorAssemble<true>(
854 Bt_1d.
layout, D1 != 0 ? Bt_1d : Gt_1d,
855 B_1d.
layout, D2 != 0 ? B_1d : G_1d,
857 D_layout.merge_23().template split_12<DOF,DOF*DOF,DOF,DOF*DOF*NC>(),
865 template <
typename qpt_layout_t,
typename qpt_data_t,
866 typename D_layout_t,
typename D_data_t>
869 const qpt_data_t &qpt_data,
870 const D_layout_t &D_layout,
871 D_data_t &D_data)
const
875 Assemble<0,0,false>(qpt_layout.ind23(0,0), qpt_data, D_layout, D_data);
876 Assemble<1,0,true >(qpt_layout.ind23(1,0), qpt_data, D_layout, D_data);
877 Assemble<2,0,true >(qpt_layout.ind23(2,0), qpt_data, D_layout, D_data);
878 Assemble<0,1,true >(qpt_layout.ind23(0,1), qpt_data, D_layout, D_data);
879 Assemble<1,1,true >(qpt_layout.ind23(1,1), qpt_data, D_layout, D_data);
880 Assemble<2,1,true >(qpt_layout.ind23(2,1), qpt_data, D_layout, D_data);
881 Assemble<0,2,true >(qpt_layout.ind23(0,2), qpt_data, D_layout, D_data);
882 Assemble<1,2,true >(qpt_layout.ind23(1,2), qpt_data, D_layout, D_data);
883 Assemble<2,2,true >(qpt_layout.ind23(2,2), qpt_data, D_layout, D_data);
885 TAssign<AssignOp::Set>(D_layout, D_data, 0.0);
886 for (
int d2 = 0; d2 < 3; d2++)
888 for (
int d1 = 0; d1 < 3; d1++)
890 Assemble(d1, d2, qpt_layout.ind23(d1,d2), qpt_data,
899 template <
class FE,
class IR,
typename real_t>
906 using base_class::B_1d;
907 using base_class::Bt_1d;
908 using base_class::G_1d;
909 using base_class::Gt_1d;
914 fe.Calc1DShapes(IR::Get1DIntRule(), B_1d.data, G_1d.data);
915 TAssign<AssignOp::Set>(Bt_1d.layout, Bt_1d,
916 B_1d.layout.transpose_12(), B_1d);
917 TAssign<AssignOp::Set>(Gt_1d.layout, Gt_1d,
918 G_1d.layout.transpose_12(), G_1d);
925 template <
class FE,
class IR,
typename real_t>
932 static const int qpts = IR::qpts;
933 static const bool tensor_prod = FE::tensor_prod && IR::tensor_prod;
938 using base_class::Calc;
939 using base_class::CalcT;
940 using base_class::CalcGrad;
941 using base_class::CalcGradT;
951 template <
typename FESpace_t,
typename VecLayout_t,
typename IR,
952 typename complex_t,
typename real_t>
964 inline MFEM_ALWAYS_INLINE
969 vec_layout(vec_layout)
973 inline MFEM_ALWAYS_INLINE
980 template <
typename FESpace_t,
typename VecLayout_t,
typename IR,
981 typename complex_t = double,
typename real_t =
double>
995 static const int dofs = FE_type::dofs;
997 static const int qpts = IR::qpts;
998 static const int vdim = VecLayout_t::vec_dim;
1013 inline MFEM_ALWAYS_INLINE
1016 const complex_t *global_data_in, complex_t *global_data_out)
1023 inline MFEM_ALWAYS_INLINE
1025 const complex_t *global_data_in, complex_t *global_data_out)
1032 inline MFEM_ALWAYS_INLINE
1034 const complex_t *global_data_in, complex_t *global_data_out)
1046 inline MFEM_ALWAYS_INLINE
1053 template <
typename val_layout_t,
typename val_data_t>
1054 inline MFEM_ALWAYS_INLINE
1055 void GetValues(
int el,
const val_layout_t &l, val_data_t &vals)
1057 const int ne = val_layout_t::dim_3;
1061 shapeEval.Calc(val_dofs.
layout.merge_23(), val_dofs, l.merge_23(), vals);
1065 template <
typename grad_layout_t,
typename grad_data_t>
1066 inline MFEM_ALWAYS_INLINE
1069 const int ne = grad_layout_t::dim_4;
1074 l.merge_34(), grad);
1079 template <
typename DataType>
1080 inline MFEM_ALWAYS_INLINE
1087 template <
typename DataType>
1088 inline MFEM_ALWAYS_INLINE
1095 template <
bool Add,
typename DataType>
1096 inline MFEM_ALWAYS_INLINE
1101 template Assemble<Add>(
vec_layout, *
this, F);
1104 template <
bool Add,
typename DataType>
1105 inline MFEM_ALWAYS_INLINE
1112 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
1113 template <
typename DataType>
1114 inline MFEM_ALWAYS_INLINE
1120 template <
bool Add,
typename DataType>
1121 inline MFEM_ALWAYS_INLINE
1125 template AssembleSerialized<Add>(*
this, F, loc_dofs);
1143 template<
int IOData,
int NE>
struct AData;
1152 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1163 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1174 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1186 template <
int IData,
int OData,
int NE>
1190 static const int ne = NE;
1198 template <
int Ops,
bool dummy>
struct Action;
1207 template <
typename vec_layout_t,
typename AData_t>
1208 static inline MFEM_ALWAYS_INLINE
1211 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1212 typename AData_t::val_dofs_t &val_dofs = D.val_dofs;
1214 typename AData_t::val_dofs_t val_dofs;
1216 T.
fespace.VectorExtract(l, T.
data_in, val_dofs.layout, val_dofs);
1217 T.
shapeEval.Calc(val_dofs.layout.merge_23(), val_dofs,
1218 D.val_qpts.layout.merge_23(), D.val_qpts);
1221 template <
bool Add,
typename vec_layout_t,
typename AData_t>
1222 static inline MFEM_ALWAYS_INLINE
1226 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1227 typename AData_t::val_dofs_t &val_dofs = D.val_dofs;
1229 typename AData_t::val_dofs_t val_dofs;
1232 D.val_qpts.layout.merge_23(), D.val_qpts,
1233 val_dofs.layout.merge_23(), val_dofs);
1234 T.
fespace.template VectorAssemble<Op>(
1235 val_dofs.layout, val_dofs, l, T.
data_out);
1238 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
1239 template <
typename AData_t>
1240 static inline MFEM_ALWAYS_INLINE
1243 T.
shapeEval.Calc(AData_t::val_dofs_t::layout.merge_23(), loc_dofs,
1244 D.val_qpts.layout.merge_23(), D.val_qpts);
1247 template <
bool Add,
typename AData_t>
1248 static inline MFEM_ALWAYS_INLINE
1252 D.val_qpts.layout.merge_23(), D.val_qpts,
1253 AData_t::val_dofs_t::layout.merge_23(), loc_dofs);
1260 template <
typename vec_layout_t,
typename AData_t>
1261 static inline MFEM_ALWAYS_INLINE
1264 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1265 typename AData_t::val_dofs_t &val_dofs = D.val_dofs;
1267 typename AData_t::val_dofs_t val_dofs;
1269 T.
fespace.VectorExtract(l, T.
data_in, val_dofs.layout, val_dofs);
1270 T.
shapeEval.CalcGrad(val_dofs.layout.merge_23(), val_dofs,
1271 D.grad_qpts.layout.merge_34(), D.grad_qpts);
1274 template <
bool Add,
typename vec_layout_t,
typename AData_t>
1275 static inline MFEM_ALWAYS_INLINE
1279 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1280 typename AData_t::val_dofs_t &val_dofs = D.val_dofs;
1282 typename AData_t::val_dofs_t val_dofs;
1285 D.grad_qpts.layout.merge_34(), D.grad_qpts,
1286 val_dofs.layout.merge_23(), val_dofs);
1287 T.
fespace.template VectorAssemble<Op>(
1288 val_dofs.layout, val_dofs, l, T.
data_out);
1291 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
1292 template <
typename AData_t>
1293 static inline MFEM_ALWAYS_INLINE
1296 T.
shapeEval.CalcGrad(AData_t::val_dofs_t::layout.merge_23(), loc_dofs,
1297 D.grad_qpts.layout.merge_34(), D.grad_qpts);
1300 template <
bool Add,
typename AData_t>
1301 static inline MFEM_ALWAYS_INLINE
1305 D.grad_qpts.layout.merge_34(), D.grad_qpts,
1306 AData_t::val_dofs_t::layout.merge_23(), loc_dofs);
1313 template <
typename vec_layout_t,
typename AData_t>
1314 static inline MFEM_ALWAYS_INLINE
1317 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1318 typename AData_t::val_dofs_t &val_dofs = D.val_dofs;
1320 typename AData_t::val_dofs_t val_dofs;
1322 T.
fespace.VectorExtract(l, T.
data_in, val_dofs.layout, val_dofs);
1323 T.
shapeEval.Calc(val_dofs.layout.merge_23(), val_dofs,
1324 D.val_qpts.layout.merge_23(), D.val_qpts);
1325 T.
shapeEval.CalcGrad(val_dofs.layout.merge_23(), val_dofs,
1326 D.grad_qpts.layout.merge_34(), D.grad_qpts);
1329 template <
bool Add,
typename vec_layout_t,
typename AData_t>
1330 static inline MFEM_ALWAYS_INLINE
1334 #ifdef MFEM_TEMPLATE_FIELD_EVAL_DATA_HAS_DOFS
1335 typename AData_t::val_dofs_t &val_dofs = D.val_dofs;
1337 typename AData_t::val_dofs_t val_dofs;
1340 D.val_qpts.layout.merge_23(), D.val_qpts,
1341 val_dofs.layout.merge_23(), val_dofs);
1343 D.grad_qpts.layout.merge_34(), D.grad_qpts,
1344 val_dofs.layout.merge_23(), val_dofs);
1345 T.
fespace.template VectorAssemble<Op>(
1346 val_dofs.layout, val_dofs, l, T.
data_out);
1349 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
1350 template <
typename AData_t>
1351 static inline MFEM_ALWAYS_INLINE
1354 T.
shapeEval.Calc(AData_t::val_dofs_t::layout.merge_23(), loc_dofs,
1355 D.val_qpts.layout.merge_23(), D.val_qpts);
1356 T.
shapeEval.CalcGrad(AData_t::val_dofs_t::layout.merge_23(), loc_dofs,
1357 D.grad_qpts.layout.merge_34(), D.grad_qpts);
1360 template <
bool Add,
typename AData_t>
1361 static inline MFEM_ALWAYS_INLINE
1365 D.val_qpts.layout.merge_23(), D.val_qpts,
1366 AData_t::val_dofs_t::layout.merge_23(), loc_dofs);
1368 D.grad_qpts.layout.merge_34(), D.grad_qpts,
1369 AData_t::val_dofs_t::layout.merge_23(), loc_dofs);
1382 template <
typename qpt_layout_t,
typename qpt_data_t,
1383 typename M_layout_t,
typename M_data_t>
1384 static inline MFEM_ALWAYS_INLINE
1385 void Compute(
const qpt_layout_t &
a,
const qpt_data_t &A,
1388 ev.Assemble(a.template split_1<qpts,1>(), A,
1389 m.template split_2<dofs,1>(), M);
1397 template <
typename qpt_layout_t,
typename qpt_data_t,
1398 typename M_layout_t,
typename M_data_t>
1399 static inline MFEM_ALWAYS_INLINE
1400 void Compute(
const qpt_layout_t &
a,
const qpt_data_t &A,
1403 ev.AssembleGradGrad(a.template split_3<dim,1>(), A,
1404 m.template split_2<dofs,1>(), M);
1408 template <
typename kernel_t,
int NE>
struct Spec
1422 #endif // MFEM_TEMPLATE_EVALUATOR
TMatrix< NIP, DOF, real_t, true > G_1d
static MFEM_ALWAYS_INLINE void Compute(const qpt_layout_t &a, const qpt_data_t &A, const M_layout_t &m, M_data_t &M, ShapeEval_type &ev)
static const bool tensor_prod
MFEM_ALWAYS_INLINE VecLayout_type & VecLayout()
static MFEM_ALWAYS_INLINE void Compute(const qpt_layout_t &a, const qpt_data_t &A, const M_layout_t &m, M_data_t &M, ShapeEval_type &ev)
ShapeEvaluator< FE_type, IR, real_t > ShapeEval_type
TMatrix< DOF, NIP, real_t, true > Bt
VecLayout_t VecLayout_type
MFEM_ALWAYS_INLINE void CalcGradT(const grad_layout_t &grad_layout, const grad_data_t &grad_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
static MFEM_ALWAYS_INLINE void Eval(const vec_layout_t &l, T_type &T, AData_t &D)
MFEM_ALWAYS_INLINE void CalcT(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
TMatrix< DOF, NIP, real_t, true > Gt_1d
MFEM_ALWAYS_INLINE void CalcGradT(const grad_layout_t &grad_layout, const grad_data_t &grad_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
static MFEM_ALWAYS_INLINE void EvalSerialized(T_type &T, const complex_t *loc_dofs, AData_t &D)
MFEM_ALWAYS_INLINE void Assemble(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const M_layout_t &M_layout, M_data_t &M_data) const
TTensor3< dofs, vdim, NE, complex_t > val_dofs_t
ShapeEvaluator_base(const FE &fe)
TProductShapeEvaluator< FE::dim, FE::dofs_1d, IR::qpts_1d, real_t > base_class
TTensor4< qpts, dim, vdim, NE, complex_t > grad_qpts
static const layout_type layout
MFEM_ALWAYS_INLINE void Calc(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data) const
MFEM_ALWAYS_INLINE void Assemble(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const D_layout_t &D_layout, D_data_t &D_data) const
MFEM_ALWAYS_INLINE void Eval(DataType &F)
TMatrix< DOF, NIP, real_t, true > Gt_1d
MFEM_ALWAYS_INLINE void Calc(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data) const
MFEM_ALWAYS_INLINE void CalcT(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
MFEM_ALWAYS_INLINE void CalcGradT(const grad_layout_t &grad_layout, const grad_data_t &grad_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
MFEM_ALWAYS_INLINE void Assemble(DataType &F)
MFEM_ALWAYS_INLINE FieldEvaluator_base(const FE_type &fe, const FiniteElementSpace &fes)
MFEM_ALWAYS_INLINE FieldEvaluator(const FiniteElementSpace &fes, const complex_t *global_data_in, complex_t *global_data_out)
TElementMatrix< InData, OutData, NE > ElementMatrix
static const layout_type layout
MFEM_ALWAYS_INLINE void AssembleGradGrad(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const D_layout_t &D_layout, D_data_t &D_data) const
static MFEM_ALWAYS_INLINE void EvalSerialized(T_type &T, const complex_t *loc_dofs, AData_t &D)
TTensor3< qpts, vdim, NE, complex_t > val_qpts
TTensor3< DOF, NIP, DIM, real_t > Gt
TTensor3< dofs, vdim, NE, complex_t, true > val_dofs_t
MFEM_ALWAYS_INLINE FieldEvaluator(const FieldEvaluator &f, const complex_t *global_data_in, complex_t *global_data_out)
FESpace_t::FE_type FE_type
static MFEM_ALWAYS_INLINE void Assemble(const vec_layout_t &l, T_type &T, AData_t &D)
MFEM_ALWAYS_INLINE void CalcGradT(const grad_layout_t &grad_layout, const grad_data_t &grad_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
MFEM_ALWAYS_INLINE void Calc(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data) const
MFEM_ALWAYS_INLINE void Assemble(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const D_layout_t &D_layout, D_data_t &D_data) const
ShapeEvaluator(const FE &fe)
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
MFEM_ALWAYS_INLINE void AssembleSerialized(const DataType &F, complex_t *loc_dofs)
static const layout_type layout
MFEM_ALWAYS_INLINE void AssembleGradGrad(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const D_layout_t &D_layout, D_data_t &D_data) const
MFEM_ALWAYS_INLINE FieldEvaluator(const FESpace_t &tfes, const ShapeEval_type &shape_eval, const VecLayout_type &vec_layout, const complex_t *global_data_in, complex_t *global_data_out)
static MFEM_ALWAYS_INLINE void AssembleSerialized(T_type &T, const AData_t &D, complex_t *loc_dofs)
TTensor3< qpts, vdim, NE, complex_t, true > val_qpts
MFEM_ALWAYS_INLINE void Assemble(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const M_layout_t &M_layout, M_data_t &M_data) const
MFEM_ALWAYS_INLINE FESpace_type & FESpace()
MFEM_ALWAYS_INLINE void EvalSerialized(const complex_t *loc_dofs, DataType &F)
TMatrix< DOF, NIP, real_t, true > Gt_1d
ShapeEvaluator_base< FE, IR, tensor_prod, real_t > base_class
static MFEM_ALWAYS_INLINE void Eval(const vec_layout_t &l, T_type &T, AData_t &D)
MFEM_ALWAYS_INLINE void Calc(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data) const
TTensor3< NIP, DIM, DOF, real_t, true > G
MFEM_ALWAYS_INLINE void CalcGrad(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const grad_layout_t &grad_layout, grad_data_t &grad_data) const
MFEM_ALWAYS_INLINE ShapeEval_type & ShapeEval()
TTensor3< dofs, vdim, NE, complex_t, true > val_dofs_t
static MFEM_ALWAYS_INLINE void Assemble(const vec_layout_t &l, T_type &T, AData_t &D)
MFEM_ALWAYS_INLINE void Eval(int el, DataType &F)
ShapeEvaluator_base(const FE &fe)
MFEM_ALWAYS_INLINE void CalcT(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
MFEM_ALWAYS_INLINE void AssembleGradGrad(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const D_layout_t &D_layout, D_data_t &D_data) const
MFEM_ALWAYS_INLINE void Calc(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data) const
MFEM_ALWAYS_INLINE void CalcGrad(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const grad_layout_t &grad_layout, grad_data_t &grad_data) const
MFEM_ALWAYS_INLINE void CalcGrad(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const grad_layout_t &grad_layout, grad_data_t &grad_data) const
ShapeEvaluator< FE_type, IR, real_t > ShapeEval_type
BData< InData, OutData, NE > DataType
static MFEM_ALWAYS_INLINE void AssembleSerialized(T_type &T, const AData_t &D, complex_t *loc_dofs)
TTensor3< dofs, vdim, NE, complex_t > val_dofs_t
MFEM_ALWAYS_INLINE void Assemble(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const M_layout_t &M_layout, M_data_t &M_data) const
MFEM_ALWAYS_INLINE void AssembleGradGrad(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const D_layout_t &D_layout, D_data_t &D_data) const
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
MFEM_ALWAYS_INLINE void CalcT(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
const complex_t * data_in
MFEM_ALWAYS_INLINE void GetValues(int el, const val_layout_t &l, val_data_t &vals)
static MFEM_ALWAYS_INLINE void Assemble(const vec_layout_t &l, T_type &T, AData_t &D)
MFEM_ALWAYS_INLINE void Assemble(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const M_layout_t &M_layout, M_data_t &M_data) const
MFEM_ALWAYS_INLINE void SetElement(int el)
TTensor4< qpts, dim, vdim, NE, complex_t > grad_qpts
TMatrix< NIP, DOF, real_t, true > G_1d
MFEM_ALWAYS_INLINE void CalcT(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
FieldEvaluator_base< FESpace_t, VecLayout_t, IR, complex_t, real_t > base_class
MFEM_ALWAYS_INLINE void GetGradients(int el, const grad_layout_t &l, grad_data_t &grad)
FieldEvaluator< FESpace_t, VecLayout_t, IR, complex_t, real_t > T_type
TMatrix< NIP, DOF, real_t, true > B
TTensor3< dofs, vdim, NE, complex_t > val_dofs_t
static MFEM_ALWAYS_INLINE void AssembleSerialized(T_type &T, const AData_t &D, complex_t *loc_dofs)
static MFEM_ALWAYS_INLINE void EvalSerialized(T_type &T, const complex_t *loc_dofs, AData_t &D)
FESpace_t::FE_type FE_type
MFEM_ALWAYS_INLINE void CalcT(const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const dof_layout_t &dof_layout, dof_data_t &dof_data) const
TTensor3< dofs, vdim, NE, complex_t, true > val_dofs_t
static MFEM_ALWAYS_INLINE void Eval(const vec_layout_t &l, T_type &T, AData_t &D)
MFEM_ALWAYS_INLINE void Assemble(int D1, int D2, const qpt_layout_t &qpt_layout, const qpt_data_t &qpt_data, const D_layout_t &D_layout, D_data_t &D_data) const
MFEM_ALWAYS_INLINE void Assemble(int el, DataType &F)
MFEM_ALWAYS_INLINE FieldEvaluator_base(const FESpace_t &tfes, const ShapeEval_type &shape_eval, const VecLayout_t &vec_layout)
TMatrix< NIP, DOF, real_t, true > G_1d
MFEM_ALWAYS_INLINE void CalcGrad(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const grad_layout_t &grad_layout, grad_data_t &grad_data) const
MFEM_ALWAYS_INLINE void Calc(const dof_layout_t &dof_layout, const dof_data_t &dof_data, const qpt_layout_t &qpt_layout, qpt_data_t &qpt_data) const