15 #include "../quadinterpolator.hpp" 16 #include "../../general/forall.hpp" 17 #include "../../linalg/dtensor.hpp" 18 #include "../../fem/kernels.hpp" 19 #include "../../linalg/kernels.hpp" 27 namespace quadrature_interpolator
32 int T_VDIM = 0,
int T_D1D = 0,
int T_Q1D = 0,
34 static void Derivatives2D(
const int NE,
44 const int D1D = T_D1D ? T_D1D : d1d;
45 const int Q1D = T_Q1D ? T_Q1D : q1d;
46 const int VDIM = T_VDIM ? T_VDIM : vdim;
47 static constexpr
int NBZ = T_NBZ ? T_NBZ : 1;
49 const auto b =
Reshape(b_, Q1D, D1D);
50 const auto g =
Reshape(g_, Q1D, D1D);
51 const auto j =
Reshape(j_, Q1D, Q1D, 2, 2, NE);
52 const auto x =
Reshape(x_, D1D, D1D, VDIM, NE);
54 Reshape(y_, Q1D, Q1D, VDIM, 2, NE):
55 Reshape(y_, VDIM, 2, Q1D, Q1D, NE);
57 MFEM_FORALL_2D(e, NE, Q1D, Q1D, NBZ,
59 const int D1D = T_D1D ? T_D1D : d1d;
60 const int Q1D = T_Q1D ? T_Q1D : q1d;
61 const int VDIM = T_VDIM ? T_VDIM : vdim;
62 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
63 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
65 const int tidz = MFEM_THREAD_ID(z);
66 MFEM_SHARED
double BG[2][MQ1*MD1];
67 kernels::internal::LoadBG<MD1,MQ1>(D1D,Q1D,
b,g,BG);
71 MFEM_SHARED
double XY[NBZ][MD1*MD1];
72 DeviceTensor<2> X((
double*)(XY+tidz), D1D, D1D);
74 MFEM_SHARED
double s_DQ[2][NBZ][MD1*MQ1];
75 DeviceTensor<2> DQ0(s_DQ[0][tidz], D1D, Q1D);
76 DeviceTensor<2> DQ1(s_DQ[1][tidz], D1D, Q1D);
78 for (
int c = 0; c < VDIM; ++c)
80 kernels::internal::LoadX<MD1,NBZ>(e,D1D,c,x,XY);
81 MFEM_FOREACH_THREAD(dy,y,D1D)
83 MFEM_FOREACH_THREAD(qx,x,Q1D)
87 for (
int dx = 0; dx < D1D; ++dx)
89 const double input = X(dx,dy);
90 u += input * B(dx,qx);
91 v += input * G(dx,qx);
98 MFEM_FOREACH_THREAD(qy,y,Q1D)
100 MFEM_FOREACH_THREAD(qx,x,Q1D)
104 for (
int dy = 0; dy < D1D; ++dy)
106 u += DQ1(dy,qx) * B(dy,qy);
107 v += DQ0(dy,qx) * G(dy,qy);
111 double Jloc[4], Jinv[4];
112 Jloc[0] = j(qx,qy,0,0,e);
113 Jloc[1] = j(qx,qy,1,0,e);
114 Jloc[2] = j(qx,qy,0,1,e);
115 Jloc[3] = j(qx,qy,1,1,e);
116 kernels::CalcInverse<2>(Jloc, Jinv);
117 const double U = Jinv[0]*
u + Jinv[1]*v;
118 const double V = Jinv[2]*
u + Jinv[3]*v;
140 int T_VDIM = 0,
int T_D1D = 0,
int T_Q1D = 0,
142 static void Derivatives3D(
const int NE,
152 const int D1D = T_D1D ? T_D1D : d1d;
153 const int Q1D = T_Q1D ? T_Q1D : q1d;
154 const int VDIM = T_VDIM ? T_VDIM : vdim;
156 const auto b =
Reshape(b_, Q1D, D1D);
157 const auto g =
Reshape(g_, Q1D, D1D);
158 const auto j =
Reshape(j_, Q1D, Q1D, Q1D, 3, 3, NE);
159 const auto x =
Reshape(x_, D1D, D1D, D1D, VDIM, NE);
161 Reshape(y_, Q1D, Q1D, Q1D, VDIM, 3, NE):
162 Reshape(y_, VDIM, 3, Q1D, Q1D, Q1D, NE);
164 MFEM_FORALL_3D(e, NE, Q1D, Q1D, Q1D,
166 const int D1D = T_D1D ? T_D1D : d1d;
167 const int Q1D = T_Q1D ? T_Q1D : q1d;
168 const int VDIM = T_VDIM ? T_VDIM : vdim;
169 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
170 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
172 MFEM_SHARED
double BG[2][MQ1*MD1];
173 kernels::internal::LoadBG<MD1,MQ1>(D1D,Q1D,
b,g,BG);
177 MFEM_SHARED
double sm0[3][MQ1*MQ1*MQ1];
178 MFEM_SHARED
double sm1[3][MQ1*MQ1*MQ1];
179 DeviceTensor<3> X(sm0[2], D1D, D1D, D1D);
180 DeviceTensor<3> DDQ0(sm0[0], D1D, D1D, Q1D);
181 DeviceTensor<3> DDQ1(sm0[1], D1D, D1D, Q1D);
182 DeviceTensor<3> DQQ0(sm1[0], D1D, Q1D, Q1D);
183 DeviceTensor<3> DQQ1(sm1[1], D1D, Q1D, Q1D);
184 DeviceTensor<3> DQQ2(sm1[2], D1D, Q1D, Q1D);
186 for (
int c = 0; c < VDIM; ++c)
188 kernels::internal::LoadX(e,D1D,c,x,X);
189 MFEM_FOREACH_THREAD(dz,z,D1D)
191 MFEM_FOREACH_THREAD(dy,y,D1D)
193 MFEM_FOREACH_THREAD(qx,x,Q1D)
197 for (
int dx = 0; dx < D1D; ++dx)
199 const double input = X(dx,dy,dz);
200 u += input * B(dx,qx);
201 v += input * G(dx,qx);
209 MFEM_FOREACH_THREAD(dz,z,D1D)
211 MFEM_FOREACH_THREAD(qy,y,Q1D)
213 MFEM_FOREACH_THREAD(qx,x,Q1D)
218 for (
int dy = 0; dy < D1D; ++dy)
220 u += DDQ1(dz,dy,qx) * B(dy,qy);
221 v += DDQ0(dz,dy,qx) * G(dy,qy);
222 w += DDQ0(dz,dy,qx) * B(dy,qy);
231 MFEM_FOREACH_THREAD(qz,z,Q1D)
233 MFEM_FOREACH_THREAD(qy,y,Q1D)
235 MFEM_FOREACH_THREAD(qx,x,Q1D)
240 for (
int dz = 0; dz < D1D; ++dz)
242 u += DQQ0(dz,qy,qx) * B(dz,qz);
243 v += DQQ1(dz,qy,qx) * B(dz,qz);
244 w += DQQ2(dz,qy,qx) * G(dz,qz);
248 double Jloc[9], Jinv[9];
249 for (
int col = 0; col < 3; col++)
251 for (
int row = 0; row < 3; row++)
253 Jloc[row+3*col] = j(qx,qy,qz,row,col,e);
256 kernels::CalcInverse<3>(Jloc, Jinv);
257 const double U = Jinv[0]*
u + Jinv[1]*v + Jinv[2]*w;
258 const double V = Jinv[3]*
u + Jinv[4]*v + Jinv[5]*w;
259 const double W = Jinv[6]*
u + Jinv[7]*v + Jinv[8]*w;
264 y(c,0,qx,qy,qz,e) =
u;
265 y(c,1,qx,qy,qz,e) = v;
266 y(c,2,qx,qy,qz,e) = w;
270 y(qx,qy,qz,c,0,e) =
u;
271 y(qx,qy,qz,c,1,e) = v;
272 y(qx,qy,qz,c,2,e) = w;
DeviceTensor< 2, double > DeviceMatrix
QVectorLayout
Type describing possible layouts for Q-vectors.
NQPT x VDIM x NE (values) / NQPT x VDIM x DIM x NE (grads)
double u(const Vector &xvec)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
VDIM x NQPT x NE (values) / VDIM x DIM x NQPT x NE (grads)