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