16 #ifndef dealii_cuda_fe_evaluation_h
17 #define dealii_cuda_fe_evaluation_h
21 #ifdef DEAL_II_COMPILER_CUDA_AWARE
31 # include <deal.II/matrix_free/cuda_matrix_free.templates.h>
47 template <
int dim,
int n_po
ints_1d>
48 __device__
inline unsigned int
52 threadIdx.x % n_points_1d :
54 threadIdx.x % n_points_1d + n_points_1d * threadIdx.y :
55 threadIdx.x % n_points_1d +
56 n_points_1d * (threadIdx.y + n_points_1d * threadIdx.z));
89 int n_q_points_1d = fe_degree + 1,
90 int n_components_ = 1,
91 typename Number =
double>
168 evaluate(
const bool evaluate_val,
const bool evaluate_grad);
178 integrate(
const bool integrate_val,
const bool integrate_grad);
187 get_value(
const unsigned int q_point)
const;
295 template <
typename Functor>
311 template <
typename Functor>
345 , padding_length(data->padding_length)
346 , constraint_mask(data->constraint_mask[cell_id])
347 , use_coloring(data->use_coloring)
348 , values(shdata->values)
354 for (
unsigned int i = 0; i < dim; ++i)
369 static_assert(n_components_ == 1,
"This function only supports FE with one \
371 const unsigned int idx = internal::compute_index<dim, n_q_points_1d>();
375 values[idx] = __ldg(&src[src_idx]);
379 internal::resolve_hanging_nodes<dim, fe_degree, false>(constraint_mask,
394 static_assert(n_components_ == 1,
"This function only supports FE with one \
396 internal::resolve_hanging_nodes<dim, fe_degree, true>(constraint_mask,
399 const unsigned int idx = internal::compute_index<dim, n_q_points_1d>();
404 dst[destination_idx] += values[idx];
419 const bool evaluate_val,
420 const bool evaluate_grad)
430 evaluator_tensor_product;
431 if (evaluate_val ==
true && evaluate_grad ==
true)
433 evaluator_tensor_product.value_and_gradient_at_quad_pts(values,
437 else if (evaluate_grad ==
true)
439 evaluator_tensor_product.gradient_at_quad_pts(values, gradients);
442 else if (evaluate_val ==
true)
444 evaluator_tensor_product.value_at_quad_pts(values);
458 const bool integrate_val,
459 const bool integrate_grad)
467 evaluator_tensor_product;
468 if (integrate_val ==
true && integrate_grad ==
true)
470 evaluator_tensor_product.integrate_value_and_gradient(values,
473 else if (integrate_val ==
true)
475 evaluator_tensor_product.integrate_value(values);
478 else if (integrate_grad ==
true)
480 evaluator_tensor_product.integrate_gradient<
false>(values, gradients);
498 const unsigned int q_point)
const
500 return values[q_point];
518 const unsigned int q_point = internal::compute_index<dim, n_q_points_1d>();
519 return values[q_point];
555 const unsigned int dof = internal::compute_index<dim, fe_degree + 1>();
570 values[q_point] = val_in * JxW[q_point];
584 const unsigned int q_point = internal::compute_index<dim, n_q_points_1d>();
585 values[q_point] = val_in * JxW[q_point];
599 values[dof] = val_in;
613 const unsigned int dof = internal::compute_index<dim, fe_degree + 1>();
614 values[dof] = val_in;
628 Number>::gradient_type
632 static_assert(n_components_ == 1,
"This function only supports FE with one \
635 const Number *inv_jacobian = &inv_jac[q_point];
637 for (
int d_1 = 0; d_1 < dim; ++d_1)
640 for (
int d_2 = 0; d_2 < dim; ++d_2)
641 tmp += inv_jacobian[padding_length *
n_cells * (dim * d_2 + d_1)] *
642 gradients[d_2][q_point];
660 Number>::gradient_type
664 static_assert(n_components_ == 1,
"This function only supports FE with one \
668 const unsigned int q_point = internal::compute_index<dim, n_q_points_1d>();
669 const Number * inv_jacobian = &inv_jac[q_point];
671 for (
int d_1 = 0; d_1 < dim; ++d_1)
674 for (
int d_2 = 0; d_2 < dim; ++d_2)
675 tmp += inv_jacobian[padding_length *
n_cells * (dim * d_2 + d_1)] *
676 gradients[d_2][q_point];
695 const Number *inv_jacobian = &inv_jac[q_point];
696 for (
int d_1 = 0; d_1 < dim; ++d_1)
699 for (
int d_2 = 0; d_2 < dim; ++d_2)
700 tmp += inv_jacobian[
n_cells * padding_length * (dim * d_1 + d_2)] *
702 gradients[d_1][q_point] = tmp * JxW[q_point];
718 const unsigned int q_point = internal::compute_index<dim, n_q_points_1d>();
719 const Number * inv_jacobian = &inv_jac[q_point];
720 for (
int d_1 = 0; d_1 < dim; ++d_1)
723 for (
int d_2 = 0; d_2 < dim; ++d_2)
724 tmp += inv_jacobian[
n_cells * padding_length * (dim * d_1 + d_2)] *
726 gradients[d_1][q_point] = tmp * JxW[q_point];
737 template <
typename Functor>
742 func(
this, internal::compute_index<dim, n_q_points_1d>());
754 template <
typename Functor>