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
74 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
81 static constexpr unsigned int dofs_per_cell =
83 static constexpr unsigned int n_q_points =
93 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
95 values(Number shape_values[],
const Number *in, Number *out)
const;
101 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
103 gradients(Number shape_gradients[],
const Number *in, Number *out)
const;
108 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
110 apply(Number shape_data[],
const Number *in, Number *out)
const;
116 value_at_quad_pts(Number *u);
122 integrate_value(Number *u);
129 gradient_at_quad_pts(
const Number *
const u, Number *grad_u[dim]);
136 value_and_gradient_at_quad_pts(Number *
const u, Number *grad_u[dim]);
144 integrate_gradient(Number *u, Number *grad_u[dim]);
151 integrate_value_and_gradient(Number *u, Number *grad_u[dim]);
158 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
164 Number>::EvaluatorTensorProduct(
int object_id)
165 : mf_object_id(object_id)
170 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
171 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
181 apply<direction, dof_to_quad, add, in_place>(shape_values, in, out);
186 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
187 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
197 apply<direction, dof_to_quad, add, in_place>(shape_gradients, in, out);
202 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
203 template <
int direction,
bool dof_to_quad,
bool add,
bool in_place>
209 Number>::apply(Number shape_data[],
213 const unsigned int i = (dim == 1) ? 0 : threadIdx.x % n_q_points_1d;
214 const unsigned int j = (dim == 3) ? threadIdx.y : 0;
215 const unsigned int q = (dim == 1) ?
216 (threadIdx.x % n_q_points_1d) :
217 (dim == 2) ? threadIdx.y : threadIdx.z;
222 for (
int k = 0; k < n_q_points_1d; ++k)
224 const unsigned int shape_idx =
225 dof_to_quad ? (q + k * n_q_points_1d) : (k + q * n_q_points_1d);
226 const unsigned int source_idx =
228 (k + n_q_points_1d * (i + n_q_points_1d * j)) :
229 (direction == 1) ? (i + n_q_points_1d * (k + n_q_points_1d * j)) :
230 (i + n_q_points_1d * (j + n_q_points_1d * k));
231 t += shape_data[shape_idx] *
232 (in_place ? out[source_idx] : in[source_idx]);
238 const unsigned int destination_idx =
240 (q + n_q_points_1d * (i + n_q_points_1d * j)) :
241 (direction == 1) ? (i + n_q_points_1d * (q + n_q_points_1d * j)) :
242 (i + n_q_points_1d * (j + n_q_points_1d * q));
245 out[destination_idx] += t;
247 out[destination_idx] = t;
252 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
253 inline __device__
void
258 Number>::value_at_quad_pts(Number *u)
264 values<0, true, false, true>(
265 get_global_shape_values<Number>(mf_object_id), u, u);
271 values<0, true, false, true>(
272 get_global_shape_values<Number>(mf_object_id), u, u);
274 values<1, true, false, true>(
275 get_global_shape_values<Number>(mf_object_id), u, u);
281 values<0, true, false, true>(
282 get_global_shape_values<Number>(mf_object_id), u, u);
284 values<1, true, false, true>(
285 get_global_shape_values<Number>(mf_object_id), u, u);
287 values<2, true, false, true>(
288 get_global_shape_values<Number>(mf_object_id), u, u);
302 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
303 inline __device__
void
308 Number>::integrate_value(Number *u)
314 values<0, false, false, true>(
315 get_global_shape_values<Number>(mf_object_id), u, u);
321 values<0, false, false, true>(
322 get_global_shape_values<Number>(mf_object_id), u, u);
324 values<1, false, false, true>(
325 get_global_shape_values<Number>(mf_object_id), u, u);
331 values<0, false, false, true>(
332 get_global_shape_values<Number>(mf_object_id), u, u);
334 values<1, false, false, true>(
335 get_global_shape_values<Number>(mf_object_id), u, u);
337 values<2, false, false, true>(
338 get_global_shape_values<Number>(mf_object_id), u, u);
352 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
353 inline __device__
void
358 Number>::gradient_at_quad_pts(
const Number *
const u,
365 gradients<0, true, false, false>(
366 get_global_shape_gradients<Number>(mf_object_id), u, grad_u[0]);
372 gradients<0, true, false, false>(
373 get_global_shape_gradients<Number>(mf_object_id), u, grad_u[0]);
374 values<0, true, false, false>(
375 get_global_shape_values<Number>(mf_object_id), u, grad_u[1]);
379 values<1, true, false, true>(get_global_shape_values<Number>(
383 gradients<1, true, false, true>(
384 get_global_shape_gradients<Number>(mf_object_id),
392 gradients<0, true, false, false>(
393 get_global_shape_gradients<Number>(mf_object_id), u, grad_u[0]);
394 values<0, true, false, false>(
395 get_global_shape_values<Number>(mf_object_id), u, grad_u[1]);
396 values<0, true, false, false>(
397 get_global_shape_values<Number>(mf_object_id), u, grad_u[2]);
401 values<1, true, false, true>(get_global_shape_values<Number>(
405 gradients<1, true, false, true>(
406 get_global_shape_gradients<Number>(mf_object_id),
409 values<1, true, false, true>(get_global_shape_values<Number>(
416 values<2, true, false, true>(get_global_shape_values<Number>(
420 values<2, true, false, true>(get_global_shape_values<Number>(
424 gradients<2, true, false, true>(
425 get_global_shape_gradients<Number>(mf_object_id),
441 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
442 inline __device__
void
448 Number>::value_and_gradient_at_quad_pts(Number *
const u,
449 Number * grad_u[dim])
455 values<0, true, false, true>(
456 get_global_shape_values<Number>(mf_object_id), u, u);
459 gradients<0, true, false, false>(
460 get_global_co_shape_gradients<Number>(mf_object_id),
468 values<0, true, false, true>(
469 get_global_shape_values<Number>(mf_object_id), u, u);
471 values<1, true, false, true>(
472 get_global_shape_values<Number>(mf_object_id), u, u);
475 gradients<0, true, false, false>(
476 get_global_co_shape_gradients<Number>(mf_object_id),
479 gradients<1, true, false, false>(
480 get_global_co_shape_gradients<Number>(mf_object_id),
488 values<0, true, false, true>(
489 get_global_shape_values<Number>(mf_object_id), u, u);
491 values<1, true, false, true>(
492 get_global_shape_values<Number>(mf_object_id), u, u);
494 values<2, true, false, true>(
495 get_global_shape_values<Number>(mf_object_id), u, u);
498 gradients<0, true, false, false>(
499 get_global_co_shape_gradients<Number>(mf_object_id),
502 gradients<1, true, false, false>(
503 get_global_co_shape_gradients<Number>(mf_object_id),
506 gradients<2, true, false, false>(
507 get_global_co_shape_gradients<Number>(mf_object_id),
523 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
525 inline __device__
void
530 Number>::integrate_gradient(Number *u,
537 gradients<0, false, add, false>(
538 get_global_shape_gradients<Number>(mf_object_id),
546 gradients<0, false, false, true>(
547 get_global_shape_gradients<Number>(mf_object_id),
550 values<0, false, false, true>(get_global_shape_values<Number>(
557 values<1, false, add, false>(
558 get_global_shape_values<Number>(mf_object_id), grad_u[0], u);
560 gradients<1, false, true, false>(
561 get_global_shape_gradients<Number>(mf_object_id), grad_u[1], u);
567 gradients<0, false, false, true>(
568 get_global_shape_gradients<Number>(mf_object_id),
571 values<0, false, false, true>(get_global_shape_values<Number>(
575 values<0, false, false, true>(get_global_shape_values<Number>(
582 values<1, false, false, true>(get_global_shape_values<Number>(
586 gradients<1, false, false, true>(
587 get_global_shape_gradients<Number>(mf_object_id),
590 values<1, false, false, true>(get_global_shape_values<Number>(
597 values<2, false, add, false>(
598 get_global_shape_values<Number>(mf_object_id), grad_u[0], u);
600 values<2, false, true, false>(
601 get_global_shape_values<Number>(mf_object_id), grad_u[1], u);
603 gradients<2, false, true, false>(
604 get_global_shape_gradients<Number>(mf_object_id), grad_u[2], u);
618 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
typename Number>
619 inline __device__
void
624 Number>::integrate_value_and_gradient(Number *u,
632 gradients<0, false, true, false>(
633 get_global_co_shape_gradients<Number>(mf_object_id),
638 values<0, false, false, true>(
639 get_global_shape_values<Number>(mf_object_id), u, u);
645 gradients<1, false, true, false>(
646 get_global_co_shape_gradients<Number>(mf_object_id),
650 gradients<0, false, true, false>(
651 get_global_co_shape_gradients<Number>(mf_object_id),
656 values<1, false, false, true>(
657 get_global_shape_values<Number>(mf_object_id), u, u);
659 values<0, false, false, true>(
660 get_global_shape_values<Number>(mf_object_id), u, u);
667 gradients<2, false, true, false>(
668 get_global_co_shape_gradients<Number>(mf_object_id),
672 gradients<1, false, true, false>(
673 get_global_co_shape_gradients<Number>(mf_object_id),
677 gradients<0, false, true, false>(
678 get_global_co_shape_gradients<Number>(mf_object_id),
683 values<2, false, false, true>(
684 get_global_shape_values<Number>(mf_object_id), u, u);
686 values<1, false, false, true>(
687 get_global_shape_values<Number>(mf_object_id), u, u);
689 values<0, false, false, true>(
690 get_global_shape_values<Number>(mf_object_id), u, u);
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
constexpr T pow(const T base, const int iexp)