24static MFEM_HOST_DEVICE 
inline 
   25void EvalH_001(
const int e, 
const int qx, 
const int qy,
 
   29   constexpr int DIM = 2;
 
   32   for (
int i = 0; i < 
DIM; i++)
 
   34      for (
int j = 0; j < 
DIM; j++)
 
   37         for (
int r = 0; r < 
DIM; r++)
 
   39            for (
int c = 0; c < 
DIM; c++)
 
   41               const real_t h = ddi1(r,c);
 
   42               H(r,c,i,j,qx,qy,e) = weight * h;
 
   50static MFEM_HOST_DEVICE 
inline 
   51void EvalH_002(
const int e, 
const int qx, 
const int qy,
 
   53               DeviceTensor<7,real_t> H)
 
   55   constexpr int DIM = 2;
 
   56   real_t ddI1[4], ddI1b[4], dI2b[4];
 
   57   kernels::InvariantsEvaluator2D ie(
Args()
 
   62   const real_t w = 0.5 * weight;
 
   63   for (
int i = 0; i < 
DIM; i++)
 
   65      for (
int j = 0; j < 
DIM; j++)
 
   68         for (
int r = 0; r < 
DIM; r++)
 
   70            for (
int c = 0; c < 
DIM; c++)
 
   72               const real_t h = ddi1b(r,c);
 
   73               H(r,c,i,j,qx,qy,e) = w * h;
 
   80static MFEM_HOST_DEVICE 
inline 
   81void EvalH_007(
const int e, 
const int qx, 
const int qy,
 
   83               DeviceTensor<7,real_t> H)
 
   85   constexpr int DIM = 2;
 
   86   real_t ddI1[4], ddI2[4], dI1[4], dI2[4], dI2b[4];
 
   87   kernels::InvariantsEvaluator2D ie(
Args()
 
   94   const real_t c1 = 1./ie.Get_I2();
 
   95   const real_t c2 = weight*c1*c1;
 
   96   const real_t c3 = ie.Get_I1()*c2;
 
  100   for (
int i = 0; i < 
DIM; i++)
 
  102      for (
int j = 0; j < 
DIM; j++)
 
  106         for (
int r = 0; r < 
DIM; r++)
 
  108            for (
int c = 0; c < 
DIM; c++)
 
  111                  weight * (1.0 + c1) * ddi1(r,c)
 
  113                  - c2 * ( di1(i,j) * di2(r,c) + di2(i,j) * di1(r,c) )
 
  114                  + 2.0 * c1 * c3 * di2(r,c) * di2(i,j);
 
  122static MFEM_HOST_DEVICE 
inline 
  123void EvalH_056(
const int e, 
const int qx, 
const int qy,
 
  125               DeviceTensor<7,real_t> H)
 
  127   constexpr int DIM = 2;
 
  129   kernels::InvariantsEvaluator2D ie(
Args().J(Jpt)
 
  132   const real_t I2b = ie.Get_I2b();
 
  134   for (
int i = 0; i < 
DIM; i++)
 
  136      for (
int j = 0; j < 
DIM; j++)
 
  139         for (
int r = 0; r < 
DIM; r++)
 
  141            for (
int c = 0; c < 
DIM; c++)
 
  144                  weight * (0.5 - 0.5/(I2b*I2b)) * ddi2b(r,c) +
 
  145                  weight / (I2b*I2b*I2b) * di2b(r,c) * di2b(i,j);
 
  152static MFEM_HOST_DEVICE 
inline 
  153void EvalH_077(
const int e, 
const int qx, 
const int qy,
 
  155               DeviceTensor<7,real_t> H)
 
  157   constexpr int DIM = 2;
 
  158   real_t dI2[4], dI2b[4], ddI2[4];
 
  159   kernels::InvariantsEvaluator2D ie(
Args()
 
  164   const real_t I2 = ie.Get_I2(), I2inv_sq = 1.0 / (I2 * I2);
 
  166   for (
int i = 0; i < 
DIM; i++)
 
  168      for (
int j = 0; j < 
DIM; j++)
 
  171         for (
int r = 0; r < 
DIM; r++)
 
  173            for (
int c = 0; c < 
DIM; c++)
 
  176                  weight * 0.5 * (1.0 - I2inv_sq) * ddi2(r,c)
 
  177                  + weight * (I2inv_sq / I2) * di2(r,c) * di2(i,j);
 
  185static MFEM_HOST_DEVICE 
inline 
  186void EvalH_080(
const int e, 
const int qx, 
const int qy,
 
  188               DeviceTensor<7,real_t> H)
 
  190   constexpr int DIM = 2;
 
  191   real_t ddI1[4], ddI1b[4], dI2[4], dI2b[4], ddI2[4];
 
  192   kernels::InvariantsEvaluator2D ie(
Args()
 
  200   const real_t I2 = ie.Get_I2(), I2inv_sq = 1.0 / (I2 * I2);
 
  202   for (
int i = 0; i < 
DIM; i++)
 
  204      for (
int j = 0; j < 
DIM; j++)
 
  208         for (
int r = 0; r < 
DIM; r++)
 
  210            for (
int c = 0; c < 
DIM; c++)
 
  213                  w[0] * 0.5 * weight * ddi1b(r,c) +
 
  214                  w[1] * ( weight * 0.5 * (1.0 - I2inv_sq) * ddi2(r,c) +
 
  215                           weight * (I2inv_sq / I2) * di2(r,c) * di2(i,j) );
 
  223static MFEM_HOST_DEVICE 
inline 
  224void EvalH_094(
const int e, 
const int qx, 
const int qy,
 
  226               DeviceTensor<7,real_t> H)
 
  228   constexpr int DIM = 2;
 
  229   real_t ddI1[4], ddI1b[4], dI2b[4], ddI2b[4];
 
  230   kernels::InvariantsEvaluator2D ie(
Args().J(Jpt)
 
  236   const real_t I2b = ie.Get_I2b();
 
  238   for (
int i = 0; i < 
DIM; i++)
 
  240      for (
int j = 0; j < 
DIM; j++)
 
  244         for (
int r = 0; r < 
DIM; r++)
 
  246            for (
int c = 0; c < 
DIM; c++)
 
  249                  w[0] * 0.5 * weight * ddi1b(r,c) +
 
  250                  w[1] * ( weight * (0.5 - 0.5/(I2b*I2b)) * ddi2b(r,c) +
 
  251                           weight / (I2b*I2b*I2b) * di2b(r,c) * di2b(i,j) );
 
  260                           const real_t metric_normal,
 
  273   MFEM_VERIFY(mid == 1 || mid == 2 || mid == 7 || mid == 77
 
  274               || mid == 80 || mid == 94,
 
  275               "2D metric not yet implemented!");
 
  277   const bool const_m0 = mc_.
Size() == 1;
 
  279   constexpr int DIM = 2;
 
  280   constexpr int NBZ = 1;
 
  281   const int D1D = T_D1D ? T_D1D : d1d;
 
  282   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  284   const auto MC = const_m0 ?
 
  294   const real_t *metric_data = metric_param.
Read();
 
  298      const int D1D = T_D1D ? T_D1D : d1d;
 
  299      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  300      constexpr int NBZ = 1;
 
  301      constexpr int MQ1 = T_Q1D ? T_Q1D : T_MAX;
 
  302      constexpr int MD1 = T_D1D ? T_D1D : T_MAX;
 
  304      MFEM_SHARED 
real_t s_BG[2][MQ1*MD1];
 
  305      MFEM_SHARED 
real_t s_X[2][NBZ][MD1*MD1];
 
  306      MFEM_SHARED 
real_t s_DQ[4][NBZ][MD1*MQ1];
 
  307      MFEM_SHARED 
real_t s_QQ[4][NBZ][MQ1*MQ1];
 
  309      kernels::internal::LoadX<MD1,NBZ>(e,D1D,X,s_X);
 
  310      kernels::internal::LoadBG<MD1,MQ1>(D1D, Q1D, 
b, g, s_BG);
 
  312      kernels::internal::GradX<MD1,MQ1,NBZ>(D1D, Q1D, s_BG, s_X, s_DQ);
 
  313      kernels::internal::GradY<MD1,MQ1,NBZ>(D1D, Q1D, s_BG, s_DQ, s_QQ);
 
  315      MFEM_FOREACH_THREAD(qy,y,Q1D)
 
  317         MFEM_FOREACH_THREAD(qx,x,Q1D)
 
  319            const real_t *Jtr = &J(0,0,qx,qy,e);
 
  321            const real_t m_coef = const_m0 ? MC(0,0,0) : MC(qx,qy,e);
 
  322            const real_t weight = metric_normal * m_coef * W(qx,qy) * detJtr;
 
  330            kernels::internal::PullGrad<MQ1,NBZ>(Q1D,qx,qy,s_QQ,Jpr);
 
  337            if (mid ==  1) { EvalH_001(e,qx,qy,weight,Jpt,H); }
 
  338            if (mid ==  2) { EvalH_002(e,qx,qy,weight,Jpt,H); }
 
  339            if (mid ==  7) { EvalH_007(e,qx,qy,weight,Jpt,H); }
 
  340            if (mid == 77) { EvalH_077(e,qx,qy,weight,Jpt,H); }
 
  341            if (mid == 56) { EvalH_056(e,qx,qy,weight,Jpt,H); }
 
  342            if (mid == 80) { EvalH_080(e,qx,qy,weight,metric_data,Jpt,H); }
 
  343            if (mid == 94) { EvalH_094(e,qx,qy,weight,metric_data,Jpt,H); }
 
 
  353   const int D1D = 
PA.maps->ndof;
 
  354   const int Q1D = 
PA.maps->nqpt;
 
  355   const int id = (D1D << 4 ) | Q1D;
 
  370   MFEM_LAUNCH_TMOP_KERNEL(SetupGradPA_2D,
id,X,mn,
MC,mp,M,N,W,B,G,J,
H);
 
 
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Rank 3 tensor (array of matrices)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
A basic generic Tensor class, appropriate for use on the GPU.
TMOP_QualityMetric * metric
void AssembleGradPA_2D(const Vector &) const
struct mfem::TMOP_Integrator::@26 PA
virtual int Id() const
Return the metric ID.
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
int Size() const
Returns the size of the vector.
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
MFEM_HOST_DEVICE real_t * Get_ddI1(int i, int j)
MFEM_HOST_DEVICE void CalcInverse(const T *data, T *inv_data)
Return the inverse of a matrix with given size and data into the matrix with data inv_data.
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 T Det(const T *data)
Compute the determinant of a square matrix of size dim with given data.
MFEM_REGISTER_TMOP_KERNELS(void, DatcSize, const int NE, const int ncomp, const int sizeidx, const real_t input_min_size, const DenseMatrix &w_, const Array< real_t > &b_, const Vector &x_, const Vector &nc_reduce, DenseTensor &j_, const int d1d, const int q1d)
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_2D_batch(int N, int X, int Y, int BZ, lambda &&body)
DeviceTensor< 2, const real_t > ConstDeviceMatrix
kernels::InvariantsEvaluator2D::Buffers Args