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);
121 static MFEM_HOST_DEVICE
inline
122 void EvalH_077(
const int e,
const int qx,
const int qy,
123 const double weight,
const double *Jpt,
124 DeviceTensor<7,double> H)
126 constexpr
int DIM = 2;
127 double dI2[4], dI2b[4], ddI2[4];
128 kernels::InvariantsEvaluator2D ie(
Args()
133 const double I2 = ie.Get_I2(), I2inv_sq = 1.0 / (I2 * I2);
135 for (
int i = 0; i <
DIM; i++)
137 for (
int j = 0; j <
DIM; j++)
140 for (
int r = 0; r <
DIM; r++)
142 for (
int c = 0; c <
DIM; c++)
145 weight * 0.5 * (1.0 - I2inv_sq) * ddi2(r,c)
146 + weight * (I2inv_sq / I2) * di2(r,c) * di2(i,j);
153 static MFEM_HOST_DEVICE
inline
154 void EvalH_080(
const int e,
const int qx,
const int qy,
155 const double weight,
const double gamma,
const double *Jpt,
156 DeviceTensor<7,double> H)
160 constexpr
int DIM = 2;
161 double ddI1[4], ddI1b[4], dI2[4], dI2b[4], ddI2[4];
162 kernels::InvariantsEvaluator2D ie(
Args()
170 const double I2 = ie.Get_I2(), I2inv_sq = 1.0 / (I2 * I2);
172 for (
int i = 0; i <
DIM; i++)
174 for (
int j = 0; j <
DIM; j++)
178 for (
int r = 0; r <
DIM; r++)
180 for (
int c = 0; c <
DIM; c++)
183 (1.0 - gamma) * 0.5 * weight * ddi1b(r,c) +
184 gamma * ( weight * 0.5 * (1.0 - I2inv_sq) * ddi2(r,c) +
185 weight * (I2inv_sq / I2) * di2(r,c) * di2(i,j) );
194 const double metric_normal,
195 const double metric_param,
206 MFEM_VERIFY(mid == 1 || mid == 2 || mid == 7 || mid == 77 || mid == 80,
207 "Metric not yet implemented!");
209 constexpr
int DIM = 2;
210 constexpr
int NBZ = 1;
211 const int D1D = T_D1D ? T_D1D : d1d;
212 const int Q1D = T_Q1D ? T_Q1D : q1d;
221 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
223 const int D1D = T_D1D ? T_D1D : d1d;
224 const int Q1D = T_Q1D ? T_Q1D : q1d;
225 constexpr
int NBZ = 1;
226 constexpr
int MQ1 = T_Q1D ? T_Q1D : T_MAX;
227 constexpr
int MD1 = T_D1D ? T_D1D : T_MAX;
229 MFEM_SHARED
double s_BG[2][MQ1*MD1];
230 MFEM_SHARED
double s_X[2][NBZ][MD1*MD1];
231 MFEM_SHARED
double s_DQ[4][NBZ][MD1*MQ1];
232 MFEM_SHARED
double s_QQ[4][NBZ][MQ1*MQ1];
234 kernels::internal::LoadX<MD1,NBZ>(e,D1D,X,s_X);
235 kernels::internal::LoadBG<MD1,MQ1>(D1D, Q1D,
b, g, s_BG);
237 kernels::internal::GradX<MD1,MQ1,NBZ>(D1D, Q1D, s_BG, s_X, s_DQ);
238 kernels::internal::GradY<MD1,MQ1,NBZ>(D1D, Q1D, s_BG, s_DQ, s_QQ);
240 MFEM_FOREACH_THREAD(qy,y,Q1D)
242 MFEM_FOREACH_THREAD(qx,x,Q1D)
244 const double *Jtr = &J(0,0,qx,qy,e);
245 const double detJtr = kernels::Det<2>(Jtr);
246 const double weight = metric_normal * W(qx,qy) * detJtr;
250 kernels::CalcInverse<2>(Jtr, Jrt);
254 kernels::internal::PullGrad<MQ1,NBZ>(Q1D,qx,qy,s_QQ,Jpr);
261 if (mid == 1) { EvalH_001(e,qx,qy,weight,Jpt,H); }
262 if (mid == 2) { EvalH_002(e,qx,qy,weight,Jpt,H); }
263 if (mid == 7) { EvalH_007(e,qx,qy,weight,Jpt,H); }
264 if (mid == 77) { EvalH_077(e,qx,qy,weight,Jpt,H); }
265 if (mid == 80) { EvalH_080(e,qx,qy,weight,metric_param,Jpt,H); }
275 const int D1D =
PA.maps->ndof;
276 const int Q1D =
PA.maps->nqpt;
277 const int id = (D1D << 4 ) | Q1D;
286 if (
auto m = dynamic_cast<TMOP_Metric_080 *>(
metric)) { mp = m->GetGamma(); }
288 MFEM_LAUNCH_TMOP_KERNEL(SetupGradPA_2D,
id,X,mn,mp,M,N,W,B,G,J,H);
void AssembleGradPA_2D(const Vector &) const
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).
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).
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).
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
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.