15#ifndef MFEM_QUADINTERP_EVAL_HDIV_HPP
16#define MFEM_QUADINTERP_EVAL_HDIV_HPP
28namespace quadrature_interpolator
33template<QVectorLayout Q_LAYOUT,
unsigned FLAGS,
int T_D1D = 0,
int T_Q1D = 0>
34inline void EvalHDiv2D(
const int NE,
43 static constexpr int DIM = 2;
45 const int D1D = T_D1D ? T_D1D : d1d;
46 const int Q1D = T_Q1D ? T_Q1D : q1d;
47 const int M1D = (Q1D > D1D) ? Q1D : D1D;
49 const auto bo =
Reshape(Bo_, Q1D, D1D-1);
50 const auto bc =
Reshape(Bc_, Q1D, D1D);
53 const auto x =
Reshape(x_, D1D*(D1D-1),
DIM, NE);
63 const int tidz = MFEM_THREAD_ID(z);
65 const int D1D = T_D1D ? T_D1D : d1d;
66 const int Q1D = T_Q1D ? T_Q1D : q1d;
67 const int M1D = (Q1D > D1D) ? Q1D : D1D;
69 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
70 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
71 constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
73 MFEM_SHARED
real_t smo[MQ1*(MD1-1)];
76 MFEM_SHARED
real_t smc[MQ1*MD1];
86 MFEM_FOREACH_THREAD(vd,z,
DIM)
88 MFEM_FOREACH_THREAD(dy,y,D1D)
90 MFEM_FOREACH_THREAD(qx,x,M1D)
92 if (qx < D1D && dy < (D1D-1))
94 X(qx + dy*D1D,vd) = x(qx+dy*D1D,vd,e);
96 if (tidz == 0 && qx < Q1D)
98 if (dy < (D1D-1)) { Bo(dy,qx) = bo(qx,dy); }
99 Bc(dy,qx) = bc(qx,dy);
106 MFEM_FOREACH_THREAD(vd,z,
DIM)
108 const int nx = (vd == 0) ? D1D : D1D-1;
109 const int ny = (vd == 1) ? D1D : D1D-1;
112 MFEM_FOREACH_THREAD(dy,y,ny)
114 MFEM_FOREACH_THREAD(qx,x,Q1D)
117 for (
int dx = 0; dx < nx; ++dx)
119 dq += Xxy(dx,dy,vd) * Bx(dx,qx);
126 MFEM_FOREACH_THREAD(vd,z,
DIM)
128 const int ny = (vd == 1) ? D1D : D1D-1;
130 MFEM_FOREACH_THREAD(qy,y,Q1D)
132 MFEM_FOREACH_THREAD(qx,x,Q1D)
135 for (
int dy = 0; dy < ny; ++dy)
137 qq += QD(qx,dy,vd) * By(dy,qy);
161 MFEM_FOREACH_THREAD(qy,y,Q1D)
163 MFEM_FOREACH_THREAD(qx,x,Q1D)
169 for (
int d = 0; d <
DIM; d++)
171 u_ref[d] = QQ(qx,qy,d);
173 for (
int sd = 0; sd <
DIM; sd++)
175 J_loc[sd+
DIM*d] = J(qx,qy,sd,d,e);
184 for (
int sd = 0; sd <
DIM; sd++)
188 y(qx,qy,sd,e) = u_phys[sd];
192 y(sd,qx,qy,e) = u_phys[sd];
210template<QVectorLayout Q_LAYOUT,
unsigned FLAGS,
int T_D1D = 0,
int T_Q1D = 0>
211inline void EvalHDiv3D(
const int NE,
220 static constexpr int DIM = 3;
222 const int D1D = T_D1D ? T_D1D : d1d;
223 const int Q1D = T_Q1D ? T_Q1D : q1d;
225 const auto bo =
Reshape(Bo_, Q1D, D1D-1);
226 const auto bc =
Reshape(Bc_, Q1D, D1D);
229 const auto x =
Reshape(x_, D1D*(D1D-1)*(D1D-1),
DIM, NE);
235 Reshape(y_, Q1D, Q1D, Q1D, 1, NE);
239 const int tidz = MFEM_THREAD_ID(z);
241 const int D1D = T_D1D ? T_D1D : d1d;
242 const int Q1D = T_Q1D ? T_Q1D : q1d;
244 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
245 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
246 constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
248 MFEM_SHARED
real_t smo[MQ1*(MD1-1)];
251 MFEM_SHARED
real_t smc[MQ1*MD1];
257 DeviceTensor<4> QDD(sm1, Q1D, D1D, D1D,
DIM);
258 DeviceTensor<4> QQD(sm0, Q1D, Q1D, D1D,
DIM);
259 DeviceTensor<4> QQQ(sm1, Q1D, Q1D, Q1D,
DIM);
262 MFEM_FOREACH_THREAD(vd,z,
DIM)
264 MFEM_FOREACH_THREAD(dz,y,D1D-1)
266 MFEM_FOREACH_THREAD(dy,x,D1D-1)
269 for (
int dx = 0; dx < D1D; ++dx)
271 X(dx+(dy+dz*(D1D-1))*D1D,vd) = x(dx+(dy+dz*(D1D-1))*D1D,vd,e);
279 MFEM_FOREACH_THREAD(d,y,D1D-1)
281 MFEM_FOREACH_THREAD(q,x,Q1D)
286 MFEM_FOREACH_THREAD(d,y,D1D)
288 MFEM_FOREACH_THREAD(q,x,Q1D)
296 MFEM_FOREACH_THREAD(vd,z,
DIM)
298 const int nx = (vd == 0) ? D1D : D1D-1;
299 const int ny = (vd == 1) ? D1D : D1D-1;
300 const int nz = (vd == 2) ? D1D : D1D-1;
301 DeviceTensor<4> Xxyz(X, nx, ny, nz,
DIM);
303 MFEM_FOREACH_THREAD(dy,y,ny)
305 MFEM_FOREACH_THREAD(qx,x,Q1D)
309 for (
int dz = 0; dz < nz; ++dz) {
u[dz] = 0.0; }
311 for (
int dx = 0; dx < nx; ++dx)
314 for (
int dz = 0; dz < nz; ++dz)
316 u[dz] += Xxyz(dx,dy,dz,vd) * Bx(dx,qx);
320 for (
int dz = 0; dz < nz; ++dz) { QDD(qx,dy,dz,vd) =
u[dz]; }
325 MFEM_FOREACH_THREAD(vd,z,
DIM)
327 const int ny = (vd == 1) ? D1D : D1D-1;
328 const int nz = (vd == 2) ? D1D : D1D-1;
330 MFEM_FOREACH_THREAD(qy,y,Q1D)
332 MFEM_FOREACH_THREAD(qx,x,Q1D)
336 for (
int dz = 0; dz < nz; ++dz) {
u[dz] = 0.0; }
338 for (
int dy = 0; dy < ny; ++dy)
341 for (
int dz = 0; dz < nz; ++dz)
343 u[dz] += QDD(qx,dy,dz,vd) * By(dy,qy);
347 for (
int dz = 0; dz < nz; ++dz) { QQD(qx,qy,dz,vd) =
u[dz]; }
352 MFEM_FOREACH_THREAD(vd,z,
DIM)
354 const int nz = (vd == 2) ? D1D : D1D-1;
356 MFEM_FOREACH_THREAD(qy,y,Q1D)
358 MFEM_FOREACH_THREAD(qx,x,Q1D)
362 for (
int qz = 0; qz < Q1D; ++qz) {
u[qz] = 0.0; }
364 for (
int dz = 0; dz < nz; ++dz)
367 for (
int qz = 0; qz < Q1D; ++qz)
369 u[qz] += QQD(qx,qy,dz,vd) * Bz(dz,qz);
373 for (
int qz = 0; qz < Q1D; ++qz)
378 QQQ(qx,qy,qz,vd) =
u[qz];
382 y(qx,qy,qz,vd,e) =
u[qz];
386 y(vd,qx,qy,qz,e) =
u[qz];
396 MFEM_FOREACH_THREAD(qz,z,Q1D)
398 MFEM_FOREACH_THREAD(qy,y,Q1D)
400 MFEM_FOREACH_THREAD(qx,x,Q1D)
406 for (
int d = 0; d <
DIM; d++)
408 u_ref[d] = QQQ(qx,qy,qz,d);
410 for (
int sd = 0; sd <
DIM; sd++)
412 J_loc[sd+
DIM*d] = J(qx,qy,qz,sd,d,e);
421 for (
int sd = 0; sd <
DIM; sd++)
425 y(qx,qy,qz,sd,e) = u_phys[sd];
429 y(sd,qx,qy,qz,e) = u_phys[sd];
450template<
int DIM, QVectorLayout Q_LAYOUT,
unsigned FLAGS,
int D1D,
int Q1D>
452QuadratureInterpolator::TensorEvalHDivKernels::Kernel()
454 using namespace internal::quadrature_interpolator;
455 static_assert(
DIM == 2 ||
DIM == 3,
"only DIM=2 and DIM=3 are implemented!");
456 if (
DIM == 2) {
return EvalHDiv2D<Q_LAYOUT, FLAGS, D1D, Q1D>; }
457 return EvalHDiv3D<Q_LAYOUT, FLAGS, D1D, Q1D>;
@ VALUES
Evaluate the values at quadrature points.
void(*)(const int, const real_t *, const real_t *, const real_t *, const real_t *, real_t *, const int, const int) TensorEvalHDivKernelType
MFEM_HOST_DEVICE void Mult(const int height, const int width, const TA *data, const TX *x, TY *y)
Matrix vector multiplication: y = A x, where the matrix A is of size height x width with given data,...
MFEM_HOST_DEVICE real_t Norml2(const int size, const T *data)
Returns the l2 norm of the Vector with given size and data.
MFEM_HOST_DEVICE void Set(const int height, const int width, const real_t alpha, const TA *Adata, TB *Bdata)
Compute B = alpha*A, where the matrices A and B are of size height x width with data Adata and Bdata.
MFEM_HOST_DEVICE T Det(const T *data)
Compute the determinant of a square matrix of size dim with given data.
DeviceTensor< 3, real_t > DeviceCube
real_t u(const Vector &xvec)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
DeviceTensor< 2, real_t > DeviceMatrix