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
struct mfem::TMOP_Integrator::@23 PA
void AssembleGradPA_2D(const Vector &) const
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