28static void PAMixedVectorGradientSetupHdiv2D(
const int Q1D,
31 const Array<real_t> &w,
36 MFEM_VERIFY(coeffDim == 1 || coeffDim == 2 || coeffDim == 4,
37 "Unsupported coefficient dimension for 2D MixedVectorGradient PA setup.");
38 const bool const_c = c.Size() == coeffDim;
39 const auto W =
Reshape(w.Read(), Q1D, Q1D);
40 const auto J =
Reshape(j.Read(), Q1D, Q1D, 2, 2, NE);
41 const auto C = const_c ?
Reshape(c.Read(), coeffDim, 1, 1, 1)
43 auto O =
Reshape(op.Write(), Q1D, Q1D, 4, NE);
45 auto get_coeff = [const_c] MFEM_HOST_DEVICE
46 (
const decltype(C) &C,
int i,
int qx,
int qy,
int e)
48 return const_c ? C(i,0,0,0) : C(i,qx,qy,e);
53 MFEM_FOREACH_THREAD(qx, x, Q1D)
55 MFEM_FOREACH_THREAD(qy, y, Q1D)
57 const real_t J11 = J(qx,qy,0,0,e);
58 const real_t J21 = J(qx,qy,1,0,e);
59 const real_t J12 = J(qx,qy,0,1,e);
60 const real_t J22 = J(qx,qy,1,1,e);
61 const real_t detJ = (J11*J22) - (J21*J12);
62 const real_t w_detJ = W(qx,qy) / detJ;
68 M11 = get_coeff(C,0,qx,qy,e);
69 M12 = get_coeff(C,1,qx,qy,e);
70 M21 = get_coeff(C,2,qx,qy,e);
71 M22 = get_coeff(C,3,qx,qy,e);
73 else if (coeffDim == 2)
75 M11 = get_coeff(C,0,qx,qy,e);
76 M22 = get_coeff(C,1,qx,qy,e);
82 M11 = get_coeff(C,0,qx,qy,e);
89 const real_t R11 = M11*J22 - M12*J12;
90 const real_t R12 = -M11*J21 + M12*J11;
91 const real_t R21 = M21*J22 - M22*J12;
92 const real_t R22 = -M21*J21 + M22*J11;
95 const real_t O11 = w_detJ * (J11*R11 + J21*R21);
96 const real_t O12 = w_detJ * (J11*R12 + J21*R22);
97 const real_t O21 = w_detJ * (J12*R11 + J22*R21);
98 const real_t O22 = w_detJ * (J12*R12 + J22*R22);
110static void PAMixedVectorGradientSetupHdiv3D(
const int Q1D,
113 const Array<real_t> &w,
118 MFEM_VERIFY(coeffDim == 1 || coeffDim == 3 || coeffDim == 9,
119 "Unsupported coefficient dimension for 3D MixedVectorGradient PA setup.");
120 const bool const_c = c.Size() == coeffDim;
121 const auto W =
Reshape(w.Read(), Q1D, Q1D, Q1D);
122 const auto J =
Reshape(j.Read(), Q1D, Q1D, Q1D, 3, 3, NE);
123 const auto C = const_c ?
Reshape(c.Read(), coeffDim, 1, 1, 1, 1)
125 auto O =
Reshape(op.Write(), Q1D, Q1D, Q1D, 9, NE);
127 auto get_coeff = [const_c] MFEM_HOST_DEVICE
128 (
const decltype(C) &C,
int i,
int qx,
int qy,
int qz,
int e)
130 return const_c ? C(i,0,0,0,0) : C(i,qx,qy,qz,e);
135 MFEM_FOREACH_THREAD(qx, x, Q1D)
137 MFEM_FOREACH_THREAD(qy, y, Q1D)
139 MFEM_FOREACH_THREAD(qz, z, Q1D)
141 const real_t J11 = J(qx,qy,qz,0,0,e);
142 const real_t J21 = J(qx,qy,qz,1,0,e);
143 const real_t J31 = J(qx,qy,qz,2,0,e);
144 const real_t J12 = J(qx,qy,qz,0,1,e);
145 const real_t J22 = J(qx,qy,qz,1,1,e);
146 const real_t J32 = J(qx,qy,qz,2,1,e);
147 const real_t J13 = J(qx,qy,qz,0,2,e);
148 const real_t J23 = J(qx,qy,qz,1,2,e);
149 const real_t J33 = J(qx,qy,qz,2,2,e);
151 const real_t detJ = J11 * (J22 * J33 - J32 * J23) -
152 J21 * (J12 * J33 - J32 * J13) +
153 J31 * (J12 * J23 - J22 * J13);
154 const real_t w_detJ = W(qx,qy,qz) / detJ;
157 const real_t A11 = (J22 * J33) - (J23 * J32);
158 const real_t A12 = (J32 * J13) - (J12 * J33);
159 const real_t A13 = (J12 * J23) - (J22 * J13);
160 const real_t A21 = (J31 * J23) - (J21 * J33);
161 const real_t A22 = (J11 * J33) - (J13 * J31);
162 const real_t A23 = (J21 * J13) - (J11 * J23);
163 const real_t A31 = (J21 * J32) - (J31 * J22);
164 const real_t A32 = (J31 * J12) - (J11 * J32);
165 const real_t A33 = (J11 * J22) - (J12 * J21);
167 real_t M11, M12, M13, M21, M22, M23, M31, M32, M33;
171 M11 = get_coeff(C,0,qx,qy,qz,e);
172 M12 = get_coeff(C,1,qx,qy,qz,e);
173 M13 = get_coeff(C,2,qx,qy,qz,e);
174 M21 = get_coeff(C,3,qx,qy,qz,e);
175 M22 = get_coeff(C,4,qx,qy,qz,e);
176 M23 = get_coeff(C,5,qx,qy,qz,e);
177 M31 = get_coeff(C,6,qx,qy,qz,e);
178 M32 = get_coeff(C,7,qx,qy,qz,e);
179 M33 = get_coeff(C,8,qx,qy,qz,e);
181 else if (coeffDim == 3)
183 M11 = get_coeff(C,0,qx,qy,qz,e);
184 M22 = get_coeff(C,1,qx,qy,qz,e);
185 M33 = get_coeff(C,2,qx,qy,qz,e);
186 M12 = M13 = M21 = M23 = M31 = M32 = 0.0;
190 M11 = get_coeff(C,0,qx,qy,qz,e);
193 M12 = M13 = M21 = M23 = M31 = M32 = 0.0;
197 const real_t R11 = M11*A11 + M12*A12 + M13*A13;
198 const real_t R12 = M11*A21 + M12*A22 + M13*A23;
199 const real_t R13 = M11*A31 + M12*A32 + M13*A33;
200 const real_t R21 = M21*A11 + M22*A12 + M23*A13;
201 const real_t R22 = M21*A21 + M22*A22 + M23*A23;
202 const real_t R23 = M21*A31 + M22*A32 + M23*A33;
203 const real_t R31 = M31*A11 + M32*A12 + M33*A13;
204 const real_t R32 = M31*A21 + M32*A22 + M33*A23;
205 const real_t R33 = M31*A31 + M32*A32 + M33*A33;
208 const real_t O11 = w_detJ * (J11*R11 + J21*R21 + J31*R31);
209 const real_t O12 = w_detJ * (J11*R12 + J21*R22 + J31*R32);
210 const real_t O13 = w_detJ * (J11*R13 + J21*R23 + J31*R33);
211 const real_t O21 = w_detJ * (J12*R11 + J22*R21 + J32*R31);
212 const real_t O22 = w_detJ * (J12*R12 + J22*R22 + J32*R32);
213 const real_t O23 = w_detJ * (J12*R13 + J22*R23 + J32*R33);
214 const real_t O31 = w_detJ * (J13*R11 + J23*R21 + J33*R31);
215 const real_t O32 = w_detJ * (J13*R12 + J23*R22 + J33*R32);
216 const real_t O33 = w_detJ * (J13*R13 + J23*R23 + J33*R33);
219 O(qx,qy,qz,0,e) = O11;
220 O(qx,qy,qz,1,e) = O12;
221 O(qx,qy,qz,2,e) = O13;
222 O(qx,qy,qz,3,e) = O21;
223 O(qx,qy,qz,4,e) = O22;
224 O(qx,qy,qz,5,e) = O23;
225 O(qx,qy,qz,6,e) = O31;
226 O(qx,qy,qz,7,e) = O32;
227 O(qx,qy,qz,8,e) = O33;
238static void PAHcurlH1Apply2D(
const int D1D,
241 const Array<real_t> &bc,
242 const Array<real_t> &gc,
243 const Array<real_t> &bot,
244 const Array<real_t> &bct,
245 const int op_entries,
246 const Vector &pa_data,
251 "Error: D1D > MAX_D1D");
253 "Error: Q1D > MAX_Q1D");
255 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
256 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
257 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
258 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
259 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, op_entries, NE);
260 auto X =
Reshape(x.Read(), D1D, D1D, NE);
261 auto Y =
Reshape(y.ReadWrite(), 2*(D1D-1)*D1D, NE);
265 constexpr static int VDIM = 2;
266 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
267 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
271 for (
int qy = 0; qy < Q1D; ++qy)
273 for (
int qx = 0; qx < Q1D; ++qx)
275 for (
int c = 0; c < VDIM; ++c)
277 mass[qy][qx][c] = 0.0;
282 for (
int dy = 0; dy < D1D; ++dy)
285 for (
int qx = 0; qx < Q1D; ++qx)
290 for (
int dx = 0; dx < D1D; ++dx)
292 const real_t s = X(dx,dy,e);
293 for (
int qx = 0; qx < Q1D; ++qx)
295 gradX[qx][0] += s * Bc(qx,dx);
296 gradX[qx][1] += s * Gc(qx,dx);
299 for (
int qy = 0; qy < Q1D; ++qy)
301 const real_t wy = Bc(qy,dy);
302 const real_t wDy = Gc(qy,dy);
303 for (
int qx = 0; qx < Q1D; ++qx)
305 const real_t wx = gradX[qx][0];
306 const real_t wDx = gradX[qx][1];
307 mass[qy][qx][0] += wDx * wy;
308 mass[qy][qx][1] += wx * wDy;
314 for (
int qy = 0; qy < Q1D; ++qy)
316 for (
int qx = 0; qx < Q1D; ++qx)
322 const real_t O11 = op(qx,qy,0,e);
323 const real_t O12 = op(qx,qy,1,e);
324 const real_t O22 = op(qx,qy,2,e);
325 mass[qy][qx][0] = (O11*massX)+(O12*massY);
326 mass[qy][qx][1] = (O12*massX)+(O22*massY);
331 const real_t O11 = op(qx,qy,0,e);
332 const real_t O21 = op(qx,qy,1,e);
333 const real_t O12 = op(qx,qy,2,e);
334 const real_t O22 = op(qx,qy,3,e);
335 mass[qy][qx][0] = (O11*massX)+(O12*massY);
336 mass[qy][qx][1] = (O21*massX)+(O22*massY);
341 for (
int qy = 0; qy < Q1D; ++qy)
345 for (
int c = 0; c < VDIM; ++c)
347 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
348 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
351 for (
int dx = 0; dx < D1Dx; ++dx)
355 for (
int qx = 0; qx < Q1D; ++qx)
357 for (
int dx = 0; dx < D1Dx; ++dx)
359 massX[dx] +=
mass[qy][qx][c] * ((c == 0) ? Bot(dx,qx) : Bct(dx,qx));
363 for (
int dy = 0; dy < D1Dy; ++dy)
365 const real_t wy = (c == 1) ? Bot(dy,qy) : Bct(dy,qy);
367 for (
int dx = 0; dx < D1Dx; ++dx)
369 Y(dx + (dy * D1Dx) + osc, e) += massX[dx] * wy;
381static void PAHcurlH1ApplyTranspose2D(
const int D1D,
384 const Array<real_t> &bc,
385 const Array<real_t> &bo,
386 const Array<real_t> &bct,
387 const Array<real_t> &gct,
388 const int op_entries,
389 const Vector &pa_data,
394 "Error: D1D > MAX_D1D");
396 "Error: Q1D > MAX_Q1D");
397 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
398 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
399 auto Bt =
Reshape(bct.Read(), D1D, Q1D);
400 auto Gt =
Reshape(gct.Read(), D1D, Q1D);
401 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, op_entries, NE);
402 auto X =
Reshape(x.Read(), 2*(D1D-1)*D1D, NE);
403 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, NE);
407 constexpr static int VDIM = 2;
408 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
409 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
413 for (
int qy = 0; qy < Q1D; ++qy)
415 for (
int qx = 0; qx < Q1D; ++qx)
417 for (
int c = 0; c < VDIM; ++c)
419 mass[qy][qx][c] = 0.0;
426 for (
int c = 0; c < VDIM; ++c)
428 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
429 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
431 for (
int dy = 0; dy < D1Dy; ++dy)
434 for (
int qx = 0; qx < Q1D; ++qx)
439 for (
int dx = 0; dx < D1Dx; ++dx)
441 const real_t t = X(dx + (dy * D1Dx) + osc, e);
442 for (
int qx = 0; qx < Q1D; ++qx)
444 massX[qx] += t * ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
448 for (
int qy = 0; qy < Q1D; ++qy)
450 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
451 for (
int qx = 0; qx < Q1D; ++qx)
453 mass[qy][qx][c] += massX[qx] * wy;
462 for (
int qy = 0; qy < Q1D; ++qy)
464 for (
int qx = 0; qx < Q1D; ++qx)
470 const real_t O11 = op(qx,qy,0,e);
471 const real_t O12 = op(qx,qy,1,e);
472 const real_t O22 = op(qx,qy,2,e);
473 mass[qy][qx][0] = (O11*massX)+(O12*massY);
474 mass[qy][qx][1] = (O12*massX)+(O22*massY);
480 const real_t O11 = op(qx,qy,0,e);
481 const real_t O21 = op(qx,qy,1,e);
482 const real_t O12 = op(qx,qy,2,e);
483 const real_t O22 = op(qx,qy,3,e);
484 mass[qy][qx][0] = (O11*massX)+(O21*massY);
485 mass[qy][qx][1] = (O12*massX)+(O22*massY);
490 for (
int qy = 0; qy < Q1D; ++qy)
493 for (
int dx = 0; dx < D1D; ++dx)
498 for (
int qx = 0; qx < Q1D; ++qx)
502 for (
int dx = 0; dx < D1D; ++dx)
504 const real_t wx = Bt(dx,qx);
505 const real_t wDx = Gt(dx,qx);
506 gradX[dx][0] += gX * wDx;
507 gradX[dx][1] += gY * wx;
510 for (
int dy = 0; dy < D1D; ++dy)
512 const real_t wy = Bt(dy,qy);
513 const real_t wDy = Gt(dy,qy);
514 for (
int dx = 0; dx < D1D; ++dx)
516 Y(dx,dy,e) += ((gradX[dx][0] * wy) + (gradX[dx][1] * wDy));
525static void PAHdivH1Apply2D(
const int D1D,
528 const Array<real_t> &bc,
529 const Array<real_t> &gc,
530 const Array<real_t> &bot,
531 const Array<real_t> &bct,
532 const int op_entries,
533 const Vector &pa_data,
538 "Error: D1D > MAX_D1D");
540 "Error: Q1D > MAX_Q1D");
542 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
543 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
544 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
545 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
546 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, op_entries, NE);
547 auto X =
Reshape(x.Read(), D1D, D1D, NE);
548 auto Y =
Reshape(y.ReadWrite(), 2*(D1D-1)*D1D, NE);
552 constexpr static int VDIM = 2;
553 constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
554 constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
557 for (
int qy = 0; qy < Q1D; ++qy)
559 for (
int qx = 0; qx < Q1D; ++qx)
561 for (
int c = 0; c < VDIM; ++c) {
mass[qy][qx][c] = 0.0; }
565 for (
int dy = 0; dy < D1D; ++dy)
568 for (
int qx = 0; qx < Q1D; ++qx) { gradX[qx][0] = 0.0; gradX[qx][1] = 0.0; }
569 for (
int dx = 0; dx < D1D; ++dx)
571 const real_t s = X(dx,dy,e);
572 for (
int qx = 0; qx < Q1D; ++qx)
574 gradX[qx][0] += s * Bc(qx,dx);
575 gradX[qx][1] += s * Gc(qx,dx);
578 for (
int qy = 0; qy < Q1D; ++qy)
580 const real_t wy = Bc(qy,dy);
581 const real_t wDy = Gc(qy,dy);
582 for (
int qx = 0; qx < Q1D; ++qx)
584 const real_t wx = gradX[qx][0];
585 const real_t wDx = gradX[qx][1];
586 mass[qy][qx][0] += wDx * wy;
587 mass[qy][qx][1] += wx * wDy;
593 for (
int qy = 0; qy < Q1D; ++qy)
595 for (
int qx = 0; qx < Q1D; ++qx)
601 const real_t O11 = op(qx,qy,0,e);
602 const real_t O12 = op(qx,qy,1,e);
603 const real_t O22 = op(qx,qy,2,e);
604 mass[qy][qx][0] = (O11*massX)+(O12*massY);
605 mass[qy][qx][1] = (O12*massX)+(O22*massY);
610 const real_t O11 = op(qx,qy,0,e);
611 const real_t O21 = op(qx,qy,1,e);
612 const real_t O12 = op(qx,qy,2,e);
613 const real_t O22 = op(qx,qy,3,e);
614 mass[qy][qx][0] = (O11*massX)+(O12*massY);
615 mass[qy][qx][1] = (O21*massX)+(O22*massY);
620 for (
int qy = 0; qy < Q1D; ++qy)
623 for (
int c = 0; c < VDIM; ++c)
625 const int D1Dx = (c == 0) ? D1D : D1D - 1;
626 const int D1Dy = (c == 0) ? D1D - 1 : D1D;
629 for (
int dx = 0; dx < D1Dx; ++dx) { massX[dx] = 0.0; }
631 for (
int qx = 0; qx < Q1D; ++qx)
633 for (
int dx = 0; dx < D1Dx; ++dx)
635 massX[dx] +=
mass[qy][qx][c] * ((c == 0) ? Bct(dx,qx) : Bot(dx,qx));
639 for (
int dy = 0; dy < D1Dy; ++dy)
641 const real_t wy = (c == 0) ? Bot(dy,qy) : Bct(dy,qy);
642 for (
int dx = 0; dx < D1Dx; ++dx)
644 Y(dx + (dy * D1Dx) + osc, e) += massX[dx] * wy;
656static void PAHdivH1ApplyTranspose2D(
const int D1D,
659 const Array<real_t> &bc,
660 const Array<real_t> &bo,
661 const Array<real_t> &bct,
662 const Array<real_t> &gct,
663 const int op_entries,
664 const Vector &pa_data,
669 "Error: D1D > MAX_D1D");
671 "Error: Q1D > MAX_Q1D");
673 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
674 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
675 auto Bt =
Reshape(bct.Read(), D1D, Q1D);
676 auto Gt =
Reshape(gct.Read(), D1D, Q1D);
677 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, op_entries, NE);
678 auto X =
Reshape(x.Read(), 2*(D1D-1)*D1D, NE);
679 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, NE);
683 constexpr static int VDIM = 2;
684 constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
685 constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
688 for (
int qy = 0; qy < Q1D; ++qy)
690 for (
int qx = 0; qx < Q1D; ++qx)
692 for (
int c = 0; c < VDIM; ++c) {
mass[qy][qx][c] = 0.0; }
697 for (
int c = 0; c < VDIM; ++c)
699 const int D1Dx = (c == 0) ? D1D : D1D - 1;
700 const int D1Dy = (c == 0) ? D1D - 1 : D1D;
702 for (
int dy = 0; dy < D1Dy; ++dy)
705 for (
int qx = 0; qx < Q1D; ++qx) { massX[qx] = 0.0; }
707 for (
int dx = 0; dx < D1Dx; ++dx)
709 const real_t t = X(dx + (dy * D1Dx) + osc, e);
710 for (
int qx = 0; qx < Q1D; ++qx)
712 massX[qx] += t * ((c == 0) ? Bc(qx,dx) : Bo(qx,dx));
716 for (
int qy = 0; qy < Q1D; ++qy)
718 const real_t wy = (c == 0) ? Bo(qy,dy) : Bc(qy,dy);
719 for (
int qx = 0; qx < Q1D; ++qx)
721 mass[qy][qx][c] += massX[qx] * wy;
730 for (
int qy = 0; qy < Q1D; ++qy)
732 for (
int qx = 0; qx < Q1D; ++qx)
738 const real_t O11 = op(qx,qy,0,e);
739 const real_t O12 = op(qx,qy,1,e);
740 const real_t O22 = op(qx,qy,2,e);
741 mass[qy][qx][0] = (O11*massX)+(O12*massY);
742 mass[qy][qx][1] = (O12*massX)+(O22*massY);
748 const real_t O11 = op(qx,qy,0,e);
749 const real_t O21 = op(qx,qy,1,e);
750 const real_t O12 = op(qx,qy,2,e);
751 const real_t O22 = op(qx,qy,3,e);
752 mass[qy][qx][0] = (O11*massX)+(O21*massY);
753 mass[qy][qx][1] = (O12*massX)+(O22*massY);
758 for (
int qy = 0; qy < Q1D; ++qy)
761 for (
int dx = 0; dx < D1D; ++dx) { gradX[dx][0] = 0.0; gradX[dx][1] = 0.0; }
763 for (
int qx = 0; qx < Q1D; ++qx)
767 for (
int dx = 0; dx < D1D; ++dx)
769 const real_t wx = Bt(dx,qx);
770 const real_t wDx = Gt(dx,qx);
771 gradX[dx][0] += gX * wDx;
772 gradX[dx][1] += gY * wx;
776 for (
int dy = 0; dy < D1D; ++dy)
778 const real_t wy = Bt(dy,qy);
779 const real_t wDy = Gt(dy,qy);
780 for (
int dx = 0; dx < D1D; ++dx)
782 Y(dx,dy,e) += ((gradX[dx][0] * wy) + (gradX[dx][1] * wDy));
791static void PAHcurlH1Apply3D(
const int D1D,
794 const Array<real_t> &bc,
795 const Array<real_t> &gc,
796 const Array<real_t> &bot,
797 const Array<real_t> &bct,
798 const int op_entries,
799 const Vector &pa_data,
804 "Error: D1D > MAX_D1D");
806 "Error: Q1D > MAX_Q1D");
808 constexpr static int VDIM = 3;
810 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
811 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
812 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
813 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
814 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, op_entries, NE);
815 auto X =
Reshape(x.Read(), D1D, D1D, D1D, NE);
816 auto Y =
Reshape(y.ReadWrite(), 3*(D1D-1)*D1D*D1D, NE);
820 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
821 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
825 for (
int qz = 0; qz < Q1D; ++qz)
827 for (
int qy = 0; qy < Q1D; ++qy)
829 for (
int qx = 0; qx < Q1D; ++qx)
831 for (
int c = 0; c < VDIM; ++c)
833 mass[qz][qy][qx][c] = 0.0;
839 for (
int dz = 0; dz < D1D; ++dz)
841 real_t gradXY[MAX_Q1D][MAX_Q1D][3];
842 for (
int qy = 0; qy < Q1D; ++qy)
844 for (
int qx = 0; qx < Q1D; ++qx)
846 gradXY[qy][qx][0] = 0.0;
847 gradXY[qy][qx][1] = 0.0;
848 gradXY[qy][qx][2] = 0.0;
851 for (
int dy = 0; dy < D1D; ++dy)
854 for (
int qx = 0; qx < Q1D; ++qx)
859 for (
int dx = 0; dx < D1D; ++dx)
861 const real_t s = X(dx,dy,dz,e);
862 for (
int qx = 0; qx < Q1D; ++qx)
864 gradX[qx][0] += s * Bc(qx,dx);
865 gradX[qx][1] += s * Gc(qx,dx);
868 for (
int qy = 0; qy < Q1D; ++qy)
870 const real_t wy = Bc(qy,dy);
871 const real_t wDy = Gc(qy,dy);
872 for (
int qx = 0; qx < Q1D; ++qx)
874 const real_t wx = gradX[qx][0];
875 const real_t wDx = gradX[qx][1];
876 gradXY[qy][qx][0] += wDx * wy;
877 gradXY[qy][qx][1] += wx * wDy;
878 gradXY[qy][qx][2] += wx * wy;
882 for (
int qz = 0; qz < Q1D; ++qz)
884 const real_t wz = Bc(qz,dz);
885 const real_t wDz = Gc(qz,dz);
886 for (
int qy = 0; qy < Q1D; ++qy)
888 for (
int qx = 0; qx < Q1D; ++qx)
890 mass[qz][qy][qx][0] += gradXY[qy][qx][0] * wz;
891 mass[qz][qy][qx][1] += gradXY[qy][qx][1] * wz;
892 mass[qz][qy][qx][2] += gradXY[qy][qx][2] * wDz;
899 for (
int qz = 0; qz < Q1D; ++qz)
901 for (
int qy = 0; qy < Q1D; ++qy)
903 for (
int qx = 0; qx < Q1D; ++qx)
910 const real_t O11 = op(qx,qy,qz,0,e);
911 const real_t O12 = op(qx,qy,qz,1,e);
912 const real_t O13 = op(qx,qy,qz,2,e);
913 const real_t O22 = op(qx,qy,qz,3,e);
914 const real_t O23 = op(qx,qy,qz,4,e);
915 const real_t O33 = op(qx,qy,qz,5,e);
916 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
917 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O23*massZ);
918 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
923 const real_t O11 = op(qx,qy,qz,0,e);
924 const real_t O12 = op(qx,qy,qz,1,e);
925 const real_t O13 = op(qx,qy,qz,2,e);
926 const real_t O21 = op(qx,qy,qz,3,e);
927 const real_t O22 = op(qx,qy,qz,4,e);
928 const real_t O23 = op(qx,qy,qz,5,e);
929 const real_t O31 = op(qx,qy,qz,6,e);
930 const real_t O32 = op(qx,qy,qz,7,e);
931 const real_t O33 = op(qx,qy,qz,8,e);
932 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
933 mass[qz][qy][qx][1] = (O21*massX)+(O22*massY)+(O23*massZ);
934 mass[qz][qy][qx][2] = (O31*massX)+(O32*massY)+(O33*massZ);
940 for (
int qz = 0; qz < Q1D; ++qz)
942 real_t massXY[MAX_D1D][MAX_D1D];
946 for (
int c = 0; c < VDIM; ++c)
948 const int D1Dz = (c == 2) ? D1D - 1 : D1D;
949 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
950 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
952 for (
int dy = 0; dy < D1Dy; ++dy)
954 for (
int dx = 0; dx < D1Dx; ++dx)
956 massXY[dy][dx] = 0.0;
959 for (
int qy = 0; qy < Q1D; ++qy)
962 for (
int dx = 0; dx < D1Dx; ++dx)
966 for (
int qx = 0; qx < Q1D; ++qx)
968 for (
int dx = 0; dx < D1Dx; ++dx)
970 massX[dx] +=
mass[qz][qy][qx][c] * ((c == 0) ? Bot(dx,qx) : Bct(dx,qx));
973 for (
int dy = 0; dy < D1Dy; ++dy)
975 const real_t wy = (c == 1) ? Bot(dy,qy) : Bct(dy,qy);
976 for (
int dx = 0; dx < D1Dx; ++dx)
978 massXY[dy][dx] += massX[dx] * wy;
983 for (
int dz = 0; dz < D1Dz; ++dz)
985 const real_t wz = (c == 2) ? Bot(dz,qz) : Bct(dz,qz);
986 for (
int dy = 0; dy < D1Dy; ++dy)
988 for (
int dx = 0; dx < D1Dx; ++dx)
990 Y(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e) += massXY[dy][dx] * wz;
995 osc += D1Dx * D1Dy * D1Dz;
1003static void PAHcurlH1ApplyTranspose3D(
const int D1D,
1006 const Array<real_t> &bc,
1007 const Array<real_t> &bo,
1008 const Array<real_t> &bct,
1009 const Array<real_t> &gct,
1010 const int op_entries,
1011 const Vector &pa_data,
1016 "Error: D1D > MAX_D1D");
1018 "Error: Q1D > MAX_Q1D");
1020 constexpr static int VDIM = 3;
1022 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
1023 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
1024 auto Bt =
Reshape(bct.Read(), D1D, Q1D);
1025 auto Gt =
Reshape(gct.Read(), D1D, Q1D);
1026 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, op_entries, NE);
1027 auto X =
Reshape(x.Read(), 3*(D1D-1)*D1D*D1D, NE);
1028 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, D1D, NE);
1032 constexpr static int MAX_D1D = DofQuadLimits::HCURL_MAX_D1D;
1033 constexpr static int MAX_Q1D = DofQuadLimits::HCURL_MAX_Q1D;
1035 real_t mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
1037 for (
int qz = 0; qz < Q1D; ++qz)
1039 for (
int qy = 0; qy < Q1D; ++qy)
1041 for (
int qx = 0; qx < Q1D; ++qx)
1043 for (
int c = 0; c < VDIM; ++c)
1045 mass[qz][qy][qx][c] = 0.0;
1053 for (
int c = 0; c < VDIM; ++c)
1055 const int D1Dz = (c == 2) ? D1D - 1 : D1D;
1056 const int D1Dy = (c == 1) ? D1D - 1 : D1D;
1057 const int D1Dx = (c == 0) ? D1D - 1 : D1D;
1059 for (
int dz = 0; dz < D1Dz; ++dz)
1061 real_t massXY[MAX_Q1D][MAX_Q1D];
1062 for (
int qy = 0; qy < Q1D; ++qy)
1064 for (
int qx = 0; qx < Q1D; ++qx)
1066 massXY[qy][qx] = 0.0;
1070 for (
int dy = 0; dy < D1Dy; ++dy)
1073 for (
int qx = 0; qx < Q1D; ++qx)
1078 for (
int dx = 0; dx < D1Dx; ++dx)
1080 const real_t t = X(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e);
1081 for (
int qx = 0; qx < Q1D; ++qx)
1083 massX[qx] += t * ((c == 0) ? Bo(qx,dx) : Bc(qx,dx));
1087 for (
int qy = 0; qy < Q1D; ++qy)
1089 const real_t wy = (c == 1) ? Bo(qy,dy) : Bc(qy,dy);
1090 for (
int qx = 0; qx < Q1D; ++qx)
1092 const real_t wx = massX[qx];
1093 massXY[qy][qx] += wx * wy;
1098 for (
int qz = 0; qz < Q1D; ++qz)
1100 const real_t wz = (c == 2) ? Bo(qz,dz) : Bc(qz,dz);
1101 for (
int qy = 0; qy < Q1D; ++qy)
1103 for (
int qx = 0; qx < Q1D; ++qx)
1105 mass[qz][qy][qx][c] += massXY[qy][qx] * wz;
1111 osc += D1Dx * D1Dy * D1Dz;
1115 for (
int qz = 0; qz < Q1D; ++qz)
1117 for (
int qy = 0; qy < Q1D; ++qy)
1119 for (
int qx = 0; qx < Q1D; ++qx)
1124 if (op_entries == 6)
1126 const real_t O11 = op(qx,qy,qz,0,e);
1127 const real_t O12 = op(qx,qy,qz,1,e);
1128 const real_t O13 = op(qx,qy,qz,2,e);
1129 const real_t O22 = op(qx,qy,qz,3,e);
1130 const real_t O23 = op(qx,qy,qz,4,e);
1131 const real_t O33 = op(qx,qy,qz,5,e);
1132 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
1133 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O23*massZ);
1134 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
1139 const real_t O11 = op(qx,qy,qz,0,e);
1140 const real_t O12 = op(qx,qy,qz,1,e);
1141 const real_t O13 = op(qx,qy,qz,2,e);
1142 const real_t O21 = op(qx,qy,qz,3,e);
1143 const real_t O22 = op(qx,qy,qz,4,e);
1144 const real_t O23 = op(qx,qy,qz,5,e);
1145 const real_t O31 = op(qx,qy,qz,6,e);
1146 const real_t O32 = op(qx,qy,qz,7,e);
1147 const real_t O33 = op(qx,qy,qz,8,e);
1148 mass[qz][qy][qx][0] = (O11*massX)+(O21*massY)+(O31*massZ);
1149 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O32*massZ);
1150 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
1156 for (
int qz = 0; qz < Q1D; ++qz)
1158 real_t gradXY[MAX_D1D][MAX_D1D][3];
1159 for (
int dy = 0; dy < D1D; ++dy)
1161 for (
int dx = 0; dx < D1D; ++dx)
1163 gradXY[dy][dx][0] = 0;
1164 gradXY[dy][dx][1] = 0;
1165 gradXY[dy][dx][2] = 0;
1168 for (
int qy = 0; qy < Q1D; ++qy)
1170 real_t gradX[MAX_D1D][3];
1171 for (
int dx = 0; dx < D1D; ++dx)
1177 for (
int qx = 0; qx < Q1D; ++qx)
1182 for (
int dx = 0; dx < D1D; ++dx)
1184 const real_t wx = Bt(dx,qx);
1185 const real_t wDx = Gt(dx,qx);
1186 gradX[dx][0] += gX * wDx;
1187 gradX[dx][1] += gY * wx;
1188 gradX[dx][2] += gZ * wx;
1191 for (
int dy = 0; dy < D1D; ++dy)
1193 const real_t wy = Bt(dy,qy);
1194 const real_t wDy = Gt(dy,qy);
1195 for (
int dx = 0; dx < D1D; ++dx)
1197 gradXY[dy][dx][0] += gradX[dx][0] * wy;
1198 gradXY[dy][dx][1] += gradX[dx][1] * wDy;
1199 gradXY[dy][dx][2] += gradX[dx][2] * wy;
1203 for (
int dz = 0; dz < D1D; ++dz)
1205 const real_t wz = Bt(dz,qz);
1206 const real_t wDz = Gt(dz,qz);
1207 for (
int dy = 0; dy < D1D; ++dy)
1209 for (
int dx = 0; dx < D1D; ++dx)
1212 ((gradXY[dy][dx][0] * wz) +
1213 (gradXY[dy][dx][1] * wz) +
1214 (gradXY[dy][dx][2] * wDz));
1224static void PAHdivH1Apply3D(
const int D1D,
1227 const Array<real_t> &bc,
1228 const Array<real_t> &gc,
1229 const Array<real_t> &bot,
1230 const Array<real_t> &bct,
1231 const int op_entries,
1232 const Vector &pa_data,
1237 "Error: D1D > MAX_D1D");
1239 "Error: Q1D > MAX_Q1D");
1241 constexpr static int VDIM = 3;
1243 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
1244 auto Gc =
Reshape(gc.Read(), Q1D, D1D);
1245 auto Bot =
Reshape(bot.Read(), D1D-1, Q1D);
1246 auto Bct =
Reshape(bct.Read(), D1D, Q1D);
1247 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, op_entries, NE);
1248 auto X =
Reshape(x.Read(), D1D, D1D, D1D, NE);
1249 auto Y =
Reshape(y.ReadWrite(), 3*D1D*(D1D-1)*(D1D-1), NE);
1253 constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
1254 constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
1256 real_t mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
1258 for (
int qz = 0; qz < Q1D; ++qz)
1260 for (
int qy = 0; qy < Q1D; ++qy)
1262 for (
int qx = 0; qx < Q1D; ++qx)
1264 for (
int c = 0; c < VDIM; ++c) {
mass[qz][qy][qx][c] = 0.0; }
1269 for (
int dz = 0; dz < D1D; ++dz)
1271 real_t gradXY[MAX_Q1D][MAX_Q1D][3];
1272 for (
int qy = 0; qy < Q1D; ++qy)
1274 for (
int qx = 0; qx < Q1D; ++qx)
1276 gradXY[qy][qx][0] = 0.0;
1277 gradXY[qy][qx][1] = 0.0;
1278 gradXY[qy][qx][2] = 0.0;
1281 for (
int dy = 0; dy < D1D; ++dy)
1283 real_t gradX[MAX_Q1D][2];
1284 for (
int qx = 0; qx < Q1D; ++qx)
1289 for (
int dx = 0; dx < D1D; ++dx)
1291 const real_t s = X(dx,dy,dz,e);
1292 for (
int qx = 0; qx < Q1D; ++qx)
1294 gradX[qx][0] += s * Bc(qx,dx);
1295 gradX[qx][1] += s * Gc(qx,dx);
1298 for (
int qy = 0; qy < Q1D; ++qy)
1300 const real_t wy = Bc(qy,dy);
1301 const real_t wDy = Gc(qy,dy);
1302 for (
int qx = 0; qx < Q1D; ++qx)
1304 const real_t wx = gradX[qx][0];
1305 const real_t wDx = gradX[qx][1];
1306 gradXY[qy][qx][0] += wDx * wy;
1307 gradXY[qy][qx][1] += wx * wDy;
1308 gradXY[qy][qx][2] += wx * wy;
1312 for (
int qz = 0; qz < Q1D; ++qz)
1314 const real_t wz = Bc(qz,dz);
1315 const real_t wDz = Gc(qz,dz);
1316 for (
int qy = 0; qy < Q1D; ++qy)
1318 for (
int qx = 0; qx < Q1D; ++qx)
1320 mass[qz][qy][qx][0] += gradXY[qy][qx][0] * wz;
1321 mass[qz][qy][qx][1] += gradXY[qy][qx][1] * wz;
1322 mass[qz][qy][qx][2] += gradXY[qy][qx][2] * wDz;
1329 for (
int qz = 0; qz < Q1D; ++qz)
1331 for (
int qy = 0; qy < Q1D; ++qy)
1333 for (
int qx = 0; qx < Q1D; ++qx)
1338 if (op_entries == 6)
1340 const real_t O11 = op(qx,qy,qz,0,e);
1341 const real_t O12 = op(qx,qy,qz,1,e);
1342 const real_t O13 = op(qx,qy,qz,2,e);
1343 const real_t O22 = op(qx,qy,qz,3,e);
1344 const real_t O23 = op(qx,qy,qz,4,e);
1345 const real_t O33 = op(qx,qy,qz,5,e);
1346 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
1347 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O23*massZ);
1348 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
1353 const real_t O11 = op(qx,qy,qz,0,e);
1354 const real_t O12 = op(qx,qy,qz,1,e);
1355 const real_t O13 = op(qx,qy,qz,2,e);
1356 const real_t O21 = op(qx,qy,qz,3,e);
1357 const real_t O22 = op(qx,qy,qz,4,e);
1358 const real_t O23 = op(qx,qy,qz,5,e);
1359 const real_t O31 = op(qx,qy,qz,6,e);
1360 const real_t O32 = op(qx,qy,qz,7,e);
1361 const real_t O33 = op(qx,qy,qz,8,e);
1362 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
1363 mass[qz][qy][qx][1] = (O21*massX)+(O22*massY)+(O23*massZ);
1364 mass[qz][qy][qx][2] = (O31*massX)+(O32*massY)+(O33*massZ);
1371 for (
int qz = 0; qz < Q1D; ++qz)
1373 real_t massXY[MAX_D1D][MAX_D1D];
1376 for (
int c = 0; c < VDIM; ++c)
1378 const int D1Dx = (c == 0) ? D1D : D1D - 1;
1379 const int D1Dy = (c == 1) ? D1D : D1D - 1;
1380 const int D1Dz = (c == 2) ? D1D : D1D - 1;
1382 for (
int dy = 0; dy < D1Dy; ++dy)
1384 for (
int dx = 0; dx < D1Dx; ++dx) { massXY[dy][dx] = 0.0; }
1387 for (
int qy = 0; qy < Q1D; ++qy)
1390 for (
int dx = 0; dx < D1Dx; ++dx) { massX[dx] = 0.0; }
1392 for (
int qx = 0; qx < Q1D; ++qx)
1394 for (
int dx = 0; dx < D1Dx; ++dx)
1396 massX[dx] +=
mass[qz][qy][qx][c] * ((c == 0) ? Bct(dx,qx) : Bot(dx,qx));
1399 for (
int dy = 0; dy < D1Dy; ++dy)
1401 const real_t wy = (c == 1) ? Bct(dy,qy) : Bot(dy,qy);
1402 for (
int dx = 0; dx < D1Dx; ++dx) { massXY[dy][dx] += massX[dx] * wy; }
1406 for (
int dz = 0; dz < D1Dz; ++dz)
1408 const real_t wz = (c == 2) ? Bct(dz,qz) : Bot(dz,qz);
1409 for (
int dy = 0; dy < D1Dy; ++dy)
1411 for (
int dx = 0; dx < D1Dx; ++dx)
1413 Y(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e) += massXY[dy][dx] * wz;
1418 osc += D1Dx * D1Dy * D1Dz;
1426static void PAHdivH1ApplyTranspose3D(
const int D1D,
1429 const Array<real_t> &bc,
1430 const Array<real_t> &bo,
1431 const Array<real_t> &bct,
1432 const Array<real_t> &gct,
1433 const int op_entries,
1434 const Vector &pa_data,
1439 "Error: D1D > MAX_D1D");
1441 "Error: Q1D > MAX_Q1D");
1443 constexpr static int VDIM = 3;
1445 auto Bc =
Reshape(bc.Read(), Q1D, D1D);
1446 auto Bo =
Reshape(bo.Read(), Q1D, D1D-1);
1447 auto Bt =
Reshape(bct.Read(), D1D, Q1D);
1448 auto Gt =
Reshape(gct.Read(), D1D, Q1D);
1449 auto op =
Reshape(pa_data.Read(), Q1D, Q1D, Q1D, op_entries, NE);
1450 auto X =
Reshape(x.Read(), 3*(D1D-1)*(D1D-1)*D1D, NE);
1451 auto Y =
Reshape(y.ReadWrite(), D1D, D1D, D1D, NE);
1455 constexpr static int MAX_D1D = DofQuadLimits::HDIV_MAX_D1D;
1456 constexpr static int MAX_Q1D = DofQuadLimits::HDIV_MAX_Q1D;
1458 real_t mass[MAX_Q1D][MAX_Q1D][MAX_Q1D][VDIM];
1459 for (
int qz = 0; qz < Q1D; ++qz)
1461 for (
int qy = 0; qy < Q1D; ++qy)
1463 for (
int qx = 0; qx < Q1D; ++qx)
1465 for (
int c = 0; c < VDIM; ++c) {
mass[qz][qy][qx][c] = 0.0; }
1471 for (
int c = 0; c < VDIM; ++c)
1473 const int D1Dx = (c == 0) ? D1D : D1D - 1;
1474 const int D1Dy = (c == 1) ? D1D : D1D - 1;
1475 const int D1Dz = (c == 2) ? D1D : D1D - 1;
1477 for (
int dz = 0; dz < D1Dz; ++dz)
1479 real_t massXY[MAX_Q1D][MAX_Q1D];
1480 for (
int qy = 0; qy < Q1D; ++qy)
1482 for (
int qx = 0; qx < Q1D; ++qx) { massXY[qy][qx] = 0.0; }
1485 for (
int dy = 0; dy < D1Dy; ++dy)
1488 for (
int qx = 0; qx < Q1D; ++qx) { massX[qx] = 0.0; }
1490 for (
int dx = 0; dx < D1Dx; ++dx)
1492 const real_t t = X(dx + ((dy + (dz * D1Dy)) * D1Dx) + osc, e);
1493 for (
int qx = 0; qx < Q1D; ++qx)
1495 massX[qx] += t * ((c == 0) ? Bc(qx,dx) : Bo(qx,dx));
1499 for (
int qy = 0; qy < Q1D; ++qy)
1501 const real_t wy = (c == 1) ? Bc(qy,dy) : Bo(qy,dy);
1502 for (
int qx = 0; qx < Q1D; ++qx) { massXY[qy][qx] += massX[qx] * wy; }
1506 for (
int qz = 0; qz < Q1D; ++qz)
1508 const real_t wz = (c == 2) ? Bc(qz,dz) : Bo(qz,dz);
1509 for (
int qy = 0; qy < Q1D; ++qy)
1511 for (
int qx = 0; qx < Q1D; ++qx)
1513 mass[qz][qy][qx][c] += massXY[qy][qx] * wz;
1519 osc += D1Dx * D1Dy * D1Dz;
1523 for (
int qz = 0; qz < Q1D; ++qz)
1525 for (
int qy = 0; qy < Q1D; ++qy)
1527 for (
int qx = 0; qx < Q1D; ++qx)
1532 if (op_entries == 6)
1534 const real_t O11 = op(qx,qy,qz,0,e);
1535 const real_t O12 = op(qx,qy,qz,1,e);
1536 const real_t O13 = op(qx,qy,qz,2,e);
1537 const real_t O22 = op(qx,qy,qz,3,e);
1538 const real_t O23 = op(qx,qy,qz,4,e);
1539 const real_t O33 = op(qx,qy,qz,5,e);
1540 mass[qz][qy][qx][0] = (O11*massX)+(O12*massY)+(O13*massZ);
1541 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O23*massZ);
1542 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
1547 const real_t O11 = op(qx,qy,qz,0,e);
1548 const real_t O12 = op(qx,qy,qz,1,e);
1549 const real_t O13 = op(qx,qy,qz,2,e);
1550 const real_t O21 = op(qx,qy,qz,3,e);
1551 const real_t O22 = op(qx,qy,qz,4,e);
1552 const real_t O23 = op(qx,qy,qz,5,e);
1553 const real_t O31 = op(qx,qy,qz,6,e);
1554 const real_t O32 = op(qx,qy,qz,7,e);
1555 const real_t O33 = op(qx,qy,qz,8,e);
1556 mass[qz][qy][qx][0] = (O11*massX)+(O21*massY)+(O31*massZ);
1557 mass[qz][qy][qx][1] = (O12*massX)+(O22*massY)+(O32*massZ);
1558 mass[qz][qy][qx][2] = (O13*massX)+(O23*massY)+(O33*massZ);
1565 for (
int qz = 0; qz < Q1D; ++qz)
1567 real_t gradXY[MAX_D1D][MAX_D1D][3];
1568 for (
int dy = 0; dy < D1D; ++dy)
1570 for (
int dx = 0; dx < D1D; ++dx)
1572 gradXY[dy][dx][0] = 0.0;
1573 gradXY[dy][dx][1] = 0.0;
1574 gradXY[dy][dx][2] = 0.0;
1578 for (
int qy = 0; qy < Q1D; ++qy)
1580 real_t gradX[MAX_D1D][3];
1581 for (
int dx = 0; dx < D1D; ++dx)
1587 for (
int qx = 0; qx < Q1D; ++qx)
1592 for (
int dx = 0; dx < D1D; ++dx)
1594 const real_t wx = Bt(dx,qx);
1595 const real_t wDx = Gt(dx,qx);
1596 gradX[dx][0] += gX * wDx;
1597 gradX[dx][1] += gY * wx;
1598 gradX[dx][2] += gZ * wx;
1601 for (
int dy = 0; dy < D1D; ++dy)
1603 const real_t wy = Bt(dy,qy);
1604 const real_t wDy = Gt(dy,qy);
1605 for (
int dx = 0; dx < D1D; ++dx)
1607 gradXY[dy][dx][0] += gradX[dx][0] * wy;
1608 gradXY[dy][dx][1] += gradX[dx][1] * wDy;
1609 gradXY[dy][dx][2] += gradX[dx][2] * wy;
1614 for (
int dz = 0; dz < D1D; ++dz)
1616 const real_t wz = Bt(dz,qz);
1617 const real_t wDz = Gt(dz,qz);
1618 for (
int dy = 0; dy < D1D; ++dy)
1620 for (
int dx = 0; dx < D1D; ++dx)
1623 ((gradXY[dy][dx][0] * wz) +
1624 (gradXY[dy][dx][1] * wz) +
1625 (gradXY[dy][dx][2] * wDz));
1644 MFEM_VERIFY(trial_el != NULL,
"Only NodalTensorFiniteElement is supported!");
1646 "Only value map type is supported!");
1650 MFEM_VERIFY(test_el != NULL,
"Only VectorTensorFiniteElement is supported!");
1655 const int dims = trial_el->
GetDim();
1656 MFEM_VERIFY(dims == 2 || dims == 3,
"");
1660 MFEM_VERIFY(dim == 2 || dim == 3,
"");
1664 ne = trial_fes.
GetNE();
1668 dofs1D = mapsC->
ndof;
1669 quad1D = mapsC->
nqpt;
1672 MFEM_VERIFY(dofs1D == mapsO->
ndof + 1 && quad1D == mapsO->
nqpt,
"");
1686 const int coeffDim = coeff.
GetVDim();
1690 op_entries = (dim == 2 ? (coeffDim == 4 ? 4 : 3) : (coeffDim == 9 ? 9 : 6));
1696 op_entries = dim * dim;
1700 MFEM_ABORT(
"Unsupported test space derivative type.");
1710 internal::PADiffusionSetup3D(quad1D, coeffDim, ne, ir->
GetWeights(), geom->
J,
1715 internal::PADiffusionSetup2D<2>(quad1D, coeffDim, ne, ir->
GetWeights(), geom->
J,
1720 MFEM_ABORT(
"Unsupported dimension.");
1727 internal::PAMixedVectorGradientSetupHdiv3D(quad1D, coeffDim, ne,
1729 geom->
J, coeff, pa_data);
1733 internal::PAMixedVectorGradientSetupHdiv2D(quad1D, coeffDim, ne,
1735 geom->
J, coeff, pa_data);
1739 MFEM_ABORT(
"Unsupported dimension.");
1750 PAHcurlH1Apply3D(dofs1D, quad1D, ne, mapsC->
B, mapsC->
G,
1751 mapsO->
Bt, mapsC->
Bt, op_entries, pa_data, x, y);
1755 PAHcurlH1Apply2D(dofs1D, quad1D, ne, mapsC->
B, mapsC->
G,
1756 mapsO->
Bt, mapsC->
Bt, op_entries, pa_data, x, y);
1760 MFEM_ABORT(
"Unsupported dimension!");
1767 PAHdivH1Apply3D(dofs1D, quad1D, ne, mapsC->
B, mapsC->
G,
1768 mapsO->
Bt, mapsC->
Bt, op_entries, pa_data, x, y);
1772 PAHdivH1Apply2D(dofs1D, quad1D, ne, mapsC->
B, mapsC->
G,
1773 mapsO->
Bt, mapsC->
Bt, op_entries, pa_data, x, y);
1777 MFEM_ABORT(
"Unsupported dimension!");
1782 MFEM_ABORT(
"Unsupported test space derivative type!");
1793 PAHcurlH1ApplyTranspose3D(dofs1D, quad1D, ne, mapsC->
B, mapsO->
B,
1794 mapsC->
Bt, mapsC->
Gt, op_entries, pa_data, x, y);
1798 PAHcurlH1ApplyTranspose2D(dofs1D, quad1D, ne, mapsC->
B, mapsO->
B,
1799 mapsC->
Bt, mapsC->
Gt, op_entries, pa_data, x, y);
1803 MFEM_ABORT(
"Unsupported dimension!");
1810 PAHdivH1ApplyTranspose3D(dofs1D, quad1D, ne, mapsC->
B, mapsO->
B,
1811 mapsC->
Bt, mapsC->
Gt, op_entries, pa_data, x, y);
1815 PAHdivH1ApplyTranspose2D(dofs1D, quad1D, ne, mapsC->
B, mapsO->
B,
1816 mapsC->
Bt, mapsC->
Gt, op_entries, pa_data, x, y);
1820 MFEM_ABORT(
"Unsupported dimension!");
1825 MFEM_ABORT(
"Unsupported test space derivative type!");
Class to represent a coefficient evaluated at quadrature points.
void SetConstant(real_t constant)
Set this vector to the given constant.
void Project(Coefficient &coeff)
Evaluate the given Coefficient at the quadrature points defined by qs.
int GetVDim() const
Return the number of values per quadrature point.
void ProjectTranspose(MatrixCoefficient &coeff)
Project the transpose of coeff.
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.
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
DerivType
Enumeration for DerivType: defines which derivative method is implemented.
@ DIV
Implements CalcDivShape methods.
@ 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, const bool stroud=false)
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.
DiagonalMatrixCoefficient * DQ
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...
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
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_2D(int N, int X, int Y, lambda &&body)
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
void forall(int N, lambda &&body)
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.