23static void PAHcurlH1Apply2D(
const int D1D,
26 const Array<real_t> &bc,
27 const Array<real_t> &gc,
28 const Array<real_t> &bot,
29 const Array<real_t> &bct,
30 const Vector &pa_data,
34 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
35 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
36 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
37 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
38 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, 3, NE);
39 auto X =
Reshape(x.Read(), D1D, D1D, NE);
40 auto Y =
Reshape(y.ReadWrite(), 2*(D1D-1)*D1D, NE);
44 constexpr static int VDIM = 2;
45 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
46 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
48 real_t mass[MAX_Q1D][MAX_Q1D][VDIM];
50 for (
int qy = 0; qy < Q1D; ++qy)
52 for (
int qx = 0; qx < Q1D; ++qx)
54 for (
int c = 0; c < VDIM; ++c)
56 mass[qy][qx][c] = 0.0;
61 for (
int dy = 0; dy < D1D; ++dy)
64 for (
int qx = 0; qx < Q1D; ++qx)
69 for (
int dx = 0; dx < D1D; ++dx)
71 const real_t s = X(dx,dy,e);
72 for (
int qx = 0; qx < Q1D; ++qx)
74 gradX[qx][0] += s * Bc(qx,dx);
75 gradX[qx][1] += s * Gc(qx,dx);
78 for (
int qy = 0; qy < Q1D; ++qy)
80 const real_t wy = Bc(qy,dy);
81 const real_t wDy = Gc(qy,dy);
82 for (
int qx = 0; qx < Q1D; ++qx)
84 const real_t wx = gradX[qx][0];
85 const real_t wDx = gradX[qx][1];
86 mass[qy][qx][0] += wDx * wy;
87 mass[qy][qx][1] += wx * wDy;
93 for (
int qy = 0; qy < Q1D; ++qy)
95 for (
int qx = 0; qx < Q1D; ++qx)
97 const real_t O11 = op(qx,qy,0,e);
98 const real_t O12 = op(qx,qy,1,e);
99 const real_t O22 = op(qx,qy,2,e);
100 const real_t massX = mass[qy][qx][0];
101 const real_t massY = mass[qy][qx][1];
102 mass[qy][qx][0] = (O11*massX)+(O12*massY);
103 mass[qy][qx][1] = (O12*massX)+(O22*massY);
107 for (
int qy = 0; qy < Q1D; ++qy)
111 for (
int c = 0; c < VDIM; ++c)
113 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
114 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
117 for (
int dx = 0; dx < D1Dx; ++dx)
121 for (
int qx = 0; qx < Q1D; ++qx)
123 for (
int dx = 0; dx < D1Dx; ++dx)
125 massX[dx] += mass[qy][qx][c] * ((c == 0) ? Bot(dx,qx) : Bct(dx,qx));
129 for (
int dy = 0; dy < D1Dy; ++dy)
131 const real_t wy = (c == 1) ? Bot(dy,qy) : Bct(dy,qy);
133 for (
int dx = 0; dx < D1Dx; ++dx)
135 Y(dx + (dy * D1Dx) + osc, e) += massX[dx] * wy;
147static void PAHcurlH1ApplyTranspose2D(
const int D1D,
150 const Array<real_t> &bc,
151 const Array<real_t> &bo,
152 const Array<real_t> &bct,
153 const Array<real_t> &gct,
154 const Vector &pa_data,
158 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
159 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
160 auto Bt =
Reshape(bct.Read(), D1D, Q1D);
161 auto Gt =
Reshape(gct.Read(), D1D, Q1D);
162 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, 3, NE);
163 auto X =
Reshape(x.Read(), 2*(D1D-1)*D1D, NE);
164 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, NE);
168 constexpr static int VDIM = 2;
169 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
170 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
172 real_t mass[MAX_Q1D][MAX_Q1D][VDIM];
174 for (
int qy = 0; qy < Q1D; ++qy)
176 for (
int qx = 0; qx < Q1D; ++qx)
178 for (
int c = 0; c < VDIM; ++c)
180 mass[qy][qx][c] = 0.0;
187 for (
int c = 0; c < VDIM; ++c)
189 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
190 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
192 for (
int dy = 0; dy < D1Dy; ++dy)
195 for (
int qx = 0; qx < Q1D; ++qx)
200 for (
int dx = 0; dx < D1Dx; ++dx)
202 const real_t t = X(dx + (dy * D1Dx) + osc, e);
203 for (
int qx = 0; qx < Q1D; ++qx)
205 massX[qx] += t * ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
209 for (
int qy = 0; qy < Q1D; ++qy)
211 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
212 for (
int qx = 0; qx < Q1D; ++qx)
214 mass[qy][qx][c] += massX[qx] * wy;
223 for (
int qy = 0; qy < Q1D; ++qy)
225 for (
int qx = 0; qx < Q1D; ++qx)
227 const real_t O11 = op(qx,qy,0,e);
228 const real_t O12 = op(qx,qy,1,e);
229 const real_t O22 = op(qx,qy,2,e);
230 const real_t massX = mass[qy][qx][0];
231 const real_t massY = mass[qy][qx][1];
232 mass[qy][qx][0] = (O11*massX)+(O12*massY);
233 mass[qy][qx][1] = (O12*massX)+(O22*massY);
237 for (
int qy = 0; qy < Q1D; ++qy)
240 for (
int dx = 0; dx < D1D; ++dx)
245 for (
int qx = 0; qx < Q1D; ++qx)
247 const real_t gX = mass[qy][qx][0];
248 const real_t gY = mass[qy][qx][1];
249 for (
int dx = 0; dx < D1D; ++dx)
251 const real_t wx = Bt(dx,qx);
252 const real_t wDx = Gt(dx,qx);
253 gradX[dx][0] += gX * wDx;
254 gradX[dx][1] += gY * wx;
257 for (
int dy = 0; dy < D1D; ++dy)
259 const real_t wy = Bt(dy,qy);
260 const real_t wDy = Gt(dy,qy);
261 for (
int dx = 0; dx < D1D; ++dx)
263 Y(dx,dy,e) += ((gradX[dx][0] * wy) + (gradX[dx][1] * wDy));
272static void PAHcurlH1Apply3D(
const int D1D,
275 const Array<real_t> &bc,
276 const Array<real_t> &gc,
277 const Array<real_t> &bot,
278 const Array<real_t> &bct,
279 const Vector &pa_data,
284 "Error: D1D > MAX_D1D");
286 "Error: Q1D > MAX_Q1D");
288 constexpr static int VDIM = 3;
290 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
291 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
292 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
293 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
294 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, 6, NE);
295 auto X =
Reshape(x.Read(), D1D, D1D, D1D, NE);
296 auto Y =
Reshape(y.ReadWrite(), 3*(D1D-1)*D1D*D1D, NE);
300 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
301 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
303 real_t mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
305 for (
int qz = 0; qz < Q1D; ++qz)
307 for (
int qy = 0; qy < Q1D; ++qy)
309 for (
int qx = 0; qx < Q1D; ++qx)
311 for (
int c = 0; c < VDIM; ++c)
313 mass[qz][qy][qx][c] = 0.0;
319 for (
int dz = 0; dz < D1D; ++dz)
321 real_t gradXY[MAX_Q1D][MAX_Q1D][3];
322 for (
int qy = 0; qy < Q1D; ++qy)
324 for (
int qx = 0; qx < Q1D; ++qx)
326 gradXY[qy][qx][0] = 0.0;
327 gradXY[qy][qx][1] = 0.0;
328 gradXY[qy][qx][2] = 0.0;
331 for (
int dy = 0; dy < D1D; ++dy)
334 for (
int qx = 0; qx < Q1D; ++qx)
339 for (
int dx = 0; dx < D1D; ++dx)
341 const real_t s = X(dx,dy,dz,e);
342 for (
int qx = 0; qx < Q1D; ++qx)
344 gradX[qx][0] += s * Bc(qx,dx);
345 gradX[qx][1] += s * Gc(qx,dx);
348 for (
int qy = 0; qy < Q1D; ++qy)
350 const real_t wy = Bc(qy,dy);
351 const real_t wDy = Gc(qy,dy);
352 for (
int qx = 0; qx < Q1D; ++qx)
354 const real_t wx = gradX[qx][0];
355 const real_t wDx = gradX[qx][1];
356 gradXY[qy][qx][0] += wDx * wy;
357 gradXY[qy][qx][1] += wx * wDy;
358 gradXY[qy][qx][2] += wx * wy;
362 for (
int qz = 0; qz < Q1D; ++qz)
364 const real_t wz = Bc(qz,dz);
365 const real_t wDz = Gc(qz,dz);
366 for (
int qy = 0; qy < Q1D; ++qy)
368 for (
int qx = 0; qx < Q1D; ++qx)
370 mass[qz][qy][qx][0] += gradXY[qy][qx][0] * wz;
371 mass[qz][qy][qx][1] += gradXY[qy][qx][1] * wz;
372 mass[qz][qy][qx][2] += gradXY[qy][qx][2] * wDz;
379 for (
int qz = 0; qz < Q1D; ++qz)
381 for (
int qy = 0; qy < Q1D; ++qy)
383 for (
int qx = 0; qx < Q1D; ++qx)
385 const real_t O11 = op(qx,qy,qz,0,e);
386 const real_t O12 = op(qx,qy,qz,1,e);
387 const real_t O13 = op(qx,qy,qz,2,e);
388 const real_t O22 = op(qx,qy,qz,3,e);
389 const real_t O23 = op(qx,qy,qz,4,e);
390 const real_t O33 = op(qx,qy,qz,5,e);
391 const real_t massX = mass[qz][qy][qx][0];
392 const real_t massY = mass[qz][qy][qx][1];
393 const real_t massZ = mass[qz][qy][qx][2];
394 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
395 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O23*massZ);
396 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
401 for (
int qz = 0; qz < Q1D; ++qz)
403 real_t massXY[MAX_D1D][MAX_D1D];
407 for (
int c = 0; c < VDIM; ++c)
409 const int D1Dz = (c == 2) ? D1D - 1 : D1D;
410 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
411 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
413 for (
int dy = 0; dy < D1Dy; ++dy)
415 for (
int dx = 0; dx < D1Dx; ++dx)
417 massXY[dy][dx] = 0.0;
420 for (
int qy = 0; qy < Q1D; ++qy)
423 for (
int dx = 0; dx < D1Dx; ++dx)
427 for (
int qx = 0; qx < Q1D; ++qx)
429 for (
int dx = 0; dx < D1Dx; ++dx)
431 massX[dx] += mass[qz][qy][qx][c] * ((c == 0) ? Bot(dx,qx) : Bct(dx,qx));
434 for (
int dy = 0; dy < D1Dy; ++dy)
436 const real_t wy = (c == 1) ? Bot(dy,qy) : Bct(dy,qy);
437 for (
int dx = 0; dx < D1Dx; ++dx)
439 massXY[dy][dx] += massX[dx] * wy;
444 for (
int dz = 0; dz < D1Dz; ++dz)
446 const real_t wz = (c == 2) ? Bot(dz,qz) : Bct(dz,qz);
447 for (
int dy = 0; dy < D1Dy; ++dy)
449 for (
int dx = 0; dx < D1Dx; ++dx)
451 Y(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e) += massXY[dy][dx] * wz;
456 osc += D1Dx * D1Dy * D1Dz;
464static void PAHcurlH1ApplyTranspose3D(
const int D1D,
467 const Array<real_t> &bc,
468 const Array<real_t> &bo,
469 const Array<real_t> &bct,
470 const Array<real_t> &gct,
471 const Vector &pa_data,
476 "Error: D1D > MAX_D1D");
478 "Error: Q1D > MAX_Q1D");
480 constexpr static int VDIM = 3;
482 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
483 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
484 auto Bt =
Reshape(bct.Read(), D1D, Q1D);
485 auto Gt =
Reshape(gct.Read(), D1D, Q1D);
486 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, 6, NE);
487 auto X =
Reshape(x.Read(), 3*(D1D-1)*D1D*D1D, NE);
488 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, D1D, NE);
492 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
493 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
495 real_t mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
497 for (
int qz = 0; qz < Q1D; ++qz)
499 for (
int qy = 0; qy < Q1D; ++qy)
501 for (
int qx = 0; qx < Q1D; ++qx)
503 for (
int c = 0; c < VDIM; ++c)
505 mass[qz][qy][qx][c] = 0.0;
513 for (
int c = 0; c < VDIM; ++c)
515 const int D1Dz = (c == 2) ? D1D - 1 : D1D;
516 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
517 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
519 for (
int dz = 0; dz < D1Dz; ++dz)
521 real_t massXY[MAX_Q1D][MAX_Q1D];
522 for (
int qy = 0; qy < Q1D; ++qy)
524 for (
int qx = 0; qx < Q1D; ++qx)
526 massXY[qy][qx] = 0.0;
530 for (
int dy = 0; dy < D1Dy; ++dy)
533 for (
int qx = 0; qx < Q1D; ++qx)
538 for (
int dx = 0; dx < D1Dx; ++dx)
540 const real_t t = X(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e);
541 for (
int qx = 0; qx < Q1D; ++qx)
543 massX[qx] += t * ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
547 for (
int qy = 0; qy < Q1D; ++qy)
549 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
550 for (
int qx = 0; qx < Q1D; ++qx)
552 const real_t wx = massX[qx];
553 massXY[qy][qx] += wx * wy;
558 for (
int qz = 0; qz < Q1D; ++qz)
560 const real_t wz = (c == 2) ? Bo(qz,dz) : Bc(qz,dz);
561 for (
int qy = 0; qy < Q1D; ++qy)
563 for (
int qx = 0; qx < Q1D; ++qx)
565 mass[qz][qy][qx][c] += massXY[qy][qx] * wz;
571 osc += D1Dx * D1Dy * D1Dz;
575 for (
int qz = 0; qz < Q1D; ++qz)
577 for (
int qy = 0; qy < Q1D; ++qy)
579 for (
int qx = 0; qx < Q1D; ++qx)
581 const real_t O11 = op(qx,qy,qz,0,e);
582 const real_t O12 = op(qx,qy,qz,1,e);
583 const real_t O13 = op(qx,qy,qz,2,e);
584 const real_t O22 = op(qx,qy,qz,3,e);
585 const real_t O23 = op(qx,qy,qz,4,e);
586 const real_t O33 = op(qx,qy,qz,5,e);
587 const real_t massX = mass[qz][qy][qx][0];
588 const real_t massY = mass[qz][qy][qx][1];
589 const real_t massZ = mass[qz][qy][qx][2];
590 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
591 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O23*massZ);
592 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
597 for (
int qz = 0; qz < Q1D; ++qz)
599 real_t gradXY[MAX_D1D][MAX_D1D][3];
600 for (
int dy = 0; dy < D1D; ++dy)
602 for (
int dx = 0; dx < D1D; ++dx)
604 gradXY[dy][dx][0] = 0;
605 gradXY[dy][dx][1] = 0;
606 gradXY[dy][dx][2] = 0;
609 for (
int qy = 0; qy < Q1D; ++qy)
612 for (
int dx = 0; dx < D1D; ++dx)
618 for (
int qx = 0; qx < Q1D; ++qx)
620 const real_t gX = mass[qz][qy][qx][0];
621 const real_t gY = mass[qz][qy][qx][1];
622 const real_t gZ = mass[qz][qy][qx][2];
623 for (
int dx = 0; dx < D1D; ++dx)
625 const real_t wx = Bt(dx,qx);
626 const real_t wDx = Gt(dx,qx);
627 gradX[dx][0] += gX * wDx;
628 gradX[dx][1] += gY * wx;
629 gradX[dx][2] += gZ * wx;
632 for (
int dy = 0; dy < D1D; ++dy)
634 const real_t wy = Bt(dy,qy);
635 const real_t wDy = Gt(dy,qy);
636 for (
int dx = 0; dx < D1D; ++dx)
638 gradXY[dy][dx][0] += gradX[dx][0] * wy;
639 gradXY[dy][dx][1] += gradX[dx][1] * wDy;
640 gradXY[dy][dx][2] += gradX[dx][2] * wy;
644 for (
int dz = 0; dz < D1D; ++dz)
646 const real_t wz = Bt(dz,qz);
647 const real_t wDz = Gt(dz,qz);
648 for (
int dy = 0; dy < D1D; ++dy)
650 for (
int dx = 0; dx < D1D; ++dx)
653 ((gradXY[dy][dx][0] * wz) +
654 (gradXY[dy][dx][1] * wz) +
655 (gradXY[dy][dx][2] * wDz));
674 MFEM_VERIFY(trial_el != NULL,
"Only NodalTensorFiniteElement is supported!");
678 MFEM_VERIFY(test_el != NULL,
"Only VectorTensorFiniteElement is supported!");
683 const int dims = trial_el->
GetDim();
684 MFEM_VERIFY(dims == 2 || dims == 3,
"");
686 const int symmDims = (dims * (dims + 1)) / 2;
689 MFEM_VERIFY(dim == 2 || dim == 3,
"");
693 ne = trial_fes.
GetNE();
697 dofs1D = mapsC->
ndof;
698 quad1D = mapsC->
nqpt;
700 MFEM_VERIFY(dofs1D == mapsO->
ndof + 1 && quad1D == mapsO->
nqpt,
"");
710 internal::PADiffusionSetup3D(quad1D, 1, ne, ir->
GetWeights(), geom->
J,
715 internal::PADiffusionSetup2D<2>(quad1D, 1, ne, ir->
GetWeights(), geom->
J,
720 MFEM_ABORT(
"Unknown kernel.");
728 PAHcurlH1Apply3D(dofs1D, quad1D, ne, mapsC->
B, mapsC->
G,
729 mapsO->
Bt, mapsC->
Bt, pa_data, x, y);
733 PAHcurlH1Apply2D(dofs1D, quad1D, ne, mapsC->
B, mapsC->
G,
734 mapsO->
Bt, mapsC->
Bt, pa_data, x, y);
738 MFEM_ABORT(
"Unsupported dimension!");
747 PAHcurlH1ApplyTranspose3D(dofs1D, quad1D, ne, mapsC->
B, mapsO->
B,
748 mapsC->
Bt, mapsC->
Gt, pa_data, x, y);
752 PAHcurlH1ApplyTranspose2D(dofs1D, quad1D, ne, mapsC->
B, mapsO->
B,
753 mapsC->
Bt, mapsC->
Gt, pa_data, x, y);
757 MFEM_ABORT(
"Unsupported dimension!");
Class to represent a coefficient evaluated at quadrature points.
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
Array< real_t > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Array< real_t > B
Basis functions evaluated at quadrature points.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
Array< real_t > Gt
Transpose of G.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Array< real_t > Bt
Transpose of B.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetNE() const
Returns number of elements in the mesh.
Mesh * GetMesh() const
Returns the mesh.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
Abstract class for all finite elements.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
int GetDerivType() const
Returns the FiniteElement::DerivType of the element describing the spatial derivative method implemen...
int GetDim() const
Returns the reference space dimension for the finite element.
@ CURL
Implements CalcCurlShape methods.
Vector J
Jacobians of the element transformations at all quadrature points.
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
const Array< real_t > & GetWeights() const
Return the quadrature weights in a contiguous array.
const IntegrationRule * IntRule
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans)
int Dimension() const
Dimension of the reference space used within the elements.
ElementTransformation * GetTypicalElementTransformation()
If the local mesh is not empty return GetElementTransformation(0); otherwise, return the identity tra...
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.
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes) override
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
Class representing the storage layout of a QuadratureFunction.
const DofToQuad & GetDofToQuadOpen(const IntegrationRule &ir, DofToQuad::Mode mode) const
const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const override
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
@ FULL
Store the coefficient as a full QuadratureFunction.
void forall(int N, lambda &&body)
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.