12 #include "../tmop.hpp"
14 #include "../../general/forall.hpp"
15 #include "../../linalg/kernels.hpp"
16 #include "../../linalg/dinvariants.hpp"
21 using Args = kernels::InvariantsEvaluator3D::Buffers;
24 static MFEM_HOST_DEVICE
inline
25 void EvalH_302(
const int e,
const int qx,
const int qy,
const int qz,
26 const double weight,
const double *J, DeviceTensor<8,double> dP,
27 double *B,
double *dI1b,
double *ddI1b,
28 double *dI2,
double *dI2b,
double *ddI2,
double *ddI2b,
31 constexpr
int DIM = 3;
32 kernels::InvariantsEvaluator3D ie(
Args()
34 .dI1b(dI1b).ddI1b(ddI1b)
35 .dI2(dI2).dI2b(dI2b).ddI2(ddI2).ddI2b(ddI2b)
37 const double c1 = weight/9.;
38 const double I1b = ie.Get_I1b();
39 const double I2b = ie.Get_I2b();
42 for (
int i = 0; i <
DIM; i++)
44 for (
int j = 0; j <
DIM; j++)
48 for (
int r = 0; r <
DIM; r++)
50 for (
int c = 0; c <
DIM; c++)
53 (di2b(r,c)*di1b(i,j) + di1b(r,c)*di2b(i,j))
56 dP(r,c,i,j,qx,qy,qz,e) = c1 * dp;
64 static MFEM_HOST_DEVICE
inline
65 void EvalH_303(
const int e,
const int qx,
const int qy,
const int qz,
66 const double weight,
const double *J, DeviceTensor<8,double> dP,
67 double *B,
double *dI1b,
double *ddI1,
double *ddI1b,
68 double *dI2,
double *dI2b,
double *ddI2,
double *ddI2b,
69 double *dI3b,
double *ddI3b)
71 constexpr
int DIM = 3;
72 kernels::InvariantsEvaluator3D ie(
Args()
74 .dI1b(dI1b).ddI1(ddI1).ddI1b(ddI1b)
75 .dI2(dI2).dI2b(dI2b).ddI2(ddI2).ddI2b(ddI2b)
76 .dI3b(dI3b).ddI3b(ddI3b));
77 const double c1 = weight/3.;
78 for (
int i = 0; i <
DIM; i++)
80 for (
int j = 0; j <
DIM; j++)
83 for (
int r = 0; r <
DIM; r++)
85 for (
int c = 0; c <
DIM; c++)
87 const double dp = ddi1b(r,c);
88 dP(r,c,i,j,qx,qy,qz,e) = c1 * dp;
96 static MFEM_HOST_DEVICE
inline
97 void EvalH_315(
const int e,
const int qx,
const int qy,
const int qz,
98 const double weight,
const double *J, DeviceTensor<8,double> dP,
99 double *dI3b,
double *ddI3b)
101 constexpr
int DIM = 3;
102 kernels::InvariantsEvaluator3D ie(
Args().
104 dI3b(dI3b).ddI3b(ddI3b));
107 const double I3b = ie.Get_I3b(sign_detJ);
110 for (
int i = 0; i <
DIM; i++)
112 for (
int j = 0; j <
DIM; j++)
115 for (
int r = 0; r <
DIM; r++)
117 for (
int c = 0; c <
DIM; c++)
119 const double dp = 2.0 * weight * (I3b - 1.0) * ddi3b(r,c) +
120 2.0 * weight * di3b(r,c) * di3b(i,j);
121 dP(r,c,i,j,qx,qy,qz,e) = dp;
132 static MFEM_HOST_DEVICE
inline
133 void EvalH_321(
const int e,
const int qx,
const int qy,
const int qz,
134 const double weight,
const double *J, DeviceTensor<8,double> dP,
135 double *B,
double *dI1b,
double *ddI1,
double *ddI1b,
136 double *dI2,
double *dI2b,
double *ddI2,
double *ddI2b,
137 double *dI3b,
double *ddI3b)
139 constexpr
int DIM = 3;
140 kernels::InvariantsEvaluator3D ie(
Args()
142 .dI1b(dI1b).ddI1(ddI1).ddI1b(ddI1b)
143 .dI2(dI2).dI2b(dI2b).ddI2(ddI2).ddI2b(ddI2b)
144 .dI3b(dI3b).ddI3b(ddI3b));
146 const double I2 = ie.Get_I2();
147 const double I3b = ie.Get_I3b(sign_detJ);
152 const double c0 = 1.0/I3b;
153 const double c1 = weight*c0*c0;
154 const double c2 = -2*c0*c1;
155 const double c3 = c2*I2;
157 for (
int i = 0; i <
DIM; i++)
159 for (
int j = 0; j <
DIM; j++)
164 for (
int r = 0; r <
DIM; r++)
166 for (
int c = 0; c <
DIM; c++)
172 + c2 * ((di2(r,c)*di3b(i,j) + di3b(r,c)*di2(i,j)))
173 -3*c0*c3 * di3b(r,c)*di3b(i,j);
174 dP(r,c,i,j,qx,qy,qz,e) = dp;
182 static MFEM_HOST_DEVICE
inline
183 void EvalH_332(
const int e,
const int qx,
const int qy,
const int qz,
184 const double weight,
const double gamma,
185 const double *J, DeviceTensor<8,double> dP,
186 double *B,
double *dI1b,
double *ddI1b,
187 double *dI2,
double *dI2b,
double *ddI2,
double *ddI2b,
188 double *dI3b,
double *ddI3b)
190 constexpr
int DIM = 3;
191 kernels::InvariantsEvaluator3D ie(
Args()
193 .dI1b(dI1b).ddI1b(ddI1b)
194 .dI2(dI2).dI2b(dI2b).ddI2(ddI2).ddI2b(ddI2b)
195 .dI3b(dI3b).ddI3b(ddI3b));
197 const double c1 = weight/9.;
198 const double I1b = ie.Get_I1b();
199 const double I2b = ie.Get_I2b();
200 const double I3b = ie.Get_I3b(sign_detJ);
204 for (
int i = 0; i <
DIM; i++)
206 for (
int j = 0; j <
DIM; j++)
211 for (
int r = 0; r <
DIM; r++)
213 for (
int c = 0; c <
DIM; c++)
215 const double dp_302 =
216 (di2b(r,c)*di1b(i,j) + di1b(r,c)*di2b(i,j))
219 const double dp_315 = 2.0 * weight * (I3b - 1.0) * ddi3b(r,c) +
220 2.0 * weight * di3b(r,c) * di3b(i,j);
221 dP(r,c,i,j,qx,qy,qz,e) = (1.0 - gamma) * c1 * dp_302 +
230 const double metric_normal,
231 const double metric_param,
243 MFEM_VERIFY(mid == 302 || mid == 303 || mid == 315 ||
244 mid == 321 || mid == 332,
"3D metric not yet implemented!");
246 constexpr
int DIM = 3;
247 const int D1D = T_D1D ? T_D1D : d1d;
248 const int Q1D = T_Q1D ? T_Q1D : q1d;
257 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
259 const int D1D = T_D1D ? T_D1D : d1d;
260 const int Q1D = T_Q1D ? T_Q1D : q1d;
261 constexpr
int MQ1 = T_Q1D ? T_Q1D : T_MAX;
262 constexpr
int MD1 = T_D1D ? T_D1D : T_MAX;
264 MFEM_SHARED
double s_BG[2][MQ1*MD1];
265 MFEM_SHARED
double s_DDD[3][MD1*MD1*MD1];
266 MFEM_SHARED
double s_DDQ[9][MD1*MD1*MQ1];
267 MFEM_SHARED
double s_DQQ[9][MD1*MQ1*MQ1];
268 MFEM_SHARED
double s_QQQ[9][MQ1*MQ1*MQ1];
270 kernels::internal::LoadX<MD1>(e,D1D,X,s_DDD);
271 kernels::internal::LoadBG<MD1,MQ1>(D1D,Q1D,
b,g,s_BG);
273 kernels::internal::GradX<MD1,MQ1>(D1D,Q1D,s_BG,s_DDD,s_DDQ);
274 kernels::internal::GradY<MD1,MQ1>(D1D,Q1D,s_BG,s_DDQ,s_DQQ);
275 kernels::internal::GradZ<MD1,MQ1>(D1D,Q1D,s_BG,s_DQQ,s_QQQ);
277 MFEM_FOREACH_THREAD(qz,z,Q1D)
279 MFEM_FOREACH_THREAD(qy,y,Q1D)
281 MFEM_FOREACH_THREAD(qx,x,Q1D)
283 const double *Jtr = &J(0,0,qx,qy,qz,e);
284 const double detJtr = kernels::Det<3>(Jtr);
285 const double weight = metric_normal * W(qx,qy,qz) * detJtr;
289 kernels::CalcInverse<3>(Jtr, Jrt);
293 kernels::internal::PullGrad<MQ1>(Q1D,qx,qy,qz, s_QQQ, Jpr);
301 double dI1b[9], ddI1[9], ddI1b[9];
302 double dI2[9], dI2b[9], ddI2[9], ddI2b[9];
304 double *dI3b=Jrt, *ddI3b=Jpr;
309 EvalH_302(e,qx,qy,qz,weight,Jpt,H,
310 B,dI1b,ddI1b,dI2,dI2b,ddI2,ddI2b,dI3b);
314 EvalH_303(e,qx,qy,qz,weight,Jpt,H,
315 B,dI1b,ddI1,ddI1b,dI2,dI2b,ddI2,ddI2b,dI3b,ddI3b);
319 EvalH_315(e,qx,qy,qz,weight,Jpt,H, dI3b,ddI3b);
323 EvalH_321(e,qx,qy,qz,weight,Jpt,H,
324 B,dI1b,ddI1,ddI1b,dI2,dI2b,ddI2,ddI2b,dI3b,ddI3b);
328 EvalH_332(e,qx,qy,qz,weight,metric_param,Jpt,H,
329 B,dI1b,ddI1b,dI2,dI2b,ddI2,ddI2b,dI3b,ddI3b);
340 const int D1D =
PA.maps->ndof;
341 const int Q1D =
PA.maps->nqpt;
343 const int id = (D1D << 4 ) | Q1D;
352 if (
auto m = dynamic_cast<TMOP_Metric_332 *>(
metric)) { mp = m->GetGamma(); }
354 MFEM_LAUNCH_TMOP_KERNEL(SetupGradPA_3D,
id,mn,mp,M,X,N,W,B,G,J,H);
virtual int Id() const
Return the metric ID.
DeviceTensor< 2, const double > ConstDeviceMatrix
struct mfem::TMOP_Integrator::@23 PA
TMOP_QualityMetric * metric
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
virtual double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
MFEM_REGISTER_TMOP_KERNELS(void, DatcSize, const int NE, const int ncomp, const int sizeidx, const DenseMatrix &w_, const Array< double > &b_, const Vector &x_, DenseTensor &j_, const int d1d, const int q1d)
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
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...
void AssembleGradPA_3D(const Vector &) const
kernels::InvariantsEvaluator2D::Buffers Args
Rank 3 tensor (array of matrices)
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims...dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.