27template<
int T_D1D = 0,
int T_Q1D = 0>
28inline void SmemPAConvectionNLGradApply2D(
const int ne,
38 static constexpr int VDIM = 2,
DIM = 2;
39 const int D1D = T_D1D ? T_D1D : d1d;
40 const int Q1D = T_Q1D ? T_Q1D : q1d;
43 const auto U =
Reshape(
u, D1D, D1D, VDIM, ne);
44 const auto dU =
Reshape(du, D1D, D1D, VDIM, ne);
45 auto Y =
Reshape(y, D1D, D1D, VDIM, ne);
49 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
50 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
52 MFEM_SHARED
real_t smem[MQ1][MQ1];
53 MFEM_SHARED
real_t sB[MD1][MQ1], sG[MD1][MQ1];
55 kernels::internal::vd_regs2d_t<VDIM, DIM, MQ1> g0, g1, g2;
56 kernels::internal::v_regs2d_t<DIM, MQ1> r0, r1, r2;
58 kernels::internal::LoadMatrix(D1D, Q1D,
b, sB);
59 kernels::internal::LoadMatrix(D1D, Q1D, g, sG);
61 kernels::internal::LoadDofs2d(e, D1D, dU, g0);
62 kernels::internal::Grad2d(D1D, Q1D, smem, sB, sG, g0, g1);
64 kernels::internal::LoadDofs2d(e, D1D, U, r0);
65 kernels::internal::Eval2d(D1D, Q1D, smem, sB, r0, r2);
67 kernels::internal::LoadDofs2d(e, D1D, dU, r0);
68 kernels::internal::Eval2d(D1D, Q1D, smem, sB, r0, r1);
70 kernels::internal::LoadDofs2d(e, D1D, U, g0);
71 kernels::internal::Grad2d(D1D, Q1D, smem, sB, sG, g0, g2);
73 MFEM_FOREACH_THREAD_DIRECT(qy, y, Q1D)
75 MFEM_FOREACH_THREAD_DIRECT(qx, x, Q1D)
78 const future::tensor<real_t, DIM> u_val =
80 r2[0][qy][qx], r2[1][qy][qx]
82 const future::tensor<real_t, VDIM, DIM> Q_adj =
84 { { A(0, 0, qx, qy, e), A(1, 0, qx, qy, e) },
85 { A(0, 1, qx, qy, e), A(1, 1, qx, qy, e) }
88 const future::tensor<real_t, VDIM, DIM> grad_dU =
90 { { g1[0][0][qy][qx], g1[1][0][qy][qx] },
91 { g1[0][1][qy][qx], g1[1][1][qy][qx] }
94 const auto one =
transpose(grad_dU) * (Q_adj * u_val);
97 const future::tensor<real_t, DIM> du_val =
99 r1[0][qy][qx], r1[1][qy][qx]
101 const future::tensor<real_t, VDIM, DIM> grad_U =
103 { { g2[0][0][qy][qx], g2[1][0][qy][qx] },
104 { g2[0][1][qy][qx], g2[1][1][qy][qx] }
107 const auto two =
transpose(grad_U) * (Q_adj * du_val);
110 r0[0][qy][qx] = one[0] + two[0];
111 r0[1][qy][qx] = one[1] + two[1];
115 kernels::internal::EvalTranspose2d(D1D, Q1D, smem, sB, r0, r1);
116 kernels::internal::WriteDofs2d(e, D1D, r1, Y);
120template<
int T_D1D = 0,
int T_Q1D = 0>
121inline void SmemPAConvectionNLGradApply3D(
const int ne,
131 static constexpr int VDIM = 3,
DIM = 3;
132 const int D1D = T_D1D ? T_D1D : d1d;
133 const int Q1D = T_Q1D ? T_Q1D : q1d;
135 const auto A =
Reshape(
a, VDIM,
DIM, Q1D, Q1D, Q1D, ne);
136 const auto U =
Reshape(
u, D1D, D1D, D1D, VDIM, ne);
137 const auto dU =
Reshape(du, D1D, D1D, D1D, VDIM, ne);
138 auto Y =
Reshape(y, D1D, D1D, D1D, VDIM, ne);
142 constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
143 constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
145 MFEM_SHARED
real_t smem[MQ1][MQ1];
146 MFEM_SHARED
real_t sB[MD1][MQ1], sG[MD1][MQ1];
148 kernels::internal::v_regs3d_t<VDIM, MQ1> r0, r1, r2;
149 kernels::internal::vd_regs3d_t<VDIM, DIM, MQ1> g0, g1, g2;
151 kernels::internal::LoadMatrix(D1D, Q1D,
b, sB);
152 kernels::internal::LoadMatrix(D1D, Q1D, g, sG);
154 kernels::internal::LoadDofs3d(e, D1D, dU, g0);
155 kernels::internal::Grad3d(D1D, Q1D, smem, sB, sG, g0, g1);
157 kernels::internal::LoadDofs3d(e, D1D, U, r0);
158 kernels::internal::Eval3d(D1D, Q1D, smem, sB, r0, r2);
160 kernels::internal::LoadDofs3d(e, D1D, dU, r0);
161 kernels::internal::Eval3d(D1D, Q1D, smem, sB, r0, r1);
163 kernels::internal::LoadDofs3d(e, D1D, U, g0);
164 kernels::internal::Grad3d(D1D, Q1D, smem, sB, sG, g0, g2);
166 for (
int qz = 0; qz < Q1D; qz++)
168 MFEM_FOREACH_THREAD_DIRECT(qy, y, Q1D)
170 MFEM_FOREACH_THREAD_DIRECT(qx, x, Q1D)
173 const future::tensor<real_t, DIM> u_val =
179 const future::tensor<real_t, VDIM, DIM> Q_adj = {{
180 {A(0,0,qx,qy,qz,e), A(1,0,qx,qy,qz,e), A(2,0,qx,qy,qz,e)},
181 {A(0,1,qx,qy,qz,e), A(1,1,qx,qy,qz,e), A(2,1,qx,qy,qz,e)},
182 {A(0,2,qx,qy,qz,e), A(1,2,qx,qy,qz,e), A(2,2,qx,qy,qz,e)}
185 const future::tensor<real_t, DIM, DIM> grad_dU = {{
186 {g1[0][0][qz][qy][qx], g1[1][0][qz][qy][qx], g1[2][0][qz][qy][qx]},
187 {g1[0][1][qz][qy][qx], g1[1][1][qz][qy][qx], g1[2][1][qz][qy][qx]},
188 {g1[0][2][qz][qy][qx], g1[1][2][qz][qy][qx], g1[2][2][qz][qy][qx]}
191 const auto one =
transpose(grad_dU) * (Q_adj * u_val);
194 const future::tensor<real_t, DIM> du_val =
196 r1[0][qz][qy][qx], r1[1][qz][qy][qx], r1[2][qz][qy][qx]
198 const future::tensor<real_t, VDIM, DIM> grad_U = {{
199 {g2[0][0][qz][qy][qx], g2[1][0][qz][qy][qx], g2[2][0][qz][qy][qx]},
200 {g2[0][1][qz][qy][qx], g2[1][1][qz][qy][qx], g2[2][1][qz][qy][qx]},
201 {g2[0][2][qz][qy][qx], g2[1][2][qz][qy][qx], g2[2][2][qz][qy][qx]}
204 const auto two =
transpose(grad_U) * (Q_adj * du_val);
207 r0[0][qz][qy][qx] = one[0] + two[0];
208 r0[1][qz][qy][qx] = one[1] + two[1];
209 r0[2][qz][qy][qx] = one[2] + two[2];
214 kernels::internal::EvalTranspose3d(D1D, Q1D, smem, sB, r0, r1);
215 kernels::internal::WriteDofs3d(e, D1D, r1, Y);
221template<
int T_D1D,
int T_Q1D>
223VectorConvectionNLFIntegrator::AddMultGradPA2D::Kernel()
225 static_assert(T_D1D <= T_Q1D,
"d1d > q1d is not supported");
226 return internal::SmemPAConvectionNLGradApply2D<T_D1D, T_Q1D>;
230VectorConvectionNLFIntegrator::AddMultGradPA2D::Fallback(
int d1d,
int q1d)
232 MFEM_VERIFY(d1d <= q1d, "d1d > q1d is not supported
");
233 MFEM_VERIFY(d1d <= DeviceDofQuadLimits::Get().MAX_D1D, "");
234 MFEM_VERIFY(q1d <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
235 return internal::SmemPAConvectionNLGradApply2D<>;
238template<int T_D1D, int T_Q1D>
239VectorConvectionNLFIntegrator::AddMultGradPAType
240VectorConvectionNLFIntegrator::AddMultGradPA3D::Kernel()
242 static_assert(T_D1D <= T_Q1D, "d1d > q1d is not supported
");
243 return internal::SmemPAConvectionNLGradApply3D<T_D1D, T_Q1D>;
246inline VectorConvectionNLFIntegrator::AddMultGradPAType
247VectorConvectionNLFIntegrator::AddMultGradPA3D::Fallback(int d1d, int q1d)
249 MFEM_VERIFY(d1d <= q1d, "d1d > q1d is not supported
");
250 MFEM_VERIFY(d1d <= DeviceDofQuadLimits::Get().MAX_D1D, "");
251 MFEM_VERIFY(q1d <= DeviceDofQuadLimits::Get().MAX_Q1D, "");
252 return internal::SmemPAConvectionNLGradApply3D<>;
void(*)(const int ne, const real_t *B, const real_t *G, const real_t *A, const real_t *u, const real_t *x, real_t *y, const int d1d, const int q1d) AddMultGradPAType
MFEM_HOST_DEVICE tensor< T, n, m > transpose(const tensor< T, m, n > &A)
Returns the transpose of the matrix.
real_t 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.
void forall_2D(int N, int X, int Y, lambda &&body)