16 #ifndef dealii_cuda_fe_evaluation_h 17 #define dealii_cuda_fe_evaluation_h 19 #include <deal.II/base/config.h> 21 #ifdef DEAL_II_COMPILER_CUDA_AWARE 23 # include <deal.II/base/tensor.h> 24 # include <deal.II/base/utilities.h> 26 # include <deal.II/lac/cuda_vector.h> 28 # include <deal.II/matrix_free/cuda_hanging_nodes_internal.h> 29 # include <deal.II/matrix_free/cuda_matrix_free.h> 30 # include <deal.II/matrix_free/cuda_matrix_free.templates.h> 31 # include <deal.II/matrix_free/cuda_tensor_product_kernels.h> 33 DEAL_II_NAMESPACE_OPEN
69 int n_q_points_1d = fe_degree + 1,
70 int n_components_ = 1,
71 typename Number =
double>
75 using value_type = Number;
78 static constexpr
unsigned int dimension = dim;
79 static constexpr
unsigned int n_components = n_components_;
80 static constexpr
unsigned int n_q_points =
82 static constexpr
unsigned int tensor_dofs_per_cell =
90 const data_type * data,
91 SharedData<dim, Number> *shdata);
121 evaluate(
const bool evaluate_val,
const bool evaluate_grad);
131 integrate(
const bool integrate_val,
const bool integrate_grad);
137 __device__ value_type
138 get_value(
const unsigned int q_point)
const;
147 submit_value(
const value_type &val_in,
const unsigned int q_point);
175 template <
typename Functor>
181 unsigned int n_cells;
182 unsigned int padding_length;
184 const unsigned int constraint_mask;
191 Number *gradients[dim];
204 const data_type * data,
205 SharedData<dim, Number> *shdata)
206 : n_cells(data->n_cells)
207 , padding_length(data->padding_length)
208 , constraint_mask(data->constraint_mask[cell_id])
209 , values(shdata->values)
211 local_to_global = data->local_to_global + padding_length * cell_id;
212 inv_jac = data->inv_jacobian + padding_length * cell_id;
213 JxW = data->JxW + padding_length * cell_id;
215 for (
unsigned int i = 0; i < dim; ++i)
216 gradients[i] = shdata->gradients[i];
230 static_assert(n_components_ == 1,
"This function only supports FE with one \ 232 const unsigned int idx =
233 (threadIdx.x % n_q_points_1d) +
234 (dim > 1 ? threadIdx.y : 0) * n_q_points_1d +
235 (dim > 2 ? threadIdx.z : 0) * n_q_points_1d * n_q_points_1d;
239 values[idx] = __ldg(&src[src_idx]);
242 internal::resolve_hanging_nodes<dim, fe_degree, false>(constraint_mask,
259 static_assert(n_components_ == 1,
"This function only supports FE with one \ 262 internal::resolve_hanging_nodes<dim, fe_degree, true>(constraint_mask,
265 const unsigned int idx =
266 (threadIdx.x % n_q_points_1d) +
267 (dim > 1 ? threadIdx.y : 0) * n_q_points_1d +
268 (dim > 2 ? threadIdx.z : 0) * n_q_points_1d * n_q_points_1d;
271 dst[destination_idx] += values[idx];
283 const bool evaluate_val,
284 const bool evaluate_grad)
289 internal::EvaluatorVariant::evaluate_general,
294 evaluator_tensor_product;
295 if (evaluate_grad ==
true)
297 evaluator_tensor_product.gradient_at_quad_pts(values, gradients);
301 if (evaluate_val ==
true)
303 evaluator_tensor_product.value_at_quad_pts(values);
317 const bool integrate_val,
318 const bool integrate_grad)
321 internal::EvaluatorVariant::evaluate_general,
326 evaluator_tensor_product;
327 if (integrate_val ==
true)
329 evaluator_tensor_product.integrate_value(values);
331 if (integrate_grad ==
true)
333 evaluator_tensor_product.integrate_gradient<
true>(values,
338 else if (integrate_grad ==
true)
340 evaluator_tensor_product.integrate_gradient<
false>(values, gradients);
358 const unsigned int q_point)
const 360 return values[q_point];
374 values[q_point] = val_in * JxW[q_point];
388 Number>::gradient_type
392 static_assert(n_components_ == 1,
"This function only supports FE with one \ 395 const Number *inv_jacobian = &inv_jac[q_point];
397 for (
int d_1 = 0; d_1 < dim; ++d_1)
400 for (
int d_2 = 0; d_2 < dim; ++d_2)
401 tmp += inv_jacobian[padding_length * n_cells * (dim * d_2 + d_1)] *
402 gradients[d_2][q_point];
421 const Number *inv_jacobian = &inv_jac[q_point];
422 for (
int d_1 = 0; d_1 < dim; ++d_1)
425 for (
int d_2 = 0; d_2 < dim; ++d_2)
426 tmp += inv_jacobian[n_cells * padding_length * (dim * d_1 + d_2)] *
428 gradients[d_1][q_point] = tmp * JxW[q_point];
439 template <
typename Functor>
444 const unsigned int q_point =
446 threadIdx.x % n_q_points_1d :
448 threadIdx.x % n_q_points_1d + n_q_points_1d * threadIdx.y :
449 threadIdx.x % n_q_points_1d +
450 n_q_points_1d * (threadIdx.y + n_q_points_1d * threadIdx.z));
457 DEAL_II_NAMESPACE_CLOSE
void submit_value(const value_type &val_in, const unsigned int q_point)
value_type get_value(const unsigned int q_point) const
gradient_type get_gradient(const unsigned int q_point) const
void evaluate(const bool evaluate_val, const bool evaluate_grad)
constexpr unsigned int pow(const unsigned int base, const int iexp)
void apply_quad_point_operations(const Functor &func)
unsigned int global_dof_index
FEEvaluation(const unsigned int cell_id, const data_type *data, SharedData< dim, Number > *shdata)
void read_dof_values(const Number *src)
void submit_gradient(const gradient_type &grad_in, const unsigned int q_point)
void distribute_local_to_global(Number *dst) const
void integrate(const bool integrate_val, const bool integrate_grad)