12 #include "../general/forall.hpp"
30 const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
31 Device::GetDeviceMemoryType() : pa_mt;
36 if (mesh->
GetNE() == 0) {
return; }
60 GeometricFactors::JACOBIANS, mt);
64 pa_data.SetSize(ne*nq, mt);
69 if (
dim==1) { MFEM_ABORT(
"Not supported yet... stay tuned!"); }
73 const int Q1D = quad1D;
74 const bool const_c = coeff.
Size() == 1;
75 const bool by_val = map_type == FiniteElement::VALUE;
77 const auto J =
Reshape(geom->J.Read(), Q1D,Q1D,2,2,NE);
78 const auto C = const_c ?
Reshape(coeff.
Read(), 1,1,1) :
80 auto v =
Reshape(pa_data.Write(), Q1D,Q1D, NE);
81 MFEM_FORALL_2D(e, NE, Q1D,Q1D,1,
83 MFEM_FOREACH_THREAD(qx,x,Q1D)
85 MFEM_FOREACH_THREAD(qy,y,Q1D)
87 const double J11 = J(qx,qy,0,0,e);
88 const double J12 = J(qx,qy,1,0,e);
89 const double J21 = J(qx,qy,0,1,e);
90 const double J22 = J(qx,qy,1,1,e);
91 const double detJ = (J11*J22)-(J21*J12);
92 const double coeff = const_c ? C(0,0,0) : C(qx,qy,e);
93 v(qx,qy,e) = W(qx,qy) * coeff * (by_val ? detJ : 1.0/detJ);
101 const int Q1D = quad1D;
102 const bool const_c = coeff.
Size() == 1;
103 const bool by_val = map_type == FiniteElement::VALUE;
105 const auto J =
Reshape(geom->J.Read(), Q1D,Q1D,Q1D,3,3,NE);
106 const auto C = const_c ?
Reshape(coeff.
Read(), 1,1,1,1) :
108 auto v =
Reshape(pa_data.Write(), Q1D,Q1D,Q1D,NE);
109 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
111 MFEM_FOREACH_THREAD(qx,x,Q1D)
113 MFEM_FOREACH_THREAD(qy,y,Q1D)
115 MFEM_FOREACH_THREAD(qz,z,Q1D)
117 const double J11 = J(qx,qy,qz,0,0,e);
118 const double J21 = J(qx,qy,qz,1,0,e);
119 const double J31 = J(qx,qy,qz,2,0,e);
120 const double J12 = J(qx,qy,qz,0,1,e);
121 const double J22 = J(qx,qy,qz,1,1,e);
122 const double J32 = J(qx,qy,qz,2,1,e);
123 const double J13 = J(qx,qy,qz,0,2,e);
124 const double J23 = J(qx,qy,qz,1,2,e);
125 const double J33 = J(qx,qy,qz,2,2,e);
126 const double detJ = J11 * (J22 * J33 - J32 * J23) -
127 J21 * (J12 * J33 - J32 * J13) +
128 J31 * (J12 * J23 - J22 * J13);
129 const double coeff = const_c ? C(0,0,0,0) : C(qx,qy,qz,e);
130 v(qx,qy,qz,e) = W(qx,qy,qz) * coeff * (by_val ? detJ : 1.0/detJ);
138 template<
int T_D1D = 0,
int T_Q1D = 0>
139 static void PAMassAssembleDiagonal2D(
const int NE,
146 const int D1D = T_D1D ? T_D1D : d1d;
147 const int Q1D = T_Q1D ? T_Q1D : q1d;
148 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
149 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
155 const int D1D = T_D1D ? T_D1D : d1d;
156 const int Q1D = T_Q1D ? T_Q1D : q1d;
157 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
158 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
160 for (
int qx = 0; qx < Q1D; ++qx)
162 for (
int dy = 0; dy < D1D; ++dy)
165 for (
int qy = 0; qy < Q1D; ++qy)
167 QD[qx][dy] += B(qy, dy) * B(qy, dy) * D(qx, qy, e);
171 for (
int dy = 0; dy < D1D; ++dy)
173 for (
int dx = 0; dx < D1D; ++dx)
175 for (
int qx = 0; qx < Q1D; ++qx)
177 Y(dx,dy,e) += B(qx, dx) * B(qx, dx) * QD[qx][dy];
184 template<
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
185 static void SmemPAMassAssembleDiagonal2D(
const int NE,
186 const Array<double> &b_,
192 const int D1D = T_D1D ? T_D1D : d1d;
193 const int Q1D = T_Q1D ? T_Q1D : q1d;
194 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
195 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
196 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
197 MFEM_VERIFY(D1D <= MD1,
"");
198 MFEM_VERIFY(Q1D <= MQ1,
"");
199 auto b =
Reshape(b_.Read(), Q1D, D1D);
200 auto D =
Reshape(d_.Read(), Q1D, Q1D, NE);
201 auto Y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
202 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
204 const int tidz = MFEM_THREAD_ID(z);
205 const int D1D = T_D1D ? T_D1D : d1d;
206 const int Q1D = T_Q1D ? T_Q1D : q1d;
207 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
208 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
209 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
210 MFEM_SHARED
double B[MQ1][MD1];
211 MFEM_SHARED
double QDZ[NBZ][MQ1][MD1];
212 double (*QD)[MD1] = (double (*)[MD1])(QDZ + tidz);
215 MFEM_FOREACH_THREAD(d,y,D1D)
217 MFEM_FOREACH_THREAD(q,x,Q1D)
224 MFEM_FOREACH_THREAD(qx,x,Q1D)
226 MFEM_FOREACH_THREAD(dy,y,D1D)
229 for (
int qy = 0; qy < Q1D; ++qy)
231 QD[qx][dy] += B[qy][dy] * B[qy][dy] * D(qx, qy, e);
236 MFEM_FOREACH_THREAD(dy,y,D1D)
238 MFEM_FOREACH_THREAD(dx,x,D1D)
240 for (
int qx = 0; qx < Q1D; ++qx)
243 Y(dx,dy,e) += B[qx][dx] * B[qx][dx] * QD[qx][dy];
250 template<
int T_D1D = 0,
int T_Q1D = 0>
251 static void PAMassAssembleDiagonal3D(
const int NE,
252 const Array<double> &b,
258 const int D1D = T_D1D ? T_D1D : d1d;
259 const int Q1D = T_Q1D ? T_Q1D : q1d;
260 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
261 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
262 auto B =
Reshape(b.Read(), Q1D, D1D);
263 auto D =
Reshape(d.Read(), Q1D, Q1D, Q1D, NE);
264 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, D1D, NE);
267 const int D1D = T_D1D ? T_D1D : d1d;
268 const int Q1D = T_Q1D ? T_Q1D : q1d;
269 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
270 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
271 double QQD[MQ1][MQ1][MD1];
272 double QDD[MQ1][MD1][MD1];
273 for (
int qx = 0; qx < Q1D; ++qx)
275 for (
int qy = 0; qy < Q1D; ++qy)
277 for (
int dz = 0; dz < D1D; ++dz)
279 QQD[qx][qy][dz] = 0.0;
280 for (
int qz = 0; qz < Q1D; ++qz)
282 QQD[qx][qy][dz] += B(qz, dz) * B(qz, dz) * D(qx, qy, qz, e);
287 for (
int qx = 0; qx < Q1D; ++qx)
289 for (
int dz = 0; dz < D1D; ++dz)
291 for (
int dy = 0; dy < D1D; ++dy)
293 QDD[qx][dy][dz] = 0.0;
294 for (
int qy = 0; qy < Q1D; ++qy)
296 QDD[qx][dy][dz] += B(qy, dy) * B(qy, dy) * QQD[qx][qy][dz];
301 for (
int dz = 0; dz < D1D; ++dz)
303 for (
int dy = 0; dy < D1D; ++dy)
305 for (
int dx = 0; dx < D1D; ++dx)
308 for (
int qx = 0; qx < Q1D; ++qx)
310 t += B(qx, dx) * B(qx, dx) * QDD[qx][dy][dz];
312 Y(dx, dy, dz, e) +=
t;
319 template<
int T_D1D = 0,
int T_Q1D = 0>
320 static void SmemPAMassAssembleDiagonal3D(
const int NE,
321 const Array<double> &b_,
327 const int D1D = T_D1D ? T_D1D : d1d;
328 const int Q1D = T_Q1D ? T_Q1D : q1d;
329 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
330 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
331 MFEM_VERIFY(D1D <= MD1,
"");
332 MFEM_VERIFY(Q1D <= MQ1,
"");
333 auto b =
Reshape(b_.Read(), Q1D, D1D);
334 auto D =
Reshape(d_.Read(), Q1D, Q1D, Q1D, NE);
335 auto Y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
336 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
338 const int tidz = MFEM_THREAD_ID(z);
339 const int D1D = T_D1D ? T_D1D : d1d;
340 const int Q1D = T_Q1D ? T_Q1D : q1d;
341 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
342 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
343 MFEM_SHARED
double B[MQ1][MD1];
344 MFEM_SHARED
double QQD[MQ1][MQ1][MD1];
345 MFEM_SHARED
double QDD[MQ1][MD1][MD1];
348 MFEM_FOREACH_THREAD(d,y,D1D)
350 MFEM_FOREACH_THREAD(q,x,Q1D)
357 MFEM_FOREACH_THREAD(qx,x,Q1D)
359 MFEM_FOREACH_THREAD(qy,y,Q1D)
361 MFEM_FOREACH_THREAD(dz,z,D1D)
363 QQD[qx][qy][dz] = 0.0;
364 for (
int qz = 0; qz < Q1D; ++qz)
366 QQD[qx][qy][dz] += B[qz][dz] * B[qz][dz] * D(qx, qy, qz, e);
372 MFEM_FOREACH_THREAD(qx,x,Q1D)
374 MFEM_FOREACH_THREAD(dz,z,D1D)
376 MFEM_FOREACH_THREAD(dy,y,D1D)
378 QDD[qx][dy][dz] = 0.0;
379 for (
int qy = 0; qy < Q1D; ++qy)
381 QDD[qx][dy][dz] += B[qy][dy] * B[qy][dy] * QQD[qx][qy][dz];
387 MFEM_FOREACH_THREAD(dz,z,D1D)
389 MFEM_FOREACH_THREAD(dy,y,D1D)
391 MFEM_FOREACH_THREAD(dx,x,D1D)
394 for (
int qx = 0; qx < Q1D; ++qx)
396 t += B[qx][dx] * B[qx][dx] * QDD[qx][dy][dz];
398 Y(dx, dy, dz, e) +=
t;
405 static void PAMassAssembleDiagonal(
const int dim,
const int D1D,
406 const int Q1D,
const int NE,
407 const Array<double> &B,
413 switch ((D1D << 4 ) | Q1D)
415 case 0x22:
return SmemPAMassAssembleDiagonal2D<2,2,16>(NE,B,D,Y);
416 case 0x33:
return SmemPAMassAssembleDiagonal2D<3,3,16>(NE,B,D,Y);
417 case 0x44:
return SmemPAMassAssembleDiagonal2D<4,4,8>(NE,B,D,Y);
418 case 0x55:
return SmemPAMassAssembleDiagonal2D<5,5,8>(NE,B,D,Y);
419 case 0x66:
return SmemPAMassAssembleDiagonal2D<6,6,4>(NE,B,D,Y);
420 case 0x77:
return SmemPAMassAssembleDiagonal2D<7,7,4>(NE,B,D,Y);
421 case 0x88:
return SmemPAMassAssembleDiagonal2D<8,8,2>(NE,B,D,Y);
422 case 0x99:
return SmemPAMassAssembleDiagonal2D<9,9,2>(NE,B,D,Y);
423 default:
return PAMassAssembleDiagonal2D(NE,B,D,Y,D1D,Q1D);
428 switch ((D1D << 4 ) | Q1D)
430 case 0x23:
return SmemPAMassAssembleDiagonal3D<2,3>(NE,B,D,Y);
431 case 0x24:
return SmemPAMassAssembleDiagonal3D<2,4>(NE,B,D,Y);
432 case 0x26:
return SmemPAMassAssembleDiagonal3D<2,6>(NE,B,D,Y);
433 case 0x34:
return SmemPAMassAssembleDiagonal3D<3,4>(NE,B,D,Y);
434 case 0x35:
return SmemPAMassAssembleDiagonal3D<3,5>(NE,B,D,Y);
435 case 0x45:
return SmemPAMassAssembleDiagonal3D<4,5>(NE,B,D,Y);
436 case 0x48:
return SmemPAMassAssembleDiagonal3D<4,8>(NE,B,D,Y);
437 case 0x56:
return SmemPAMassAssembleDiagonal3D<5,6>(NE,B,D,Y);
438 case 0x67:
return SmemPAMassAssembleDiagonal3D<6,7>(NE,B,D,Y);
439 case 0x78:
return SmemPAMassAssembleDiagonal3D<7,8>(NE,B,D,Y);
440 case 0x89:
return SmemPAMassAssembleDiagonal3D<8,9>(NE,B,D,Y);
441 default:
return PAMassAssembleDiagonal3D(NE,B,D,Y,D1D,Q1D);
444 MFEM_ABORT(
"Unknown kernel.");
447 void MassIntegrator::AssembleDiagonalPA(
Vector &diag)
451 ceedOp->GetDiagonal(diag);
455 PAMassAssembleDiagonal(dim, dofs1D, quad1D, ne, maps->B, pa_data, diag);
462 static void OccaPAMassApply2D(
const int D1D,
471 occa::properties props;
472 props[
"defines/D1D"] = D1D;
473 props[
"defines/Q1D"] = Q1D;
479 const occa_id_t id = std::make_pair(D1D,Q1D);
480 if (!Device::Allows(Backend::OCCA_CUDA))
483 if (OccaMassApply2D_cpu.find(
id) == OccaMassApply2D_cpu.end())
485 const occa::kernel MassApply2D_CPU =
487 "MassApply2D_CPU", props);
488 OccaMassApply2D_cpu.emplace(
id, MassApply2D_CPU);
490 OccaMassApply2D_cpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
495 if (OccaMassApply2D_gpu.find(
id) == OccaMassApply2D_gpu.end())
497 const occa::kernel MassApply2D_GPU =
499 "MassApply2D_GPU", props);
500 OccaMassApply2D_gpu.emplace(
id, MassApply2D_GPU);
502 OccaMassApply2D_gpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
507 static void OccaPAMassApply3D(
const int D1D,
510 const Array<double> &B,
511 const Array<double> &Bt,
516 occa::properties props;
517 props[
"defines/D1D"] = D1D;
518 props[
"defines/Q1D"] = Q1D;
520 const occa::memory o_Bt =
OccaMemoryRead(Bt.GetMemory(), Bt.Size());
524 const occa_id_t id = std::make_pair(D1D,Q1D);
525 if (!Device::Allows(Backend::OCCA_CUDA))
528 if (OccaMassApply3D_cpu.find(
id) == OccaMassApply3D_cpu.end())
530 const occa::kernel MassApply3D_CPU =
532 "MassApply3D_CPU", props);
533 OccaMassApply3D_cpu.emplace(
id, MassApply3D_CPU);
535 OccaMassApply3D_cpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
540 if (OccaMassApply3D_gpu.find(
id) == OccaMassApply3D_gpu.end())
542 const occa::kernel MassApply3D_GPU =
544 "MassApply3D_GPU", props);
545 OccaMassApply3D_gpu.emplace(
id, MassApply3D_GPU);
547 OccaMassApply3D_gpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
550 #endif // MFEM_USE_OCCA
552 template<
int T_D1D = 0,
int T_Q1D = 0>
553 static void PAMassApply2D(
const int NE,
554 const Array<double> &b_,
555 const Array<double> &bt_,
562 MFEM_VERIFY(T_D1D ? T_D1D : d1d <=
MAX_D1D,
"");
563 MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <=
MAX_Q1D,
"");
565 const auto B = b_.Read();
566 const auto Bt = bt_.Read();
567 const auto D = d_.Read();
568 const auto X = x_.Read();
569 auto Y = y_.ReadWrite();
573 internal::PAMassApply2D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
577 template<
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
578 static void SmemPAMassApply2D(
const int NE,
579 const Array<double> &b_,
580 const Array<double> &bt_,
587 MFEM_CONTRACT_VAR(bt_);
588 const int D1D = T_D1D ? T_D1D : d1d;
589 const int Q1D = T_Q1D ? T_Q1D : q1d;
590 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
591 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
592 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
593 MFEM_VERIFY(D1D <= MD1,
"");
594 MFEM_VERIFY(Q1D <= MQ1,
"");
595 const auto b = b_.Read();
596 const auto D = d_.Read();
597 const auto x = x_.Read();
598 auto Y = y_.ReadWrite();
599 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
601 internal::SmemPAMassApply2D_Element<T_D1D,T_Q1D,T_NBZ>(e, NE,
b, D, x, Y, d1d, q1d);
605 template<
int T_D1D = 0,
int T_Q1D = 0>
606 static void PAMassApply3D(
const int NE,
607 const Array<double> &b_,
608 const Array<double> &bt_,
615 MFEM_VERIFY(T_D1D ? T_D1D : d1d <=
MAX_D1D,
"");
616 MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <=
MAX_Q1D,
"");
618 const auto B = b_.Read();
619 const auto Bt = bt_.Read();
620 const auto D = d_.Read();
621 const auto X = x_.Read();
622 auto Y = y_.ReadWrite();
626 internal::PAMassApply3D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
630 template<
int T_D1D = 0,
int T_Q1D = 0>
631 static void SmemPAMassApply3D(
const int NE,
632 const Array<double> &b_,
633 const Array<double> &bt_,
640 MFEM_CONTRACT_VAR(bt_);
641 const int D1D = T_D1D ? T_D1D : d1d;
642 const int Q1D = T_Q1D ? T_Q1D : q1d;
643 constexpr
int M1Q = T_Q1D ? T_Q1D :
MAX_Q1D;
644 constexpr
int M1D = T_D1D ? T_D1D :
MAX_D1D;
645 MFEM_VERIFY(D1D <= M1D,
"");
646 MFEM_VERIFY(Q1D <= M1Q,
"");
650 auto y = y_.ReadWrite();
651 MFEM_FORALL_3D(e, NE, Q1D, Q1D, 1,
653 internal::SmemPAMassApply3D_Element<T_D1D,T_Q1D>(e, NE,
b, d, x, y, d1d, q1d);
657 static void PAMassApply(
const int dim,
661 const Array<double> &B,
662 const Array<double> &Bt,
672 return OccaPAMassApply2D(D1D,Q1D,NE,B,Bt,D,X,Y);
676 return OccaPAMassApply3D(D1D,Q1D,NE,B,Bt,D,X,Y);
678 MFEM_ABORT(
"OCCA PA Mass Apply unknown kernel!");
680 #endif // MFEM_USE_OCCA
681 const int id = (D1D << 4) | Q1D;
687 case 0x22:
return SmemPAMassApply2D<2,2,16>(NE,B,Bt,D,X,Y);
688 case 0x24:
return SmemPAMassApply2D<2,4,16>(NE,B,Bt,D,X,Y);
689 case 0x33:
return SmemPAMassApply2D<3,3,16>(NE,B,Bt,D,X,Y);
690 case 0x34:
return SmemPAMassApply2D<3,4,16>(NE,B,Bt,D,X,Y);
691 case 0x35:
return SmemPAMassApply2D<3,5,16>(NE,B,Bt,D,X,Y);
692 case 0x36:
return SmemPAMassApply2D<3,6,16>(NE,B,Bt,D,X,Y);
693 case 0x44:
return SmemPAMassApply2D<4,4,8>(NE,B,Bt,D,X,Y);
694 case 0x46:
return SmemPAMassApply2D<4,6,8>(NE,B,Bt,D,X,Y);
695 case 0x48:
return SmemPAMassApply2D<4,8,4>(NE,B,Bt,D,X,Y);
696 case 0x55:
return SmemPAMassApply2D<5,5,8>(NE,B,Bt,D,X,Y);
697 case 0x57:
return SmemPAMassApply2D<5,7,8>(NE,B,Bt,D,X,Y);
698 case 0x58:
return SmemPAMassApply2D<5,8,2>(NE,B,Bt,D,X,Y);
699 case 0x66:
return SmemPAMassApply2D<6,6,4>(NE,B,Bt,D,X,Y);
700 case 0x77:
return SmemPAMassApply2D<7,7,4>(NE,B,Bt,D,X,Y);
701 case 0x88:
return SmemPAMassApply2D<8,8,2>(NE,B,Bt,D,X,Y);
702 case 0x99:
return SmemPAMassApply2D<9,9,2>(NE,B,Bt,D,X,Y);
703 default:
return PAMassApply2D(NE,B,Bt,D,X,Y,D1D,Q1D);
710 case 0x22:
return SmemPAMassApply3D<2,2>(NE,B,Bt,D,X,Y);
711 case 0x23:
return SmemPAMassApply3D<2,3>(NE,B,Bt,D,X,Y);
712 case 0x24:
return SmemPAMassApply3D<2,4>(NE,B,Bt,D,X,Y);
713 case 0x26:
return SmemPAMassApply3D<2,6>(NE,B,Bt,D,X,Y);
714 case 0x34:
return SmemPAMassApply3D<3,4>(NE,B,Bt,D,X,Y);
715 case 0x35:
return SmemPAMassApply3D<3,5>(NE,B,Bt,D,X,Y);
716 case 0x36:
return SmemPAMassApply3D<3,6>(NE,B,Bt,D,X,Y);
717 case 0x37:
return SmemPAMassApply3D<3,7>(NE,B,Bt,D,X,Y);
718 case 0x45:
return SmemPAMassApply3D<4,5>(NE,B,Bt,D,X,Y);
719 case 0x46:
return SmemPAMassApply3D<4,6>(NE,B,Bt,D,X,Y);
720 case 0x48:
return SmemPAMassApply3D<4,8>(NE,B,Bt,D,X,Y);
721 case 0x56:
return SmemPAMassApply3D<5,6>(NE,B,Bt,D,X,Y);
722 case 0x58:
return SmemPAMassApply3D<5,8>(NE,B,Bt,D,X,Y);
723 case 0x67:
return SmemPAMassApply3D<6,7>(NE,B,Bt,D,X,Y);
724 case 0x78:
return SmemPAMassApply3D<7,8>(NE,B,Bt,D,X,Y);
725 case 0x89:
return SmemPAMassApply3D<8,9>(NE,B,Bt,D,X,Y);
726 case 0x9A:
return SmemPAMassApply3D<9,10>(NE,B,Bt,D,X,Y);
727 default:
return PAMassApply3D(NE,B,Bt,D,X,Y,D1D,Q1D);
730 mfem::out <<
"Unknown kernel 0x" << std::hex <<
id << std::endl;
731 MFEM_ABORT(
"Unknown kernel.");
738 ceedOp->AddMult(x, y);
742 PAMassApply(dim, dofs1D, quad1D, ne, maps->B, maps->Bt, pa_data, x, y);
746 void MassIntegrator::AddMultTransposePA(
const Vector &x,
Vector &y)
const
int GetNPoints() const
Returns the number of the points in the integration rule.
Abstract class for all finite elements.
int Size() const
Return the logical size of the array.
Class for an integration rule - an Array of IntegrationPoint.
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
const GeometricFactors * GetGeometricFactors(const IntegrationRule &ir, const int flags, MemoryType d_mt=MemoryType::DEFAULT)
Return the mesh geometric factors corresponding to the given integration rule.
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
occa::device & OccaDev()
Return the default occa::device used by MFEM.
int Size() const
Returns the size of the vector.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
int GetNE() const
Returns number of elements.
const Array< double > & GetWeights() const
Return the quadrature weights in a contiguous array.
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
std::map< occa_id_t, occa::kernel > occa_kernel_t
Memory< double > & GetMemory()
Return a reference to the Memory object used by the Vector.
Class to represent a coefficient evaluated at quadrature points.
occa::memory OccaMemoryReadWrite(Memory< T > &mem, size_t size)
Wrap a Memory object as occa::memory for read-write access with the mfem::Device MemoryClass. The returned occa::memory is associated with the default occa::device used by MFEM.
Mesh * GetMesh() const
Returns the mesh.
bool DeviceCanUseOcca()
Function that determines if an OCCA kernel should be used, based on the current mfem::Device configur...
const occa::memory OccaMemoryRead(const Memory< T > &mem, size_t size)
Wrap a Memory object as occa::memory for read only access with the mfem::Device MemoryClass. The returned occa::memory is associated with the default occa::device used by MFEM.
Represent a MassIntegrator with AssemblyLevel::Partial using libCEED.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
MemoryType
Memory types supported by MFEM.
bool DeviceCanUseCeed()
Function that determines if a CEED kernel should be used, based on the current mfem::Device configura...
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
const IntegrationRule & GetRule(const Integrator &integ, const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
std::pair< int, int > occa_id_t
Class representing the storage layout of a QuadratureFunction.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims...dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.