12 #include "../general/forall.hpp" 30 const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
31 Device::GetDeviceMemoryType() : pa_mt;
36 if (mesh->
GetNE() == 0) {
return; }
63 pa_data.SetSize(ne*nq, mt);
68 if (
dim==1) { MFEM_ABORT(
"Not supported yet... stay tuned!"); }
72 const int Q1D = quad1D;
73 const bool const_c = coeff.
Size() == 1;
74 const bool by_val = map_type == FiniteElement::VALUE;
76 const auto J =
Reshape(geom->detJ.Read(), Q1D,Q1D,NE);
77 const auto C = const_c ?
Reshape(coeff.
Read(), 1,1,1) :
79 auto v =
Reshape(pa_data.Write(), Q1D,Q1D, NE);
80 MFEM_FORALL_2D(e, NE, Q1D,Q1D,1,
82 MFEM_FOREACH_THREAD(qx,x,Q1D)
84 MFEM_FOREACH_THREAD(qy,y,Q1D)
86 const double detJ = J(qx,qy,e);
87 const double coeff = const_c ? C(0,0,0) : C(qx,qy,e);
88 v(qx,qy,e) = W(qx,qy) * coeff * (by_val ? detJ : 1.0/detJ);
96 const int Q1D = quad1D;
97 const bool const_c = coeff.
Size() == 1;
98 const bool by_val = map_type == FiniteElement::VALUE;
100 const auto J =
Reshape(geom->detJ.Read(), Q1D,Q1D,Q1D,NE);
101 const auto C = const_c ?
Reshape(coeff.
Read(), 1,1,1,1) :
103 auto v =
Reshape(pa_data.Write(), Q1D,Q1D,Q1D,NE);
104 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
106 MFEM_FOREACH_THREAD(qx,x,Q1D)
108 MFEM_FOREACH_THREAD(qy,y,Q1D)
110 MFEM_FOREACH_THREAD(qz,z,Q1D)
112 const double detJ = J(qx,qy,qz,e);
113 const double coeff = const_c ? C(0,0,0,0) : C(qx,qy,qz,e);
114 v(qx,qy,qz,e) = W(qx,qy,qz) * coeff * (by_val ? detJ : 1.0/detJ);
122 template<
int T_D1D = 0,
int T_Q1D = 0>
123 static void PAMassAssembleDiagonal2D(
const int NE,
130 const int D1D = T_D1D ? T_D1D : d1d;
131 const int Q1D = T_Q1D ? T_Q1D : q1d;
132 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
133 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
134 auto B =
Reshape(
b.Read(), Q1D, D1D);
139 const int D1D = T_D1D ? T_D1D : d1d;
140 const int Q1D = T_Q1D ? T_Q1D : q1d;
141 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
142 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
144 for (
int qx = 0; qx < Q1D; ++qx)
146 for (
int dy = 0; dy < D1D; ++dy)
149 for (
int qy = 0; qy < Q1D; ++qy)
151 QD[qx][dy] += B(qy, dy) * B(qy, dy) * D(qx, qy, e);
155 for (
int dy = 0; dy < D1D; ++dy)
157 for (
int dx = 0; dx < D1D; ++dx)
159 for (
int qx = 0; qx < Q1D; ++qx)
161 Y(dx,dy,e) += B(qx, dx) * B(qx, dx) * QD[qx][dy];
168 template<
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
169 static void SmemPAMassAssembleDiagonal2D(
const int NE,
170 const Array<double> &b_,
176 const int D1D = T_D1D ? T_D1D : d1d;
177 const int Q1D = T_Q1D ? T_Q1D : q1d;
178 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
179 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
180 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
181 MFEM_VERIFY(D1D <= MD1,
"");
182 MFEM_VERIFY(Q1D <= MQ1,
"");
183 auto b =
Reshape(b_.Read(), Q1D, D1D);
184 auto D =
Reshape(d_.Read(), Q1D, Q1D, NE);
185 auto Y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
186 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
188 const int tidz = MFEM_THREAD_ID(z);
189 const int D1D = T_D1D ? T_D1D : d1d;
190 const int Q1D = T_Q1D ? T_Q1D : q1d;
191 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
192 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
193 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
194 MFEM_SHARED
double B[MQ1][MD1];
195 MFEM_SHARED
double QDZ[NBZ][MQ1][MD1];
196 double (*QD)[MD1] = (double (*)[MD1])(QDZ + tidz);
199 MFEM_FOREACH_THREAD(d,y,D1D)
201 MFEM_FOREACH_THREAD(q,x,Q1D)
208 MFEM_FOREACH_THREAD(qx,x,Q1D)
210 MFEM_FOREACH_THREAD(dy,y,D1D)
213 for (
int qy = 0; qy < Q1D; ++qy)
215 QD[qx][dy] += B[qy][dy] * B[qy][dy] * D(qx, qy, e);
220 MFEM_FOREACH_THREAD(dy,y,D1D)
222 MFEM_FOREACH_THREAD(dx,x,D1D)
224 for (
int qx = 0; qx < Q1D; ++qx)
227 Y(dx,dy,e) += B[qx][dx] * B[qx][dx] * QD[qx][dy];
234 template<
int T_D1D = 0,
int T_Q1D = 0>
235 static void PAMassAssembleDiagonal3D(
const int NE,
236 const Array<double> &
b,
242 const int D1D = T_D1D ? T_D1D : d1d;
243 const int Q1D = T_Q1D ? T_Q1D : q1d;
244 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
245 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
246 auto B =
Reshape(
b.Read(), Q1D, D1D);
247 auto D =
Reshape(d.Read(), Q1D, Q1D, Q1D, NE);
248 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, D1D, NE);
251 const int D1D = T_D1D ? T_D1D : d1d;
252 const int Q1D = T_Q1D ? T_Q1D : q1d;
253 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
254 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
255 double QQD[MQ1][MQ1][MD1];
256 double QDD[MQ1][MD1][MD1];
257 for (
int qx = 0; qx < Q1D; ++qx)
259 for (
int qy = 0; qy < Q1D; ++qy)
261 for (
int dz = 0; dz < D1D; ++dz)
263 QQD[qx][qy][dz] = 0.0;
264 for (
int qz = 0; qz < Q1D; ++qz)
266 QQD[qx][qy][dz] += B(qz, dz) * B(qz, dz) * D(qx, qy, qz, e);
271 for (
int qx = 0; qx < Q1D; ++qx)
273 for (
int dz = 0; dz < D1D; ++dz)
275 for (
int dy = 0; dy < D1D; ++dy)
277 QDD[qx][dy][dz] = 0.0;
278 for (
int qy = 0; qy < Q1D; ++qy)
280 QDD[qx][dy][dz] += B(qy, dy) * B(qy, dy) * QQD[qx][qy][dz];
285 for (
int dz = 0; dz < D1D; ++dz)
287 for (
int dy = 0; dy < D1D; ++dy)
289 for (
int dx = 0; dx < D1D; ++dx)
292 for (
int qx = 0; qx < Q1D; ++qx)
294 t += B(qx, dx) * B(qx, dx) * QDD[qx][dy][dz];
296 Y(dx, dy, dz, e) +=
t;
303 template<
int T_D1D = 0,
int T_Q1D = 0>
304 static void SmemPAMassAssembleDiagonal3D(
const int NE,
305 const Array<double> &b_,
311 const int D1D = T_D1D ? T_D1D : d1d;
312 const int Q1D = T_Q1D ? T_Q1D : q1d;
313 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
314 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
315 MFEM_VERIFY(D1D <= MD1,
"");
316 MFEM_VERIFY(Q1D <= MQ1,
"");
317 auto b =
Reshape(b_.Read(), Q1D, D1D);
318 auto D =
Reshape(d_.Read(), Q1D, Q1D, Q1D, NE);
319 auto Y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
320 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
322 const int tidz = MFEM_THREAD_ID(z);
323 const int D1D = T_D1D ? T_D1D : d1d;
324 const int Q1D = T_Q1D ? T_Q1D : q1d;
325 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
326 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
327 MFEM_SHARED
double B[MQ1][MD1];
328 MFEM_SHARED
double QQD[MQ1][MQ1][MD1];
329 MFEM_SHARED
double QDD[MQ1][MD1][MD1];
332 MFEM_FOREACH_THREAD(d,y,D1D)
334 MFEM_FOREACH_THREAD(q,x,Q1D)
341 MFEM_FOREACH_THREAD(qx,x,Q1D)
343 MFEM_FOREACH_THREAD(qy,y,Q1D)
345 MFEM_FOREACH_THREAD(dz,z,D1D)
347 QQD[qx][qy][dz] = 0.0;
348 for (
int qz = 0; qz < Q1D; ++qz)
350 QQD[qx][qy][dz] += B[qz][dz] * B[qz][dz] * D(qx, qy, qz, e);
356 MFEM_FOREACH_THREAD(qx,x,Q1D)
358 MFEM_FOREACH_THREAD(dz,z,D1D)
360 MFEM_FOREACH_THREAD(dy,y,D1D)
362 QDD[qx][dy][dz] = 0.0;
363 for (
int qy = 0; qy < Q1D; ++qy)
365 QDD[qx][dy][dz] += B[qy][dy] * B[qy][dy] * QQD[qx][qy][dz];
371 MFEM_FOREACH_THREAD(dz,z,D1D)
373 MFEM_FOREACH_THREAD(dy,y,D1D)
375 MFEM_FOREACH_THREAD(dx,x,D1D)
378 for (
int qx = 0; qx < Q1D; ++qx)
380 t += B[qx][dx] * B[qx][dx] * QDD[qx][dy][dz];
382 Y(dx, dy, dz, e) +=
t;
389 static void PAMassAssembleDiagonal(
const int dim,
const int D1D,
390 const int Q1D,
const int NE,
391 const Array<double> &B,
397 switch ((D1D << 4 ) | Q1D)
399 case 0x22:
return SmemPAMassAssembleDiagonal2D<2,2,16>(NE,B,D,Y);
400 case 0x33:
return SmemPAMassAssembleDiagonal2D<3,3,16>(NE,B,D,Y);
401 case 0x44:
return SmemPAMassAssembleDiagonal2D<4,4,8>(NE,B,D,Y);
402 case 0x55:
return SmemPAMassAssembleDiagonal2D<5,5,8>(NE,B,D,Y);
403 case 0x66:
return SmemPAMassAssembleDiagonal2D<6,6,4>(NE,B,D,Y);
404 case 0x77:
return SmemPAMassAssembleDiagonal2D<7,7,4>(NE,B,D,Y);
405 case 0x88:
return SmemPAMassAssembleDiagonal2D<8,8,2>(NE,B,D,Y);
406 case 0x99:
return SmemPAMassAssembleDiagonal2D<9,9,2>(NE,B,D,Y);
407 default:
return PAMassAssembleDiagonal2D(NE,B,D,Y,D1D,Q1D);
412 switch ((D1D << 4 ) | Q1D)
414 case 0x23:
return SmemPAMassAssembleDiagonal3D<2,3>(NE,B,D,Y);
415 case 0x24:
return SmemPAMassAssembleDiagonal3D<2,4>(NE,B,D,Y);
416 case 0x26:
return SmemPAMassAssembleDiagonal3D<2,6>(NE,B,D,Y);
417 case 0x34:
return SmemPAMassAssembleDiagonal3D<3,4>(NE,B,D,Y);
418 case 0x35:
return SmemPAMassAssembleDiagonal3D<3,5>(NE,B,D,Y);
419 case 0x45:
return SmemPAMassAssembleDiagonal3D<4,5>(NE,B,D,Y);
420 case 0x48:
return SmemPAMassAssembleDiagonal3D<4,8>(NE,B,D,Y);
421 case 0x56:
return SmemPAMassAssembleDiagonal3D<5,6>(NE,B,D,Y);
422 case 0x67:
return SmemPAMassAssembleDiagonal3D<6,7>(NE,B,D,Y);
423 case 0x78:
return SmemPAMassAssembleDiagonal3D<7,8>(NE,B,D,Y);
424 case 0x89:
return SmemPAMassAssembleDiagonal3D<8,9>(NE,B,D,Y);
425 default:
return PAMassAssembleDiagonal3D(NE,B,D,Y,D1D,Q1D);
428 MFEM_ABORT(
"Unknown kernel.");
431 void MassIntegrator::AssembleDiagonalPA(
Vector &diag)
435 ceedOp->GetDiagonal(diag);
439 PAMassAssembleDiagonal(
dim, dofs1D, quad1D, ne, maps->B, pa_data, diag);
446 static void OccaPAMassApply2D(
const int D1D,
455 occa::properties props;
456 props[
"defines/D1D"] = D1D;
457 props[
"defines/Q1D"] = Q1D;
463 const occa_id_t id = std::make_pair(D1D,Q1D);
464 if (!Device::Allows(Backend::OCCA_CUDA))
467 if (OccaMassApply2D_cpu.find(
id) == OccaMassApply2D_cpu.end())
469 const occa::kernel MassApply2D_CPU =
471 "MassApply2D_CPU", props);
472 OccaMassApply2D_cpu.emplace(
id, MassApply2D_CPU);
474 OccaMassApply2D_cpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
479 if (OccaMassApply2D_gpu.find(
id) == OccaMassApply2D_gpu.end())
481 const occa::kernel MassApply2D_GPU =
483 "MassApply2D_GPU", props);
484 OccaMassApply2D_gpu.emplace(
id, MassApply2D_GPU);
486 OccaMassApply2D_gpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
491 static void OccaPAMassApply3D(
const int D1D,
494 const Array<double> &B,
495 const Array<double> &Bt,
500 occa::properties props;
501 props[
"defines/D1D"] = D1D;
502 props[
"defines/Q1D"] = Q1D;
504 const occa::memory o_Bt =
OccaMemoryRead(Bt.GetMemory(), Bt.Size());
508 const occa_id_t id = std::make_pair(D1D,Q1D);
509 if (!Device::Allows(Backend::OCCA_CUDA))
512 if (OccaMassApply3D_cpu.find(
id) == OccaMassApply3D_cpu.end())
514 const occa::kernel MassApply3D_CPU =
516 "MassApply3D_CPU", props);
517 OccaMassApply3D_cpu.emplace(
id, MassApply3D_CPU);
519 OccaMassApply3D_cpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
524 if (OccaMassApply3D_gpu.find(
id) == OccaMassApply3D_gpu.end())
526 const occa::kernel MassApply3D_GPU =
528 "MassApply3D_GPU", props);
529 OccaMassApply3D_gpu.emplace(
id, MassApply3D_GPU);
531 OccaMassApply3D_gpu.at(
id)(NE, o_B, o_Bt, o_D, o_X, o_Y);
534 #endif // MFEM_USE_OCCA 536 template<
int T_D1D = 0,
int T_Q1D = 0>
537 static void PAMassApply2D(
const int NE,
538 const Array<double> &b_,
539 const Array<double> &bt_,
546 MFEM_VERIFY(T_D1D ? T_D1D : d1d <=
MAX_D1D,
"");
547 MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <=
MAX_Q1D,
"");
549 const auto B = b_.Read();
550 const auto Bt = bt_.Read();
551 const auto D = d_.Read();
552 const auto X = x_.Read();
553 auto Y = y_.ReadWrite();
557 internal::PAMassApply2D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
561 template<
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
562 static void SmemPAMassApply2D(
const int NE,
563 const Array<double> &b_,
564 const Array<double> &bt_,
571 MFEM_CONTRACT_VAR(bt_);
572 const int D1D = T_D1D ? T_D1D : d1d;
573 const int Q1D = T_Q1D ? T_Q1D : q1d;
574 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
575 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
576 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
577 MFEM_VERIFY(D1D <= MD1,
"");
578 MFEM_VERIFY(Q1D <= MQ1,
"");
579 const auto b = b_.Read();
580 const auto D = d_.Read();
581 const auto x = x_.Read();
582 auto Y = y_.ReadWrite();
583 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
585 internal::SmemPAMassApply2D_Element<T_D1D,T_Q1D,T_NBZ>(e, NE,
b, D, x, Y, d1d, q1d);
589 template<
int T_D1D = 0,
int T_Q1D = 0>
590 static void PAMassApply3D(
const int NE,
591 const Array<double> &b_,
592 const Array<double> &bt_,
599 MFEM_VERIFY(T_D1D ? T_D1D : d1d <=
MAX_D1D,
"");
600 MFEM_VERIFY(T_Q1D ? T_Q1D : q1d <=
MAX_Q1D,
"");
602 const auto B = b_.Read();
603 const auto Bt = bt_.Read();
604 const auto D = d_.Read();
605 const auto X = x_.Read();
606 auto Y = y_.ReadWrite();
610 internal::PAMassApply3D_Element(e, NE, B, Bt, D, X, Y, d1d, q1d);
614 template<
int T_D1D = 0,
int T_Q1D = 0>
615 static void SmemPAMassApply3D(
const int NE,
616 const Array<double> &b_,
617 const Array<double> &bt_,
624 MFEM_CONTRACT_VAR(bt_);
625 const int D1D = T_D1D ? T_D1D : d1d;
626 const int Q1D = T_Q1D ? T_Q1D : q1d;
627 constexpr
int M1Q = T_Q1D ? T_Q1D :
MAX_Q1D;
628 constexpr
int M1D = T_D1D ? T_D1D :
MAX_D1D;
629 MFEM_VERIFY(D1D <= M1D,
"");
630 MFEM_VERIFY(Q1D <= M1Q,
"");
634 auto y = y_.ReadWrite();
635 MFEM_FORALL_3D(e, NE, Q1D, Q1D, 1,
637 internal::SmemPAMassApply3D_Element<T_D1D,T_Q1D>(e, NE,
b, d, x, y, d1d, q1d);
641 static void PAMassApply(
const int dim,
645 const Array<double> &B,
646 const Array<double> &Bt,
656 return OccaPAMassApply2D(D1D,Q1D,NE,B,Bt,D,X,Y);
660 return OccaPAMassApply3D(D1D,Q1D,NE,B,Bt,D,X,Y);
662 MFEM_ABORT(
"OCCA PA Mass Apply unknown kernel!");
664 #endif // MFEM_USE_OCCA 665 const int id = (D1D << 4) | Q1D;
671 case 0x22:
return SmemPAMassApply2D<2,2,16>(NE,B,Bt,D,X,Y);
672 case 0x24:
return SmemPAMassApply2D<2,4,16>(NE,B,Bt,D,X,Y);
673 case 0x33:
return SmemPAMassApply2D<3,3,16>(NE,B,Bt,D,X,Y);
674 case 0x34:
return SmemPAMassApply2D<3,4,16>(NE,B,Bt,D,X,Y);
675 case 0x35:
return SmemPAMassApply2D<3,5,16>(NE,B,Bt,D,X,Y);
676 case 0x36:
return SmemPAMassApply2D<3,6,16>(NE,B,Bt,D,X,Y);
677 case 0x44:
return SmemPAMassApply2D<4,4,8>(NE,B,Bt,D,X,Y);
678 case 0x46:
return SmemPAMassApply2D<4,6,8>(NE,B,Bt,D,X,Y);
679 case 0x48:
return SmemPAMassApply2D<4,8,4>(NE,B,Bt,D,X,Y);
680 case 0x55:
return SmemPAMassApply2D<5,5,8>(NE,B,Bt,D,X,Y);
681 case 0x57:
return SmemPAMassApply2D<5,7,8>(NE,B,Bt,D,X,Y);
682 case 0x58:
return SmemPAMassApply2D<5,8,2>(NE,B,Bt,D,X,Y);
683 case 0x66:
return SmemPAMassApply2D<6,6,4>(NE,B,Bt,D,X,Y);
684 case 0x77:
return SmemPAMassApply2D<7,7,4>(NE,B,Bt,D,X,Y);
685 case 0x88:
return SmemPAMassApply2D<8,8,2>(NE,B,Bt,D,X,Y);
686 case 0x99:
return SmemPAMassApply2D<9,9,2>(NE,B,Bt,D,X,Y);
687 default:
return PAMassApply2D(NE,B,Bt,D,X,Y,D1D,Q1D);
694 case 0x22:
return SmemPAMassApply3D<2,2>(NE,B,Bt,D,X,Y);
695 case 0x23:
return SmemPAMassApply3D<2,3>(NE,B,Bt,D,X,Y);
696 case 0x24:
return SmemPAMassApply3D<2,4>(NE,B,Bt,D,X,Y);
697 case 0x26:
return SmemPAMassApply3D<2,6>(NE,B,Bt,D,X,Y);
698 case 0x34:
return SmemPAMassApply3D<3,4>(NE,B,Bt,D,X,Y);
699 case 0x35:
return SmemPAMassApply3D<3,5>(NE,B,Bt,D,X,Y);
700 case 0x36:
return SmemPAMassApply3D<3,6>(NE,B,Bt,D,X,Y);
701 case 0x37:
return SmemPAMassApply3D<3,7>(NE,B,Bt,D,X,Y);
702 case 0x45:
return SmemPAMassApply3D<4,5>(NE,B,Bt,D,X,Y);
703 case 0x46:
return SmemPAMassApply3D<4,6>(NE,B,Bt,D,X,Y);
704 case 0x48:
return SmemPAMassApply3D<4,8>(NE,B,Bt,D,X,Y);
705 case 0x56:
return SmemPAMassApply3D<5,6>(NE,B,Bt,D,X,Y);
706 case 0x58:
return SmemPAMassApply3D<5,8>(NE,B,Bt,D,X,Y);
707 case 0x67:
return SmemPAMassApply3D<6,7>(NE,B,Bt,D,X,Y);
708 case 0x78:
return SmemPAMassApply3D<7,8>(NE,B,Bt,D,X,Y);
709 case 0x89:
return SmemPAMassApply3D<8,9>(NE,B,Bt,D,X,Y);
710 case 0x9A:
return SmemPAMassApply3D<9,10>(NE,B,Bt,D,X,Y);
711 default:
return PAMassApply3D(NE,B,Bt,D,X,Y,D1D,Q1D);
714 mfem::out <<
"Unknown kernel 0x" << std::hex <<
id << std::endl;
715 MFEM_ABORT(
"Unknown kernel.");
722 ceedOp->AddMult(x, y);
726 PAMassApply(
dim, dofs1D, quad1D, ne, maps->B, maps->Bt, pa_data, x, y);
730 void MassIntegrator::AddMultTransposePA(
const Vector &x,
Vector &y)
const const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Abstract class for all finite elements.
int GetNPoints() const
Returns the number of the points in the integration rule.
Class for an integration rule - an Array of IntegrationPoint.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
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.
occa::device & OccaDev()
Return the default occa::device used by MFEM.
int Size() const
Returns the size of the vector.
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
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.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
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.
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 Array< double > & GetWeights() const
Return the quadrature weights in a contiguous array.
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.
Mesh * GetMesh() const
Returns the mesh.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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...
int GetNE() const
Returns number of elements.
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)
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
int Size() const
Return the logical size of the array.
std::pair< int, int > occa_id_t
Class representing the storage layout of a QuadratureFunction.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.