17 #ifndef dealii_cuda_tensor_product_kernels_h 18 #define dealii_cuda_tensor_product_kernels_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/utilities.h> 24 #include <deal.II/matrix_free/cuda_matrix_free.templates.h> 26 #ifdef DEAL_II_COMPILER_CUDA_AWARE 28 DEAL_II_NAMESPACE_OPEN
72 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
79 static constexpr
unsigned int dofs_per_cell =
81 static constexpr
unsigned int n_q_points =
91 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
93 values(
const Number *in, Number *out)
const;
99 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
101 gradients(
const Number *in, Number *out)
const;
106 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
108 apply(Number shape_data[],
const Number *in, Number *out)
const;
114 value_at_quad_pts(Number *u);
120 integrate_value(Number *u);
127 gradient_at_quad_pts(
const Number *
const u, Number *grad_u[dim]);
135 integrate_gradient(Number *u, Number *grad_u[dim]);
140 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
151 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
152 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
154 EvaluatorTensorProduct<evaluate_general,
158 Number>::values(
const Number *in, Number *out)
const 160 apply<direction, dof_to_quad, add, in_place>(global_shape_values,
167 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
168 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
174 Number>::gradients(
const Number *in,
177 apply<direction, dof_to_quad, add, in_place>(global_shape_gradients,
184 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
185 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
191 Number>::apply(Number shape_data[],
195 const unsigned int i = (dim == 1) ? 0 : threadIdx.x % n_q_points_1d;
196 const unsigned int j = (dim == 3) ? threadIdx.y : 0;
197 const unsigned int q = (dim == 1) ?
198 (threadIdx.x % n_q_points_1d) :
199 (dim == 2) ? threadIdx.y : threadIdx.z;
204 for (
int k = 0; k < n_q_points_1d; ++k)
206 const unsigned int shape_idx =
207 dof_to_quad ? (q + k * n_q_points_1d) : (k + q * n_q_points_1d);
208 const unsigned int source_idx =
210 (k + n_q_points_1d * (i + n_q_points_1d * j)) :
211 (direction == 1) ? (i + n_q_points_1d * (k + n_q_points_1d * j)) :
212 (i + n_q_points_1d * (j + n_q_points_1d * k));
213 t += shape_data[shape_idx] *
214 (in_place ? out[source_idx] : in[source_idx]);
220 const unsigned int destination_idx =
222 (q + n_q_points_1d * (i + n_q_points_1d * j)) :
223 (direction == 1) ? (i + n_q_points_1d * (q + n_q_points_1d * j)) :
224 (i + n_q_points_1d * (j + n_q_points_1d * q));
227 out[destination_idx] += t;
229 out[destination_idx] = t;
234 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
235 inline __device__
void 240 Number>::value_at_quad_pts(Number *u)
246 values<0, true, false, true>(u, u);
252 values<0, true, false, true>(u, u);
254 values<1, true, false, true>(u, u);
260 values<0, true, false, true>(u, u);
262 values<1, true, false, true>(u, u);
264 values<2, true, false, true>(u, u);
278 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
279 inline __device__
void 284 Number>::integrate_value(Number *u)
290 values<0, false, false, true>(u, u);
296 values<0, false, false, true>(u, u);
298 values<1, false, false, true>(u, u);
304 values<0, false, false, true>(u, u);
306 values<1, false, false, true>(u, u);
308 values<2, false, false, true>(u, u);
322 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
323 inline __device__
void 328 Number>::gradient_at_quad_pts(
const Number *
const u,
335 gradients<0, true, false, false>(u, grad_u[0]);
341 gradients<0, true, false, false>(u, grad_u[0]);
342 values<0, true, false, false>(u, grad_u[1]);
346 values<1, true, false, true>(grad_u[0], grad_u[0]);
347 gradients<1, true, false, true>(grad_u[1], grad_u[1]);
353 gradients<0, true, false, false>(u, grad_u[0]);
354 values<0, true, false, false>(u, grad_u[1]);
355 values<0, true, false, false>(u, grad_u[2]);
359 values<1, true, false, true>(grad_u[0], grad_u[0]);
360 gradients<1, true, false, true>(grad_u[1], grad_u[1]);
361 values<1, true, false, true>(grad_u[2], grad_u[2]);
365 values<2, true, false, true>(grad_u[0], grad_u[0]);
366 values<2, true, false, true>(grad_u[1], grad_u[1]);
367 gradients<2, true, false, true>(grad_u[2], grad_u[2]);
381 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
383 inline __device__
void 388 Number>::integrate_gradient(Number *u,
395 gradients<0, false, add, false>(grad_u[dim], u);
401 gradients<0, false, false, true>(grad_u[0], grad_u[0]);
402 values<0, false, false, true>(grad_u[1], grad_u[1]);
406 values<1, false, add, false>(grad_u[0], u);
408 gradients<1, false, true, false>(grad_u[1], u);
414 gradients<0, false, false, true>(grad_u[0], grad_u[0]);
415 values<0, false, false, true>(grad_u[1], grad_u[1]);
416 values<0, false, false, true>(grad_u[2], grad_u[2]);
420 values<1, false, false, true>(grad_u[0], grad_u[0]);
421 gradients<1, false, false, true>(grad_u[1], grad_u[1]);
422 values<1, false, false, true>(grad_u[2], grad_u[2]);
426 values<2, false, add, false>(grad_u[0], u);
428 values<2, false, true, false>(grad_u[1], u);
430 gradients<2, false, true, false>(grad_u[2], u);
444 DEAL_II_NAMESPACE_CLOSE
constexpr unsigned int pow(const unsigned int base, const int iexp)