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 double EvalW_302(
const double *J)
29 kernels::InvariantsEvaluator3D ie(
Args().J(J).B(B));
30 return ie.Get_I1b()*ie.Get_I2b()/9. - 1.;
34 static MFEM_HOST_DEVICE
inline
35 double EvalW_303(
const double *J)
38 kernels::InvariantsEvaluator3D ie(
Args().J(J).B(B));
39 return ie.Get_I1b()/3. - 1.;
43 static MFEM_HOST_DEVICE
inline
44 double EvalW_315(
const double *J)
47 kernels::InvariantsEvaluator3D ie(
Args().J(J).B(B));
48 const double a = ie.Get_I3b() - 1.0;
53 static MFEM_HOST_DEVICE
inline
54 double EvalW_321(
const double *J)
57 kernels::InvariantsEvaluator3D ie(
Args().J(J).B(B));
58 return ie.Get_I1() + ie.Get_I2()/ie.Get_I3() - 6.0;
61 static MFEM_HOST_DEVICE
inline
62 double EvalW_332(
const double *J,
double gamma)
64 return (1.0 - gamma) * EvalW_302(J) + gamma * EvalW_315(J);
68 const double metric_normal,
69 const double metric_param,
82 MFEM_VERIFY(mid == 302 || mid == 303 || mid == 315 ||
83 mid == 321 || mid == 332,
"3D metric not yet implemented!");
85 constexpr
int DIM = 3;
86 const int D1D = T_D1D ? T_D1D : d1d;
87 const int Q1D = T_Q1D ? T_Q1D : q1d;
97 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
99 const int D1D = T_D1D ? T_D1D : d1d;
100 const int Q1D = T_Q1D ? T_Q1D : q1d;
101 constexpr
int MQ1 = T_Q1D ? T_Q1D : T_MAX;
102 constexpr
int MD1 = T_D1D ? T_D1D : T_MAX;
104 MFEM_SHARED
double BG[2][MQ1*MD1];
105 MFEM_SHARED
double DDD[3][MD1*MD1*MD1];
106 MFEM_SHARED
double DDQ[6][MD1*MD1*MQ1];
107 MFEM_SHARED
double DQQ[9][MD1*MQ1*MQ1];
108 MFEM_SHARED
double QQQ[9][MQ1*MQ1*MQ1];
110 kernels::internal::LoadX<MD1>(e,D1D,X,DDD);
111 kernels::internal::LoadBG<MD1,MQ1>(D1D,Q1D,
b,g,BG);
113 kernels::internal::GradX<MD1,MQ1>(D1D,Q1D,BG,DDD,DDQ);
114 kernels::internal::GradY<MD1,MQ1>(D1D,Q1D,BG,DDQ,DQQ);
115 kernels::internal::GradZ<MD1,MQ1>(D1D,Q1D,BG,DQQ,QQQ);
117 MFEM_FOREACH_THREAD(qz,z,Q1D)
119 MFEM_FOREACH_THREAD(qy,y,Q1D)
121 MFEM_FOREACH_THREAD(qx,x,Q1D)
123 const double *Jtr = &J(0,0,qx,qy,qz,e);
124 const double detJtr = kernels::Det<3>(Jtr);
125 const double weight = metric_normal * W(qx,qy,qz) * detJtr;
129 kernels::CalcInverse<3>(Jtr, Jrt);
133 kernels::internal::PullGrad<MQ1>(Q1D,qx,qy,qz, QQQ, Jpr);
141 mid == 302 ? EvalW_302(Jpt) :
142 mid == 303 ? EvalW_303(Jpt) :
143 mid == 315 ? EvalW_315(Jpt) :
144 mid == 321 ? EvalW_321(Jpt) :
145 mid == 332 ? EvalW_332(Jpt, metric_param) : 0.0;
147 E(qx,qy,qz,e) = weight * EvalW;
152 return energy * ones;
159 const int D1D =
PA.maps->ndof;
160 const int Q1D =
PA.maps->nqpt;
161 const int id = (D1D << 4 ) | Q1D;
171 if (
auto m = dynamic_cast<TMOP_Metric_332 *>(
metric)) { mp = m->GetGamma(); }
173 MFEM_LAUNCH_TMOP_KERNEL(EnergyPA_3D,
id,mn,mp,M,N,J,W,B,G,O,X,E);
virtual int Id() const
Return the metric ID.
double GetLocalStateEnergyPA_3D(const Vector &) const
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...
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.