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;
778 if (DeviceCanUseCeed())
781 ceedOp =
new ceed::PAConvectionIntegrator(fes, *ir,
Q, alpha);
784 const int dims = el.
GetDim();
785 const int symmDims = dims;
796 dynamic_cast<VectorConstantCoefficient*>(
Q))
801 dynamic_cast<VectorGridFunctionCoefficient*>(
Q))
803 vel.
SetSize(dim * nq * ne, mt);
819 qi->DisableTensorProducts(!use_tensor_products);
823 dynamic_cast<VectorQuadratureFunctionCoefficient*>(
Q))
826 MFEM_VERIFY(qFun.
Size() == dim * nq *
ne,
827 "Incompatible QuadratureFunction dimension \n");
830 "IntegrationRule used within integrator and in"
831 " QuadratureFunction appear to be different");
834 vel.
MakeRef(const_cast<QuadratureFunction &>(qFun),0);
841 for (
int e = 0; e <
ne; ++e)
844 Q->
Eval(Q_ir, T, *ir);
845 for (
int q = 0; q <
nq; ++q)
847 for (
int i = 0; i <
dim; ++i)
849 C(i,q,e) = Q_ir(i,q);
858 static void PAConvectionApply(
const int dim,
872 switch ((D1D << 4 ) | Q1D)
874 case 0x22:
return SmemPAConvectionApply2D<2,2,8>(NE,B,G,Bt,Gt,op,x,y);
875 case 0x33:
return SmemPAConvectionApply2D<3,3,4>(NE,B,G,Bt,Gt,op,x,y);
876 case 0x34:
return SmemPAConvectionApply2D<3,4,4>(NE,B,G,Bt,Gt,op,x,y);
877 case 0x44:
return SmemPAConvectionApply2D<4,4,4>(NE,B,G,Bt,Gt,op,x,y);
878 case 0x46:
return SmemPAConvectionApply2D<4,6,4>(NE,B,G,Bt,Gt,op,x,y);
879 case 0x55:
return SmemPAConvectionApply2D<5,5,2>(NE,B,G,Bt,Gt,op,x,y);
880 case 0x58:
return SmemPAConvectionApply2D<5,8,2>(NE,B,G,Bt,Gt,op,x,y);
881 case 0x66:
return SmemPAConvectionApply2D<6,6,1>(NE,B,G,Bt,Gt,op,x,y);
882 case 0x77:
return SmemPAConvectionApply2D<7,7,1>(NE,B,G,Bt,Gt,op,x,y);
883 case 0x88:
return SmemPAConvectionApply2D<8,8,1>(NE,B,G,Bt,Gt,op,x,y);
884 case 0x99:
return SmemPAConvectionApply2D<9,9,1>(NE,B,G,Bt,Gt,op,x,y);
885 default:
return PAConvectionApply2D(NE,B,G,Bt,Gt,op,x,y,D1D,Q1D);
890 switch ((D1D << 4 ) | Q1D)
892 case 0x23:
return SmemPAConvectionApply3D<2,3>(NE,B,G,Bt,Gt,op,x,y);
893 case 0x24:
return SmemPAConvectionApply3D<2,4>(NE,B,G,Bt,Gt,op,x,y);
894 case 0x26:
return SmemPAConvectionApply3D<2,6>(NE,B,G,Bt,Gt,op,x,y);
895 case 0x34:
return SmemPAConvectionApply3D<3,4>(NE,B,G,Bt,Gt,op,x,y);
896 case 0x35:
return SmemPAConvectionApply3D<3,5>(NE,B,G,Bt,Gt,op,x,y);
897 case 0x45:
return SmemPAConvectionApply3D<4,5>(NE,B,G,Bt,Gt,op,x,y);
898 case 0x48:
return SmemPAConvectionApply3D<4,8>(NE,B,G,Bt,Gt,op,x,y);
899 case 0x56:
return SmemPAConvectionApply3D<5,6>(NE,B,G,Bt,Gt,op,x,y);
900 case 0x67:
return SmemPAConvectionApply3D<6,7>(NE,B,G,Bt,Gt,op,x,y);
901 case 0x78:
return SmemPAConvectionApply3D<7,8>(NE,B,G,Bt,Gt,op,x,y);
902 case 0x89:
return SmemPAConvectionApply3D<8,9>(NE,B,G,Bt,Gt,op,x,y);
903 default:
return PAConvectionApply3D(NE,B,G,Bt,Gt,op,x,y,D1D,Q1D);
906 MFEM_ABORT(
"Unknown kernel.");
912 if (DeviceCanUseCeed())
926 if (DeviceCanUseCeed())
928 ceedOp->GetDiagonal(diag);
932 MFEM_ABORT(
"AssembleDiagonalPA not yet implemented for"
933 " 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 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.