12 #include "../general/forall.hpp"
15 #include "ceed/convection.hpp"
24 static void PAConvectionSetup2D(
const int NQ,
26 const Array<double> &w,
32 constexpr
int DIM = 2;
34 const bool const_v = vel.Size() ==
DIM;
36 const auto W = w.Read();
38 const auto V = const_v ?
43 MFEM_FORALL(q_global, NE*NQ,
45 const int e = q_global / NQ;
46 const int q = q_global % NQ;
47 const double J11 = J(q,0,0,e);
48 const double J21 = J(q,1,0,e);
49 const double J12 = J(q,0,1,e);
50 const double J22 = J(q,1,1,e);
51 const double w = alpha * W[q];
52 const double v0 = const_v ? V(0,0,0) : V(0,q,e);
53 const double v1 = const_v ? V(1,0,0) : V(1,q,e);
54 const double wx = w * v0;
55 const double wy = w * v1;
57 y(q,0,e) = wx * J22 - wy * J12;
58 y(q,1,e) = -wx * J21 + wy * J11;
63 static void PAConvectionSetup3D(
const int NQ,
65 const Array<double> &w,
71 constexpr
int DIM = 3;
73 const auto W =
Reshape(w.Read(), NQ);
75 const bool const_v = vel.Size() ==
DIM;
76 const auto V = const_v ?
79 auto y =
Reshape(op.Write(), NQ,3,NE);
80 MFEM_FORALL(q_global, NE*NQ,
82 const int e = q_global / NQ;
83 const int q = q_global % NQ;
84 const double J11 = J(q,0,0,e);
85 const double J12 = J(q,0,1,e);
86 const double J13 = J(q,0,2,e);
87 const double J21 = J(q,1,0,e);
88 const double J22 = J(q,1,1,e);
89 const double J23 = J(q,1,2,e);
90 const double J31 = J(q,2,0,e);
91 const double J32 = J(q,2,1,e);
92 const double J33 = J(q,2,2,e);
93 const double w = alpha * W(q);
94 const double v0 = const_v ? V(0,0,0) : V(0,q,e);
95 const double v1 = const_v ? V(1,0,0) : V(1,q,e);
96 const double v2 = const_v ? V(2,0,0) : V(2,q,e);
97 const double wx = w * v0;
98 const double wy = w * v1;
99 const double wz = w * v2;
101 const double A11 = (J22 * J33) - (J23 * J32);
102 const double A12 = (J32 * J13) - (J12 * J33);
103 const double A13 = (J12 * J23) - (J22 * J13);
104 const double A21 = (J31 * J23) - (J21 * J33);
105 const double A22 = (J11 * J33) - (J13 * J31);
106 const double A23 = (J21 * J13) - (J11 * J23);
107 const double A31 = (J21 * J32) - (J31 * J22);
108 const double A32 = (J31 * J12) - (J11 * J32);
109 const double A33 = (J11 * J22) - (J12 * J21);
111 y(q,0,e) = wx * A11 + wy * A12 + wz * A13;
112 y(q,1,e) = wx * A21 + wy * A22 + wz * A23;
113 y(q,2,e) = wx * A31 + wy * A32 + wz * A33;
117 static void PAConvectionSetup(
const int dim,
120 const Array<double> &W,
126 if (dim == 1) { MFEM_ABORT(
"dim==1 not supported in PAConvectionSetup"); }
129 PAConvectionSetup2D(NQ, NE, W, J, coeff, alpha, op);
133 PAConvectionSetup3D(NQ, NE, W, J, coeff, alpha, op);
138 template<
int T_D1D = 0,
int T_Q1D = 0>
static
139 void PAConvectionApply2D(
const int ne,
140 const Array<double> &
b,
141 const Array<double> &g,
142 const Array<double> &bt,
143 const Array<double> >,
151 const int D1D = T_D1D ? T_D1D : d1d;
152 const int Q1D = T_Q1D ? T_Q1D : q1d;
153 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
154 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
155 auto B =
Reshape(b.Read(), Q1D, D1D);
156 auto G =
Reshape(g.Read(), Q1D, D1D);
157 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
158 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
159 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
160 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
163 const int D1D = T_D1D ? T_D1D : d1d;
164 const int Q1D = T_Q1D ? T_Q1D : q1d;
166 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
167 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
169 double u[max_D1D][max_D1D];
170 for (
int dy = 0; dy < D1D; ++dy)
172 for (
int dx = 0; dx < D1D; ++dx)
174 u[dy][dx] = x(dx,dy,e);
177 double Bu[max_D1D][max_Q1D];
178 double Gu[max_D1D][max_Q1D];
179 for (
int dy = 0; dy < D1D; ++dy)
181 for (
int qx = 0; qx < Q1D; ++qx)
185 for (
int dx = 0; dx < D1D; ++dx)
187 const double bx = B(qx,dx);
188 const double gx = G(qx,dx);
189 const double x = u[dy][dx];
190 Bu[dy][qx] += bx * x;
191 Gu[dy][qx] += gx * x;
195 double GBu[max_Q1D][max_Q1D];
196 double BGu[max_Q1D][max_Q1D];
197 for (
int qx = 0; qx < Q1D; ++qx)
199 for (
int qy = 0; qy < Q1D; ++qy)
203 for (
int dy = 0; dy < D1D; ++dy)
205 const double bx = B(qy,dy);
206 const double gx = G(qy,dy);
207 GBu[qy][qx] += gx * Bu[dy][qx];
208 BGu[qy][qx] += bx * Gu[dy][qx];
213 double DGu[max_Q1D][max_Q1D];
214 for (
int qy = 0; qy < Q1D; ++qy)
216 for (
int qx = 0; qx < Q1D; ++qx)
218 const double O1 = op(qx,qy,0,e);
219 const double O2 = op(qx,qy,1,e);
221 const double gradX = BGu[qy][qx];
222 const double gradY = GBu[qy][qx];
224 DGu[qy][qx] = (O1 * gradX) + (O2 * gradY);
227 double BDGu[max_D1D][max_Q1D];
228 for (
int qx = 0; qx < Q1D; ++qx)
230 for (
int dy = 0; dy < D1D; ++dy)
233 for (
int qy = 0; qy < Q1D; ++qy)
235 const double w = Bt(dy,qy);
236 BDGu[dy][qx] += w * DGu[qy][qx];
240 for (
int dx = 0; dx < D1D; ++dx)
242 for (
int dy = 0; dy < D1D; ++dy)
245 for (
int qx = 0; qx < Q1D; ++qx)
247 const double w = Bt(dx,qx);
248 BBDGu += w * BDGu[dy][qx];
257 template<
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
static
258 void SmemPAConvectionApply2D(
const int ne,
259 const Array<double> &b,
260 const Array<double> &g,
261 const Array<double> &bt,
262 const Array<double> >,
270 const int D1D = T_D1D ? T_D1D : d1d;
271 const int Q1D = T_Q1D ? T_Q1D : q1d;
272 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
273 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
274 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
275 auto B =
Reshape(b.Read(), Q1D, D1D);
276 auto G =
Reshape(g.Read(), Q1D, D1D);
277 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
278 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
279 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
280 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
281 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
283 const int tidz = MFEM_THREAD_ID(z);
284 const int D1D = T_D1D ? T_D1D : d1d;
285 const int Q1D = T_Q1D ? T_Q1D : q1d;
287 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
288 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
289 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
291 MFEM_SHARED
double u[NBZ][max_D1D][max_D1D];
292 MFEM_FOREACH_THREAD(dy,y,D1D)
294 MFEM_FOREACH_THREAD(dx,x,D1D)
297 u[tidz][dy][dx] = x(dx,dy,e);
301 MFEM_SHARED
double Bu[NBZ][max_D1D][max_Q1D];
302 MFEM_SHARED
double Gu[NBZ][max_D1D][max_Q1D];
303 MFEM_FOREACH_THREAD(dy,y,D1D)
305 MFEM_FOREACH_THREAD(qx,x,Q1D)
307 Bu[tidz][dy][qx] = 0.0;
308 Gu[tidz][dy][qx] = 0.0;
309 for (
int dx = 0; dx < D1D; ++dx)
311 const double bx = B(qx,dx);
312 const double gx = G(qx,dx);
313 const double x = u[tidz][dy][dx];
314 Bu[tidz][dy][qx] += bx * x;
315 Gu[tidz][dy][qx] += gx * x;
320 MFEM_SHARED
double GBu[NBZ][max_Q1D][max_Q1D];
321 MFEM_SHARED
double BGu[NBZ][max_Q1D][max_Q1D];
322 MFEM_FOREACH_THREAD(qx,x,Q1D)
324 MFEM_FOREACH_THREAD(qy,y,Q1D)
326 GBu[tidz][qy][qx] = 0.0;
327 BGu[tidz][qy][qx] = 0.0;
328 for (
int dy = 0; dy < D1D; ++dy)
330 const double bx = B(qy,dy);
331 const double gx = G(qy,dy);
332 GBu[tidz][qy][qx] += gx * Bu[tidz][dy][qx];
333 BGu[tidz][qy][qx] += bx * Gu[tidz][dy][qx];
339 MFEM_SHARED
double DGu[NBZ][max_Q1D][max_Q1D];
340 MFEM_FOREACH_THREAD(qy,y,Q1D)
342 MFEM_FOREACH_THREAD(qx,x,Q1D)
344 const double O1 = op(qx,qy,0,e);
345 const double O2 = op(qx,qy,1,e);
347 const double gradX = BGu[tidz][qy][qx];
348 const double gradY = GBu[tidz][qy][qx];
350 DGu[tidz][qy][qx] = (O1 * gradX) + (O2 * gradY);
354 MFEM_SHARED
double BDGu[NBZ][max_D1D][max_Q1D];
355 MFEM_FOREACH_THREAD(qx,x,Q1D)
357 MFEM_FOREACH_THREAD(dy,y,D1D)
359 BDGu[tidz][dy][qx] = 0.0;
360 for (
int qy = 0; qy < Q1D; ++qy)
362 const double w = Bt(dy,qy);
363 BDGu[tidz][dy][qx] += w * DGu[tidz][qy][qx];
368 MFEM_FOREACH_THREAD(dx,x,D1D)
370 MFEM_FOREACH_THREAD(dy,y,D1D)
373 for (
int qx = 0; qx < Q1D; ++qx)
375 const double w = Bt(dx,qx);
376 BBDGu += w * BDGu[tidz][dy][qx];
385 template<
int T_D1D = 0,
int T_Q1D = 0>
static
386 void PAConvectionApply3D(
const int ne,
387 const Array<double> &b,
388 const Array<double> &g,
389 const Array<double> &bt,
390 const Array<double> >,
398 const int D1D = T_D1D ? T_D1D : d1d;
399 const int Q1D = T_Q1D ? T_Q1D : q1d;
400 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
401 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
402 auto B =
Reshape(b.Read(), Q1D, D1D);
403 auto G =
Reshape(g.Read(), Q1D, D1D);
404 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
405 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
406 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
407 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
410 const int D1D = T_D1D ? T_D1D : d1d;
411 const int Q1D = T_Q1D ? T_Q1D : q1d;
413 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
414 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
416 double u[max_D1D][max_D1D][max_D1D];
417 for (
int dz = 0; dz < D1D; ++dz)
419 for (
int dy = 0; dy < D1D; ++dy)
421 for (
int dx = 0; dx < D1D; ++dx)
423 u[dz][dy][dx] = x(dx,dy,dz,e);
427 double Bu[max_D1D][max_D1D][max_Q1D];
428 double Gu[max_D1D][max_D1D][max_Q1D];
429 for (
int dz = 0; dz < D1D; ++dz)
431 for (
int dy = 0; dy < D1D; ++dy)
433 for (
int qx = 0; qx < Q1D; ++qx)
435 Bu[dz][dy][qx] = 0.0;
436 Gu[dz][dy][qx] = 0.0;
437 for (
int dx = 0; dx < D1D; ++dx)
439 const double bx = B(qx,dx);
440 const double gx = G(qx,dx);
441 const double x = u[dz][dy][dx];
442 Bu[dz][dy][qx] += bx * x;
443 Gu[dz][dy][qx] += gx * x;
448 double BBu[max_D1D][max_Q1D][max_Q1D];
449 double GBu[max_D1D][max_Q1D][max_Q1D];
450 double BGu[max_D1D][max_Q1D][max_Q1D];
451 for (
int dz = 0; dz < D1D; ++dz)
453 for (
int qx = 0; qx < Q1D; ++qx)
455 for (
int qy = 0; qy < Q1D; ++qy)
457 BBu[dz][qy][qx] = 0.0;
458 GBu[dz][qy][qx] = 0.0;
459 BGu[dz][qy][qx] = 0.0;
460 for (
int dy = 0; dy < D1D; ++dy)
462 const double bx = B(qy,dy);
463 const double gx = G(qy,dy);
464 BBu[dz][qy][qx] += bx * Bu[dz][dy][qx];
465 GBu[dz][qy][qx] += gx * Bu[dz][dy][qx];
466 BGu[dz][qy][qx] += bx * Gu[dz][dy][qx];
471 double GBBu[max_Q1D][max_Q1D][max_Q1D];
472 double BGBu[max_Q1D][max_Q1D][max_Q1D];
473 double BBGu[max_Q1D][max_Q1D][max_Q1D];
474 for (
int qx = 0; qx < Q1D; ++qx)
476 for (
int qy = 0; qy < Q1D; ++qy)
478 for (
int qz = 0; qz < Q1D; ++qz)
480 GBBu[qz][qy][qx] = 0.0;
481 BGBu[qz][qy][qx] = 0.0;
482 BBGu[qz][qy][qx] = 0.0;
483 for (
int dz = 0; dz < D1D; ++dz)
485 const double bx = B(qz,dz);
486 const double gx = G(qz,dz);
487 GBBu[qz][qy][qx] += gx * BBu[dz][qy][qx];
488 BGBu[qz][qy][qx] += bx * GBu[dz][qy][qx];
489 BBGu[qz][qy][qx] += bx * BGu[dz][qy][qx];
495 double DGu[max_Q1D][max_Q1D][max_Q1D];
496 for (
int qz = 0; qz < Q1D; ++qz)
498 for (
int qy = 0; qy < Q1D; ++qy)
500 for (
int qx = 0; qx < Q1D; ++qx)
502 const double O1 = op(qx,qy,qz,0,e);
503 const double O2 = op(qx,qy,qz,1,e);
504 const double O3 = op(qx,qy,qz,2,e);
506 const double gradX = BBGu[qz][qy][qx];
507 const double gradY = BGBu[qz][qy][qx];
508 const double gradZ = GBBu[qz][qy][qx];
510 DGu[qz][qy][qx] = (O1 * gradX) + (O2 * gradY) + (O3 * gradZ);
514 double BDGu[max_D1D][max_Q1D][max_Q1D];
515 for (
int qx = 0; qx < Q1D; ++qx)
517 for (
int qy = 0; qy < Q1D; ++qy)
519 for (
int dz = 0; dz < D1D; ++dz)
521 BDGu[dz][qy][qx] = 0.0;
522 for (
int qz = 0; qz < Q1D; ++qz)
524 const double w = Bt(dz,qz);
525 BDGu[dz][qy][qx] += w * DGu[qz][qy][qx];
530 double BBDGu[max_D1D][max_D1D][max_Q1D];
531 for (
int dz = 0; dz < D1D; ++dz)
533 for (
int qx = 0; qx < Q1D; ++qx)
535 for (
int dy = 0; dy < D1D; ++dy)
537 BBDGu[dz][dy][qx] = 0.0;
538 for (
int qy = 0; qy < Q1D; ++qy)
540 const double w = Bt(dy,qy);
541 BBDGu[dz][dy][qx] += w * BDGu[dz][qy][qx];
546 for (
int dz = 0; dz < D1D; ++dz)
548 for (
int dy = 0; dy < D1D; ++dy)
550 for (
int dx = 0; dx < D1D; ++dx)
553 for (
int qx = 0; qx < Q1D; ++qx)
555 const double w = Bt(dx,qx);
556 BBBDGu += w * BBDGu[dz][dy][qx];
558 y(dx,dy,dz,e) += BBBDGu;
566 template<
int T_D1D = 0,
int T_Q1D = 0>
static
567 void SmemPAConvectionApply3D(
const int ne,
568 const Array<double> &b,
569 const Array<double> &g,
570 const Array<double> &bt,
571 const Array<double> >,
579 const int D1D = T_D1D ? T_D1D : d1d;
580 const int Q1D = T_Q1D ? T_Q1D : q1d;
581 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
582 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
583 auto B =
Reshape(b.Read(), Q1D, D1D);
584 auto G =
Reshape(g.Read(), Q1D, D1D);
585 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
586 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
587 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
588 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
589 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
591 const int D1D = T_D1D ? T_D1D : d1d;
592 const int Q1D = T_Q1D ? T_Q1D : q1d;
594 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
595 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
596 constexpr
int max_DQ = (max_Q1D > max_D1D) ? max_Q1D : max_D1D;
597 MFEM_SHARED
double sm0[max_DQ*max_DQ*max_DQ];
598 MFEM_SHARED
double sm1[max_DQ*max_DQ*max_DQ];
599 MFEM_SHARED
double sm2[max_DQ*max_DQ*max_DQ];
600 MFEM_SHARED
double sm3[max_DQ*max_DQ*max_DQ];
601 MFEM_SHARED
double sm4[max_DQ*max_DQ*max_DQ];
602 MFEM_SHARED
double sm5[max_DQ*max_DQ*max_DQ];
604 double (*u)[max_D1D][max_D1D] = (double (*)[max_D1D][max_D1D]) sm0;
605 MFEM_FOREACH_THREAD(dz,z,D1D)
607 MFEM_FOREACH_THREAD(dy,y,D1D)
609 MFEM_FOREACH_THREAD(dx,x,D1D)
611 u[dz][dy][dx] = x(dx,dy,dz,e);
616 double (*Bu)[max_D1D][max_Q1D] = (double (*)[max_D1D][max_Q1D])sm1;
617 double (*Gu)[max_D1D][max_Q1D] = (double (*)[max_D1D][max_Q1D])sm2;
618 MFEM_FOREACH_THREAD(dz,z,D1D)
620 MFEM_FOREACH_THREAD(dy,y,D1D)
622 MFEM_FOREACH_THREAD(qx,x,Q1D)
626 for (
int dx = 0; dx < D1D; ++dx)
628 const double bx = B(qx,dx);
629 const double gx = G(qx,dx);
630 const double x = u[dz][dy][dx];
634 Bu[dz][dy][qx] = Bu_;
635 Gu[dz][dy][qx] = Gu_;
640 double (*BBu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm3;
641 double (*GBu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm4;
642 double (*BGu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm5;
643 MFEM_FOREACH_THREAD(dz,z,D1D)
645 MFEM_FOREACH_THREAD(qx,x,Q1D)
647 MFEM_FOREACH_THREAD(qy,y,Q1D)
652 for (
int dy = 0; dy < D1D; ++dy)
654 const double bx = B(qy,dy);
655 const double gx = G(qy,dy);
656 BBu_ += bx * Bu[dz][dy][qx];
657 GBu_ += gx * Bu[dz][dy][qx];
658 BGu_ += bx * Gu[dz][dy][qx];
660 BBu[dz][qy][qx] = BBu_;
661 GBu[dz][qy][qx] = GBu_;
662 BGu[dz][qy][qx] = BGu_;
667 double (*GBBu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm0;
668 double (*BGBu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm1;
669 double (*BBGu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm2;
670 MFEM_FOREACH_THREAD(qx,x,Q1D)
672 MFEM_FOREACH_THREAD(qy,y,Q1D)
674 MFEM_FOREACH_THREAD(qz,z,Q1D)
679 for (
int dz = 0; dz < D1D; ++dz)
681 const double bx = B(qz,dz);
682 const double gx = G(qz,dz);
683 GBBu_ += gx * BBu[dz][qy][qx];
684 BGBu_ += bx * GBu[dz][qy][qx];
685 BBGu_ += bx * BGu[dz][qy][qx];
687 GBBu[qz][qy][qx] = GBBu_;
688 BGBu[qz][qy][qx] = BGBu_;
689 BBGu[qz][qy][qx] = BBGu_;
694 double (*DGu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm3;
695 MFEM_FOREACH_THREAD(qz,z,Q1D)
697 MFEM_FOREACH_THREAD(qy,y,Q1D)
699 MFEM_FOREACH_THREAD(qx,x,Q1D)
701 const double O1 = op(qx,qy,qz,0,e);
702 const double O2 = op(qx,qy,qz,1,e);
703 const double O3 = op(qx,qy,qz,2,e);
705 const double gradX = BBGu[qz][qy][qx];
706 const double gradY = BGBu[qz][qy][qx];
707 const double gradZ = GBBu[qz][qy][qx];
709 DGu[qz][qy][qx] = (O1 * gradX) + (O2 * gradY) + (O3 * gradZ);
714 double (*BDGu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm4;
715 MFEM_FOREACH_THREAD(qx,x,Q1D)
717 MFEM_FOREACH_THREAD(qy,y,Q1D)
719 MFEM_FOREACH_THREAD(dz,z,D1D)
722 for (
int qz = 0; qz < Q1D; ++qz)
724 const double w = Bt(dz,qz);
725 BDGu_ += w * DGu[qz][qy][qx];
727 BDGu[dz][qy][qx] = BDGu_;
732 double (*BBDGu)[max_D1D][max_Q1D] = (double (*)[max_D1D][max_Q1D])sm5;
733 MFEM_FOREACH_THREAD(dz,z,D1D)
735 MFEM_FOREACH_THREAD(qx,x,Q1D)
737 MFEM_FOREACH_THREAD(dy,y,D1D)
740 for (
int qy = 0; qy < Q1D; ++qy)
742 const double w = Bt(dy,qy);
743 BBDGu_ += w * BDGu[dz][qy][qx];
745 BBDGu[dz][dy][qx] = BBDGu_;
750 MFEM_FOREACH_THREAD(dz,z,D1D)
752 MFEM_FOREACH_THREAD(dy,y,D1D)
754 MFEM_FOREACH_THREAD(dx,x,D1D)
757 for (
int qx = 0; qx < Q1D; ++qx)
759 const double w = Bt(dx,qx);
760 BBBDGu += w * BBDGu[dz][dy][qx];
762 y(dx,dy,dz,e) += BBBDGu;
770 template<
int T_D1D = 0,
int T_Q1D = 0>
static
771 void PAConvectionApplyT2D(
const int ne,
772 const Array<double> &b,
773 const Array<double> &g,
774 const Array<double> &bt,
775 const Array<double> >,
783 const int D1D = T_D1D ? T_D1D : d1d;
784 const int Q1D = T_Q1D ? T_Q1D : q1d;
785 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
786 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
787 auto B =
Reshape(b.Read(), Q1D, D1D);
788 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
789 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
790 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
791 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
792 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
795 const int D1D = T_D1D ? T_D1D : d1d;
796 const int Q1D = T_Q1D ? T_Q1D : q1d;
798 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
799 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
801 double u[max_D1D][max_D1D];
802 for (
int dy = 0; dy < D1D; ++dy)
804 for (
int dx = 0; dx < D1D; ++dx)
806 u[dy][dx] = x(dx,dy,e);
809 double Bu[max_D1D][max_Q1D];
810 for (
int dy = 0; dy < D1D; ++dy)
812 for (
int qx = 0; qx < Q1D; ++qx)
815 for (
int dx = 0; dx < D1D; ++dx)
817 const double bx = B(qx,dx);
818 const double x = u[dy][dx];
819 Bu[dy][qx] += bx * x;
823 double BBu[max_Q1D][max_Q1D];
824 for (
int qx = 0; qx < Q1D; ++qx)
826 for (
int qy = 0; qy < Q1D; ++qy)
829 for (
int dy = 0; dy < D1D; ++dy)
831 const double bx = B(qy,dy);
832 BBu[qy][qx] += bx * Bu[dy][qx];
837 double DBu[max_Q1D][max_Q1D][2];
838 for (
int qy = 0; qy < Q1D; ++qy)
840 for (
int qx = 0; qx < Q1D; ++qx)
842 const double O1 = op(qx,qy,0,e);
843 const double O2 = op(qx,qy,1,e);
845 const double X = BBu[qy][qx];
847 DBu[qy][qx][0] = O1 * X;
848 DBu[qy][qx][1] = O2 * X;
851 double GDBu[max_D1D][max_Q1D][2];
852 for (
int qx = 0; qx < Q1D; ++qx)
854 for (
int dy = 0; dy < D1D; ++dy)
856 GDBu[dy][qx][0] = 0.0;
857 GDBu[dy][qx][1] = 0.0;
858 for (
int qy = 0; qy < Q1D; ++qy)
860 const double by = Bt(dy,qy);
861 const double gy = Gt(dy,qy);
862 GDBu[dy][qx][0] += by * DBu[qy][qx][0];
863 GDBu[dy][qx][1] += gy * DBu[qy][qx][1];
867 for (
int dx = 0; dx < D1D; ++dx)
869 for (
int dy = 0; dy < D1D; ++dy)
872 for (
int qx = 0; qx < Q1D; ++qx)
874 const double bx = Bt(dx,qx);
875 const double gx = Gt(dx,qx);
876 res += gx * GDBu[dy][qx][0] + bx * GDBu[dy][qx][1];
885 template<
int T_D1D = 0,
int T_Q1D = 0,
int T_NBZ = 0>
static
886 void SmemPAConvectionApplyT2D(
const int ne,
887 const Array<double> &b,
888 const Array<double> &g,
889 const Array<double> &bt,
890 const Array<double> >,
898 const int D1D = T_D1D ? T_D1D : d1d;
899 const int Q1D = T_Q1D ? T_Q1D : q1d;
900 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
901 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
902 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
903 auto B =
Reshape(b.Read(), Q1D, D1D);
904 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
905 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
906 auto op =
Reshape(op_.Read(), Q1D, Q1D, 2, NE);
907 auto x =
Reshape(x_.Read(), D1D, D1D, NE);
908 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, NE);
909 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
911 const int tidz = MFEM_THREAD_ID(z);
912 const int D1D = T_D1D ? T_D1D : d1d;
913 const int Q1D = T_Q1D ? T_Q1D : q1d;
915 constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
916 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
917 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
918 MFEM_SHARED
double u[NBZ][max_D1D][max_D1D];
919 MFEM_FOREACH_THREAD(dy,y,D1D)
921 MFEM_FOREACH_THREAD(dx,x,D1D)
924 u[tidz][dy][dx] = x(dx,dy,e);
928 MFEM_SHARED
double Bu[NBZ][max_D1D][max_Q1D];
929 MFEM_FOREACH_THREAD(dy,y,D1D)
931 MFEM_FOREACH_THREAD(qx,x,Q1D)
933 Bu[tidz][dy][qx] = 0.0;
934 for (
int dx = 0; dx < D1D; ++dx)
936 const double bx = B(qx,dx);
937 const double x = u[tidz][dy][dx];
938 Bu[tidz][dy][qx] += bx * x;
943 MFEM_SHARED
double BBu[NBZ][max_Q1D][max_Q1D];
944 MFEM_FOREACH_THREAD(qx,x,Q1D)
946 MFEM_FOREACH_THREAD(qy,y,Q1D)
948 BBu[tidz][qy][qx] = 0.0;
949 for (
int dy = 0; dy < D1D; ++dy)
951 const double bx = B(qy,dy);
952 BBu[tidz][qy][qx] += bx * Bu[tidz][dy][qx];
958 MFEM_SHARED
double DBu[NBZ][max_Q1D][max_Q1D][2];
959 MFEM_FOREACH_THREAD(qy,y,Q1D)
961 MFEM_FOREACH_THREAD(qx,x,Q1D)
963 const double O1 = op(qx,qy,0,e);
964 const double O2 = op(qx,qy,1,e);
966 const double X = BBu[tidz][qy][qx];
968 DBu[tidz][qy][qx][0] = O1 * X;
969 DBu[tidz][qy][qx][1] = O2 * X;
973 MFEM_SHARED
double GDBu[NBZ][max_D1D][max_Q1D][2];
974 MFEM_FOREACH_THREAD(qx,x,Q1D)
976 MFEM_FOREACH_THREAD(dy,y,D1D)
978 GDBu[tidz][dy][qx][0] = 0.0;
979 GDBu[tidz][dy][qx][1] = 0.0;
980 for (
int qy = 0; qy < Q1D; ++qy)
982 const double by = Bt(dy,qy);
983 const double gy = Gt(dy,qy);
984 GDBu[tidz][dy][qx][0] += by * DBu[tidz][qy][qx][0];
985 GDBu[tidz][dy][qx][1] += gy * DBu[tidz][qy][qx][1];
990 MFEM_FOREACH_THREAD(dx,x,D1D)
992 MFEM_FOREACH_THREAD(dy,y,D1D)
995 for (
int qx = 0; qx < Q1D; ++qx)
997 const double bx = Bt(dx,qx);
998 const double gx = Gt(dx,qx);
999 res += gx * GDBu[tidz][dy][qx][0] + bx * GDBu[tidz][dy][qx][1];
1008 template<
int T_D1D = 0,
int T_Q1D = 0>
static
1009 void PAConvectionApplyT3D(
const int ne,
1010 const Array<double> &b,
1011 const Array<double> &g,
1012 const Array<double> &bt,
1013 const Array<double> >,
1021 const int D1D = T_D1D ? T_D1D : d1d;
1022 const int Q1D = T_Q1D ? T_Q1D : q1d;
1023 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
1024 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
1025 auto B =
Reshape(b.Read(), Q1D, D1D);
1026 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
1027 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
1028 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
1029 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
1030 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
1033 const int D1D = T_D1D ? T_D1D : d1d;
1034 const int Q1D = T_Q1D ? T_Q1D : q1d;
1036 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
1037 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
1039 double u[max_D1D][max_D1D][max_D1D];
1040 for (
int dz = 0; dz < D1D; ++dz)
1042 for (
int dy = 0; dy < D1D; ++dy)
1044 for (
int dx = 0; dx < D1D; ++dx)
1046 u[dz][dy][dx] = x(dx,dy,dz,e);
1050 double Bu[max_D1D][max_D1D][max_Q1D];
1051 for (
int dz = 0; dz < D1D; ++dz)
1053 for (
int dy = 0; dy < D1D; ++dy)
1055 for (
int qx = 0; qx < Q1D; ++qx)
1057 Bu[dz][dy][qx] = 0.0;
1058 for (
int dx = 0; dx < D1D; ++dx)
1060 const double bx = B(qx,dx);
1061 const double x = u[dz][dy][dx];
1062 Bu[dz][dy][qx] += bx * x;
1067 double BBu[max_D1D][max_Q1D][max_Q1D];
1068 for (
int dz = 0; dz < D1D; ++dz)
1070 for (
int qx = 0; qx < Q1D; ++qx)
1072 for (
int qy = 0; qy < Q1D; ++qy)
1074 BBu[dz][qy][qx] = 0.0;
1075 for (
int dy = 0; dy < D1D; ++dy)
1077 const double bx = B(qy,dy);
1078 BBu[dz][qy][qx] += bx * Bu[dz][dy][qx];
1083 double BBBu[max_Q1D][max_Q1D][max_Q1D];
1084 for (
int qx = 0; qx < Q1D; ++qx)
1086 for (
int qy = 0; qy < Q1D; ++qy)
1088 for (
int qz = 0; qz < Q1D; ++qz)
1090 BBBu[qz][qy][qx] = 0.0;
1091 for (
int dz = 0; dz < D1D; ++dz)
1093 const double bx = B(qz,dz);
1094 BBBu[qz][qy][qx] += bx * BBu[dz][qy][qx];
1100 double DBu[max_Q1D][max_Q1D][max_Q1D][3];
1101 for (
int qz = 0; qz < Q1D; ++qz)
1103 for (
int qy = 0; qy < Q1D; ++qy)
1105 for (
int qx = 0; qx < Q1D; ++qx)
1107 const double O1 = op(qx,qy,qz,0,e);
1108 const double O2 = op(qx,qy,qz,1,e);
1109 const double O3 = op(qx,qy,qz,2,e);
1111 const double X = BBBu[qz][qy][qx];
1113 DBu[qz][qy][qx][0] = O1 * X;
1114 DBu[qz][qy][qx][1] = O2 * X;
1115 DBu[qz][qy][qx][2] = O3 * X;
1119 double GDBu[max_D1D][max_Q1D][max_Q1D][3];
1120 for (
int qx = 0; qx < Q1D; ++qx)
1122 for (
int qy = 0; qy < Q1D; ++qy)
1124 for (
int dz = 0; dz < D1D; ++dz)
1126 GDBu[dz][qy][qx][0] = 0.0;
1127 GDBu[dz][qy][qx][1] = 0.0;
1128 GDBu[dz][qy][qx][2] = 0.0;
1129 for (
int qz = 0; qz < Q1D; ++qz)
1131 const double bz = Bt(dz,qz);
1132 const double gz = Gt(dz,qz);
1133 GDBu[dz][qy][qx][0] += bz * DBu[qz][qy][qx][0];
1134 GDBu[dz][qy][qx][1] += bz * DBu[qz][qy][qx][1];
1135 GDBu[dz][qy][qx][2] += gz * DBu[qz][qy][qx][2];
1140 double GGDBu[max_D1D][max_D1D][max_Q1D][3];
1141 for (
int dz = 0; dz < D1D; ++dz)
1143 for (
int qx = 0; qx < Q1D; ++qx)
1145 for (
int dy = 0; dy < D1D; ++dy)
1147 GGDBu[dz][dy][qx][0] = 0.0;
1148 GGDBu[dz][dy][qx][1] = 0.0;
1149 GGDBu[dz][dy][qx][2] = 0.0;
1150 for (
int qy = 0; qy < Q1D; ++qy)
1152 const double by = Bt(dy,qy);
1153 const double gy = Gt(dy,qy);
1154 GGDBu[dz][dy][qx][0] += by * GDBu[dz][qy][qx][0];
1155 GGDBu[dz][dy][qx][1] += gy * GDBu[dz][qy][qx][1];
1156 GGDBu[dz][dy][qx][2] += by * GDBu[dz][qy][qx][2];
1161 for (
int dz = 0; dz < D1D; ++dz)
1163 for (
int dy = 0; dy < D1D; ++dy)
1165 for (
int dx = 0; dx < D1D; ++dx)
1168 for (
int qx = 0; qx < Q1D; ++qx)
1170 const double bx = Bt(dx,qx);
1171 const double gx = Gt(dx,qx);
1172 res += gx * GGDBu[dz][dy][qx][0];
1173 res += bx * GGDBu[dz][dy][qx][1];
1174 res += bx * GGDBu[dz][dy][qx][2];
1176 y(dx,dy,dz,e) += res;
1184 template<
int T_D1D = 0,
int T_Q1D = 0>
static
1185 void SmemPAConvectionApplyT3D(
const int ne,
1186 const Array<double> &b,
1187 const Array<double> &g,
1188 const Array<double> &bt,
1189 const Array<double> >,
1197 const int D1D = T_D1D ? T_D1D : d1d;
1198 const int Q1D = T_Q1D ? T_Q1D : q1d;
1199 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
1200 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
1201 auto B =
Reshape(b.Read(), Q1D, D1D);
1202 auto Bt =
Reshape(bt.Read(), D1D, Q1D);
1203 auto Gt =
Reshape(gt.Read(), D1D, Q1D);
1204 auto op =
Reshape(op_.Read(), Q1D, Q1D, Q1D, 3, NE);
1205 auto x =
Reshape(x_.Read(), D1D, D1D, D1D, NE);
1206 auto y =
Reshape(y_.ReadWrite(), D1D, D1D, D1D, NE);
1207 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
1209 const int D1D = T_D1D ? T_D1D : d1d;
1210 const int Q1D = T_Q1D ? T_Q1D : q1d;
1212 constexpr
int max_D1D = T_D1D ? T_D1D :
MAX_D1D;
1213 constexpr
int max_Q1D = T_Q1D ? T_Q1D :
MAX_Q1D;
1214 constexpr
int max_DQ = (max_Q1D > max_D1D) ? max_Q1D : max_D1D;
1215 MFEM_SHARED
double sm0[3*max_DQ*max_DQ*max_DQ];
1216 MFEM_SHARED
double sm1[3*max_DQ*max_DQ*max_DQ];
1218 double (*u)[max_D1D][max_D1D] = (double (*)[max_D1D][max_D1D]) sm0;
1219 MFEM_FOREACH_THREAD(dz,z,D1D)
1221 MFEM_FOREACH_THREAD(dy,y,D1D)
1223 MFEM_FOREACH_THREAD(dx,x,D1D)
1225 u[dz][dy][dx] = x(dx,dy,dz,e);
1230 double (*Bu)[max_D1D][max_Q1D] = (double (*)[max_D1D][max_Q1D])sm1;
1231 MFEM_FOREACH_THREAD(dz,z,D1D)
1233 MFEM_FOREACH_THREAD(dy,y,D1D)
1235 MFEM_FOREACH_THREAD(qx,x,Q1D)
1238 for (
int dx = 0; dx < D1D; ++dx)
1240 const double bx = B(qx,dx);
1241 const double x = u[dz][dy][dx];
1244 Bu[dz][dy][qx] = Bu_;
1249 double (*BBu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm0;
1250 MFEM_FOREACH_THREAD(dz,z,D1D)
1252 MFEM_FOREACH_THREAD(qx,x,Q1D)
1254 MFEM_FOREACH_THREAD(qy,y,Q1D)
1257 for (
int dy = 0; dy < D1D; ++dy)
1259 const double bx = B(qy,dy);
1260 BBu_ += bx * Bu[dz][dy][qx];
1262 BBu[dz][qy][qx] = BBu_;
1267 double (*BBBu)[max_Q1D][max_Q1D] = (double (*)[max_Q1D][max_Q1D])sm1;
1268 MFEM_FOREACH_THREAD(qx,x,Q1D)
1270 MFEM_FOREACH_THREAD(qy,y,Q1D)
1272 MFEM_FOREACH_THREAD(qz,z,Q1D)
1275 for (
int dz = 0; dz < D1D; ++dz)
1277 const double bx = B(qz,dz);
1278 BBBu_ += bx * BBu[dz][qy][qx];
1280 BBBu[qz][qy][qx] = BBBu_;
1285 double (*DBu)[max_Q1D][max_Q1D][3] = (double (*)[max_Q1D][max_Q1D][3])sm0;
1286 MFEM_FOREACH_THREAD(qz,z,Q1D)
1288 MFEM_FOREACH_THREAD(qy,y,Q1D)
1290 MFEM_FOREACH_THREAD(qx,x,Q1D)
1292 const double O1 = op(qx,qy,qz,0,e);
1293 const double O2 = op(qx,qy,qz,1,e);
1294 const double O3 = op(qx,qy,qz,2,e);
1296 const double X = BBBu[qz][qy][qx];
1298 DBu[qz][qy][qx][0] = O1 * X;
1299 DBu[qz][qy][qx][1] = O2 * X;
1300 DBu[qz][qy][qx][2] = O3 * X;
1305 double (*GDBu)[max_Q1D][max_Q1D][3] = (double (*)[max_Q1D][max_Q1D][3])sm1;
1306 MFEM_FOREACH_THREAD(qx,x,Q1D)
1308 MFEM_FOREACH_THREAD(qy,y,Q1D)
1310 MFEM_FOREACH_THREAD(dz,z,D1D)
1315 for (
int qz = 0; qz < Q1D; ++qz)
1317 const double bz = Bt(dz,qz);
1318 const double gz = Gt(dz,qz);
1319 GDBu0 += bz * DBu[qz][qy][qx][0];
1320 GDBu1 += bz * DBu[qz][qy][qx][1];
1321 GDBu2 += gz * DBu[qz][qy][qx][2];
1323 GDBu[dz][qy][qx][0] = GDBu0;
1324 GDBu[dz][qy][qx][1] = GDBu1;
1325 GDBu[dz][qy][qx][2] = GDBu2;
1330 double (*GGDBu)[max_D1D][max_Q1D][3] = (double (*)[max_D1D][max_Q1D][3])sm0;
1331 MFEM_FOREACH_THREAD(dz,z,D1D)
1333 MFEM_FOREACH_THREAD(qx,x,Q1D)
1335 MFEM_FOREACH_THREAD(dy,y,D1D)
1337 double GGDBu0 = 0.0;
1338 double GGDBu1 = 0.0;
1339 double GGDBu2 = 0.0;
1340 for (
int qy = 0; qy < Q1D; ++qy)
1342 const double by = Bt(dy,qy);
1343 const double gy = Gt(dy,qy);
1344 GGDBu0 += by * GDBu[dz][qy][qx][0];
1345 GGDBu1 += gy * GDBu[dz][qy][qx][1];
1346 GGDBu2 += by * GDBu[dz][qy][qx][2];
1348 GGDBu[dz][dy][qx][0] = GGDBu0;
1349 GGDBu[dz][dy][qx][1] = GGDBu1;
1350 GGDBu[dz][dy][qx][2] = GGDBu2;
1355 MFEM_FOREACH_THREAD(dz,z,D1D)
1357 MFEM_FOREACH_THREAD(dy,y,D1D)
1359 MFEM_FOREACH_THREAD(dx,x,D1D)
1362 for (
int qx = 0; qx < Q1D; ++qx)
1364 const double bx = Bt(dx,qx);
1365 const double gx = Gt(dx,qx);
1366 res += gx * GGDBu[dz][dy][qx][0];
1367 res += bx * GGDBu[dz][dy][qx][1];
1368 res += bx * GGDBu[dz][dy][qx][2];
1370 y(dx,dy,dz,e) += res;
1386 if (DeviceCanUseCeed())
1389 ceedOp =
new ceed::PAConvectionIntegrator(fes, *ir,
Q, alpha);
1392 const int dims = el.
GetDim();
1393 const int symmDims = dims;
1404 dynamic_cast<VectorConstantCoefficient*>(
Q))
1409 dynamic_cast<VectorGridFunctionCoefficient*>(
Q))
1427 qi->DisableTensorProducts(!use_tensor_products);
1431 dynamic_cast<VectorQuadratureFunctionCoefficient*>(
Q))
1434 MFEM_VERIFY(qFun.
Size() == dim *
nq *
ne,
1435 "Incompatible QuadratureFunction dimension \n");
1438 "IntegrationRule used within integrator and in"
1439 " QuadratureFunction appear to be different");
1442 vel.
MakeRef(const_cast<QuadratureFunction &>(qFun),0);
1449 for (
int e = 0; e <
ne; ++e)
1452 Q->
Eval(MQ_ir, T, *ir);
1453 for (
int q = 0; q <
nq; ++q)
1455 for (
int i = 0; i <
dim; ++i)
1457 C(i,q,e) = MQ_ir(i,q);
1466 static void PAConvectionApply(
const int dim,
1480 switch ((D1D << 4 ) | Q1D)
1482 case 0x22:
return SmemPAConvectionApply2D<2,2,8>(NE,B,G,Bt,Gt,op,x,y);
1483 case 0x33:
return SmemPAConvectionApply2D<3,3,4>(NE,B,G,Bt,Gt,op,x,y);
1484 case 0x34:
return SmemPAConvectionApply2D<3,4,4>(NE,B,G,Bt,Gt,op,x,y);
1485 case 0x44:
return SmemPAConvectionApply2D<4,4,4>(NE,B,G,Bt,Gt,op,x,y);
1486 case 0x46:
return SmemPAConvectionApply2D<4,6,4>(NE,B,G,Bt,Gt,op,x,y);
1487 case 0x55:
return SmemPAConvectionApply2D<5,5,2>(NE,B,G,Bt,Gt,op,x,y);
1488 case 0x58:
return SmemPAConvectionApply2D<5,8,2>(NE,B,G,Bt,Gt,op,x,y);
1489 case 0x66:
return SmemPAConvectionApply2D<6,6,1>(NE,B,G,Bt,Gt,op,x,y);
1490 case 0x77:
return SmemPAConvectionApply2D<7,7,1>(NE,B,G,Bt,Gt,op,x,y);
1491 case 0x88:
return SmemPAConvectionApply2D<8,8,1>(NE,B,G,Bt,Gt,op,x,y);
1492 case 0x99:
return SmemPAConvectionApply2D<9,9,1>(NE,B,G,Bt,Gt,op,x,y);
1493 default:
return PAConvectionApply2D(NE,B,G,Bt,Gt,op,x,y,D1D,Q1D);
1498 switch ((D1D << 4 ) | Q1D)
1500 case 0x23:
return SmemPAConvectionApply3D<2,3>(NE,B,G,Bt,Gt,op,x,y);
1501 case 0x24:
return SmemPAConvectionApply3D<2,4>(NE,B,G,Bt,Gt,op,x,y);
1502 case 0x26:
return SmemPAConvectionApply3D<2,6>(NE,B,G,Bt,Gt,op,x,y);
1503 case 0x34:
return SmemPAConvectionApply3D<3,4>(NE,B,G,Bt,Gt,op,x,y);
1504 case 0x35:
return SmemPAConvectionApply3D<3,5>(NE,B,G,Bt,Gt,op,x,y);
1505 case 0x45:
return SmemPAConvectionApply3D<4,5>(NE,B,G,Bt,Gt,op,x,y);
1506 case 0x48:
return SmemPAConvectionApply3D<4,8>(NE,B,G,Bt,Gt,op,x,y);
1507 case 0x56:
return SmemPAConvectionApply3D<5,6>(NE,B,G,Bt,Gt,op,x,y);
1508 case 0x67:
return SmemPAConvectionApply3D<6,7>(NE,B,G,Bt,Gt,op,x,y);
1509 case 0x78:
return SmemPAConvectionApply3D<7,8>(NE,B,G,Bt,Gt,op,x,y);
1510 case 0x89:
return SmemPAConvectionApply3D<8,9>(NE,B,G,Bt,Gt,op,x,y);
1511 default:
return PAConvectionApply3D(NE,B,G,Bt,Gt,op,x,y,D1D,Q1D);
1514 MFEM_ABORT(
"Unknown kernel.");
1517 static void PAConvectionApplyT(
const int dim,
1521 const Array<double> &B,
1522 const Array<double> &G,
1523 const Array<double> &Bt,
1524 const Array<double> &Gt,
1531 switch ((D1D << 4 ) | Q1D)
1533 case 0x22:
return SmemPAConvectionApplyT2D<2,2,8>(NE,B,G,Bt,Gt,op,x,y);
1534 case 0x33:
return SmemPAConvectionApplyT2D<3,3,4>(NE,B,G,Bt,Gt,op,x,y);
1535 case 0x34:
return SmemPAConvectionApplyT2D<3,4,4>(NE,B,G,Bt,Gt,op,x,y);
1536 case 0x44:
return SmemPAConvectionApplyT2D<4,4,4>(NE,B,G,Bt,Gt,op,x,y);
1537 case 0x46:
return SmemPAConvectionApplyT2D<4,6,4>(NE,B,G,Bt,Gt,op,x,y);
1538 case 0x55:
return SmemPAConvectionApplyT2D<5,5,2>(NE,B,G,Bt,Gt,op,x,y);
1539 case 0x58:
return SmemPAConvectionApplyT2D<5,8,2>(NE,B,G,Bt,Gt,op,x,y);
1540 case 0x66:
return SmemPAConvectionApplyT2D<6,6,1>(NE,B,G,Bt,Gt,op,x,y);
1541 case 0x77:
return SmemPAConvectionApplyT2D<7,7,1>(NE,B,G,Bt,Gt,op,x,y);
1542 case 0x88:
return SmemPAConvectionApplyT2D<8,8,1>(NE,B,G,Bt,Gt,op,x,y);
1543 case 0x99:
return SmemPAConvectionApplyT2D<9,9,1>(NE,B,G,Bt,Gt,op,x,y);
1544 default:
return PAConvectionApplyT2D(NE,B,G,Bt,Gt,op,x,y,D1D,Q1D);
1549 switch ((D1D << 4 ) | Q1D)
1551 case 0x23:
return SmemPAConvectionApplyT3D<2,3>(NE,B,G,Bt,Gt,op,x,y);
1552 case 0x24:
return SmemPAConvectionApplyT3D<2,4>(NE,B,G,Bt,Gt,op,x,y);
1553 case 0x26:
return SmemPAConvectionApplyT3D<2,6>(NE,B,G,Bt,Gt,op,x,y);
1554 case 0x34:
return SmemPAConvectionApplyT3D<3,4>(NE,B,G,Bt,Gt,op,x,y);
1555 case 0x35:
return SmemPAConvectionApplyT3D<3,5>(NE,B,G,Bt,Gt,op,x,y);
1556 case 0x45:
return SmemPAConvectionApplyT3D<4,5>(NE,B,G,Bt,Gt,op,x,y);
1557 case 0x48:
return SmemPAConvectionApplyT3D<4,8>(NE,B,G,Bt,Gt,op,x,y);
1558 case 0x56:
return SmemPAConvectionApplyT3D<5,6>(NE,B,G,Bt,Gt,op,x,y);
1559 case 0x67:
return SmemPAConvectionApplyT3D<6,7>(NE,B,G,Bt,Gt,op,x,y);
1560 case 0x78:
return SmemPAConvectionApplyT3D<7,8>(NE,B,G,Bt,Gt,op,x,y);
1561 case 0x89:
return SmemPAConvectionApplyT3D<8,9>(NE,B,G,Bt,Gt,op,x,y);
1562 default:
return PAConvectionApplyT3D(NE,B,G,Bt,Gt,op,x,y,D1D,Q1D);
1565 MFEM_ABORT(
"Unknown kernel.");
1571 if (DeviceCanUseCeed())
1586 if (DeviceCanUseCeed())
1588 MFEM_ABORT(
"AddMultPA not yet implemented with libCEED for"
1589 " ConvectionIntegrator.");
1601 if (DeviceCanUseCeed())
1603 ceedOp->GetDiagonal(diag);
1607 MFEM_ABORT(
"AssembleDiagonalPA not yet implemented for"
1608 " ConvectionIntegrator.");
int GetNPoints() const
Returns the number of the points in the integration rule.
Abstract class for all finite elements.
int GetDim() const
Returns the reference space dimension for the finite element.
Class for an integration rule - an Array of IntegrationPoint.
Class for grid function - Vector with associated FE space.
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
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.
const IntegrationRule & GetElementIntRule(int idx) const
Get the IntegrationRule associated with mesh element idx.
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
void SetSize(int s)
Resize the vector to size s.
const GeometricFactors * geom
Not owned.
Vector quadrature function coefficient which requires that the quadrature rules used for this vector ...
Vector coefficient that is constant in space and time.
Data type dense matrix using column-major storage.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
virtual double * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
int Size() const
Returns the size of the vector.
Array< double > Gt
Transpose of G.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
const Array< double > & GetWeights() const
Return the quadrature weights in a contiguous array.
bool UsesTensorBasis(const FiniteElementSpace &fes)
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
virtual void AssembleDiagonalPA(Vector &diag)
Assemble diagonal and add it to Vector diag.
const Operator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims...dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
int GetNE() const
Returns number of elements in the mesh.
Vector J
Jacobians of the element transformations at all quadrature points.
Native ordering as defined by the FiniteElement.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Mesh * GetMesh() const
Returns the mesh.
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
QuadratureSpace * GetSpace() const
Get the associated QuadratureSpace.
FiniteElementSpace * FESpace()
virtual void AddMultPA(const Vector &, Vector &) const
Method for partially assembled action.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
Array< double > Bt
Transpose of B.
virtual void AssemblePA(const FiniteElementSpace &)
Method defining partial assembly.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
MemoryType
Memory types supported by MFEM.
static const IntegrationRule & GetRule(const FiniteElement &el, ElementTransformation &Trans)
Array< double > B
Basis functions evaluated at quadrature points.
virtual void AddMultTransposePA(const Vector &x, Vector &y) const
Method for partially assembled transposed action.
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...
void vel(const Vector &x, double t, Vector &u)
const QuadratureInterpolator * GetQuadratureInterpolator(const IntegrationRule &ir) const
Return a QuadratureInterpolator that interpolates E-vectors to quadrature point values and/or derivat...
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
Array< double > G
Gradients/divergences/curls of basis functions 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...
Lexicographic ordering for tensor-product FiniteElements.
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
Vector coefficient defined by a vector GridFunction.
double u(const Vector &xvec)
Class representing a function through its values (scalar or vector) at quadrature points...
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
VDIM x NQPT x NE (values) / VDIM x DIM x NQPT x NE (grads)
const DofToQuad * maps
Not owned.