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::InvariantsEvaluator2D::Buffers;
24 static MFEM_HOST_DEVICE
inline
25 double EvalW_001(
const double *Jpt)
27 kernels::InvariantsEvaluator2D ie(
Args().J(Jpt));
31 static MFEM_HOST_DEVICE
inline
32 double EvalW_002(
const double *Jpt)
34 kernels::InvariantsEvaluator2D ie(
Args().J(Jpt));
35 return 0.5 * ie.Get_I1b() - 1.0;
38 static MFEM_HOST_DEVICE
inline
39 double EvalW_007(
const double *Jpt)
41 kernels::InvariantsEvaluator2D ie(
Args().J(Jpt));
42 return ie.Get_I1() * (1.0 + 1.0/ie.Get_I2()) - 4.0;
45 static MFEM_HOST_DEVICE
inline
46 double EvalW_077(
const double *Jpt)
48 kernels::InvariantsEvaluator2D ie(
Args().J(Jpt));
49 const double I2b = ie.Get_I2b();
50 return 0.5*(I2b*I2b + 1./(I2b*I2b) - 2.);
53 static MFEM_HOST_DEVICE
inline
54 double EvalW_080(
const double *Jpt,
double gamma)
56 return (1.0 - gamma) * EvalW_002(Jpt) + gamma * EvalW_077(Jpt);
60 const double metric_normal,
61 const double metric_param,
74 MFEM_VERIFY(mid == 1 || mid == 2 || mid == 7 || mid == 77 || mid == 80,
75 "2D metric not yet implemented!");
77 constexpr
int DIM = 2;
78 constexpr
int NBZ = 1;
80 const int D1D = T_D1D ? T_D1D : d1d;
81 const int Q1D = T_Q1D ? T_Q1D : q1d;
91 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
93 constexpr
int NBZ = 1;
94 constexpr
int MQ1 = T_Q1D ? T_Q1D : T_MAX;
95 constexpr
int MD1 = T_D1D ? T_D1D : T_MAX;
96 const int D1D = T_D1D ? T_D1D : d1d;
97 const int Q1D = T_Q1D ? T_Q1D : q1d;
99 MFEM_SHARED
double BG[2][MQ1*MD1];
100 MFEM_SHARED
double XY[2][NBZ][MD1*MD1];
101 MFEM_SHARED
double DQ[4][NBZ][MD1*MQ1];
102 MFEM_SHARED
double QQ[4][NBZ][MQ1*MQ1];
104 kernels::internal::LoadX<MD1,NBZ>(e,D1D,X,XY);
105 kernels::internal::LoadBG<MD1,MQ1>(D1D,Q1D,
b,g,BG);
107 kernels::internal::GradX<MD1,MQ1,NBZ>(D1D,Q1D,BG,XY,DQ);
108 kernels::internal::GradY<MD1,MQ1,NBZ>(D1D,Q1D,BG,DQ,QQ);
110 MFEM_FOREACH_THREAD(qy,y,Q1D)
112 MFEM_FOREACH_THREAD(qx,x,Q1D)
114 const double *Jtr = &J(0,0,qx,qy,e);
115 const double detJtr = kernels::Det<2>(Jtr);
116 const double weight = metric_normal * W(qx,qy) * detJtr;
120 kernels::CalcInverse<2>(Jtr, Jrt);
124 kernels::internal::PullGrad<MQ1,NBZ>(Q1D,qx,qy,QQ,Jpr);
132 mid == 1 ? EvalW_001(Jpt) :
133 mid == 2 ? EvalW_002(Jpt) :
134 mid == 7 ? EvalW_007(Jpt) :
135 mid == 77 ? EvalW_077(Jpt) :
136 mid == 80 ? EvalW_080(Jpt, metric_param) : 0.0;
138 E(qx,qy,e) = weight * EvalW;
142 return energy * ones;
149 const int D1D =
PA.maps->ndof;
150 const int Q1D =
PA.maps->nqpt;
151 const int id = (D1D << 4 ) | Q1D;
161 if (
auto m = dynamic_cast<TMOP_Metric_080 *>(
metric)) { mp = m->GetGamma(); }
163 MFEM_LAUNCH_TMOP_KERNEL(EnergyPA_2D,
id,mn,mp,M,N,J,W,B,G,X,O,E);
virtual int Id() const
Return the metric ID.
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).
double GetLocalStateEnergyPA_2D(const Vector &) const
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.