20void PAHcurlMassAssembleDiagonal2D(
const int D1D,
24 const Array<real_t> &bo,
25 const Array<real_t> &bc,
26 const Vector &pa_data,
29 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
30 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
31 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, symmetric ? 3 : 4, NE);
32 auto D =
Reshape(diag.ReadWrite(), 2*(D1D-1)*D1D, NE);
36 constexpr static int VDIM = 2;
37 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
41 for (
int c = 0; c < VDIM; ++c)
43 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
44 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
48 for (
int dy = 0; dy < D1Dy; ++dy)
50 for (
int qx = 0; qx < Q1D; ++qx)
53 for (
int qy = 0; qy < Q1D; ++qy)
55 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
57 mass[qx] += wy * wy * ((c == 0) ? op(qx,qy,0,e) :
58 op(qx,qy,symmetric ? 2 : 3, e));
62 for (
int dx = 0; dx < D1Dx; ++dx)
64 for (
int qx = 0; qx < Q1D; ++qx)
66 const real_t wx = ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
67 D(dx + (dy * D1Dx) + osc, e) +=
mass[qx] * wx * wx;
77void PAHcurlMassAssembleDiagonal3D(
const int D1D,
81 const Array<real_t> &bo,
82 const Array<real_t> &bc,
83 const Vector &pa_data,
87 "Error: D1D > MAX_D1D");
89 "Error: Q1D > MAX_Q1D");
90 constexpr static int VDIM = 3;
92 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
93 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
94 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, symmetric ? 6 : 9, NE);
95 auto D =
Reshape(diag.ReadWrite(), 3*(D1D-1)*D1D*D1D, NE);
99 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
103 for (
int c = 0; c < VDIM; ++c)
105 const int D1Dz = (c == 2) ? D1D - 1 : D1D;
106 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
107 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
109 const int opc = (c == 0) ? 0 : ((c == 1) ? (symmetric ? 3 : 4) :
110 (symmetric ? 5 : 8));
114 for (
int dz = 0; dz < D1Dz; ++dz)
116 for (
int dy = 0; dy < D1Dy; ++dy)
118 for (
int qx = 0; qx < Q1D; ++qx)
121 for (
int qy = 0; qy < Q1D; ++qy)
123 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
125 for (
int qz = 0; qz < Q1D; ++qz)
127 const real_t wz = (c == 2) ? Bo(qz,dz) : Bc(qz,dz);
129 mass[qx] += wy * wy * wz * wz * op(qx,qy,qz,opc,e);
134 for (
int dx = 0; dx < D1Dx; ++dx)
136 for (
int qx = 0; qx < Q1D; ++qx)
138 const real_t wx = ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
139 D(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e) +=
mass[qx] * wx * wx;
145 osc += D1Dx * D1Dy * D1Dz;
150void PAHcurlMassApply2D(
const int NE,
const bool symmetric,
151 [[maybe_unused]]
const bool scalar_coeff,
152 const Array<real_t> &bo,
const Array<real_t> &bc,
153 const Array<real_t> &bot,
const Array<real_t> &bct,
154 const Vector &pa_data,
const Vector &x, Vector &y,
155 const int D1D, [[maybe_unused]]
const int TestD1D,
158 MFEM_ASSERT(D1D == TestD1D,
159 "Trial and Test space must have the same number of dofs");
160 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
161 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
162 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
163 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
164 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, symmetric ? 3 : 4, NE);
165 auto X =
Reshape(x.Read(), 2*(D1D-1)*D1D, NE);
166 auto Y =
Reshape(y.ReadWrite(), 2*(D1D-1)*D1D, NE);
170 constexpr static int VDIM = 2;
171 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
172 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
176 for (
int qy = 0; qy < Q1D; ++qy)
178 for (
int qx = 0; qx < Q1D; ++qx)
180 for (
int c = 0; c < VDIM; ++c)
182 mass[qy][qx][c] = 0.0;
189 for (
int c = 0; c < VDIM; ++c)
191 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
192 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
194 for (
int dy = 0; dy < D1Dy; ++dy)
197 for (
int qx = 0; qx < Q1D; ++qx)
202 for (
int dx = 0; dx < D1Dx; ++dx)
204 const real_t t = X(dx + (dy * D1Dx) + osc, e);
205 for (
int qx = 0; qx < Q1D; ++qx)
207 massX[qx] += t * ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
211 for (
int qy = 0; qy < Q1D; ++qy)
213 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
214 for (
int qx = 0; qx < Q1D; ++qx)
216 mass[qy][qx][c] += massX[qx] * wy;
225 for (
int qy = 0; qy < Q1D; ++qy)
227 for (
int qx = 0; qx < Q1D; ++qx)
229 const real_t O11 = op(qx,qy,0,e);
230 const real_t O21 = op(qx,qy,1,e);
231 const real_t O12 = symmetric ? O21 : op(qx,qy,2,e);
232 const real_t O22 = symmetric ? op(qx,qy,2,e) : op(qx,qy,3,e);
235 mass[qy][qx][0] = (O11*massX)+(O12*massY);
236 mass[qy][qx][1] = (O21*massX)+(O22*massY);
240 for (
int qy = 0; qy < Q1D; ++qy)
244 for (
int c = 0; c < VDIM; ++c)
246 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
247 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
250 for (
int dx = 0; dx < D1Dx; ++dx)
254 for (
int qx = 0; qx < Q1D; ++qx)
256 for (
int dx = 0; dx < D1Dx; ++dx)
258 massX[dx] +=
mass[qy][qx][c] * ((c == 0) ? Bot(dx,qx) : Bct(dx,qx));
262 for (
int dy = 0; dy < D1Dy; ++dy)
264 const real_t wy = (c == 1) ? Bot(dy,qy) : Bct(dy,qy);
266 for (
int dx = 0; dx < D1Dx; ++dx)
268 Y(dx + (dy * D1Dx) + osc, e) += massX[dx] * wy;
278void PAHcurlMassApply3D(
const int NE,
const bool symmetric,
279 [[maybe_unused]]
const bool scalar_coeff,
280 const Array<real_t> &bo,
const Array<real_t> &bc,
281 const Array<real_t> &bot,
const Array<real_t> &bct,
282 const Vector &pa_data,
const Vector &x, Vector &y,
283 const int D1D, [[maybe_unused]]
const int TestD1D,
286 MFEM_VERIFY(D1D == TestD1D,
287 "Trial and test spaces must have same number of dofs");
289 "Error: D1D > MAX_D1D");
291 "Error: Q1D > MAX_Q1D");
292 constexpr static int VDIM = 3;
294 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
295 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
296 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
297 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
298 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, symmetric ? 6 : 9, NE);
299 auto X =
Reshape(x.Read(), 3*(D1D-1)*D1D*D1D, NE);
300 auto Y =
Reshape(y.ReadWrite(), 3*(D1D-1)*D1D*D1D, NE);
304 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
305 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
309 for (
int qz = 0; qz < Q1D; ++qz)
311 for (
int qy = 0; qy < Q1D; ++qy)
313 for (
int qx = 0; qx < Q1D; ++qx)
315 for (
int c = 0; c < VDIM; ++c)
317 mass[qz][qy][qx][c] = 0.0;
325 for (
int c = 0; c < VDIM; ++c)
327 const int D1Dz = (c == 2) ? D1D - 1 : D1D;
328 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
329 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
331 for (
int dz = 0; dz < D1Dz; ++dz)
333 real_t massXY[MAX_Q1D][MAX_Q1D];
334 for (
int qy = 0; qy < Q1D; ++qy)
336 for (
int qx = 0; qx < Q1D; ++qx)
338 massXY[qy][qx] = 0.0;
342 for (
int dy = 0; dy < D1Dy; ++dy)
345 for (
int qx = 0; qx < Q1D; ++qx)
350 for (
int dx = 0; dx < D1Dx; ++dx)
352 const real_t t = X(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e);
353 for (
int qx = 0; qx < Q1D; ++qx)
355 massX[qx] += t * ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
359 for (
int qy = 0; qy < Q1D; ++qy)
361 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
362 for (
int qx = 0; qx < Q1D; ++qx)
364 const real_t wx = massX[qx];
365 massXY[qy][qx] += wx * wy;
370 for (
int qz = 0; qz < Q1D; ++qz)
372 const real_t wz = (c == 2) ? Bo(qz,dz) : Bc(qz,dz);
373 for (
int qy = 0; qy < Q1D; ++qy)
375 for (
int qx = 0; qx < Q1D; ++qx)
377 mass[qz][qy][qx][c] += massXY[qy][qx] * wz;
383 osc += D1Dx * D1Dy * D1Dz;
387 for (
int qz = 0; qz < Q1D; ++qz)
389 for (
int qy = 0; qy < Q1D; ++qy)
391 for (
int qx = 0; qx < Q1D; ++qx)
393 const real_t O11 = op(qx,qy,qz,0,e);
394 const real_t O12 = op(qx,qy,qz,1,e);
395 const real_t O13 = op(qx,qy,qz,2,e);
396 const real_t O21 = symmetric ? O12 : op(qx,qy,qz,3,e);
397 const real_t O22 = symmetric ? op(qx,qy,qz,3,e) : op(qx,qy,qz,4,e);
398 const real_t O23 = symmetric ? op(qx,qy,qz,4,e) : op(qx,qy,qz,5,e);
399 const real_t O31 = symmetric ? O13 : op(qx,qy,qz,6,e);
400 const real_t O32 = symmetric ? O23 : op(qx,qy,qz,7,e);
401 const real_t O33 = symmetric ? op(qx,qy,qz,5,e) : op(qx,qy,qz,8,e);
405 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
406 mass[qz][qy][qx][1] = (O21*massX)+(O22*massY)+(O23*massZ);
407 mass[qz][qy][qx][2] = (O31*massX)+(O32*massY)+(O33*massZ);
412 for (
int qz = 0; qz < Q1D; ++qz)
414 real_t massXY[MAX_D1D][MAX_D1D];
418 for (
int c = 0; c < VDIM; ++c)
420 const int D1Dz = (c == 2) ? D1D - 1 : D1D;
421 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
422 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
424 for (
int dy = 0; dy < D1Dy; ++dy)
426 for (
int dx = 0; dx < D1Dx; ++dx)
428 massXY[dy][dx] = 0.0;
431 for (
int qy = 0; qy < Q1D; ++qy)
434 for (
int dx = 0; dx < D1Dx; ++dx)
438 for (
int qx = 0; qx < Q1D; ++qx)
440 for (
int dx = 0; dx < D1Dx; ++dx)
442 massX[dx] +=
mass[qz][qy][qx][c] * ((c == 0) ? Bot(dx,qx) : Bct(dx,qx));
445 for (
int dy = 0; dy < D1Dy; ++dy)
447 const real_t wy = (c == 1) ? Bot(dy,qy) : Bct(dy,qy);
448 for (
int dx = 0; dx < D1Dx; ++dx)
450 massXY[dy][dx] += massX[dx] * wy;
455 for (
int dz = 0; dz < D1Dz; ++dz)
457 const real_t wz = (c == 2) ? Bot(dz,qz) : Bct(dz,qz);
458 for (
int dy = 0; dy < D1Dy; ++dy)
460 for (
int dx = 0; dx < D1Dx; ++dx)
462 Y(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e) += massXY[dy][dx] * wz;
467 osc += D1Dx * D1Dy * D1Dz;
473void PACurlCurlSetup2D(
const int Q1D,
475 const Array<real_t> &w,
480 const int NQ = Q1D*Q1D;
482 auto J =
Reshape(j.Read(), NQ, 2, 2, NE);
483 auto C =
Reshape(coeff.Read(), NQ, NE);
484 auto y =
Reshape(op.Write(), NQ, NE);
487 for (
int q = 0; q < NQ; ++q)
489 const real_t J11 = J(q,0,0,e);
490 const real_t J21 = J(q,1,0,e);
491 const real_t J12 = J(q,0,1,e);
492 const real_t J22 = J(q,1,1,e);
493 const real_t detJ = (J11*J22)-(J21*J12);
494 y(q,e) = W[q] * C(q,e) / detJ;
499void PACurlCurlSetup3D(
const int Q1D,
502 const Array<real_t> &w,
507 const int NQ = Q1D*Q1D*Q1D;
508 const bool symmetric = (coeffDim != 9);
510 auto J =
Reshape(j.Read(), NQ, 3, 3, NE);
511 auto C =
Reshape(coeff.Read(), coeffDim, NQ, NE);
512 auto y =
Reshape(op.Write(), NQ, symmetric ? 6 : 9, NE);
516 for (
int q = 0; q < NQ; ++q)
518 const real_t J11 = J(q,0,0,e);
519 const real_t J21 = J(q,1,0,e);
520 const real_t J31 = J(q,2,0,e);
521 const real_t J12 = J(q,0,1,e);
522 const real_t J22 = J(q,1,1,e);
523 const real_t J32 = J(q,2,1,e);
524 const real_t J13 = J(q,0,2,e);
525 const real_t J23 = J(q,1,2,e);
526 const real_t J33 = J(q,2,2,e);
527 const real_t detJ = J11 * (J22 * J33 - J32 * J23) -
528 J21 * (J12 * J33 - J32 * J13) +
529 J31 * (J12 * J23 - J22 * J13);
531 const real_t c_detJ = W[q] / detJ;
533 if (coeffDim == 6 || coeffDim == 9)
536 const real_t M11 = C(0, q, e);
537 const real_t M12 = C(1, q, e);
538 const real_t M13 = C(2, q, e);
539 const real_t M21 = (!symmetric) ? C(3, q, e) : M12;
540 const real_t M22 = (!symmetric) ? C(4, q, e) : C(3, q, e);
541 const real_t M23 = (!symmetric) ? C(5, q, e) : C(4, q, e);
542 const real_t M31 = (!symmetric) ? C(6, q, e) : M13;
543 const real_t M32 = (!symmetric) ? C(7, q, e) : M23;
544 const real_t M33 = (!symmetric) ? C(8, q, e) : C(5, q, e);
547 const real_t R11 = M11*J11 + M12*J21 + M13*J31;
548 const real_t R12 = M11*J12 + M12*J22 + M13*J32;
549 const real_t R13 = M11*J13 + M12*J23 + M13*J33;
550 const real_t R21 = M21*J11 + M22*J21 + M23*J31;
551 const real_t R22 = M21*J12 + M22*J22 + M23*J32;
552 const real_t R23 = M21*J13 + M22*J23 + M23*J33;
553 const real_t R31 = M31*J11 + M32*J21 + M33*J31;
554 const real_t R32 = M31*J12 + M32*J22 + M33*J32;
555 const real_t R33 = M31*J13 + M32*J23 + M33*J33;
558 y(q,0,e) = c_detJ * (J11*R11 + J21*R21 + J31*R31);
559 const real_t Y12 = c_detJ * (J11*R12 + J21*R22 + J31*R32);
561 y(q,2,e) = c_detJ * (J11*R13 + J21*R23 + J31*R33);
563 const real_t Y21 = c_detJ * (J12*R11 + J22*R21 + J32*R31);
564 const real_t Y22 = c_detJ * (J12*R12 + J22*R22 + J32*R32);
565 const real_t Y23 = c_detJ * (J12*R13 + J22*R23 + J32*R33);
567 const real_t Y33 = c_detJ * (J13*R13 + J23*R23 + J33*R33);
569 y(q,3,e) = symmetric ? Y22 : Y21;
570 y(q,4,e) = symmetric ? Y23 : Y22;
571 y(q,5,e) = symmetric ? Y33 : Y23;
575 y(q,6,e) = c_detJ * (J13*R11 + J23*R21 + J33*R31);
576 y(q,7,e) = c_detJ * (J13*R12 + J23*R22 + J33*R32);
583 const real_t D1 = C(0, q, e);
584 const real_t D2 = coeffDim == 3 ? C(1, q, e) : D1;
585 const real_t D3 = coeffDim == 3 ? C(2, q, e) : D1;
587 y(q,0,e) = c_detJ * (D1*J11*J11 + D2*J21*J21 + D3*J31*J31);
588 y(q,1,e) = c_detJ * (D1*J11*J12 + D2*J21*J22 + D3*J31*J32);
589 y(q,2,e) = c_detJ * (D1*J11*J13 + D2*J21*J23 + D3*J31*J33);
590 y(q,3,e) = c_detJ * (D1*J12*J12 + D2*J22*J22 + D3*J32*J32);
591 y(q,4,e) = c_detJ * (D1*J12*J13 + D2*J22*J23 + D3*J32*J33);
592 y(q,5,e) = c_detJ * (D1*J13*J13 + D2*J23*J23 + D3*J33*J33);
598void PACurlCurlAssembleDiagonal2D(
const int D1D,
const int Q1D,
const bool,
599 const int NE,
const Array<real_t> &bo,
600 const Array<real_t> &,
const Array<real_t> &,
601 const Array<real_t> &gc,
602 const Vector &pa_data, Vector &diag)
604 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
605 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
606 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, NE);
607 auto D =
Reshape(diag.ReadWrite(), 2*(D1D-1)*D1D, NE);
611 constexpr static int VDIM = 2;
612 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
616 for (
int c = 0; c < VDIM; ++c)
618 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
619 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
623 for (
int dy = 0; dy < D1Dy; ++dy)
625 for (
int qx = 0; qx < Q1D; ++qx)
628 for (
int qy = 0; qy < Q1D; ++qy)
630 const real_t wy = (c == 1) ? Bo(qy,dy) : -Gc(qy,dy);
631 t[qx] += wy * wy * op(qx,qy,e);
635 for (
int dx = 0; dx < D1Dx; ++dx)
637 for (
int qx = 0; qx < Q1D; ++qx)
639 const real_t wx = ((c == 0) ? Bo(qx,dx) : Gc(qx,dx));
640 D(dx + (dy * D1Dx) + osc, e) += t[qx] * wx * wx;
650void PACurlCurlApply2D(
const int D1D,
const int Q1D,
const bool,
const int NE,
651 const Array<real_t> &bo,
const Array<real_t> &,
652 const Array<real_t> &bot,
const Array<real_t> &,
653 const Array<real_t> &gc,
const Array<real_t> &gct,
654 const Vector &pa_data,
const Vector &x, Vector &y,
658 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
659 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
660 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
661 auto Gct =
Reshape(gct.Read(), D1D, Q1D);
662 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, NE);
663 auto X =
Reshape(x.Read(), 2*(D1D-1)*D1D, NE);
664 auto Y =
Reshape(y.ReadWrite(), 2*(D1D-1)*D1D, NE);
668 constexpr static int VDIM = 2;
669 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
670 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
672 real_t curl[MAX_Q1D][MAX_Q1D];
676 for (
int qy = 0; qy < Q1D; ++qy)
678 for (
int qx = 0; qx < Q1D; ++qx)
686 for (
int c = 0; c < VDIM; ++c)
688 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
689 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
691 for (
int dy = 0; dy < D1Dy; ++dy)
694 for (
int qx = 0; qx < Q1D; ++qx)
699 for (
int dx = 0; dx < D1Dx; ++dx)
701 const real_t t = X(dx + (dy * D1Dx) + osc, e);
702 for (
int qx = 0; qx < Q1D; ++qx)
704 gradX[qx] += t * ((c == 0) ? Bo(qx,dx) : Gc(qx,dx));
708 for (
int qy = 0; qy < Q1D; ++qy)
710 const int sign = useAbs ? 1 : -1;
711 const real_t wy = (c == 0) ? (sign*Gc(qy,dy)) : Bo(qy,dy);
712 for (
int qx = 0; qx < Q1D; ++qx)
714 curl[qy][qx] += gradX[qx] * wy;
723 for (
int qy = 0; qy < Q1D; ++qy)
725 for (
int qx = 0; qx < Q1D; ++qx)
727 curl[qy][qx] *= op(qx,qy,e);
731 for (
int qy = 0; qy < Q1D; ++qy)
735 for (
int c = 0; c < VDIM; ++c)
737 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
738 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
741 for (
int dx = 0; dx < D1Dx; ++dx)
745 for (
int qx = 0; qx < Q1D; ++qx)
747 for (
int dx = 0; dx < D1Dx; ++dx)
749 gradX[dx] += curl[qy][qx] * ((c == 0) ? Bot(dx,qx) : Gct(dx,qx));
752 for (
int dy = 0; dy < D1Dy; ++dy)
754 const int sign = useAbs ? 1 : -1;
755 const real_t wy = (c == 0) ? (sign*Gct(dy,qy)) : Bot(dy,qy);
757 for (
int dx = 0; dx < D1Dx; ++dx)
759 Y(dx + (dy * D1Dx) + osc, e) += gradX[dx] * wy;
769void PAHcurlL2Setup2D(
const int Q1D,
771 const Array<real_t> &w,
775 const int NQ = Q1D*Q1D;
777 auto C =
Reshape(coeff.Read(), NQ, NE);
778 auto y =
Reshape(op.Write(), NQ, NE);
781 for (
int q = 0; q < NQ; ++q)
783 y(q,e) = W[q] * C(q,e);
788void PAHcurlL2IntSetup2D(
const int Q1D,
const int NE,
const Array<real_t> &w,
789 Vector &coeff,
const Vector &detJ, Vector &op)
791 const int NQ = Q1D*Q1D;
793 auto C =
Reshape(coeff.Read(), NQ, NE);
794 auto J =
Reshape(detJ.Read(), NQ, NE);
795 auto y =
Reshape(op.Write(), NQ, NE);
798 for (
int q = 0; q < NQ; ++q)
800 y(q,e) = W[q] * C(q,e) / J(q,e);
805void PAHcurlL2Setup3D(
const int NQ,
808 const Array<real_t> &w,
813 auto C =
Reshape(coeff.Read(), coeffDim, NQ, NE);
814 auto y =
Reshape(op.Write(), coeffDim, NQ, NE);
818 for (
int q = 0; q < NQ; ++q)
820 for (
int c=0; c<coeffDim; ++c)
822 y(c,q,e) = W[q] * C(c,q,e);
828void PAHcurlL2Apply2D(
const int D1D,
832 const Array<real_t> &bo,
833 const Array<real_t> &bot,
834 const Array<real_t> &bt,
835 const Array<real_t> &gc,
836 const Vector &pa_data,
840 const int H1 = (D1Dtest == D1D);
842 MFEM_VERIFY(y.Size() == NE*D1Dtest*D1Dtest,
"Test vector of wrong dimension");
844 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
845 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
846 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
847 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
848 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, NE);
849 auto X =
Reshape(x.Read(), 2*(D1D-1)*D1D, NE);
850 auto Y =
Reshape(y.ReadWrite(), D1Dtest, D1Dtest, NE);
854 constexpr static int VDIM = 2;
855 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
856 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
858 real_t curl[MAX_Q1D][MAX_Q1D];
862 for (
int qy = 0; qy < Q1D; ++qy)
864 for (
int qx = 0; qx < Q1D; ++qx)
872 for (
int c = 0; c < VDIM; ++c)
874 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
875 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
877 for (
int dy = 0; dy < D1Dy; ++dy)
880 for (
int qx = 0; qx < Q1D; ++qx)
885 for (
int dx = 0; dx < D1Dx; ++dx)
887 const real_t t = X(dx + (dy * D1Dx) + osc, e);
888 for (
int qx = 0; qx < Q1D; ++qx)
890 gradX[qx] += t * ((c == 0) ? Bo(qx,dx) : Gc(qx,dx));
894 for (
int qy = 0; qy < Q1D; ++qy)
896 const real_t wy = (c == 0) ? -Gc(qy,dy) : Bo(qy,dy);
897 for (
int qx = 0; qx < Q1D; ++qx)
899 curl[qy][qx] += gradX[qx] * wy;
908 for (
int qy = 0; qy < Q1D; ++qy)
910 for (
int qx = 0; qx < Q1D; ++qx)
912 curl[qy][qx] *= op(qx,qy,e);
916 for (
int qy = 0; qy < Q1D; ++qy)
919 for (
int dx = 0; dx < D1Dtest; ++dx)
923 for (
int qx = 0; qx < Q1D; ++qx)
925 const real_t s = curl[qy][qx];
926 for (
int dx = 0; dx < D1Dtest; ++dx)
928 sol_x[dx] += s * ((H1 == 1) ? Bt(dx,qx) : Bot(dx,qx));
931 for (
int dy = 0; dy < D1Dtest; ++dy)
933 const real_t wy = (H1 == 1) ? Bt(dy,qy) : Bot(dy,qy);
935 for (
int dx = 0; dx < D1Dtest; ++dx)
937 Y(dx,dy,e) += sol_x[dx] * wy;
944void PAHcurlL2ApplyTranspose2D(
const int D1D,
948 const Array<real_t> &bo,
949 const Array<real_t> &bot,
950 const Array<real_t> &
b,
951 const Array<real_t> &gct,
952 const Vector &pa_data,
956 const int H1 = (D1Dtest == D1D);
958 MFEM_VERIFY(x.Size() == NE*D1Dtest*D1Dtest,
"Test vector of wrong dimension");
960 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
961 auto B =
Reshape(
b.Read(), Q1D, D1D);
962 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
963 auto Gct =
Reshape(gct.Read(), D1D, Q1D);
964 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, NE);
965 auto X =
Reshape(x.Read(), D1Dtest, D1Dtest, NE);
966 auto Y =
Reshape(y.ReadWrite(), 2*(D1D-1)*D1D, NE);
970 constexpr static int VDIM = 2;
971 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
972 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
978 for (
int qy = 0; qy < Q1D; ++qy)
980 for (
int qx = 0; qx < Q1D; ++qx)
986 for (
int dy = 0; dy < D1Dtest; ++dy)
989 for (
int qy = 0; qy < Q1D; ++qy)
993 for (
int dx = 0; dx < D1Dtest; ++dx)
995 const real_t s = X(dx,dy,e);
996 for (
int qx = 0; qx < Q1D; ++qx)
998 sol_x[qx] += s * ((H1 == 1) ? B(qx,dx) : Bo(qx,dx));
1001 for (
int qy = 0; qy < Q1D; ++qy)
1003 const real_t d2q = (H1 == 1) ? B(qy,dy) : Bo(qy,dy);
1004 for (
int qx = 0; qx < Q1D; ++qx)
1006 mass[qy][qx] += d2q * sol_x[qx];
1012 for (
int qy = 0; qy < Q1D; ++qy)
1014 for (
int qx = 0; qx < Q1D; ++qx)
1016 mass[qy][qx] *= op(qx,qy,e);
1020 for (
int qy = 0; qy < Q1D; ++qy)
1024 for (
int c = 0; c < VDIM; ++c)
1026 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
1027 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
1030 for (
int dx = 0; dx < D1Dx; ++dx)
1034 for (
int qx = 0; qx < Q1D; ++qx)
1036 for (
int dx = 0; dx < D1Dx; ++dx)
1038 gradX[dx] +=
mass[qy][qx] * ((c == 0) ? Bot(dx,qx) : Gct(dx,qx));
1041 for (
int dy = 0; dy < D1Dy; ++dy)
1043 const real_t wy = (c == 0) ? -Gct(dy,qy) : Bot(dy,qy);
1045 for (
int dx = 0; dx < D1Dx; ++dx)
1047 Y(dx + (dy * D1Dx) + osc, e) += gradX[dx] * wy;
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void forall(int N, lambda &&body)
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.