12 #include "../tmop.hpp" 14 #include "../../general/forall.hpp" 15 #include "../../linalg/kernels.hpp" 16 #include "../../linalg/dinvariants.hpp" 24 static MFEM_HOST_DEVICE
inline 25 void EvalH_001(
const int e,
const int qx,
const int qy,
26 const double weight,
const double *Jpt,
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 double h = ddi1(r,c);
42 H(r,c,i,j,qx,qy,e) = weight * h;
50 static MFEM_HOST_DEVICE
inline 51 void EvalH_002(
const int e,
const int qx,
const int qy,
52 const double weight,
const double *Jpt,
53 DeviceTensor<7,double> H)
55 constexpr
int DIM = 2;
56 double ddI1[4], ddI1b[4], dI2b[4];
57 kernels::InvariantsEvaluator2D ie(
Args()
62 const double 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 double h = ddi1b(r,c);
73 H(r,c,i,j,qx,qy,e) = w * h;
80 static MFEM_HOST_DEVICE
inline 81 void EvalH_007(
const int e,
const int qx,
const int qy,
82 const double weight,
const double *Jpt,
83 DeviceTensor<7,double> H)
85 constexpr
int DIM = 2;
86 double ddI1[4], ddI2[4], dI1[4], dI2[4], dI2b[4];
87 kernels::InvariantsEvaluator2D ie(
Args()
94 const double c1 = 1./ie.Get_I2();
95 const double c2 = weight*c1*c1;
96 const double 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);
122 static MFEM_HOST_DEVICE
inline 123 void EvalH_056(
const int e,
const int qx,
const int qy,
124 const double weight,
const double *Jpt,
125 DeviceTensor<7,double> H)
127 constexpr
int DIM = 2;
128 double dI2b[4], ddI2b[4];
129 kernels::InvariantsEvaluator2D ie(
Args().J(Jpt)
132 const double 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);
152 static MFEM_HOST_DEVICE
inline 153 void EvalH_077(
const int e,
const int qx,
const int qy,
154 const double weight,
const double *Jpt,
155 DeviceTensor<7,double> H)
157 constexpr
int DIM = 2;
158 double dI2[4], dI2b[4], ddI2[4];
159 kernels::InvariantsEvaluator2D ie(
Args()
164 const double 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);
185 static MFEM_HOST_DEVICE
inline 186 void EvalH_080(
const int e,
const int qx,
const int qy,
187 const double weight,
const double *w,
const double *Jpt,
188 DeviceTensor<7,double> H)
190 constexpr
int DIM = 2;
191 double ddI1[4], ddI1b[4], dI2[4], dI2b[4], ddI2[4];
192 kernels::InvariantsEvaluator2D ie(
Args()
200 const double 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) );
223 static MFEM_HOST_DEVICE
inline 224 void EvalH_094(
const int e,
const int qx,
const int qy,
225 const double weight,
const double *w,
const double *Jpt,
226 DeviceTensor<7,double> H)
228 constexpr
int DIM = 2;
229 double ddI1[4], ddI1b[4], dI2b[4], ddI2b[4];
230 kernels::InvariantsEvaluator2D ie(
Args().J(Jpt)
236 const double 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 double metric_normal,
272 MFEM_VERIFY(mid == 1 || mid == 2 || mid == 7 || mid == 77
273 || mid == 80 || mid == 94,
274 "2D metric not yet implemented!");
276 constexpr
int DIM = 2;
277 constexpr
int NBZ = 1;
278 const int D1D = T_D1D ? T_D1D : d1d;
279 const int Q1D = T_Q1D ? T_Q1D : q1d;
288 const double *metric_data = metric_param.
Read();
292 const int D1D = T_D1D ? T_D1D : d1d;
293 const int Q1D = T_Q1D ? T_Q1D : q1d;
294 constexpr
int NBZ = 1;
295 constexpr
int MQ1 = T_Q1D ? T_Q1D : T_MAX;
296 constexpr
int MD1 = T_D1D ? T_D1D : T_MAX;
298 MFEM_SHARED
double s_BG[2][MQ1*MD1];
299 MFEM_SHARED
double s_X[2][NBZ][MD1*MD1];
300 MFEM_SHARED
double s_DQ[4][NBZ][MD1*MQ1];
301 MFEM_SHARED
double s_QQ[4][NBZ][MQ1*MQ1];
303 kernels::internal::LoadX<MD1,NBZ>(e,D1D,X,s_X);
304 kernels::internal::LoadBG<MD1,MQ1>(D1D, Q1D,
b, g, s_BG);
306 kernels::internal::GradX<MD1,MQ1,NBZ>(D1D, Q1D, s_BG, s_X, s_DQ);
307 kernels::internal::GradY<MD1,MQ1,NBZ>(D1D, Q1D, s_BG, s_DQ, s_QQ);
309 MFEM_FOREACH_THREAD(qy,y,Q1D)
311 MFEM_FOREACH_THREAD(qx,x,Q1D)
313 const double *Jtr = &J(0,0,qx,qy,e);
314 const double detJtr = kernels::Det<2>(Jtr);
315 const double weight = metric_normal * W(qx,qy) * detJtr;
319 kernels::CalcInverse<2>(Jtr, Jrt);
323 kernels::internal::PullGrad<MQ1,NBZ>(Q1D,qx,qy,s_QQ,Jpr);
330 if (mid == 1) { EvalH_001(e,qx,qy,weight,Jpt,H); }
331 if (mid == 2) { EvalH_002(e,qx,qy,weight,Jpt,H); }
332 if (mid == 7) { EvalH_007(e,qx,qy,weight,Jpt,H); }
333 if (mid == 77) { EvalH_077(e,qx,qy,weight,Jpt,H); }
334 if (mid == 56) { EvalH_056(e,qx,qy,weight,Jpt,H); }
335 if (mid == 80) { EvalH_080(e,qx,qy,weight,metric_data,Jpt,H); }
336 if (mid == 94) { EvalH_094(e,qx,qy,weight,metric_data,Jpt,H); }
346 const int D1D =
PA.maps->ndof;
347 const int Q1D =
PA.maps->nqpt;
348 const int id = (D1D << 4 ) | Q1D;
357 if (
auto m = dynamic_cast<TMOP_Combo_QualityMetric *>(
metric))
362 MFEM_LAUNCH_TMOP_KERNEL(SetupGradPA_2D,
id,X,mn,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).
DeviceTensor< 2, const double > ConstDeviceMatrix
struct mfem::TMOP_Integrator::@23 PA
void AssembleGradPA_2D(const Vector &) const
TMOP_QualityMetric * metric
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
MFEM_REGISTER_TMOP_KERNELS(void, DatcSize, const int NE, const int ncomp, const int sizeidx, const double input_min_size, const DenseMatrix &w_, const Array< double > &b_, const Vector &x_, const Vector &nc_reduce, DenseTensor &j_, const int d1d, const int q1d)
virtual int Id() const
Return the metric ID.
MFEM_HOST_DEVICE double * Get_ddI1(int i, int j)
virtual double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void forall_2D_batch(int N, int X, int Y, int BZ, lambda &&body)
A basic generic Tensor class, appropriate for use on the GPU.
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...
kernels::InvariantsEvaluator2D::Buffers Args
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
Rank 3 tensor (array of matrices)