17 #ifndef dealii_cuda_tensor_product_kernels_h
18 #define dealii_cuda_tensor_product_kernels_h
24 #include <deal.II/matrix_free/cuda_matrix_free.templates.h>
26 #ifdef DEAL_II_COMPILER_CUDA_AWARE
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(Number shape_values[],
const Number *in, Number *out)
const;
99 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
101 gradients(Number shape_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]);
134 value_and_gradient_at_quad_pts(Number *
const u, Number *grad_u[dim]);
142 integrate_gradient(Number *u, Number *grad_u[dim]);
149 integrate_value_and_gradient(Number *u, Number *grad_u[dim]);
154 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
165 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
166 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
172 Number>::values(Number shape_values[],
176 apply<direction, dof_to_quad, add, in_place>(shape_values, in, out);
181 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
182 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
188 Number>::gradients(Number shape_gradients[],
192 apply<direction, dof_to_quad, add, in_place>(shape_gradients, in, out);
197 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
198 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
208 const unsigned int i = (dim == 1) ? 0 : threadIdx.x % n_q_points_1d;
209 const unsigned int j = (dim == 3) ? threadIdx.y : 0;
210 const unsigned int q = (dim == 1) ?
211 (threadIdx.x % n_q_points_1d) :
212 (dim == 2) ? threadIdx.y : threadIdx.z;
217 for (
int k = 0; k < n_q_points_1d; ++k)
219 const unsigned int shape_idx =
220 dof_to_quad ? (q + k * n_q_points_1d) : (k + q * n_q_points_1d);
221 const unsigned int source_idx =
223 (k + n_q_points_1d * (i + n_q_points_1d * j)) :
224 (direction == 1) ? (i + n_q_points_1d * (k + n_q_points_1d * j)) :
225 (i + n_q_points_1d * (j + n_q_points_1d * k));
226 t += shape_data[shape_idx] *
227 (in_place ? out[source_idx] : in[source_idx]);
233 const unsigned int destination_idx =
235 (q + n_q_points_1d * (i + n_q_points_1d * j)) :
236 (direction == 1) ? (i + n_q_points_1d * (q + n_q_points_1d * j)) :
237 (i + n_q_points_1d * (j + n_q_points_1d * q));
240 out[destination_idx] += t;
242 out[destination_idx] = t;
247 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
248 inline __device__
void
253 Number>::value_at_quad_pts(Number *u)
259 values<0, true, false, true>(get_global_shape_values<Number>(),
267 values<0, true, false, true>(get_global_shape_values<Number>(),
271 values<1, true, false, true>(get_global_shape_values<Number>(),
279 values<0, true, false, true>(get_global_shape_values<Number>(),
283 values<1, true, false, true>(get_global_shape_values<Number>(),
287 values<2, true, false, true>(get_global_shape_values<Number>(),
303 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
304 inline __device__
void
309 Number>::integrate_value(Number *u)
315 values<0, false, false, true>(get_global_shape_values<Number>(),
323 values<0, false, false, true>(get_global_shape_values<Number>(),
327 values<1, false, false, true>(get_global_shape_values<Number>(),
335 values<0, false, false, true>(get_global_shape_values<Number>(),
339 values<1, false, false, true>(get_global_shape_values<Number>(),
343 values<2, false, false, true>(get_global_shape_values<Number>(),
359 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
360 inline __device__
void
365 Number>::gradient_at_quad_pts(
const Number *
const u,
372 gradients<0, true, false, false>(
373 get_global_shape_gradients<Number>(), u, grad_u[0]);
379 gradients<0, true, false, false>(
380 get_global_shape_gradients<Number>(), u, grad_u[0]);
381 values<0, true, false, false>(get_global_shape_values<Number>(),
387 values<1, true, false, true>(get_global_shape_values<Number>(),
390 gradients<1, true, false, true>(
391 get_global_shape_gradients<Number>(), grad_u[1], grad_u[1]);
397 gradients<0, true, false, false>(
398 get_global_shape_gradients<Number>(), u, grad_u[0]);
399 values<0, true, false, false>(get_global_shape_values<Number>(),
402 values<0, true, false, false>(get_global_shape_values<Number>(),
408 values<1, true, false, true>(get_global_shape_values<Number>(),
411 gradients<1, true, false, true>(
412 get_global_shape_gradients<Number>(), grad_u[1], grad_u[1]);
413 values<1, true, false, true>(get_global_shape_values<Number>(),
419 values<2, true, false, true>(get_global_shape_values<Number>(),
422 values<2, true, false, true>(get_global_shape_values<Number>(),
425 gradients<2, true, false, true>(
426 get_global_shape_gradients<Number>(), grad_u[2], grad_u[2]);
440 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
441 inline __device__
void
447 Number>::value_and_gradient_at_quad_pts(Number *
const u,
448 Number * grad_u[dim])
454 values<0, true, false, true>(get_global_shape_values<Number>(),
459 gradients<0, true, false, false>(
460 get_global_co_shape_gradients<Number>(), u, grad_u[0]);
466 values<0, true, false, true>(get_global_shape_values<Number>(),
470 values<1, true, false, true>(get_global_shape_values<Number>(),
475 gradients<0, true, false, false>(
476 get_global_co_shape_gradients<Number>(), u, grad_u[0]);
477 gradients<1, true, false, false>(
478 get_global_co_shape_gradients<Number>(), u, grad_u[1]);
484 values<0, true, false, true>(get_global_shape_values<Number>(),
488 values<1, true, false, true>(get_global_shape_values<Number>(),
492 values<2, true, false, true>(get_global_shape_values<Number>(),
497 gradients<0, true, false, false>(
498 get_global_co_shape_gradients<Number>(), u, grad_u[0]);
499 gradients<1, true, false, false>(
500 get_global_co_shape_gradients<Number>(), u, grad_u[1]);
501 gradients<2, true, false, false>(
502 get_global_co_shape_gradients<Number>(), u, grad_u[2]);
516 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
518 inline __device__
void
523 Number>::integrate_gradient(Number *u,
530 gradients<0, false, add, false>(
531 get_global_shape_gradients<Number>(), grad_u[dim], u);
537 gradients<0, false, false, true>(
538 get_global_shape_gradients<Number>(), grad_u[0], grad_u[0]);
539 values<0, false, false, true>(get_global_shape_values<Number>(),
545 values<1, false, add, false>(get_global_shape_values<Number>(),
549 gradients<1, false, true, false>(
550 get_global_shape_gradients<Number>(), grad_u[1], u);
556 gradients<0, false, false, true>(
557 get_global_shape_gradients<Number>(), grad_u[0], grad_u[0]);
558 values<0, false, false, true>(get_global_shape_values<Number>(),
561 values<0, false, false, true>(get_global_shape_values<Number>(),
567 values<1, false, false, true>(get_global_shape_values<Number>(),
570 gradients<1, false, false, true>(
571 get_global_shape_gradients<Number>(), grad_u[1], grad_u[1]);
572 values<1, false, false, true>(get_global_shape_values<Number>(),
578 values<2, false, add, false>(get_global_shape_values<Number>(),
582 values<2, false, true, false>(get_global_shape_values<Number>(),
586 gradients<2, false, true, false>(
587 get_global_shape_gradients<Number>(), grad_u[2], u);
601 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
602 inline __device__
void
607 Number>::integrate_value_and_gradient(Number *u,
615 gradients<0, false, true, false>(
616 get_global_co_shape_gradients<Number>(), grad_u[0], u);
619 values<0, false, false, true>(get_global_shape_values<Number>(),
627 gradients<1, false, true, false>(
628 get_global_co_shape_gradients<Number>(), grad_u[1], u);
630 gradients<0, false, true, false>(
631 get_global_co_shape_gradients<Number>(), grad_u[0], u);
634 values<1, false, false, true>(get_global_shape_values<Number>(),
638 values<0, false, false, true>(get_global_shape_values<Number>(),
647 gradients<2, false, true, false>(
648 get_global_co_shape_gradients<Number>(), grad_u[2], u);
650 gradients<1, false, true, false>(
651 get_global_co_shape_gradients<Number>(), grad_u[1], u);
653 gradients<0, false, true, false>(
654 get_global_co_shape_gradients<Number>(), grad_u[0], u);
657 values<2, false, false, true>(get_global_shape_values<Number>(),
661 values<1, false, false, true>(get_global_shape_values<Number>(),
665 values<0, false, false, true>(get_global_shape_values<Number>(),