12 #include "../tmop.hpp"
14 #include "../linearform.hpp"
15 #include "../../general/forall.hpp"
16 #include "../../linalg/kernels.hpp"
17 #include "../../linalg/dinvariants.hpp"
22 using Args = kernels::InvariantsEvaluator3D::Buffers;
25 static MFEM_HOST_DEVICE
inline
26 void EvalP_302(
const double *J,
double *P)
29 double dI1b[9], dI2[9], dI2b[9], dI3b[9];
30 kernels::InvariantsEvaluator3D ie(
Args()
35 const double alpha = ie.Get_I1b()/9.;
36 const double beta = ie.Get_I2b()/9.;
37 kernels::Add(3,3, alpha, ie.Get_dI2b(), beta, ie.Get_dI1b(), P);
41 static MFEM_HOST_DEVICE
inline
42 void EvalP_303(
const double *J,
double *P)
45 double dI1b[9], dI3b[9];
46 kernels::InvariantsEvaluator3D ie(
Args().J(J).B(B).dI1b(dI1b).dI3b(dI3b));
51 static MFEM_HOST_DEVICE
inline
52 void EvalP_315(
const double *J,
double *P)
55 kernels::InvariantsEvaluator3D ie(
Args().J(J).dI3b(dI3b));
58 const double I3b = ie.Get_I3b(sign_detJ);
59 kernels::Set(3,3, 2.0 * (I3b - 1.0), ie.Get_dI3b(sign_detJ), P);
63 static MFEM_HOST_DEVICE
inline
64 void EvalP_321(
const double *J,
double *P)
67 double dI1[9], dI2[9], dI3b[9];
68 kernels::InvariantsEvaluator3D ie(
Args().J(J).B(B)
69 .dI1(dI1).dI2(dI2).dI3b(dI3b));
71 const double I3 = ie.Get_I3();
72 const double alpha = 1.0/I3;
73 const double beta = -2.*ie.Get_I2()/(I3*ie.Get_I3b(sign_detJ));
74 kernels::Add(3,3, alpha, ie.Get_dI2(), beta, ie.Get_dI3b(sign_detJ), P);
79 static MFEM_HOST_DEVICE
inline
80 void EvalP_332(
const double *J,
double gamma,
double *P)
83 double dI1b[9], dI2[9], dI2b[9], dI3b[9];
84 kernels::InvariantsEvaluator3D ie(
Args()
89 const double alpha = (1.0 - gamma) * ie.Get_I1b()/9.;
90 const double beta = (1.0 - gamma) * ie.Get_I2b()/9.;
91 kernels::Add(3,3, alpha, ie.Get_dI2b(), beta, ie.Get_dI1b(), P);
94 const double I3b = ie.Get_I3b(sign_detJ);
95 kernels::Add(3,3, gamma * 2.0 * (I3b - 1.0), ie.Get_dI3b(sign_detJ), P);
99 const double metric_normal,
112 MFEM_VERIFY(mid == 302 || mid == 303 || mid == 315 ||
113 mid == 321 || mid == 332,
"3D metric not yet implemented!");
115 constexpr
int DIM = 3;
116 const int D1D = T_D1D ? T_D1D : d1d;
117 const int Q1D = T_Q1D ? T_Q1D : q1d;
126 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
128 const int D1D = T_D1D ? T_D1D : d1d;
129 const int Q1D = T_Q1D ? T_Q1D : q1d;
130 constexpr
int MQ1 = T_Q1D ? T_Q1D : T_MAX;
131 constexpr
int MD1 = T_D1D ? T_D1D : T_MAX;
133 MFEM_SHARED
double s_BG[2][MQ1*MD1];
134 MFEM_SHARED
double s_DDD[3][MD1*MD1*MD1];
135 MFEM_SHARED
double s_DDQ[9][MD1*MD1*MQ1];
136 MFEM_SHARED
double s_DQQ[9][MD1*MQ1*MQ1];
137 MFEM_SHARED
double s_QQQ[9][MQ1*MQ1*MQ1];
139 kernels::internal::LoadX<MD1>(e,D1D,X,s_DDD);
140 kernels::internal::LoadBG<MD1,MQ1>(D1D,Q1D,
b,g,s_BG);
142 kernels::internal::GradX<MD1,MQ1>(D1D,Q1D,s_BG,s_DDD,s_DDQ);
143 kernels::internal::GradY<MD1,MQ1>(D1D,Q1D,s_BG,s_DDQ,s_DQQ);
144 kernels::internal::GradZ<MD1,MQ1>(D1D,Q1D,s_BG,s_DQQ,s_QQQ);
146 MFEM_FOREACH_THREAD(qz,z,Q1D)
148 MFEM_FOREACH_THREAD(qy,y,Q1D)
150 MFEM_FOREACH_THREAD(qx,x,Q1D)
152 const double *Jtr = &J(0,0,qx,qy,qz,e);
153 const double detJtr = kernels::Det<3>(Jtr);
154 const double weight = metric_normal * W(qx,qy,qz) * detJtr;
158 kernels::CalcInverse<3>(Jtr, Jrt);
162 kernels::internal::PullGrad<MQ1>(Q1D,qx,qy,qz,s_QQQ,Jpr);
170 if (mid == 302) { EvalP_302(Jpt, P); }
171 if (mid == 303) { EvalP_303(Jpt, P); }
172 if (mid == 315) { EvalP_315(Jpt, P); }
173 if (mid == 321) { EvalP_321(Jpt, P); }
174 if (mid == 332) { EvalP_332(Jpt, metric_param, P); }
175 for (
int i = 0; i < 9; i++) { P[i] *= weight; }
180 kernels::internal::PushGrad<MQ1>(Q1D,qx,qy,qz,A,s_QQQ);
185 kernels::internal::LoadBGt<MD1,MQ1>(D1D,Q1D,
b,g,s_BG);
186 kernels::internal::GradZt<MD1,MQ1>(D1D,Q1D,s_BG,s_QQQ,s_DQQ);
187 kernels::internal::GradYt<MD1,MQ1>(D1D,Q1D,s_BG,s_DQQ,s_DDQ);
188 kernels::internal::GradXt<MD1,MQ1>(D1D,Q1D,s_BG,s_DDQ,Y,e);
196 const int D1D =
PA.maps->ndof;
197 const int Q1D =
PA.maps->nqpt;
198 const int id = (D1D << 4 ) | Q1D;
206 if (
auto m = dynamic_cast<TMOP_Metric_332 *>(
metric)) { mp = m->GetGamma(); }
208 MFEM_LAUNCH_TMOP_KERNEL(AddMultPA_Kernel_3D,
id,mn,mp,M,N,J,W,B,G,X,Y);
virtual int Id() const
Return the metric ID.
MFEM_HOST_DEVICE void MultABt(const int Aheight, const int Awidth, const int Bheight, const TA *Adata, const TB *Bdata, TC *ABtdata)
Multiply a matrix of size Aheight x Awidth and data Adata with the transpose of a matrix of size Bhei...
struct mfem::TMOP_Integrator::@23 PA
TMOP_QualityMetric * metric
MFEM_HOST_DEVICE void Add(const int height, const int width, const TALPHA alpha, const TA *Adata, const TB *Bdata, TC *Cdata)
Compute C = A + alpha*B, where the matrices A, B and C are of size height x width with data Adata...
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 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 AddMultPA_3D(const Vector &, Vector &) const
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
kernels::InvariantsEvaluator2D::Buffers Args
MFEM_HOST_DEVICE void Set(const int height, const int width, const double alpha, const TA *Adata, TB *Bdata)
Compute B = alpha*A, where the matrices A and B are of size height x width with data Adata and Bdata...
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.