13#ifndef dealii_portable_fe_evaluation_h
14#define dealii_portable_fe_evaluation_h
26#include <deal.II/matrix_free/portable_matrix_free.templates.h>
29#include <Kokkos_Core.hpp>
63 int n_q_points_1d = fe_degree + 1,
64 int n_components_ = 1,
73 using value_type = std::conditional_t<(n_components_ == 1),
83 std::conditional_t<n_components_ == dim,
300 template <
typename Functor>
333 "Portable::FEEvaluation initialized with wrong number of components. Should be " +
335 " but the template argument 4 is set to " +
386 Kokkos::parallel_for(Kokkos::TeamThreadRange(
data->team_member,
389 for (unsigned int c = 0; c < n_components_; ++c)
390 shared_data->values(i, c) =
391 src[precomputed_data->local_to_global(
392 i + tensor_dofs_per_component * c, cell_id)];
394 data->team_member.team_barrier();
396 for (
unsigned int c = 0; c < n_components_; ++c)
405 Kokkos::subview(
shared_data->values, Kokkos::ALL, c));
420 for (
unsigned int c = 0; c < n_components_; ++c)
429 Kokkos::subview(
shared_data->values, Kokkos::ALL, c));
434 Kokkos::parallel_for(
437 for (unsigned int c = 0; c < n_components_; ++c)
438 dst[precomputed_data->local_to_global(
439 i + tensor_dofs_per_component * c, cell_id)] +=
440 shared_data->values(i, c);
445 Kokkos::parallel_for(
448 for (unsigned int c = 0; c < n_components_; ++c)
449 Kokkos::atomic_add(&dst[precomputed_data->local_to_global(
450 i + (tensor_dofs_per_component)*c, cell_id)],
451 shared_data->values(i, c));
469 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
471 ElementType::tensor_symmetric_collocation)
478 else if (fe_degree >= 0 &&
492 ElementType::tensor_symmetric_no_collocation)
499 Kokkos::abort(
"The element type is not yet supported by the portable "
500 "matrix-free module.");
517 if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
519 ElementType::tensor_symmetric_collocation)
526 else if (fe_degree >= 0 &&
540 ElementType::tensor_symmetric_no_collocation)
547 Kokkos::abort(
"The element type is not yet supported by the portable "
548 "matrix-free module.");
565 const int q_point)
const
568 if constexpr (n_components_ == 1)
597 if constexpr (n_components_ == 1)
623 ExcMessage(
"submit_value() requires precomputed JxW"));
624 if constexpr (n_components_ == 1)
649 if constexpr (n_components_ == 1)
671 Number>::gradient_type
677 ExcMessage(
"get_gradient() requires precomputed inv_jacobian"));
680 if constexpr (n_components_ == 1)
682 for (
unsigned int d_1 = 0; d_1 < dim; ++d_1)
685 for (
unsigned int d_2 = 0; d_2 < dim; ++d_2)
695 for (
unsigned int d_1 = 0; d_1 < dim; ++d_1)
698 for (
unsigned int d_2 = 0; d_2 < dim; ++d_2)
722 ExcMessage(
"submit_gradient() requires precomputed inv_jacobian"));
724 ExcMessage(
"submit_gradient() requires precomputed JxW"));
726 if constexpr (n_components_ == 1)
728 for (
unsigned int d_1 = 0; d_1 < dim; ++d_1)
731 for (
unsigned int d_2 = 0; d_2 < dim; ++d_2)
742 for (
unsigned int d_1 = 0; d_1 < dim; ++d_1)
745 for (
unsigned int d_2 = 0; d_2 < dim; ++d_2)
767 Assert(n_components_ == dim,
768 ExcMessage(
"Function get_symmetric_gradient() only works when the "
769 "number of components and the number of dimensions are "
787 Assert(n_components_ == dim,
788 ExcMessage(
"Function get_divergence() only works when the "
789 "number of components and the number of dimensions are "
792 ExcMessage(
"get_divergence() requires precomputed inv_jacobian"));
794 Number divergence = 0.;
795 for (
unsigned int c = 0; c < dim; ++c)
796 for (
unsigned int d = 0; d < dim; ++d)
814 Assert(n_components_ == dim,
815 ExcMessage(
"Function submit_divergence() only works when the "
816 "number of components and the number of dimensions are "
819 ExcMessage(
"submit_divergence() requires precomputed inv_jacobian"));
821 ExcMessage(
"submit_divergence() requires precomputed JxW"));
823 for (
unsigned int c = 0; c < dim; ++c)
824 for (
unsigned int d_1 = 0; d_1 < dim; ++d_1)
843 Assert(n_components_ == dim,
844 ExcMessage(
"Function submit_symmetric_gradient() only works when "
845 "the number of components and the number of dimensions "
849 "submit_symmetric_gradient() requires precomputed inv_jacobian"));
851 ExcMessage(
"submit_symmetric_gradient() requires precomputed JxW"));
853 for (
unsigned int c = 0; c < dim; ++c)
854 for (
unsigned int d_1 = 0; d_1 < dim; ++d_1)
857 for (
unsigned int d_2 = 0; d_2 < dim; ++d_2)
872 template <
typename Functor>
877 Kokkos::parallel_for(Kokkos::TeamThreadRange(
data->team_member,
n_q_points),
878 [&](
const int &i) { func(this, i); });
879 data->team_member.team_barrier();
890 constexpr unsigned int
friend class FEEvaluation
int get_current_cell_index()
static constexpr unsigned int n_q_points
SharedData< dim, Number > * shared_data
void integrate(const EvaluationFlags::EvaluationFlags integration_flag)
static constexpr unsigned int dimension
const data_type * get_matrix_free_data()
const MatrixFree< dim, Number >::Data * data
static constexpr unsigned int n_components
void submit_gradient(const gradient_type &gradient, const int q_point)
void submit_divergence(const Number &div_in, const int q_point)
void evaluate(const EvaluationFlags::EvaluationFlags evaluate_flag)
void read_dof_values(const DeviceVector< Number > &src)
Number get_divergence(const int q_point) const
std::conditional_t<(n_components_==1), Number, Tensor< 1, n_components_, Number > > value_type
void distribute_local_to_global(DeviceVector< Number > &dst) const
static constexpr unsigned int tensor_dofs_per_cell
void submit_value(const value_type &val_in, const int q_point)
const MatrixFree< dim, Number >::PrecomputedData * precomputed_data
const unsigned int dof_handler_index
SymmetricTensor< 2, dim, Number > get_symmetric_gradient(const int q_point) const
void submit_dof_value(const value_type &value, const int dof_index)
value_type get_value(const int q_point) const
void submit_symmetric_gradient(const SymmetricTensor< 2, dim, Number > &sym_grad, const int q_point)
static constexpr unsigned int tensor_dofs_per_component
typename MatrixFree< dim, Number >::Data data_type
std::conditional_t< n_components_==1, Tensor< 1, dim, Number >, std::conditional_t< n_components_==dim, Tensor< 2, dim, Number >, Tensor< 1, n_components_, Tensor< 1, dim, Number > > > > gradient_type
gradient_type get_gradient(const int q_point) const
FEEvaluation(const data_type *data, const unsigned int dof_handler_index=0)
value_type get_dof_value(const int dof_index) const
void apply_for_each_quad_point(const Functor &func)
#define DEAL_II_DEPRECATED
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_HOST_DEVICE
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcMessage(std::string arg1)
const bool IsBlockVector< VectorType >::value
EvaluationFlags
The EvaluationFlags enum.
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
void resolve_hanging_nodes(const Kokkos::TeamPolicy< MemorySpace::Default::kokkos_space::execution_space >::member_type &team_member, Kokkos::View< Number *, MemorySpace::Default::kokkos_space > constraint_weights, const ::internal::MatrixFreeFunctions::ConstraintKinds constraint_mask, ViewType values)
constexpr bool use_collocation_evaluation(const unsigned int fe_degree, const unsigned int n_q_points_1d)
Kokkos::View< Number *, MemorySpace::Default::kokkos_space > DeviceVector
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
constexpr T pow(const T base, const int iexp)
static void integrate(const unsigned int dof_handler_index, const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, const typename MatrixFree< dim, Number >::Data *data)
static void evaluate(const unsigned int dof_handler_index, const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const typename MatrixFree< dim, Number >::Data *data)
static void evaluate(const unsigned int dof_handler_index, const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const typename MatrixFree< dim, Number >::Data *data)
static void integrate(const unsigned int dof_handler_index, const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, const typename MatrixFree< dim, Number >::Data *data)
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)