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;
48 const auto bo =
Reshape(Bo_, Q1D, D1D-1);
49 const auto bc =
Reshape(Bc_, Q1D, D1D);
52 const auto x =
Reshape(x_, D1D*(D1D-1),
DIM, NE);
62 const int tidz = MFEM_THREAD_ID(z);
64 const int D1D = T_D1D ? T_D1D : d1d;
65 const int Q1D = T_Q1D ? T_Q1D : q1d;
67 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
68 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
69 constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
71 MFEM_SHARED
real_t smo[MQ1*(MD1-1)];
74 MFEM_SHARED
real_t smc[MQ1*MD1];
84 MFEM_FOREACH_THREAD(vd,z,
DIM)
86 MFEM_FOREACH_THREAD(dy,y,D1D)
88 MFEM_FOREACH_THREAD(qx,x,Q1D)
90 if (qx < D1D && dy < (D1D-1))
92 X(qx + dy*D1D,vd) = x(qx+dy*D1D,vd,e);
96 if (dy < (D1D-1)) { Bo(dy,qx) = bo(qx,dy); }
97 Bc(dy,qx) = bc(qx,dy);
104 MFEM_FOREACH_THREAD(vd,z,
DIM)
106 const int nx = (vd == 0) ? D1D : D1D-1;
107 const int ny = (vd == 1) ? D1D : D1D-1;
110 MFEM_FOREACH_THREAD(dy,y,ny)
112 MFEM_FOREACH_THREAD(qx,x,Q1D)
115 for (
int dx = 0; dx < nx; ++dx)
117 dq += Xxy(dx,dy,vd) * Bx(dx,qx);
124 MFEM_FOREACH_THREAD(vd,z,
DIM)
126 const int ny = (vd == 1) ? D1D : D1D-1;
128 MFEM_FOREACH_THREAD(qy,y,Q1D)
130 MFEM_FOREACH_THREAD(qx,x,Q1D)
133 for (
int dy = 0; dy < ny; ++dy)
135 qq += QD(qx,dy,vd) * By(dy,qy);
159 MFEM_FOREACH_THREAD(qy,y,Q1D)
161 MFEM_FOREACH_THREAD(qx,x,Q1D)
167 for (
int d = 0; d <
DIM; d++)
169 u_ref[d] = QQ(qx,qy,d);
171 for (
int sd = 0; sd <
DIM; sd++)
173 J_loc[sd+
DIM*d] = J(qx,qy,sd,d,e);
182 for (
int sd = 0; sd <
DIM; sd++)
186 y(qx,qy,sd,e) = u_phys[sd];
190 y(sd,qx,qy,e) = u_phys[sd];
208template<QVectorLayout Q_LAYOUT,
unsigned FLAGS,
int T_D1D = 0,
int T_Q1D = 0>
209inline void EvalHDiv3D(
const int NE,
218 static constexpr int DIM = 3;
220 const int D1D = T_D1D ? T_D1D : d1d;
221 const int Q1D = T_Q1D ? T_Q1D : q1d;
223 const auto bo =
Reshape(Bo_, Q1D, D1D-1);
224 const auto bc =
Reshape(Bc_, Q1D, D1D);
227 const auto x =
Reshape(x_, D1D*(D1D-1)*(D1D-1),
DIM, NE);
233 Reshape(y_, Q1D, Q1D, Q1D, 1, NE);
237 const int tidz = MFEM_THREAD_ID(z);
239 const int D1D = T_D1D ? T_D1D : d1d;
240 const int Q1D = T_Q1D ? T_Q1D : q1d;
242 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::HDIV_MAX_Q1D;
243 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::HDIV_MAX_D1D;
244 constexpr int MDQ = (MQ1 > MD1) ? MQ1 : MD1;
246 MFEM_SHARED
real_t smo[MQ1*(MD1-1)];
249 MFEM_SHARED
real_t smc[MQ1*MD1];
255 DeviceTensor<4> QDD(sm1, Q1D, D1D, D1D,
DIM);
256 DeviceTensor<4> QQD(sm0, Q1D, Q1D, D1D,
DIM);
257 DeviceTensor<4> QQQ(sm1, Q1D, Q1D, Q1D,
DIM);
260 MFEM_FOREACH_THREAD(vd,z,
DIM)
262 MFEM_FOREACH_THREAD(dz,y,D1D-1)
264 MFEM_FOREACH_THREAD(dy,x,D1D-1)
267 for (
int dx = 0; dx < D1D; ++dx)
269 X(dx+(dy+dz*(D1D-1))*D1D,vd) = x(dx+(dy+dz*(D1D-1))*D1D,vd,e);
277 MFEM_FOREACH_THREAD(d,y,D1D-1)
279 MFEM_FOREACH_THREAD(q,x,Q1D)
284 MFEM_FOREACH_THREAD(d,y,D1D)
286 MFEM_FOREACH_THREAD(q,x,Q1D)
294 MFEM_FOREACH_THREAD(vd,z,
DIM)
296 const int nx = (vd == 0) ? D1D : D1D-1;
297 const int ny = (vd == 1) ? D1D : D1D-1;
298 const int nz = (vd == 2) ? D1D : D1D-1;
299 DeviceTensor<4> Xxyz(X, nx, ny, nz,
DIM);
301 MFEM_FOREACH_THREAD(dy,y,ny)
303 MFEM_FOREACH_THREAD(qx,x,Q1D)
307 for (
int dz = 0; dz < nz; ++dz) {
u[dz] = 0.0; }
309 for (
int dx = 0; dx < nx; ++dx)
312 for (
int dz = 0; dz < nz; ++dz)
314 u[dz] += Xxyz(dx,dy,dz,vd) * Bx(dx,qx);
318 for (
int dz = 0; dz < nz; ++dz) { QDD(qx,dy,dz,vd) =
u[dz]; }
323 MFEM_FOREACH_THREAD(vd,z,
DIM)
325 const int ny = (vd == 1) ? D1D : D1D-1;
326 const int nz = (vd == 2) ? D1D : D1D-1;
328 MFEM_FOREACH_THREAD(qy,y,Q1D)
330 MFEM_FOREACH_THREAD(qx,x,Q1D)
334 for (
int dz = 0; dz < nz; ++dz) {
u[dz] = 0.0; }
336 for (
int dy = 0; dy < ny; ++dy)
339 for (
int dz = 0; dz < nz; ++dz)
341 u[dz] += QDD(qx,dy,dz,vd) * By(dy,qy);
345 for (
int dz = 0; dz < nz; ++dz) { QQD(qx,qy,dz,vd) =
u[dz]; }
350 MFEM_FOREACH_THREAD(vd,z,
DIM)
352 const int nz = (vd == 2) ? D1D : D1D-1;
354 MFEM_FOREACH_THREAD(qy,y,Q1D)
356 MFEM_FOREACH_THREAD(qx,x,Q1D)
360 for (
int qz = 0; qz < Q1D; ++qz) {
u[qz] = 0.0; }
362 for (
int dz = 0; dz < nz; ++dz)
365 for (
int qz = 0; qz < Q1D; ++qz)
367 u[qz] += QQD(qx,qy,dz,vd) * Bz(dz,qz);
371 for (
int qz = 0; qz < Q1D; ++qz)
376 QQQ(qx,qy,qz,vd) =
u[qz];
380 y(qx,qy,qz,vd,e) =
u[qz];
384 y(vd,qx,qy,qz,e) =
u[qz];
394 MFEM_FOREACH_THREAD(qz,z,Q1D)
396 MFEM_FOREACH_THREAD(qy,y,Q1D)
398 MFEM_FOREACH_THREAD(qx,x,Q1D)
404 for (
int d = 0; d <
DIM; d++)
406 u_ref[d] = QQQ(qx,qy,qz,d);
408 for (
int sd = 0; sd <
DIM; sd++)
410 J_loc[sd+
DIM*d] = J(qx,qy,qz,sd,d,e);
419 for (
int sd = 0; sd <
DIM; sd++)
423 y(qx,qy,qz,sd,e) = u_phys[sd];
427 y(sd,qx,qy,qz,e) = u_phys[sd];
448template<
int DIM, QVectorLayout Q_LAYOUT,
unsigned FLAGS,
int D1D,
int Q1D>
450QuadratureInterpolator::TensorEvalHDivKernels::Kernel()
452 using namespace internal::quadrature_interpolator;
453 static_assert(
DIM == 2 ||
DIM == 3,
"only DIM=2 and DIM=3 are implemented!");
454 if (
DIM == 2) {
return EvalHDiv2D<Q_LAYOUT, FLAGS, D1D, Q1D>; }
455 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.
real_t u(const Vector &xvec)
DeviceTensor< 2, real_t > DeviceMatrix
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< 3, real_t > DeviceCube