17 #ifndef dealii_matrix_free_fe_evaluation_h 18 #define dealii_matrix_free_fe_evaluation_h 21 #include <deal.II/base/config.h> 23 #include <deal.II/base/array_view.h> 24 #include <deal.II/base/exceptions.h> 25 #include <deal.II/base/smartpointer.h> 27 #include <deal.II/base/template_constraints.h> 28 #include <deal.II/base/vectorization.h> 30 #include <deal.II/lac/vector_operation.h> 32 #include <deal.II/matrix_free/evaluation_kernels.h> 33 #include <deal.II/matrix_free/evaluation_selector.h> 34 #include <deal.II/matrix_free/mapping_data_on_the_fly.h> 35 #include <deal.II/matrix_free/matrix_free.h> 36 #include <deal.II/matrix_free/shape_info.h> 37 #include <deal.II/matrix_free/tensor_product_kernels.h> 38 #include <deal.II/matrix_free/type_traits.h> 41 DEAL_II_NAMESPACE_OPEN
52 int n_q_points_1d = fe_degree + 1,
53 int n_components_ = 1,
54 typename Number =
double>
83 template <
int dim,
int n_components_,
typename Number,
bool is_face = false>
87 using number_type = Number;
91 static constexpr
unsigned int dimension = dim;
92 static constexpr
unsigned int n_components = n_components_;
108 get_cell_data_number()
const;
119 get_mapping_data_index_offset()
const;
128 get_cell_type()
const;
134 get_shape_info()
const;
174 template <
typename VectorType>
176 read_dof_values(
const VectorType &src,
const unsigned int first_index = 0);
206 template <
typename VectorType>
208 read_dof_values_plain(
const VectorType & src,
209 const unsigned int first_index = 0);
241 template <
typename VectorType>
243 distribute_local_to_global(
245 const unsigned int first_index = 0,
281 template <
typename VectorType>
285 const unsigned int first_index = 0,
312 get_dof_value(
const unsigned int dof)
const;
325 submit_dof_value(
const value_type val_in,
const unsigned int dof);
339 get_value(
const unsigned int q_point)
const;
353 submit_value(
const value_type val_in,
const unsigned int q_point);
365 get_gradient(
const unsigned int q_point)
const;
381 get_normal_derivative(
const unsigned int q_point)
const;
396 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
416 submit_normal_derivative(
const value_type grad_in,
417 const unsigned int q_point);
430 get_hessian(
const unsigned int q_point)
const;
441 get_hessian_diagonal(
const unsigned int q_point)
const;
454 get_laplacian(
const unsigned int q_point)
const;
465 get_divergence(
const unsigned int q_point)
const;
471 get_symmetric_gradient(
const unsigned int q_point)
const;
477 get_curl(
const unsigned int q_point)
const;
489 const unsigned int q_point);
501 submit_symmetric_gradient(
503 const unsigned int q_point);
517 const unsigned int q_point);
538 integrate_value()
const;
545 JxW(
const unsigned int q_index)
const;
552 DEAL_II_DEPRECATED
void 562 inverse_jacobian(
const unsigned int q_index)
const;
577 get_normal_vector(
const unsigned int q_point)
const;
603 begin_dof_values()
const;
627 begin_values()
const;
654 begin_gradients()
const;
683 begin_hessians()
const;
705 const std::vector<unsigned int> &
706 get_internal_dof_numbering()
const;
715 get_scratch_data()
const;
729 const unsigned int dof_no,
730 const unsigned int first_selected_component,
731 const unsigned int quad_no,
732 const unsigned int fe_degree,
733 const unsigned int n_q_points,
734 const bool is_interior_face);
770 template <
int n_components_other>
776 const unsigned int first_selected_component,
785 FEEvaluationBase(
const FEEvaluationBase &other);
794 operator=(
const FEEvaluationBase &other);
802 template <
typename VectorType,
typename VectorOperation>
804 read_write_operation(
806 VectorType * vectors[],
808 const bool apply_constraints =
true)
const;
817 template <
typename VectorType,
typename VectorOperation>
819 read_write_operation_contiguous(
821 VectorType * vectors[],
831 template <
typename VectorType,
typename VectorOperation>
834 VectorType * vectors[])
const;
949 const internal::MatrixFreeFunctions::
950 MappingInfoStorage<(is_face ? dim - 1 : dim), dim, Number> *mapping_data;
1104 set_data_pointers();
1109 template <
int,
int,
typename,
bool>
1111 template <
int,
int,
int,
int,
typename>
1126 template <
int dim,
int n_components_,
typename Number,
bool is_face>
1131 using number_type = Number;
1135 static constexpr
unsigned int dimension = dim;
1136 static constexpr
unsigned int n_components = n_components_;
1148 const unsigned int dof_no,
1149 const unsigned int first_selected_component,
1150 const unsigned int quad_no,
1151 const unsigned int fe_degree,
1152 const unsigned int n_q_points,
1153 const bool is_interior_face =
true);
1159 template <
int n_components_other>
1165 const unsigned int first_selected_component,
1171 FEEvaluationAccess(
const FEEvaluationAccess &other);
1176 FEEvaluationAccess &
1177 operator=(
const FEEvaluationAccess &other);
1192 template <
int dim,
typename Number,
bool is_face>
1197 using number_type = Number;
1200 static constexpr
unsigned int dimension = dim;
1206 get_dof_value(
const unsigned int dof)
const;
1211 submit_dof_value(
const value_type val_in,
const unsigned int dof);
1216 get_value(
const unsigned int q_point)
const;
1221 submit_value(
const value_type val_in,
const unsigned int q_point);
1227 const unsigned int q_point);
1232 get_gradient(
const unsigned int q_point)
const;
1237 get_normal_derivative(
const unsigned int q_point)
const;
1242 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
1247 submit_normal_derivative(
const value_type grad_in,
1248 const unsigned int q_point);
1253 get_hessian(
unsigned int q_point)
const;
1258 get_hessian_diagonal(
const unsigned int q_point)
const;
1263 get_laplacian(
const unsigned int q_point)
const;
1268 integrate_value()
const;
1279 const unsigned int dof_no,
1280 const unsigned int first_selected_component,
1281 const unsigned int quad_no,
1282 const unsigned int fe_degree,
1283 const unsigned int n_q_points,
1284 const bool is_interior_face =
true);
1290 template <
int n_components_other>
1296 const unsigned int first_selected_component,
1302 FEEvaluationAccess(
const FEEvaluationAccess &other);
1307 FEEvaluationAccess &
1308 operator=(
const FEEvaluationAccess &other);
1324 template <
int dim,
typename Number,
bool is_face>
1329 using number_type = Number;
1332 static constexpr
unsigned int dimension = dim;
1333 static constexpr
unsigned int n_components = dim;
1339 get_gradient(
const unsigned int q_point)
const;
1346 get_divergence(
const unsigned int q_point)
const;
1355 get_symmetric_gradient(
const unsigned int q_point)
const;
1362 get_curl(
const unsigned int q_point)
const;
1367 get_hessian(
const unsigned int q_point)
const;
1372 get_hessian_diagonal(
const unsigned int q_point)
const;
1377 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
1390 const unsigned int q_point);
1402 const unsigned int q_point);
1413 submit_symmetric_gradient(
1415 const unsigned int q_point);
1424 const unsigned int q_point);
1435 const unsigned int dof_no,
1436 const unsigned int first_selected_component,
1437 const unsigned int quad_no,
1438 const unsigned int dofs_per_cell,
1439 const unsigned int n_q_points,
1440 const bool is_interior_face =
true);
1446 template <
int n_components_other>
1452 const unsigned int first_selected_component,
1458 FEEvaluationAccess(
const FEEvaluationAccess &other);
1463 FEEvaluationAccess &
1464 operator=(
const FEEvaluationAccess &other);
1479 template <
typename Number,
bool is_face>
1484 using number_type = Number;
1487 static constexpr
unsigned int dimension = 1;
1493 get_dof_value(
const unsigned int dof)
const;
1498 submit_dof_value(
const value_type val_in,
const unsigned int dof);
1503 get_value(
const unsigned int q_point)
const;
1508 submit_value(
const value_type val_in,
const unsigned int q_point);
1513 submit_value(
const gradient_type val_in,
const unsigned int q_point);
1518 get_gradient(
const unsigned int q_point)
const;
1523 get_normal_derivative(
const unsigned int q_point)
const;
1528 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
1533 submit_gradient(
const value_type grad_in,
const unsigned int q_point);
1538 submit_normal_derivative(
const value_type grad_in,
1539 const unsigned int q_point);
1545 const unsigned int q_point);
1550 get_hessian(
unsigned int q_point)
const;
1555 get_hessian_diagonal(
const unsigned int q_point)
const;
1560 get_laplacian(
const unsigned int q_point)
const;
1565 integrate_value()
const;
1576 const unsigned int dof_no,
1577 const unsigned int first_selected_component,
1578 const unsigned int quad_no,
1579 const unsigned int fe_degree,
1580 const unsigned int n_q_points,
1581 const bool is_interior_face =
true);
1587 template <
int n_components_other>
1593 const unsigned int first_selected_component,
1599 FEEvaluationAccess(
const FEEvaluationAccess &other);
1604 FEEvaluationAccess &
1605 operator=(
const FEEvaluationAccess &other);
2176 using number_type = Number;
2195 static constexpr
unsigned int dimension = dim;
2201 static constexpr
unsigned int n_components = n_components_;
2209 static constexpr
unsigned int static_n_q_points =
2219 static constexpr
unsigned int static_dofs_per_component =
2229 static constexpr
unsigned int tensor_dofs_per_cell =
2230 static_dofs_per_component * n_components;
2239 static constexpr
unsigned int static_dofs_per_cell =
2240 static_dofs_per_component * n_components;
2268 const unsigned int dof_no = 0,
2269 const unsigned int quad_no = 0,
2270 const unsigned int first_selected_component = 0);
2302 const unsigned int first_selected_component = 0);
2312 const unsigned int first_selected_component = 0);
2324 template <
int n_components_other>
2327 const unsigned int first_selected_component = 0);
2355 reinit(
const unsigned int cell_batch_index);
2369 template <
typename DoFHandlerType,
bool level_dof_access>
2397 evaluate(
const bool evaluate_values,
2398 const bool evaluate_gradients,
2399 const bool evaluate_hessians =
false);
2415 const bool evaluate_values,
2416 const bool evaluate_gradients,
2417 const bool evaluate_hessians =
false);
2432 template <
typename VectorType>
2434 gather_evaluate(
const VectorType &input_vector,
2435 const bool evaluate_values,
2436 const bool evaluate_gradients,
2437 const bool evaluate_hessians =
false);
2450 integrate(
const bool integrate_values,
const bool integrate_gradients);
2464 integrate(
const bool integrate_values,
2465 const bool integrate_gradients,
2481 template <
typename VectorType>
2483 integrate_scatter(
const bool integrate_values,
2484 const bool integrate_gradients,
2485 VectorType &output_vector);
2492 quadrature_point(
const unsigned int q_point)
const;
2525 check_template_arguments(
const unsigned int fe_no,
2526 const unsigned int first_selected_component);
2564 int n_q_points_1d = fe_degree + 1,
2565 int n_components_ = 1,
2566 typename Number =
double>
2579 using number_type = Number;
2598 static constexpr
unsigned int dimension = dim;
2604 static constexpr
unsigned int n_components = n_components_;
2613 static constexpr
unsigned int static_n_q_points =
2622 static constexpr
unsigned int static_n_q_points_cell =
2631 static constexpr
unsigned int static_dofs_per_component =
2640 static constexpr
unsigned int tensor_dofs_per_cell =
2641 static_dofs_per_component * n_components;
2649 static constexpr
unsigned int static_dofs_per_cell =
2650 static_dofs_per_component * n_components;
2682 const bool is_interior_face =
true,
2683 const unsigned int dof_no = 0,
2684 const unsigned int quad_no = 0,
2685 const unsigned int first_selected_component = 0);
2698 reinit(
const unsigned int face_batch_number);
2708 reinit(
const unsigned int cell_batch_number,
const unsigned int face_number);
2721 evaluate(
const bool evaluate_values,
const bool evaluate_gradients);
2737 const bool evaluate_values,
2738 const bool evaluate_gradients);
2751 template <
typename VectorType>
2753 gather_evaluate(
const VectorType &input_vector,
2754 const bool evaluate_values,
2755 const bool evaluate_gradients);
2767 integrate(
const bool integrate_values,
const bool integrate_gradients);
2778 integrate(
const bool integrate_values,
2779 const bool integrate_gradients,
2793 template <
typename VectorType>
2795 integrate_scatter(
const bool integrate_values,
2796 const bool integrate_gradients,
2797 VectorType &output_vector);
2804 quadrature_point(
const unsigned int q_point)
const;
2838 adjust_for_face_orientation(
const bool integrate,
2840 const bool gradients);
2847 namespace MatrixFreeFunctions
2851 template <
int dim,
int degree>
2852 struct DGP_dofs_per_component
2855 static constexpr
unsigned int value =
2856 (DGP_dofs_per_component<dim - 1, degree>::value * (degree + dim)) / dim;
2860 template <
int degree>
2861 struct DGP_dofs_per_component<1, degree>
2863 static constexpr
unsigned int value = degree + 1;
2877 template <
int dim,
int n_components_,
typename Number,
bool is_face>
2880 const unsigned int dof_no,
2881 const unsigned int first_selected_component,
2882 const unsigned int quad_no_in,
2883 const unsigned int fe_degree,
2884 const unsigned int n_q_points,
2885 const bool is_interior_face)
2886 : scratch_data_array(data_in.acquire_scratch_data())
2887 , quad_no(quad_no_in)
2888 , n_fe_components(data_in.get_dof_info(dof_no).start_components.back())
2889 , active_fe_index(fe_degree !=
numbers::invalid_unsigned_int ?
2890 data_in.get_dof_info(dof_no).fe_index_from_degree(
2891 first_selected_component,
2894 , active_quad_index(fe_degree !=
numbers::invalid_unsigned_int ?
2895 (is_face ? data_in.get_mapping_info()
2896 .face_data[quad_no_in]
2897 .quad_index_from_n_q_points(n_q_points) :
2898 data_in.get_mapping_info()
2899 .cell_data[quad_no_in]
2900 .quad_index_from_n_q_points(n_q_points)) :
2902 , n_quadrature_points(fe_degree !=
numbers::invalid_unsigned_int ?
2905 .get_shape_info(dof_no,
2911 .get_shape_info(dof_no,
2916 , matrix_info(&data_in)
2917 , dof_info(&data_in.get_dof_info(dof_no))
2918 , mapping_data(
internal::MatrixFreeFunctions::
2919 MappingInfoCellsOrFaces<dim, Number, is_face>::get(
2920 data_in.get_mapping_info(),
2922 , data(&data_in.get_shape_info(
2925 dof_info->component_to_base_index[first_selected_component],
2930 , normal_vectors(nullptr)
2931 , normal_x_jacobian(nullptr)
2932 , quadrature_weights(
2933 mapping_data->descriptor[active_quad_index].quadrature_weights.begin())
2934 , cell(
numbers::invalid_unsigned_int)
2935 , is_interior_face(is_interior_face)
2939 internal::MatrixFreeFunctions::DoFInfo::dof_access_face_interior :
2940 internal::MatrixFreeFunctions::DoFInfo::dof_access_face_exterior) :
2941 internal::MatrixFreeFunctions::DoFInfo::dof_access_cell)
2943 , dof_values_initialized(false)
2944 , values_quad_initialized(false)
2945 , gradients_quad_initialized(false)
2946 , hessians_quad_initialized(false)
2947 , values_quad_submitted(false)
2948 , gradients_quad_submitted(false)
2949 , first_selected_component(first_selected_component)
2961 static_cast<int>(n_components_) <=
2967 "You tried to construct a vector-valued evaluator with " +
2969 " components. However, " 2970 "the current base element has only " +
2974 first_selected_component) +
2975 " components left when starting from local element index " +
2977 first_selected_component -
2989 template <
int dim,
int n_components_,
typename Number,
bool is_face>
2990 template <
int n_components_other>
2996 const unsigned int first_selected_component,
3004 Utilities::fixed_power < is_face ? dim - 1 : dim > (quadrature.size()))
3005 , matrix_info(nullptr)
3013 fe.component_to_base_index(first_selected_component).first))
3016 , normal_vectors(nullptr)
3017 , normal_x_jacobian(nullptr)
3021 , is_interior_face(true)
3032 first_selected_component(first_selected_component)
3038 if (other !=
nullptr &&
3044 mapping, quadrature, update_flags);
3051 const unsigned int base_element_number =
3055 first_selected_component >=
3057 ExcMessage(
"The underlying element must at least contain as many " 3058 "components as requested by this class"));
3059 (void)base_element_number;
3064 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3069 other.matrix_info->acquire_scratch_data())
3075 , matrix_info(other.matrix_info)
3076 , dof_info(other.dof_info)
3079 other.matrix_info == nullptr ?
3085 , normal_vectors(nullptr)
3086 , normal_x_jacobian(nullptr)
3088 other.matrix_info == nullptr ?
3093 , is_interior_face(other.is_interior_face)
3101 , first_selected_component(other.first_selected_component)
3123 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3135 if (matrix_info ==
nullptr)
3190 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3194 if (matrix_info !=
nullptr)
3214 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3220 const unsigned int tensor_dofs_per_component =
3221 Utilities::fixed_power<dim>(this->data->
fe_degree + 1);
3227 const unsigned int shift =
3228 std::max(tensor_dofs_per_component + 1, dofs_per_component) *
3231 const unsigned int allocated_size =
3232 shift + n_components_ * dofs_per_component +
3233 (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3237 for (
unsigned int c = 0; c < n_components_; ++c)
3244 for (
unsigned int d = 0; d < dim; ++d)
3249 for (
unsigned int d = 0; d < (dim * dim + dim) / 2; ++d)
3250 this->hessians_quad[c][d] =
3253 ((dim + 1) * n_quadrature_points + dofs_per_component) +
3258 (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3263 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3273 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3278 if (matrix_info ==
nullptr)
3289 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3299 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3309 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3324 JxW_values[q] = J_value[q];
3329 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3332 const unsigned int q_index)
const 3337 return normal_vectors[0];
3339 return normal_vectors[q_index];
3344 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3347 const unsigned int q_index)
const 3357 return J_value[q_index];
3362 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3365 const unsigned int q_index)
const 3372 return jacobian[q_index];
3377 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3388 const unsigned int * cells =
3392 for (
unsigned int i = 0; i < VectorizedArray<Number>::n_array_elements;
3412 template <
typename VectorType,
3413 typename std::enable_if<!has_local_element<VectorType>::value,
3414 VectorType>::type * =
nullptr>
3415 inline typename VectorType::value_type
3416 vector_access(
const VectorType &vec,
const unsigned int entry)
3426 template <
typename VectorType,
3427 typename std::enable_if<!has_local_element<VectorType>::value,
3428 VectorType>::type * =
nullptr>
3429 inline typename VectorType::value_type &
3430 vector_access(VectorType &vec,
const unsigned int entry)
3440 template <
typename VectorType,
3441 typename std::enable_if<has_local_element<VectorType>::value,
3442 VectorType>::type * =
nullptr>
3443 inline typename VectorType::value_type &
3444 vector_access(VectorType &vec,
const unsigned int entry)
3446 return vec.local_element(entry);
3452 template <
typename VectorType,
3453 typename std::enable_if<has_local_element<VectorType>::value,
3454 VectorType>::type * =
nullptr>
3455 inline typename VectorType::value_type
3456 vector_access(
const VectorType &vec,
const unsigned int entry)
3458 return vec.local_element(entry);
3463 template <
typename VectorType,
3464 typename std::enable_if<has_add_local_element<VectorType>::value,
3465 VectorType>::type * =
nullptr>
3467 vector_access_add(VectorType & vec,
3468 const unsigned int entry,
3469 const typename VectorType::value_type &val)
3471 vec.add_local_element(entry, val);
3476 template <
typename VectorType,
3477 typename std::enable_if<!has_add_local_element<VectorType>::value,
3478 VectorType>::type * =
nullptr>
3480 vector_access_add(VectorType & vec,
3481 const unsigned int entry,
3482 const typename VectorType::value_type &val)
3484 vector_access(vec, entry) += val;
3489 template <
typename VectorType,
3490 typename std::enable_if<has_add_local_element<VectorType>::value,
3491 VectorType>::type * =
nullptr>
3493 vector_access_add_global(VectorType & vec,
3495 const typename VectorType::value_type &val)
3497 vec.add(entry, val);
3502 template <
typename VectorType,
3503 typename std::enable_if<!has_add_local_element<VectorType>::value,
3504 VectorType>::type * =
nullptr>
3506 vector_access_add_global(VectorType & vec,
3508 const typename VectorType::value_type &val)
3515 template <
typename VectorType,
3516 typename std::enable_if<has_set_local_element<VectorType>::value,
3517 VectorType>::type * =
nullptr>
3519 vector_access_set(VectorType & vec,
3520 const unsigned int entry,
3521 const typename VectorType::value_type &val)
3523 vec.set_local_element(entry, val);
3528 template <
typename VectorType,
3529 typename std::enable_if<!has_set_local_element<VectorType>::value,
3530 VectorType>::type * =
nullptr>
3532 vector_access_set(VectorType & vec,
3533 const unsigned int entry,
3534 const typename VectorType::value_type &val)
3536 vector_access(vec, entry) = val;
3546 typename VectorType,
3547 typename std::enable_if<!has_partitioners_are_compatible<VectorType>::value,
3548 VectorType>::type * =
nullptr>
3550 check_vector_compatibility(
3551 const VectorType & vec,
3564 typename VectorType,
3565 typename std::enable_if<has_partitioners_are_compatible<VectorType>::value,
3566 VectorType>::type * =
nullptr>
3568 check_vector_compatibility(
3569 const VectorType & vec,
3576 "The parallel layout of the given vector is not " 3577 "compatible with the parallel partitioning in MatrixFree. " 3578 "Use MatrixFree::initialize_dof_vector to get a " 3579 "compatible vector."));
3590 template <
typename Number>
3593 template <
typename VectorType>
3595 process_dof(
const unsigned int index,
3596 const VectorType & vec,
3599 res = vector_access(vec, index);
3604 template <
typename VectorType>
3607 const unsigned int dof_index,
3610 std::integral_constant<bool, true>)
const 3612 const Number *vec_ptr = vec.begin() + dof_index;
3615 dof_values[i].load(vec_ptr);
3620 template <
typename VectorType>
3622 process_dofs_vectorized(
const unsigned int dofs_per_cell,
3623 const unsigned int dof_index,
3624 const VectorType & vec,
3626 std::integral_constant<bool, false>)
const 3629 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3631 dof_values[i][v] = vector_access(
3637 template <
typename VectorType>
3639 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3640 const unsigned int * dof_indices,
3643 std::integral_constant<bool, true>)
const 3645 ::vectorized_load_and_transpose(dofs_per_cell,
3653 template <
typename VectorType>
3655 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3656 const unsigned int * dof_indices,
3657 const VectorType & vec,
3659 std::integral_constant<bool, false>)
const 3662 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3664 dof_values[d][v] = vector_access(vec, dof_indices[v] + d);
3671 template <
typename VectorType>
3673 process_dof_gather(
const unsigned int * indices,
3675 const unsigned int constant_offset,
3677 std::integral_constant<bool, true>)
const 3679 res.
gather(vec.begin() + constant_offset, indices);
3686 template <
typename VectorType>
3688 process_dof_gather(
const unsigned int * indices,
3689 const VectorType & vec,
3690 const unsigned int constant_offset,
3692 std::integral_constant<bool, false>)
const 3694 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3696 res[v] = vector_access(vec, indices[v] + constant_offset);
3701 template <
typename VectorType>
3704 const VectorType & vec,
3713 pre_constraints(
const Number &, Number &res)
const 3720 template <
typename VectorType>
3722 process_constraint(
const unsigned int index,
3723 const Number weight,
3724 const VectorType & vec,
3727 res += weight * vector_access(vec, index);
3733 post_constraints(
const Number &sum, Number &write_pos)
const 3751 template <
typename Number>
3752 struct VectorDistributorLocalToGlobal
3754 template <
typename VectorType>
3756 process_dof(
const unsigned int index, VectorType &vec, Number &res)
const 3758 vector_access_add(vec, index, res);
3763 template <
typename VectorType>
3765 process_dofs_vectorized(
const unsigned int dofs_per_cell,
3766 const unsigned int dof_index,
3769 std::integral_constant<bool, true>)
const 3771 Number *vec_ptr = vec.begin() + dof_index;
3777 tmp += dof_values[i];
3784 template <
typename VectorType>
3786 process_dofs_vectorized(
const unsigned int dofs_per_cell,
3787 const unsigned int dof_index,
3790 std::integral_constant<bool, false>)
const 3793 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3795 vector_access_add(vec,
3803 template <
typename VectorType>
3805 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3806 const unsigned int * dof_indices,
3809 std::integral_constant<bool, true>)
const 3811 vectorized_transpose_and_store(
3812 true, dofs_per_cell, dof_values, dof_indices, vec.begin());
3817 template <
typename VectorType>
3819 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3820 const unsigned int * dof_indices,
3823 std::integral_constant<bool, false>)
const 3826 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3828 vector_access_add(vec, dof_indices[v] + d, dof_values[d][v]);
3835 template <
typename VectorType>
3837 process_dof_gather(
const unsigned int * indices,
3839 const unsigned int constant_offset,
3841 std::integral_constant<bool, true>)
const 3843 # if DEAL_II_COMPILER_VECTORIZATION_LEVEL < 3 3844 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3846 vector_access(vec, indices[v] + constant_offset) += res[v];
3850 tmp.
gather(vec.begin() + constant_offset, indices);
3852 tmp.
scatter(indices, vec.begin() + constant_offset);
3860 template <
typename VectorType>
3862 process_dof_gather(
const unsigned int * indices,
3864 const unsigned int constant_offset,
3866 std::integral_constant<bool, false>)
const 3868 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3870 vector_access_add(vec, indices[v] + constant_offset, res[v]);
3875 template <
typename VectorType>
3881 vector_access_add_global(vec, index, res);
3887 pre_constraints(
const Number &input, Number &res)
const 3894 template <
typename VectorType>
3896 process_constraint(
const unsigned int index,
3897 const Number weight,
3901 vector_access_add(vec, index, weight * res);
3907 post_constraints(
const Number &, Number &)
const 3920 template <
typename Number>
3923 template <
typename VectorType>
3925 process_dof(
const unsigned int index, VectorType &vec, Number &res)
const 3927 vector_access(vec, index) = res;
3932 template <
typename VectorType>
3934 process_dofs_vectorized(
const unsigned int dofs_per_cell,
3935 const unsigned int dof_index,
3938 std::integral_constant<bool, true>)
const 3940 Number *vec_ptr = vec.begin() + dof_index;
3943 dof_values[i].store(vec_ptr);
3948 template <
typename VectorType>
3950 process_dofs_vectorized(
const unsigned int dofs_per_cell,
3951 const unsigned int dof_index,
3954 std::integral_constant<bool, false>)
const 3957 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3967 template <
typename VectorType>
3969 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3970 const unsigned int * dof_indices,
3973 std::integral_constant<bool, true>)
const 3975 vectorized_transpose_and_store(
3976 false, dofs_per_cell, dof_values, dof_indices, vec.begin());
3981 template <
typename VectorType,
bool booltype>
3983 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3984 const unsigned int * dof_indices,
3987 std::integral_constant<bool, false>)
const 3990 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3992 vector_access(vec, dof_indices[v] + i) = dof_values[i][v];
3997 template <
typename VectorType>
3999 process_dof_gather(
const unsigned int * indices,
4001 const unsigned int constant_offset,
4003 std::integral_constant<bool, true>)
const 4005 res.
scatter(indices, vec.begin() + constant_offset);
4010 template <
typename VectorType>
4012 process_dof_gather(
const unsigned int * indices,
4014 const unsigned int constant_offset,
4016 std::integral_constant<bool, false>)
const 4018 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
4020 vector_access(vec, indices[v] + constant_offset) = res[v];
4025 template <
typename VectorType>
4037 pre_constraints(
const Number &, Number &)
const 4042 template <
typename VectorType>
4044 process_constraint(
const unsigned int,
4053 post_constraints(
const Number &, Number &)
const 4068 template <
typename VectorType,
bool>
4069 struct BlockVectorSelector
4072 template <
typename VectorType>
4073 struct BlockVectorSelector<VectorType, true>
4075 using BaseVectorType =
typename VectorType::BlockType;
4077 static BaseVectorType *
4078 get_vector_component(VectorType &vec,
const unsigned int component)
4081 return &vec.block(component);
4085 template <
typename VectorType>
4086 struct BlockVectorSelector<VectorType, false>
4088 using BaseVectorType = VectorType;
4090 static BaseVectorType *
4091 get_vector_component(VectorType &vec,
const unsigned int component)
4110 template <
typename VectorType>
4111 struct BlockVectorSelector<
std::vector<VectorType>, false>
4113 using BaseVectorType = VectorType;
4115 static BaseVectorType *
4116 get_vector_component(std::vector<VectorType> &vec,
4117 const unsigned int component)
4120 return &vec[component];
4124 template <
typename VectorType>
4125 struct BlockVectorSelector<
std::vector<VectorType *>, false>
4127 using BaseVectorType = VectorType;
4129 static BaseVectorType *
4130 get_vector_component(std::vector<VectorType *> &vec,
4131 const unsigned int component)
4134 return vec[component];
4141 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4142 template <
typename VectorType,
typename VectorOperation>
4148 const bool apply_constraints)
const 4153 if (matrix_info ==
nullptr)
4162 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4163 internal::check_vector_compatibility(*src[comp], *dof_info);
4166 internal::check_vector_compatibility(*src[0], *dof_info);
4185 constexpr
unsigned int n_vectorization =
4187 Assert(mask.count() == n_vectorization,
4189 "non-contiguous DoF storage"));
4191 std::integral_constant<bool,
4192 internal::is_vectorizable<VectorType, Number>::value>
4195 const unsigned int dofs_per_component =
4203 const unsigned int *dof_indices =
4211 ++i, dof_indices += n_vectorization)
4212 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4213 operation.process_dof_gather(dof_indices,
4219 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4221 ++i, dof_indices += n_vectorization)
4222 operation.process_dof_gather(
4223 dof_indices, *src[0], 0,
values_dofs[comp][i], vector_selector);
4227 const unsigned int * dof_indices[n_vectorization];
4231 unsigned int cells_copied[n_vectorization];
4232 const unsigned int *cells;
4233 unsigned int n_vectorization_actual =
4235 bool has_constraints =
false;
4240 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4249 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4268 for (
unsigned int v = n_vectorization_actual; v < n_vectorization; ++v)
4269 dof_indices[v] =
nullptr;
4275 const unsigned int n_components_read =
4277 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4280 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
4281 first_selected_component + n_components_read]
4285 first_selected_component]
4287 has_constraints =
true;
4290 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
4291 first_selected_component + n_components_read]
4294 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
4295 first_selected_component]
4298 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
4299 first_selected_component]
4300 .first < dof_info->dof_indices.size(),
4304 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
4305 first_selected_component]
4312 first_selected_component]
4315 for (
unsigned int v = n_vectorization_actual; v < n_vectorization; ++v)
4316 dof_indices[v] =
nullptr;
4321 if (!has_constraints)
4323 if (n_vectorization_actual < n_vectorization)
4324 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4326 operation.process_empty(values_dofs[comp][i]);
4327 if (n_components == 1 || n_fe_components == 1)
4329 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4331 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4332 operation.process_dof(dof_indices[v][i],
4334 values_dofs[comp][i][v]);
4338 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4339 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4341 operation.process_dof(
4342 dof_indices[v][comp * dofs_per_component + i],
4344 values_dofs[comp][i][v]);
4354 if (n_vectorization_actual < n_vectorization)
4355 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4357 operation.process_empty(values_dofs[comp][i]);
4358 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4360 unsigned int index_indicators, next_index_indicators;
4361 const unsigned int n_components_read =
4365 index_indicators = dof_info
4369 next_index_indicators = dof_info
4371 first_selected_component + 1]
4379 first_selected_component]
4381 next_index_indicators =
4384 first_selected_component + 1]
4388 if (apply_constraints ==
false &&
4390 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
4395 first_selected_component + n_components_read]
4409 next_index_indicators = index_indicators;
4412 if (n_components == 1 || n_fe_components == 1)
4415 Assert(src[c] !=
nullptr,
4417 "The finite element underlying this FEEvaluation " 4418 "object is scalar, but you requested " +
4419 std::to_string(n_components) +
4420 " components via the template argument in " 4421 "FEEvaluation. In that case, you must pass an " 4422 "std::vector<VectorType> or a BlockVector to " +
4423 "read_dof_values and distribute_local_to_global."));
4425 unsigned int ind_local = 0;
4426 for (; index_indicators != next_index_indicators; ++index_indicators)
4428 const std::pair<unsigned short, unsigned short> indicator =
4431 for (
unsigned int j = 0; j < indicator.first; ++j)
4432 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4433 operation.process_dof(dof_indices[v][j],
4435 values_dofs[comp][ind_local + j][v]);
4437 ind_local += indicator.first;
4438 dof_indices[v] += indicator.first;
4443 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4444 operation.pre_constraints(values_dofs[comp][ind_local][v],
4447 const Number *data_val =
4449 const Number *end_pool =
4451 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4452 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4453 operation.process_constraint(*dof_indices[v],
4458 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4459 operation.post_constraints(value[comp],
4460 values_dofs[comp][ind_local][v]);
4467 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4468 operation.process_dof(*dof_indices[v],
4470 values_dofs[comp][ind_local][v]);
4479 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4481 unsigned int ind_local = 0;
4484 for (; index_indicators != next_index_indicators;
4487 const std::pair<unsigned short, unsigned short> indicator =
4491 for (
unsigned int j = 0; j < indicator.first; ++j)
4492 operation.process_dof(dof_indices[v][j],
4494 values_dofs[comp][ind_local + j][v]);
4495 ind_local += indicator.first;
4496 dof_indices[v] += indicator.first;
4501 operation.pre_constraints(values_dofs[comp][ind_local][v],
4504 const Number *data_val =
4506 const Number *end_pool =
4509 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4510 operation.process_constraint(*dof_indices[v],
4515 operation.post_constraints(value,
4516 values_dofs[comp][ind_local][v]);
4524 ++dof_indices[v], ++ind_local)
4527 operation.process_dof(*dof_indices[v],
4529 values_dofs[comp][ind_local][v]);
4532 if (apply_constraints ==
true && comp + 1 < n_components)
4535 next_index_indicators =
4538 first_selected_component + comp + 2]
4541 next_index_indicators =
4545 first_selected_component + comp + 2]
4555 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4556 template <
typename VectorType,
typename VectorOperation>
4560 VectorType * src[])
const 4564 unsigned int index =
4566 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4571 operation.process_empty(values_dofs[comp][i]);
4572 operation.process_dof_global(
4575 values_dofs[comp][i][0]);
4582 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4583 template <
typename VectorType,
typename VectorOperation>
4598 std::integral_constant<bool,
4599 internal::is_vectorizable<VectorType, Number>::value>
4604 const unsigned int n_lanes = mask.count();
4606 const std::vector<unsigned int> &dof_indices_cont =
4613 interleaved_contiguous &&
4616 const unsigned int dof_index =
4621 if (n_components == 1 || n_fe_components == 1)
4622 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4640 const unsigned int vectorization_populated =
4644 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4648 [first_selected_component] *
4652 for (
unsigned int v = vectorization_populated;
4653 v < VectorizedArray<Number>::n_array_elements;
4666 if (n_components == 1 || n_fe_components == 1)
4667 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4668 operation.process_dofs_vectorized_transpose(
4675 operation.process_dofs_vectorized_transpose(
4684 interleaved_contiguous_strided)
4686 if (n_components == 1 || n_fe_components == 1)
4689 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4690 operation.process_dof_gather(
4694 values_dofs[comp][i],
4698 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4702 operation.process_dof_gather(
4707 values_dofs[comp][i],
4715 IndexStorageVariants::interleaved_contiguous_mixed_strides,
4717 const unsigned int *offsets =
4720 if (n_components == 1 || n_fe_components == 1)
4723 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4724 operation.process_dof_gather(dof_indices,
4727 values_dofs[comp][i],
4729 DEAL_II_OPENMP_SIMD_PRAGMA
4730 for (
unsigned int v = 0;
4731 v < VectorizedArray<Number>::n_array_elements;
4733 dof_indices[v] += offsets[v];
4736 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4740 operation.process_dof_gather(dof_indices,
4743 values_dofs[comp][i],
4745 DEAL_II_OPENMP_SIMD_PRAGMA
4746 for (
unsigned int v = 0;
4747 v < VectorizedArray<Number>::n_array_elements;
4749 dof_indices[v] += offsets[v];
4754 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4757 operation.process_empty(values_dofs[comp][i]);
4762 if (n_components == 1 || n_fe_components == 1)
4764 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4765 if (mask[v] ==
true)
4766 for (
unsigned int i = 0;
4769 operation.process_dof(dof_indices[v] + i,
4771 values_dofs[comp][i][v]);
4775 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4776 if (mask[v] ==
true)
4777 for (
unsigned int i = 0;
4780 operation.process_dof(
4781 dof_indices[v] + i +
4784 values_dofs[comp][i][v]);
4789 const unsigned int *offsets =
4792 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4795 if (n_components == 1 || n_fe_components == 1)
4796 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4798 if (mask[v] ==
true)
4799 for (
unsigned int i = 0;
4802 operation.process_dof(dof_indices[v] + i * offsets[v],
4804 values_dofs[comp][i][v]);
4808 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4809 if (mask[v] ==
true)
4810 for (
unsigned int i = 0;
4813 operation.process_dof(
4818 values_dofs[comp][i][v]);
4826 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4827 template <
typename VectorType>
4830 const VectorType & src,
4831 const unsigned int first_index)
4835 typename internal::BlockVectorSelector<
4840 internal::BlockVectorSelector<VectorType,
4842 get_vector_component(const_cast<VectorType &>(src), d + first_index);
4844 internal::VectorReader<Number> reader;
4858 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4859 template <
typename VectorType>
4862 const VectorType & src,
4863 const unsigned int first_index)
4867 typename internal::BlockVectorSelector<
4872 internal::BlockVectorSelector<VectorType,
4874 get_vector_component(const_cast<VectorType &>(src), d + first_index);
4876 internal::VectorReader<Number> reader;
4890 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4891 template <
typename VectorType>
4896 const unsigned int first_index,
4904 typename internal::BlockVectorSelector<
4908 dst_data[d] = internal::BlockVectorSelector<
4913 internal::VectorDistributorLocalToGlobal<Number> distributor;
4919 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4920 template <
typename VectorType>
4924 const unsigned int first_index,
4932 typename internal::BlockVectorSelector<
4936 dst_data[d] = internal::BlockVectorSelector<
4941 internal::VectorSetter<Number> setter;
4949 template <
int dim,
int n_components,
typename Number,
bool is_face>
4950 inline const std::vector<unsigned int> &
4959 template <
int dim,
int n_components,
typename Number,
bool is_face>
4970 template <
int dim,
int n_components,
typename Number,
bool is_face>
4974 return &values_dofs[0][0];
4979 template <
int dim,
int n_components,
typename Number,
bool is_face>
4986 return &values_dofs[0][0];
4991 template <
int dim,
int n_components,
typename Number,
bool is_face>
5001 template <
int dim,
int n_components,
typename Number,
bool is_face>
5014 template <
int dim,
int n_components,
typename Number,
bool is_face>
5025 template <
int dim,
int n_components,
typename Number,
bool is_face>
5038 template <
int dim,
int n_components,
typename Number,
bool is_face>
5043 return &hessians_quad[0][0][0];
5048 template <
int dim,
int n_components,
typename Number,
bool is_face>
5055 return &hessians_quad[0][0][0];
5060 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5063 const unsigned int dof)
const 5067 for (
unsigned int comp = 0; comp <
n_components; comp++)
5068 return_value[comp] = this->values_dofs[comp][dof];
5069 return return_value;
5074 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5077 const unsigned int q_point)
const 5083 for (
unsigned int comp = 0; comp <
n_components; comp++)
5084 return_value[comp] = this->
values_quad[comp][q_point];
5085 return return_value;
5090 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5091 inline DEAL_II_ALWAYS_INLINE
5094 const unsigned int q_point)
const 5107 for (
unsigned int comp = 0; comp <
n_components; comp++)
5108 for (
unsigned int d = 0; d < dim; ++d)
5119 for (
unsigned int comp = 0; comp <
n_components; comp++)
5120 for (
unsigned int d = 0; d < dim; ++d)
5124 for (
unsigned int e = 1; e < dim; ++e)
5125 grad_out[comp][d] +=
5126 jac[d][e] * this->gradients_quad[comp][e][q_point];
5134 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5137 const unsigned int q_point)
const 5147 for (
unsigned int comp = 0; comp <
n_components; comp++)
5149 (this->normal_x_jacobian[0][dim - 1]);
5152 const unsigned int index =
5154 for (
unsigned int comp = 0; comp <
n_components; comp++)
5157 this->normal_x_jacobian[index][0];
5158 for (
unsigned int d = 1; d < dim; ++d)
5160 this->normal_x_jacobian[index][d];
5172 template <
typename Number>
5176 const unsigned int q_point,
5179 tmp[0][0] = jac[0][0] * hessians_quad[0][q_point];
5182 template <
typename Number>
5186 const unsigned int q_point,
5189 for (
unsigned int d = 0; d < 2; ++d)
5191 tmp[0][d] = (jac[d][0] * hessians_quad[0][q_point] +
5192 jac[d][1] * hessians_quad[2][q_point]);
5193 tmp[1][d] = (jac[d][0] * hessians_quad[2][q_point] +
5194 jac[d][1] * hessians_quad[1][q_point]);
5198 template <
typename Number>
5202 const unsigned int q_point,
5205 for (
unsigned int d = 0; d < 3; ++d)
5207 tmp[0][d] = (jac[d][0] * hessians_quad[0][q_point] +
5208 jac[d][1] * hessians_quad[3][q_point] +
5209 jac[d][2] * hessians_quad[4][q_point]);
5210 tmp[1][d] = (jac[d][0] * hessians_quad[3][q_point] +
5211 jac[d][1] * hessians_quad[1][q_point] +
5212 jac[d][2] * hessians_quad[5][q_point]);
5213 tmp[2][d] = (jac[d][0] * hessians_quad[4][q_point] +
5214 jac[d][1] * hessians_quad[5][q_point] +
5215 jac[d][2] * hessians_quad[2][q_point]);
5222 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5225 const unsigned int q_point)
const 5243 for (
unsigned int comp = 0; comp <
n_components; comp++)
5244 for (
unsigned int d = 0; d < dim; ++d)
5246 hessian_out[comp][d][d] =
5247 (this->hessians_quad[comp][d][q_point] * jac[d][d] * jac[d][d]);
5253 hessian_out[comp][0][1] =
5254 (this->hessians_quad[comp][2][q_point] * jac[0][0] *
5258 hessian_out[comp][0][1] =
5259 (this->hessians_quad[comp][3][q_point] * jac[0][0] *
5261 hessian_out[comp][0][2] =
5262 (this->hessians_quad[comp][4][q_point] * jac[0][0] *
5264 hessian_out[comp][1][2] =
5265 (this->hessians_quad[comp][5][q_point] * jac[1][1] *
5271 for (
unsigned int e = d + 1; e < dim; ++e)
5272 hessian_out[comp][e][d] = hessian_out[comp][d][e];
5278 for (
unsigned int comp = 0; comp <
n_components; comp++)
5283 internal::hessian_unit_times_jac(jac,
5284 this->hessians_quad[comp],
5289 for (
unsigned int d = 0; d < dim; ++d)
5290 for (
unsigned int e = d; e < dim; ++e)
5292 hessian_out[comp][d][e] = jac[d][0] * tmp[0][e];
5293 for (
unsigned int f = 1; f < dim; ++f)
5294 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
5301 for (
unsigned int d = 0; d < dim; ++d)
5302 for (
unsigned int e = d + 1; e < dim; ++e)
5303 hessian_out[comp][e][d] = hessian_out[comp][d][e];
5313 [1 - this->is_interior_face]
5314 [this->mapping_data->data_index_offsets[this->cell] + q_point];
5315 for (
unsigned int comp = 0; comp <
n_components; comp++)
5320 internal::hessian_unit_times_jac(jac,
5321 this->hessians_quad[comp],
5326 for (
unsigned int d = 0; d < dim; ++d)
5327 for (
unsigned int e = d; e < dim; ++e)
5329 hessian_out[comp][d][e] = jac[d][0] * tmp[0][e];
5330 for (
unsigned int f = 1; f < dim; ++f)
5331 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
5335 for (
unsigned int d = 0; d < dim; ++d)
5336 for (
unsigned int e = 0; e < dim; ++e)
5337 hessian_out[comp][d][d] +=
5341 for (
unsigned int d = 0, count = dim; d < dim; ++d)
5342 for (
unsigned int e = d + 1; e < dim; ++e, ++count)
5343 for (
unsigned int f = 0; f < dim; ++f)
5344 hessian_out[comp][d][e] +=
5348 for (
unsigned int d = 0; d < dim; ++d)
5349 for (
unsigned int e = d + 1; e < dim; ++e)
5350 hessian_out[comp][e][d] = hessian_out[comp][d][e];
5359 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5362 const unsigned int q_point)
const 5380 for (
unsigned int comp = 0; comp <
n_components; comp++)
5381 for (
unsigned int d = 0; d < dim; ++d)
5382 hessian_out[comp][d] =
5383 (this->hessians_quad[comp][d][q_point] * jac[d][d] * jac[d][d]);
5388 for (
unsigned int comp = 0; comp <
n_components; comp++)
5393 internal::hessian_unit_times_jac(jac,
5394 this->hessians_quad[comp],
5400 for (
unsigned int d = 0; d < dim; ++d)
5402 hessian_out[comp][d] = jac[d][0] * tmp[0][d];
5403 for (
unsigned int f = 1; f < dim; ++f)
5404 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
5415 [0][this->mapping_data->data_index_offsets[this->cell] + q_point];
5416 for (
unsigned int comp = 0; comp <
n_components; comp++)
5421 internal::hessian_unit_times_jac(jac,
5422 this->hessians_quad[comp],
5428 for (
unsigned int d = 0; d < dim; ++d)
5430 hessian_out[comp][d] = jac[d][0] * tmp[0][d];
5431 for (
unsigned int f = 1; f < dim; ++f)
5432 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
5435 for (
unsigned int d = 0; d < dim; ++d)
5436 for (
unsigned int e = 0; e < dim; ++e)
5437 hessian_out[comp][d] +=
5446 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5449 const unsigned int q_point)
const 5459 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5461 laplacian_out[comp] = hess_diag[comp][0];
5462 for (
unsigned int d = 1; d < dim; ++d)
5463 laplacian_out[comp] += hess_diag[comp][d];
5465 return laplacian_out;
5470 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5471 inline DEAL_II_ALWAYS_INLINE
void 5474 const unsigned int dof)
5480 for (
unsigned int comp = 0; comp <
n_components; comp++)
5481 this->values_dofs[comp][dof] = val_in[comp];
5486 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5487 inline DEAL_II_ALWAYS_INLINE
void 5490 const unsigned int q_point)
5503 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5504 this->
values_quad[comp][q_point] = val_in[comp] * JxW;
5509 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5510 this->
values_quad[comp][q_point] = val_in[comp] * JxW;
5516 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5517 inline DEAL_II_ALWAYS_INLINE
void 5521 const unsigned int q_point)
5534 J_value[0] * quadrature_weights[q_point];
5535 for (
unsigned int comp = 0; comp <
n_components; comp++)
5536 for (
unsigned int d = 0; d < dim; ++d)
5538 (grad_in[comp][d] * jacobian[0][d][d] * JxW);
5549 J_value[0] * quadrature_weights[q_point];
5550 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5551 for (
unsigned int d = 0; d < dim; ++d)
5554 for (
unsigned int e = 1; e < dim; ++e)
5555 new_val += (jac[e][d] * grad_in[comp][e]);
5563 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5564 inline DEAL_II_ALWAYS_INLINE
void 5567 const unsigned int q_point)
5576 for (
unsigned int comp = 0; comp <
n_components; comp++)
5578 for (
unsigned int d = 0; d < dim - 1; ++d)
5582 (this->normal_x_jacobian[0][dim - 1] * this->J_value[0] *
5583 this->quadrature_weights[q_point]);
5587 const unsigned int index =
5589 for (
unsigned int comp = 0; comp <
n_components; comp++)
5593 factor = factor * this->quadrature_weights[q_point];
5594 for (
unsigned int d = 0; d < dim; ++d)
5596 factor * this->normal_x_jacobian[index][d];
5603 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5613 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5616 for (
unsigned int q = 1; q <
n_q_points; ++q)
5617 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5619 return (return_value);
5627 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5630 const unsigned int dof_no,
5631 const unsigned int first_selected_component,
5632 const unsigned int quad_no_in,
5633 const unsigned int fe_degree,
5634 const unsigned int n_q_points,
5635 const bool is_interior_face)
5639 first_selected_component,
5648 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5649 template <
int n_components_other>
5656 const unsigned int first_selected_component,
5663 first_selected_component,
5669 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5678 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5692 template <
int dim,
typename Number,
bool is_face>
5695 const unsigned int dof_no,
5696 const unsigned int first_selected_component,
5697 const unsigned int quad_no_in,
5698 const unsigned int fe_degree,
5699 const unsigned int n_q_points,
5700 const bool is_interior_face)
5703 first_selected_component,
5712 template <
int dim,
typename Number,
bool is_face>
5713 template <
int n_components_other>
5719 const unsigned int first_selected_component,
5725 first_selected_component,
5731 template <
int dim,
typename Number,
bool is_face>
5739 template <
int dim,
typename Number,
bool is_face>
5750 template <
int dim,
typename Number,
bool is_face>
5753 const unsigned int dof)
const 5756 return this->values_dofs[0][dof];
5761 template <
int dim,
typename Number,
bool is_face>
5764 const unsigned int q_point)
const 5774 template <
int dim,
typename Number,
bool is_face>
5777 const unsigned int q_point)
const 5784 template <
int dim,
typename Number,
bool is_face>
5787 const unsigned int q_point)
const 5802 for (
unsigned int d = 0; d < dim; ++d)
5813 for (
unsigned int d = 0; d < dim; ++d)
5816 for (
unsigned int e = 1; e < dim; ++e)
5817 grad_out[d] += jac[d][e] * this->gradients_quad[0][e][q_point];
5825 template <
int dim,
typename Number,
bool is_face>
5828 const unsigned int q_point)
const 5835 template <
int dim,
typename Number,
bool is_face>
5838 const unsigned int q_point)
const 5845 template <
int dim,
typename Number,
bool is_face>
5848 const unsigned int q_point)
const 5855 template <
int dim,
typename Number,
bool is_face>
5856 inline void DEAL_II_ALWAYS_INLINE
5859 const unsigned int dof)
5865 this->values_dofs[0][dof] = val_in;
5870 template <
int dim,
typename Number,
bool is_face>
5871 inline void DEAL_II_ALWAYS_INLINE
5874 const unsigned int q_index)
5885 this->J_value[0] * this->quadrature_weights[q_index];
5890 this->
values_quad[0][q_index] = val_in * this->J_value[q_index];
5896 template <
int dim,
typename Number,
bool is_face>
5897 inline DEAL_II_ALWAYS_INLINE
void 5900 const unsigned int q_point)
5907 template <
int dim,
typename Number,
bool is_face>
5908 inline DEAL_II_ALWAYS_INLINE
void 5911 const unsigned int q_point)
5920 template <
int dim,
typename Number,
bool is_face>
5921 inline DEAL_II_ALWAYS_INLINE
void 5924 const unsigned int q_index)
5937 this->J_value[0] * this->quadrature_weights[q_index];
5938 for (
unsigned int d = 0; d < dim; ++d)
5940 (grad_in[d] * this->jacobian[0][d][d] * JxW);
5947 this->jacobian[q_index] :
5951 this->J_value[q_index] :
5952 this->J_value[0] * this->quadrature_weights[q_index];
5953 for (
unsigned int d = 0; d < dim; ++d)
5956 for (
unsigned int e = 1; e < dim; ++e)
5957 new_val += jac[e][d] * grad_in[e];
5965 template <
int dim,
typename Number,
bool is_face>
5977 template <
int dim,
typename Number,
bool is_face>
5980 const unsigned int dof_no,
5981 const unsigned int first_selected_component,
5982 const unsigned int quad_no_in,
5983 const unsigned int fe_degree,
5984 const unsigned int n_q_points,
5985 const bool is_interior_face)
5988 first_selected_component,
5997 template <
int dim,
typename Number,
bool is_face>
5998 template <
int n_components_other>
6004 const unsigned int first_selected_component,
6010 first_selected_component,
6016 template <
int dim,
typename Number,
bool is_face>
6024 template <
int dim,
typename Number,
bool is_face>
6035 template <
int dim,
typename Number,
bool is_face>
6038 const unsigned int q_point)
const 6045 template <
int dim,
typename Number,
bool is_face>
6048 const unsigned int q_point)
const 6062 for (
unsigned int d = 1; d < dim; ++d)
6071 this->jacobian[q_point] :
6074 for (
unsigned int e = 1; e < dim; ++e)
6076 for (
unsigned int d = 1; d < dim; ++d)
6077 for (
unsigned int e = 0; e < dim; ++e)
6085 template <
int dim,
typename Number,
bool is_face>
6088 const unsigned int q_point)
const 6094 for (
unsigned int d = 0; d < dim; ++d)
6095 symmetrized[d] = grad[d][d];
6101 symmetrized[2] = grad[0][1] + grad[1][0];
6102 symmetrized[2] *= half;
6105 symmetrized[3] = grad[0][1] + grad[1][0];
6106 symmetrized[3] *= half;
6107 symmetrized[4] = grad[0][2] + grad[2][0];
6108 symmetrized[4] *= half;
6109 symmetrized[5] = grad[1][2] + grad[2][1];
6110 symmetrized[5] *= half;
6120 template <
int dim,
typename Number,
bool is_face>
6121 inline DEAL_II_ALWAYS_INLINE
6124 const unsigned int q_point)
const 6134 "Computing the curl in 1d is not a useful operation"));
6137 curl[0] = grad[1][0] - grad[0][1];
6140 curl[0] = grad[2][1] - grad[1][2];
6141 curl[1] = grad[0][2] - grad[2][0];
6142 curl[2] = grad[1][0] - grad[0][1];
6152 template <
int dim,
typename Number,
bool is_face>
6155 const unsigned int q_point)
const 6162 template <
int dim,
typename Number,
bool is_face>
6165 const unsigned int q_point)
const 6175 template <
int dim,
typename Number,
bool is_face>
6176 inline DEAL_II_ALWAYS_INLINE
void 6179 const unsigned int q_point)
6186 template <
int dim,
typename Number,
bool is_face>
6187 inline DEAL_II_ALWAYS_INLINE
void 6190 const unsigned int q_point)
6197 template <
int dim,
typename Number,
bool is_face>
6198 inline DEAL_II_ALWAYS_INLINE
void 6201 const unsigned int q_point)
6214 this->J_value[0] * this->quadrature_weights[q_point] * div_in;
6215 for (
unsigned int d = 0; d < dim; ++d)
6217 this->
gradients_quad[d][d][q_point] = (fac * this->jacobian[0][d][d]);
6218 for (
unsigned int e = d + 1; e < dim; ++e)
6229 this->jacobian[q_point] :
6233 this->J_value[q_point] :
6234 this->J_value[0] * this->quadrature_weights[q_point]) *
6236 for (
unsigned int d = 0; d < dim; ++d)
6238 for (
unsigned int e = 0; e < dim; ++e)
6246 template <
int dim,
typename Number,
bool is_face>
6247 inline DEAL_II_ALWAYS_INLINE
void 6250 const unsigned int q_point)
6266 this->J_value[0] * this->quadrature_weights[q_point];
6267 for (
unsigned int d = 0; d < dim; ++d)
6269 (sym_grad.access_raw_entry(d) * JxW * this->jacobian[0][d][d]);
6270 for (
unsigned int e = 0, counter = dim; e < dim; ++e)
6271 for (
unsigned int d = e + 1; d < dim; ++d, ++counter)
6274 sym_grad.access_raw_entry(counter) *
JxW;
6276 (value * this->jacobian[0][d][d]);
6278 (value * this->jacobian[0][e][e]);
6286 this->J_value[q_point] :
6287 this->J_value[0] * this->quadrature_weights[q_point];
6290 this->jacobian[q_point] :
6293 for (
unsigned int i = 0; i < dim; ++i)
6294 weighted[i][i] = sym_grad.access_raw_entry(i) *
JxW;
6295 for (
unsigned int i = 0, counter = dim; i < dim; ++i)
6296 for (
unsigned int j = i + 1; j < dim; ++j, ++counter)
6299 sym_grad.access_raw_entry(counter) *
JxW;
6300 weighted[i][j] = value;
6301 weighted[j][i] = value;
6303 for (
unsigned int comp = 0; comp < dim; ++comp)
6304 for (
unsigned int d = 0; d < dim; ++d)
6307 for (
unsigned int e = 1; e < dim; ++e)
6308 new_val += jac[e][d] * weighted[comp][e];
6316 template <
int dim,
typename Number,
bool is_face>
6317 inline DEAL_II_ALWAYS_INLINE
void 6320 const unsigned int q_point)
6328 "Testing by the curl in 1d is not a useful operation"));
6331 grad[1][0] = curl[0];
6332 grad[0][1] = -curl[0];
6335 grad[2][1] = curl[0];
6336 grad[1][2] = -curl[0];
6337 grad[0][2] = curl[1];
6338 grad[2][0] = -curl[1];
6339 grad[1][0] = curl[2];
6340 grad[0][1] = -curl[2];
6352 template <
typename Number,
bool is_face>
6355 const unsigned int dof_no,
6356 const unsigned int first_selected_component,
6357 const unsigned int quad_no_in,
6358 const unsigned int fe_degree,
6359 const unsigned int n_q_points,
6360 const bool is_interior_face)
6363 first_selected_component,
6372 template <
typename Number,
bool is_face>
6373 template <
int n_components_other>
6379 const unsigned int first_selected_component,
6385 first_selected_component,
6391 template <
typename Number,
bool is_face>
6399 template <
typename Number,
bool is_face>
6410 template <
typename Number,
bool is_face>
6413 const unsigned int dof)
const 6416 return this->values_dofs[0][dof];
6421 template <
typename Number,
bool is_face>
6424 const unsigned int q_point)
const 6434 template <
typename Number,
bool is_face>
6437 const unsigned int q_point)
const 6448 this->jacobian[q_point] :
6459 template <
typename Number,
bool is_face>
6462 const unsigned int q_point)
const 6469 template <
typename Number,
bool is_face>
6472 const unsigned int q_point)
const 6479 template <
typename Number,
bool is_face>
6482 const unsigned int q_point)
const 6489 template <
typename Number,
bool is_face>
6492 const unsigned int q_point)
const 6499 template <
typename Number,
bool is_face>
6500 inline DEAL_II_ALWAYS_INLINE
void DEAL_II_ALWAYS_INLINE
6503 const unsigned int dof)
6509 this->values_dofs[0][dof] = val_in;
6514 template <
typename Number,
bool is_face>
6515 inline DEAL_II_ALWAYS_INLINE
void 6518 const unsigned int q_point)
6533 this->J_value[0] * this->quadrature_weights[q_point];
6540 template <
typename Number,
bool is_face>
6541 inline DEAL_II_ALWAYS_INLINE
void 6544 const unsigned int q_point)
6551 template <
typename Number,
bool is_face>
6552 inline DEAL_II_ALWAYS_INLINE
void 6555 const unsigned int q_point)
6562 template <
typename Number,
bool is_face>
6563 inline DEAL_II_ALWAYS_INLINE
void 6566 const unsigned int q_point)
6576 this->jacobian[q_point] :
6580 this->J_value[q_point] :
6581 this->J_value[0] * this->quadrature_weights[q_point];
6588 template <
typename Number,
bool is_face>
6589 inline DEAL_II_ALWAYS_INLINE
void 6592 const unsigned int q_point)
6601 template <
typename Number,
bool is_face>
6602 inline DEAL_II_ALWAYS_INLINE
void 6605 const unsigned int q_point)
6612 template <
typename Number,
bool is_face>
6631 const unsigned int fe_no,
6633 const unsigned int first_selected_component)
6636 first_selected_component,
6640 , dofs_per_component(this->data->dofs_per_component_on_cell)
6641 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6642 , n_q_points(this->data->n_q_points)
6644 check_template_arguments(fe_no, 0);
6659 const unsigned int first_selected_component)
6664 first_selected_component,
6666 , dofs_per_component(this->data->dofs_per_component_on_cell)
6667 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6668 , n_q_points(this->data->n_q_points)
6684 const unsigned int first_selected_component)
6689 first_selected_component,
6691 , dofs_per_component(this->data->dofs_per_component_on_cell)
6692 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6693 , n_q_points(this->data->n_q_points)
6705 template <
int n_components_other>
6709 const unsigned int first_selected_component)
6714 first_selected_component,
6716 , dofs_per_component(this->data->dofs_per_component_on_cell)
6717 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6718 , n_q_points(this->data->n_q_points)
6733 , dofs_per_component(this->data->dofs_per_component_on_cell)
6734 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6735 , n_q_points(this->data->n_q_points)
6766 const unsigned int first_selected_component)
6769 (void)first_selected_component;
6775 static_cast<unsigned int>(fe_degree) != this->data->
fe_degree) ||
6778 std::string message =
6779 "-------------------------------------------------------\n";
6780 message +=
"Illegal arguments in constructor/wrong template arguments!\n";
6781 message +=
" Called --> FEEvaluation<dim,";
6785 message +=
",Number>(data";
6801 if (static_cast<unsigned int>(fe_degree) == this->data->
fe_degree)
6803 proposed_dof_comp = dof_no;
6807 for (
unsigned int no = 0; no < this->matrix_info->
n_components();
6809 for (
unsigned int nf = 0;
6812 if (this->matrix_info
6814 .
fe_degree ==
static_cast<unsigned int>(fe_degree))
6816 proposed_dof_comp = no;
6817 proposed_fe_comp = nf;
6823 proposed_quad_comp = this->
quad_no;
6825 for (
unsigned int no = 0;
6826 no < this->matrix_info->get_mapping_info().cell_data.size();
6828 if (this->matrix_info->get_mapping_info()
6833 proposed_quad_comp = no;
6840 if (proposed_dof_comp != first_selected_component)
6841 message +=
"Wrong vector component selection:\n";
6843 message +=
"Wrong quadrature formula selection:\n";
6844 message +=
" Did you mean FEEvaluation<dim,";
6848 message +=
",Number>(data";
6857 std::string correct_pos;
6858 if (proposed_dof_comp != dof_no)
6859 correct_pos =
" ^ ";
6862 if (proposed_quad_comp != this->
quad_no)
6863 correct_pos +=
" ^ ";
6866 if (proposed_fe_comp != first_selected_component)
6867 correct_pos +=
" ^\n";
6869 correct_pos +=
" \n";
6875 const unsigned int proposed_n_q_points_1d =
static_cast<unsigned int>(
6877 message +=
"Wrong template arguments:\n";
6878 message +=
" Did you mean FEEvaluation<dim,";
6882 message +=
",Number>(data";
6890 std::string correct_pos;
6891 if (this->data->
fe_degree != static_cast<unsigned int>(fe_degree))
6895 if (proposed_n_q_points_1d != n_q_points_1d)
6896 correct_pos +=
" ^\n";
6898 correct_pos +=
" \n";
6899 message +=
" " + correct_pos;
6901 Assert(static_cast<unsigned int>(fe_degree) == this->data->
fe_degree &&
6902 n_q_points == this->n_quadrature_points,
6921 const unsigned int cell_index)
6924 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 6925 " Integer indexing is not possible"));
6931 this->
cell = cell_index;
6933 this->matrix_info->get_mapping_info().get_cell_type(cell_index);
6935 const unsigned int offsets =
6955 template <
typename DoFHandlerType,
bool level_dof_access>
6960 Assert(this->matrix_info ==
nullptr,
6961 ExcMessage(
"Cannot use initialization from cell iterator if " 6962 "initialized from MatrixFree object. Use variant for " 6963 "on the fly computation with arguments as for FEValues " 6968 this->local_dof_indices.resize(
cell->get_fe().dofs_per_cell);
6969 if (level_dof_access)
6970 cell->get_mg_dof_indices(this->local_dof_indices);
6972 cell->get_dof_indices(this->local_dof_indices);
6986 Assert(this->matrix_info == 0,
6987 ExcMessage(
"Cannot use initialization from cell iterator if " 6988 "initialized from MatrixFree object. Use variant for " 6989 "on the fly computation with arguments as for FEValues " 7006 if (this->matrix_info ==
nullptr)
7020 const unsigned int n_q_points_1d_actual =
7021 fe_degree == -1 ? this->data->
n_q_points_1d : n_q_points_1d;
7035 return quadrature_points[q];
7037 point[0] = quadrature_points[q % n_q_points_1d_actual][0];
7038 point[1] = quadrature_points[q / n_q_points_1d_actual][1];
7041 point[0] = quadrature_points[q % n_q_points_1d_actual][0];
7042 point[1] = quadrature_points[(q / n_q_points_1d_actual) %
7043 n_q_points_1d_actual][1];
7044 point[2] = quadrature_points[q / (n_q_points_1d_actual *
7045 n_q_points_1d_actual)][2];
7054 return quadrature_points[q];
7066 const bool evaluate_values,
7067 const bool evaluate_gradients,
7068 const bool evaluate_hessians)
7088 const bool evaluate_values,
7089 const bool evaluate_gradients,
7090 const bool evaluate_hessians)
7102 this->hessians_quad[0][0],
7109 if (evaluate_values ==
true)
7111 if (evaluate_gradients ==
true)
7113 if (evaluate_hessians ==
true)
7125 template <
typename VectorType>
7129 const bool evaluate_values,
7130 const bool evaluate_gradients,
7131 const bool evaluate_hessians)
7137 if (std::is_same<typename VectorType::value_type, Number>::value &&
7141 IndexStorageVariants::interleaved_contiguous &&
7142 reinterpret_cast<std::size_t>(
7143 input_vector.begin() +
7152 input_vector.begin() +
7185 const bool integrate_values,
7186 const bool integrate_gradients)
7188 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7204 const bool integrate_values,
7205 const bool integrate_gradients,
7208 if (integrate_values ==
true)
7211 if (integrate_gradients ==
true)
7214 Assert(this->matrix_info !=
nullptr ||
7229 integrate_gradients,
7244 template <
typename VectorType>
7248 const bool integrate_gradients,
7249 VectorType &destination)
7256 if (std::is_same<typename VectorType::value_type, Number>::value &&
7260 IndexStorageVariants::interleaved_contiguous &&
7261 reinterpret_cast<std::size_t>(
7262 destination.begin() +
7271 destination.begin() +
7290 integrate_gradients,
7296 integrate_gradients,
7315 const bool is_interior_face,
7316 const unsigned int dof_no,
7318 const unsigned int first_selected_component)
7321 first_selected_component,
7326 , dofs_per_component(this->data->dofs_per_component_on_cell)
7327 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
7328 , n_q_points(this->data->n_q_points_face)
7340 const unsigned int face_index)
7343 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 7344 " Integer indexing is not possible"));
7348 this->cell = face_index;
7350 this->is_interior_face ?
7361 Assert(this->is_interior_face,
7362 ExcMessage(
"Boundary faces do not have a neighbor"));
7367 if (this->is_interior_face ==
true)
7385 this->cell_type = this->matrix_info->get_mapping_info().face_type[face_index];
7386 const unsigned int offsets =
7392 this->normal_x_jacobian =
7413 const unsigned int cell_index,
7414 const unsigned int face_number)
7418 this->matrix_info->get_mapping_info().face_data_by_cells.size(),
7420 "You must set MatrixFree::AdditionalData::mapping_update_flags_faces_by_cells to use the present reinit method."));
7423 this->matrix_info->get_mapping_info().cell_type.size());
7425 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 7426 " Integer indexing is not possible"));
7427 Assert(this->is_interior_face ==
true,
7429 "Cell-based FEFaceEvaluation::reinit only possible for the " 7430 "interior face with second argument to constructor as true"));
7435 this->cell_type = this->matrix_info->get_mapping_info().cell_type[cell_index];
7436 this->cell = cell_index;
7443 const unsigned int offsets =
7444 this->matrix_info->get_mapping_info()
7445 .face_data_by_cells[this->
quad_no]
7449 this->matrix_info->get_mapping_info()
7450 .face_data_by_cells[this->
quad_no]
7451 .JxW_values.size());
7452 this->J_value = &this->matrix_info->get_mapping_info()
7453 .face_data_by_cells[this->
quad_no]
7454 .JxW_values[offsets];
7455 this->normal_vectors = &this->matrix_info->get_mapping_info()
7456 .face_data_by_cells[this->
quad_no]
7457 .normal_vectors[offsets];
7458 this->jacobian = &this->matrix_info->get_mapping_info()
7459 .face_data_by_cells[this->
quad_no]
7460 .jacobians[0][offsets];
7461 this->normal_x_jacobian = &this->matrix_info->get_mapping_info()
7462 .face_data_by_cells[this->
quad_no]
7463 .normals_times_jacobians[0][offsets];
7482 const bool evaluate_values,
7483 const bool evaluate_gradients)
7487 evaluate(this->values_dofs[0], evaluate_values, evaluate_gradients);
7500 const bool evaluate_values,
7501 const bool evaluate_gradients)
7503 if (!(evaluate_values + evaluate_gradients))
7506 constexpr
unsigned int static_dofs_per_face =
7508 numbers::invalid_unsigned_int;
7509 const unsigned int dofs_per_face =
7510 fe_degree > -1 ? static_dofs_per_face :
7519 constexpr
unsigned int stack_array_size_threshold = 100;
7522 temp_data[static_dofs_per_face < stack_array_size_threshold ?
7523 n_components * 2 * static_dofs_per_face :
7526 if (static_dofs_per_face < stack_array_size_threshold)
7527 temp1 = &temp_data[0];
7531 internal::FEFaceNormalEvaluationImpl<dim,
7535 template interpolate<true, false>(
7536 *this->
data, values_array, temp1, evaluate_gradients, this->
face_no);
7538 const unsigned int n_q_points_1d_actual = fe_degree > -1 ? n_q_points_1d : 0;
7539 if (fe_degree > -1 &&
7541 this->data->element_type <=
7543 internal::FEFaceEvaluationImpl<
7547 n_q_points_1d_actual,
7560 internal::FEFaceEvaluationImpl<
7564 n_q_points_1d_actual,
7581 if (evaluate_values ==
true)
7583 if (evaluate_gradients ==
true)
7597 integrate(
const bool integrate_values,
const bool integrate_gradients)
7599 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7616 const bool integrate_gradients,
7619 if (!(integrate_values + integrate_gradients))
7625 constexpr
unsigned int static_dofs_per_face =
7627 numbers::invalid_unsigned_int;
7628 const unsigned int dofs_per_face =
7629 fe_degree > -1 ? static_dofs_per_face :
7632 constexpr
unsigned int stack_array_size_threshold = 100;
7635 temp_data[static_dofs_per_face < stack_array_size_threshold ?
7636 n_components * 2 * static_dofs_per_face :
7639 if (static_dofs_per_face < stack_array_size_threshold)
7640 temp1 = &temp_data[0];
7644 const unsigned int n_q_points_1d_actual = fe_degree > -1 ? n_q_points_1d : 0;
7645 if (fe_degree > -1 &&
7647 this->data->element_type <=
7649 internal::FEFaceEvaluationImpl<
7653 n_q_points_1d_actual,
7663 integrate_gradients,
7666 internal::FEFaceEvaluationImpl<
7670 n_q_points_1d_actual,
7680 integrate_gradients,
7683 internal::FEFaceNormalEvaluationImpl<dim,
7687 template interpolate<false, false>(
7688 *this->
data, temp1, values_array, integrate_gradients, this->
face_no);
7698 template <
typename VectorType>
7702 const bool evaluate_values,
7703 const bool evaluate_gradients)
7705 const unsigned int side = this->
face_no % 2;
7707 constexpr
unsigned int static_dofs_per_face =
7709 numbers::invalid_unsigned_int;
7710 const unsigned int dofs_per_face =
7711 fe_degree > -1 ? static_dofs_per_face :
7714 constexpr
unsigned int stack_array_size_threshold = 100;
7717 temp_data[static_dofs_per_face < stack_array_size_threshold ?
7718 n_components_ * 2 * dofs_per_face :
7721 if (static_dofs_per_face < stack_array_size_threshold)
7722 temp1 = &temp_data[0];
7726 internal::VectorReader<Number> reader;
7727 std::integral_constant<bool,
7728 internal::is_vectorizable<VectorType, Number>::value>
7732 if (((evaluate_gradients ==
false &&
7733 this->data->nodal_at_cell_boundaries ==
true) ||
7734 (this->data->element_type ==
7738 ->index_storage_variants[this->dof_access_index][this->cell] ==
7740 interleaved_contiguous)
7746 const unsigned int dof_index =
7756 if (fe_degree > 1 && evaluate_gradients ==
true)
7762 this->data->shape_data_on_face[0][fe_degree + 1 + side];
7765 const unsigned int *index_array =
7766 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
7767 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7769 const unsigned int ind1 = index_array[2 * i];
7770 const unsigned int ind2 = index_array[2 * i + 1];
7773 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7775 reader.process_dofs_vectorized(
7780 temp1 + i + 2 * comp * dofs_per_face,
7782 reader.process_dofs_vectorized(
7784 dof_index + (ind2 + comp * static_dofs_per_component) *
7785 VectorizedArray<Number>::n_array_elements,
7787 temp1 + dofs_per_face + i + 2 * comp * dofs_per_face,
7789 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
7791 (temp1[i + 2 * comp * dofs_per_face] -
7792 temp1[i + dofs_per_face + 2 * comp * dofs_per_face]);
7800 const unsigned int *index_array =
7801 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
7802 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7804 const unsigned int ind = index_array[i];
7805 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7806 reader.process_dofs_vectorized(
7811 temp1 + i + 2 * comp * dofs_per_face,
7818 else if (((evaluate_gradients ==
false &&
7819 this->data->nodal_at_cell_boundaries ==
true) ||
7820 (this->data->element_type ==
7824 ->index_storage_variants[this->dof_access_index][this->cell] ==
7826 interleaved_contiguous_strided)
7832 const unsigned int *indices =
7837 if (fe_degree > 1 && evaluate_gradients ==
true)
7843 this->data->shape_data_on_face[0][fe_degree + 1 + side];
7847 const unsigned int *index_array =
7848 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
7849 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7851 const unsigned int ind1 =
7853 const unsigned int ind2 =
7854 index_array[2 * i + 1] *
7855 VectorizedArray<Number>::n_array_elements;
7856 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7858 reader.process_dof_gather(
7863 VectorizedArray<Number>::n_array_elements +
7865 [this->active_fe_index]
7866 [this->first_selected_component] *
7867 VectorizedArray<Number>::n_array_elements,
7868 temp1[i + 2 * comp * dofs_per_face],
7871 reader.process_dof_gather(
7876 VectorizedArray<Number>::n_array_elements +
7878 [this->active_fe_index]
7879 [this->first_selected_component] *
7880 VectorizedArray<Number>::n_array_elements,
7883 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
7884 grad_weight * (temp1[i + 2 * comp * dofs_per_face] - grad);
7892 const unsigned int *index_array =
7893 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
7894 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7896 const unsigned int ind =
7897 index_array[i] * VectorizedArray<Number>::n_array_elements;
7898 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7899 reader.process_dof_gather(
7904 VectorizedArray<Number>::n_array_elements +
7905 this->dof_info->component_dof_indices_offset
7906 [this->active_fe_index]
7907 [this->first_selected_component] *
7908 VectorizedArray<Number>::n_array_elements,
7909 temp1[i + 2 * comp * dofs_per_face],
7916 else if (((evaluate_gradients ==
false &&
7917 this->data->nodal_at_cell_boundaries ==
true) ||
7918 (this->data->element_type ==
7922 ->index_storage_variants[this->dof_access_index][this->cell] ==
7924 interleaved_contiguous_mixed_strides)
7926 const unsigned int *strides =
7929 [this->cell * VectorizedArray<Number>::n_array_elements];
7930 unsigned int indices[VectorizedArray<Number>::n_array_elements];
7931 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
7935 [this->dof_access_index]
7936 [this->cell * VectorizedArray<Number>::n_array_elements + v] +
7938 ->component_dof_indices_offset[this->active_fe_index]
7939 [this->first_selected_component] *
7941 const unsigned int nvec =
7943 ->n_vectorization_lanes_filled[this->dof_access_index][this->cell];
7945 if (fe_degree > 1 && evaluate_gradients ==
true)
7951 this->data->shape_data_on_face[0][fe_degree + 1 + side];
7955 const unsigned int *index_array =
7956 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
7957 if (nvec == VectorizedArray<Number>::n_array_elements)
7958 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7959 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7961 unsigned int ind1[VectorizedArray<Number>::n_array_elements];
7962 DEAL_II_OPENMP_SIMD_PRAGMA
7963 for (
unsigned int v = 0;
7964 v < VectorizedArray<Number>::n_array_elements;
7967 index_array[2 * i]) *
7969 unsigned int ind2[VectorizedArray<Number>::n_array_elements];
7970 DEAL_II_OPENMP_SIMD_PRAGMA
7971 for (
unsigned int v = 0;
7972 v < VectorizedArray<Number>::n_array_elements;
7975 index_array[2 * i + 1]) *
7977 reader.process_dof_gather(ind1,
7980 temp1[i + 2 * comp * dofs_per_face],
7983 reader.process_dof_gather(
7984 ind2, input_vector, 0, grad, vector_selector);
7985 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
7986 grad_weight * (temp1[i + 2 * comp * dofs_per_face] - grad);
7990 for (
unsigned int i = 0; i < n_components_ * 2 * dofs_per_face;
7993 for (
unsigned int v = 0; v < nvec; ++v)
7994 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7995 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7997 const unsigned int ind1 =
7999 index_array[2 * i]) *
8001 const unsigned int ind2 =
8003 index_array[2 * i + 1]) *
8007 const_cast<VectorType &>(input_vector),
8008 temp1[i + 2 * comp * dofs_per_face][v]);
8010 reader.process_dof(ind2,
8011 const_cast<VectorType &>(input_vector),
8013 temp1[i + dofs_per_face + 2 * comp * dofs_per_face][v] =
8015 (temp1[i + 2 * comp * dofs_per_face][v] - grad);
8023 const unsigned int *index_array =
8024 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
8025 if (nvec == VectorizedArray<Number>::n_array_elements)
8026 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8027 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8029 unsigned int ind[VectorizedArray<Number>::n_array_elements];
8030 DEAL_II_OPENMP_SIMD_PRAGMA
8031 for (
unsigned int v = 0;
8032 v < VectorizedArray<Number>::n_array_elements;
8037 reader.process_dof_gather(ind,
8040 temp1[i + 2 * comp * dofs_per_face],
8045 for (
unsigned int i = 0; i < n_components_ * dofs_per_face; ++i)
8047 for (
unsigned int v = 0; v < nvec; ++v)
8048 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8049 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8051 const unsigned int ind1 =
8057 const_cast<VectorType &>(input_vector),
8058 temp1[i + 2 * comp * dofs_per_face][v]);
8065 else if (((evaluate_gradients ==
false &&
8066 this->data->nodal_at_cell_boundaries ==
true) ||
8067 (this->data->element_type ==
8071 ->index_storage_variants[this->dof_access_index][this->cell] ==
8074 this->dof_info->n_vectorization_lanes_filled[this->dof_access_index]
8076 VectorizedArray<Number>::n_array_elements)
8078 const unsigned int *indices =
8082 VectorizedArray<Number>::n_array_elements];
8083 if (evaluate_gradients ==
true &&
8084 this->data->element_type ==
8091 this->data->shape_data_on_face[0][fe_degree + 1 + side];
8095 const unsigned int *index_array =
8096 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
8097 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8099 const unsigned int ind1 = index_array[2 * i];
8100 const unsigned int ind2 = index_array[2 * i + 1];
8101 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8103 reader.process_dof_gather(
8108 [this->active_fe_index][this->first_selected_component],
8109 temp1[i + 2 * comp * dofs_per_face],
8112 reader.process_dof_gather(
8117 [this->active_fe_index][this->first_selected_component],
8120 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
8121 grad_weight * (temp1[i + 2 * comp * dofs_per_face] - grad);
8129 const unsigned int *index_array =
8130 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
8131 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8132 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8134 const unsigned int ind = index_array[i];
8135 reader.process_dof_gather(
8140 [this->active_fe_index][this->first_selected_component],
8141 temp1[i + comp * 2 * dofs_per_face],
8151 internal::FEFaceNormalEvaluationImpl<dim,
8155 template interpolate<true, false>(*this->
data,
8156 this->values_dofs[0],
8162 if (fe_degree > -1 &&
8164 this->data->element_type <=
8166 internal::FEFaceEvaluationImpl<
8183 internal::FEFaceEvaluationImpl<
8204 if (evaluate_values ==
true)
8206 if (evaluate_gradients ==
true)
8218 template <
typename VectorType>
8222 const bool integrate_gradients,
8223 VectorType &destination)
8225 const unsigned int side = this->
face_no % 2;
8226 const unsigned int dofs_per_face =
8228 Utilities::pow(this->data->fe_degree + 1, dim - 1);
8230 constexpr
unsigned int stack_array_size_threshold = 100;
8233 n_components_ * 2 * dofs_per_face :
8236 if (dofs_per_face < stack_array_size_threshold)
8237 temp1 = &temp_data[0];
8243 if (fe_degree > -1 &&
8245 this->data->element_type <=
8247 internal::FEFaceEvaluationImpl<
8261 integrate_gradients,
8264 internal::FEFaceEvaluationImpl<
8278 integrate_gradients,
8285 internal::VectorDistributorLocalToGlobal<Number> writer;
8286 std::integral_constant<bool,
8287 internal::is_vectorizable<VectorType, Number>::value>
8291 if (((integrate_gradients ==
false &&
8292 this->data->nodal_at_cell_boundaries ==
true) ||
8293 (this->data->element_type ==
8297 ->index_storage_variants[this->dof_access_index][this->cell] ==
8299 interleaved_contiguous)
8304 VectorizedArray<Number>::n_array_elements);
8305 const unsigned int dof_index =
8309 VectorizedArray<Number>::n_array_elements] +
8313 VectorizedArray<Number>::n_array_elements;
8315 if (fe_degree > 1 && integrate_gradients ==
true)
8321 this->data->shape_data_on_face[0][fe_degree + 2 - side];
8324 const unsigned int *index_array =
8325 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
8326 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8328 const unsigned int ind1 = index_array[2 * i];
8329 const unsigned int ind2 = index_array[2 * i + 1];
8332 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8335 temp1[i + 2 * comp * dofs_per_face] -
8337 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8340 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8341 writer.process_dofs_vectorized(
8344 VectorizedArray<Number>::n_array_elements,
8348 writer.process_dofs_vectorized(
8350 dof_index + (ind2 + comp * static_dofs_per_component) *
8351 VectorizedArray<Number>::n_array_elements,
8362 const unsigned int *index_array =
8363 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
8364 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8366 const unsigned int ind = index_array[i];
8367 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8368 writer.process_dofs_vectorized(
8371 VectorizedArray<Number>::n_array_elements,
8373 temp1 + i + 2 * comp * dofs_per_face,
8380 else if (((integrate_gradients ==
false &&
8381 this->data->nodal_at_cell_boundaries ==
true) ||
8382 (this->data->element_type ==
8386 ->index_storage_variants[this->dof_access_index][this->cell] ==
8388 interleaved_contiguous_strided)
8393 VectorizedArray<Number>::n_array_elements);
8394 const unsigned int *indices =
8398 VectorizedArray<Number>::n_array_elements];
8399 if (fe_degree > 1 && integrate_gradients ==
true)
8405 this->data->shape_data_on_face[0][fe_degree + 2 - side];
8409 const unsigned int *index_array =
8410 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
8411 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8413 const unsigned int ind1 =
8414 index_array[2 * i] * VectorizedArray<Number>::n_array_elements;
8415 const unsigned int ind2 =
8416 index_array[2 * i + 1] *
8417 VectorizedArray<Number>::n_array_elements;
8418 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8421 temp1[i + 2 * comp * dofs_per_face] -
8423 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8426 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8427 writer.process_dof_gather(
8432 VectorizedArray<Number>::n_array_elements +
8434 [this->active_fe_index]
8435 [this->first_selected_component] *
8436 VectorizedArray<Number>::n_array_elements,
8439 writer.process_dof_gather(
8444 VectorizedArray<Number>::n_array_elements +
8446 [this->active_fe_index]
8447 [this->first_selected_component] *
8448 VectorizedArray<Number>::n_array_elements,
8458 const unsigned int *index_array =
8459 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
8460 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8462 const unsigned int ind =
8463 index_array[i] * VectorizedArray<Number>::n_array_elements;
8464 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8465 writer.process_dof_gather(
8470 VectorizedArray<Number>::n_array_elements +
8471 this->dof_info->component_dof_indices_offset
8472 [this->active_fe_index]
8473 [this->first_selected_component] *
8474 VectorizedArray<Number>::n_array_elements,
8475 temp1[i + 2 * comp * dofs_per_face],
8482 else if (((integrate_gradients ==
false &&
8483 this->data->nodal_at_cell_boundaries ==
true) ||
8484 (this->data->element_type ==
8488 ->index_storage_variants[this->dof_access_index][this->cell] ==
8490 interleaved_contiguous_mixed_strides)
8492 const unsigned int *strides =
8495 [this->cell * VectorizedArray<Number>::n_array_elements];
8496 unsigned int indices[VectorizedArray<Number>::n_array_elements];
8497 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
8501 [this->dof_access_index]
8502 [this->cell * VectorizedArray<Number>::n_array_elements + v] +
8504 ->component_dof_indices_offset[this->active_fe_index]
8505 [this->first_selected_component] *
8507 const unsigned int nvec =
8509 ->n_vectorization_lanes_filled[this->dof_access_index][this->cell];
8511 if (fe_degree > 1 && integrate_gradients ==
true)
8517 this->data->shape_data_on_face[0][fe_degree + 2 - side];
8521 const unsigned int *index_array =
8522 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
8523 if (nvec == VectorizedArray<Number>::n_array_elements)
8524 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8525 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8527 unsigned int ind1[VectorizedArray<Number>::n_array_elements];
8528 DEAL_II_OPENMP_SIMD_PRAGMA
8529 for (
unsigned int v = 0;
8530 v < VectorizedArray<Number>::n_array_elements;
8533 index_array[2 * i]) *
8535 unsigned int ind2[VectorizedArray<Number>::n_array_elements];
8536 DEAL_II_OPENMP_SIMD_PRAGMA
8537 for (
unsigned int v = 0;
8538 v < VectorizedArray<Number>::n_array_elements;
8541 index_array[2 * i + 1]) *
8544 temp1[i + 2 * comp * dofs_per_face] -
8546 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8549 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8550 writer.process_dof_gather(
8551 ind1, destination, 0, val, vector_selector);
8552 writer.process_dof_gather(
8553 ind2, destination, 0, grad, vector_selector);
8557 for (
unsigned int v = 0; v < nvec; ++v)
8558 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8559 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8561 const unsigned int ind1 =
8563 index_array[2 * i]) *
8565 const unsigned int ind2 =
8567 index_array[2 * i + 1]) *
8570 temp1[i + 2 * comp * dofs_per_face][v] -
8571 grad_weight[0] * temp1[i + dofs_per_face +
8572 2 * comp * dofs_per_face][v];
8575 temp1[i + dofs_per_face + 2 * comp * dofs_per_face][v];
8576 writer.process_dof(ind1, destination, val);
8577 writer.process_dof(ind2, destination, grad);
8585 const unsigned int *index_array =
8586 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
8587 if (nvec == VectorizedArray<Number>::n_array_elements)
8588 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8589 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8591 unsigned int ind[VectorizedArray<Number>::n_array_elements];
8592 DEAL_II_OPENMP_SIMD_PRAGMA
8593 for (
unsigned int v = 0;
8594 v < VectorizedArray<Number>::n_array_elements;
8599 writer.process_dof_gather(ind,
8602 temp1[i + 2 * comp * dofs_per_face],
8607 for (
unsigned int v = 0; v < nvec; ++v)
8608 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8609 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8611 const unsigned int ind1 =
8618 temp1[i + 2 * comp * dofs_per_face][v]);
8625 else if (((integrate_gradients ==
false &&
8626 this->data->nodal_at_cell_boundaries ==
true) ||
8627 (this->data->element_type ==
8631 ->index_storage_variants[this->dof_access_index][this->cell] ==
8634 this->dof_info->n_vectorization_lanes_filled[this->dof_access_index]
8636 VectorizedArray<Number>::n_array_elements)
8638 const unsigned int *indices =
8642 VectorizedArray<Number>::n_array_elements];
8644 if (integrate_gradients ==
true &&
8645 this->data->element_type ==
8652 this->data->shape_data_on_face[0][fe_degree + 2 - side];
8655 const unsigned int *index_array =
8656 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
8657 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8659 const unsigned int ind1 = index_array[2 * i];
8660 const unsigned int ind2 = index_array[2 * i + 1];
8661 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8664 temp1[i + 2 * comp * dofs_per_face] -
8666 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8669 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
8670 writer.process_dof_gather(
8675 [this->active_fe_index][this->first_selected_component],
8678 writer.process_dof_gather(
8683 [this->active_fe_index][this->first_selected_component],
8693 const unsigned int *index_array =
8694 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
8695 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8697 const unsigned int ind = index_array[i];
8698 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8699 writer.process_dof_gather(
8703 this->dof_info->component_dof_indices_offset
8704 [this->active_fe_index][this->first_selected_component],
8705 temp1[i + 2 * comp * dofs_per_face],
8714 internal::FEFaceNormalEvaluationImpl<dim,
8718 template interpolate<false, false>(*this->
data,
8720 this->values_dofs[0],
8721 integrate_gradients,
8738 const bool gradients)
8741 const unsigned int * orientations =
8749 for (
unsigned int q = 0; q <
n_q_points; ++q)
8750 tmp_values[q] = this->
values_quad[c][orientations[q]];
8752 for (
unsigned int q = 0; q <
n_q_points; ++q)
8753 tmp_values[orientations[q]] = this->
values_quad[c][q];
8754 for (
unsigned int q = 0; q <
n_q_points; ++q)
8757 if (gradients ==
true)
8758 for (
unsigned int d = 0; d < dim; ++d)
8761 for (
unsigned int q = 0; q <
n_q_points; ++q)
8764 for (
unsigned int q = 0; q <
n_q_points; ++q)
8766 for (
unsigned int q = 0; q <
n_q_points; ++q)
8795 Assert(this->matrix_info->get_mapping_info()
8796 .face_data_by_cells[this->
quad_no]
8797 .quadrature_point_offsets.empty() ==
false,
8799 const unsigned int index =
8802 this->matrix_info->get_mapping_info()
8803 .face_data_by_cells[this->
quad_no]
8804 .quadrature_point_offsets.size());
8805 return this->matrix_info->get_mapping_info()
8806 .face_data_by_cells[this->
quad_no]
8807 .quadrature_points[this->matrix_info->get_mapping_info()
8808 .face_data_by_cells[this->
quad_no]
8809 .quadrature_point_offsets[index] +
8819 #endif // ifndef DOXYGEN 8822 DEAL_II_NAMESPACE_CLOSE
gradient_type get_gradient(const unsigned int q_point) const
const unsigned int active_quad_index
std::vector< unsigned int > plain_dof_indices
bool gradients_quad_submitted
AlignedVector< Tensor< 1, spacedim, VectorizedArray< Number > > > normals_times_jacobians[2]
static const unsigned int invalid_unsigned_int
const Number * constraint_pool_begin(const unsigned int pool_index) const
unsigned int dofs_per_component_on_cell
void store(Number *ptr) const
const VectorizedArray< Number > * begin_hessians() const
AlignedVector< unsigned int > data_index_offsets
#define AssertDimension(dim1, dim2)
void submit_divergence(const VectorizedArray< Number > div_in, const unsigned int q_point)
bool values_quad_initialized
void check_template_arguments(const unsigned int fe_no, const unsigned int first_selected_component)
FEEvaluation & operator=(const FEEvaluation &other)
AlignedVector< Tensor< 1, spacedim *(spacedim+1)/2, Tensor< 1, spacedim, VectorizedArray< Number > > > > jacobian_gradients[2]
internal::MatrixFreeFunctions::GeometryType get_cell_type() const
internal::MatrixFreeFunctions::GeometryType cell_type
static ::ExceptionBase & ExcAccessToUninitializedField()
std::vector< unsigned int > component_to_base_index
const internal::MatrixFreeFunctions::TaskInfo & get_size_info() const
std::vector< IndexStorageVariants > index_storage_variants[3]
const unsigned int dofs_per_cell
unsigned int n_components() const
void evaluate(const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
AlignedVector< unsigned int > quadrature_point_offsets
void integrate(const bool integrate_values, const bool integrate_gradients)
void read_write_operation(const VectorOperation &operation, VectorType *vectors[], const std::bitset< VectorizedArray< Number >::n_array_elements > &mask, const bool apply_constraints=true) const
Point< dim, VectorizedArray< Number > > quadrature_point(const unsigned int q_point) const
std::vector< unsigned int > dof_indices_interleave_strides[3]
void submit_normal_derivative(const value_type grad_in, const unsigned int q_point)
unsigned char face_orientation
#define AssertIndexRange(index, range)
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
ArrayView< VectorizedArray< Number > > get_scratch_data() const
FEEvaluationBase & operator=(const FEEvaluationBase &other)
const internal::MatrixFreeFunctions::MappingInfoStorage<(is_face ? dim - 1 :dim), dim, Number > * mapping_data
const unsigned int active_fe_index
const VectorizedArray< Number > * begin_dof_values() const
void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector)
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > * data
Transformed quadrature points.
static ::ExceptionBase & ExcNotInitialized()
std::vector< unsigned int > cell_partition_data
void read_dof_values(const VectorType &src, const unsigned int first_index=0)
bool values_quad_submitted
FEEvaluationAccess & operator=(const FEEvaluationAccess &other)
AlignedVector< VectorizedArray< Number > > * scratch_data_array
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
void scatter(const unsigned int *offsets, Number *base_ptr) const
std::vector< unsigned int > dof_indices
SymmetricTensor< 2, dim, VectorizedArray< Number > > get_symmetric_gradient(const unsigned int q_point) const
value_type integrate_value() const
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
const unsigned int dofs_per_component
value_type get_value(const unsigned int q_point) const
void submit_value(const value_type val_in, const unsigned int q_point)
std::vector< QuadratureDescriptor > descriptor
VectorizedArray< Number > JxW(const unsigned int q_index) const
std::vector< unsigned char > n_vectorization_lanes_filled[3]
AlignedVector< VectorizedArray< Number > > * acquire_scratch_data() const
unsigned int vectorization_length
const Tensor< 1, dim, VectorizedArray< Number > > * normal_vectors
const Number * quadrature_weights
void set_dof_values(VectorType &dst, const unsigned int first_index=0, const std::bitset< VectorizedArray< Number >::n_array_elements > &mask=std::bitset< VectorizedArray< Number >::n_array_elements >().flip()) const
void read_dof_values_plain(const VectorType &src, const unsigned int first_index=0)
const unsigned int dofs_per_cell
internal::MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index
static ::ExceptionBase & ExcMessage(std::string arg1)
gradient_type get_hessian_diagonal(const unsigned int q_point) const
const unsigned int n_q_points
value_type get_laplacian(const unsigned int q_point) const
void submit_symmetric_gradient(const SymmetricTensor< 2, dim, VectorizedArray< Number >> grad_in, const unsigned int q_point)
const Tensor< 2, dim, VectorizedArray< Number > > * jacobian
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > & get_shape_info() const
std::pair< unsigned int, unsigned int > component_to_base_index(const unsigned int component) const
VectorizedArray< Number > get_divergence(const unsigned int q_point) const
std::vector< unsigned int > dof_indices_interleaved
const unsigned int quad_no
VectorizedArray< Number > * scratch_data
#define Assert(cond, exc)
unsigned int element_multiplicity(const unsigned int index) const
Point< dim, VectorizedArray< Number > > quadrature_point(const unsigned int q_point) const
const internal::MatrixFreeFunctions::DoFInfo * dof_info
const VectorizedArray< Number > * begin_values() const
unsigned int subface_index
std::vector< unsigned int > row_starts_plain_indices
void read_write_operation_contiguous(const VectorOperation &operation, VectorType *vectors[], const std::bitset< VectorizedArray< Number >::n_array_elements > &mask) const
constexpr unsigned int pow(const unsigned int base, const int iexp)
unsigned int n_q_points_face
const MatrixFree< dim, Number > * matrix_info
#define DeclException0(Exception0)
std::vector< unsigned int > boundary_partition_data
const Number * constraint_pool_end(const unsigned int pool_index) const
Tensor< 2, dim, VectorizedArray< Number > > inverse_jacobian(const unsigned int q_index) const
void read_write_operation_global(const VectorOperation &operation, VectorType *vectors[]) const
std::vector< std::pair< unsigned int, unsigned int > > row_starts
unsigned int get_mapping_data_index_offset() const
void reinit(const unsigned int face_batch_number)
VectorizedArray< Number > * gradients_quad[n_components][dim]
void submit_curl(const Tensor< 1, dim==2 ? 1 :dim, VectorizedArray< Number >> curl_in, const unsigned int q_point)
std::shared_ptr< internal::MatrixFreeFunctions::MappingDataOnTheFly< dim, Number > > mapped_geometry
friend class FEEvaluationBase
void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients)
std::vector< std::pair< unsigned short, unsigned short > > constraint_indicator
unsigned char subface_index
const VectorizedArray< Number > * J_value
bool mapping_initialized() const
bool hessians_quad_initialized
AlignedVector< Point< spacedim, VectorizedArray< Number > > > quadrature_points
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Tensor< 1, n_components_, Tensor< 2, dim, VectorizedArray< Number > > > get_hessian(const unsigned int q_point) const
void reinit(const unsigned int cell_batch_index)
void adjust_for_face_orientation(const bool integrate, const bool values, const bool gradients)
void integrate(const bool integrate_values, const bool integrate_gradients)
static constexpr unsigned int n_components
std::vector< unsigned int > face_partition_data
unsigned int global_dof_index
unsigned char exterior_face_no
FEFaceEvaluation(const MatrixFree< dim, Number > &matrix_free, const bool is_interior_face=true, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
void resize_fast(const size_type size)
unsigned int n_q_points_1d
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0, const std::bitset< VectorizedArray< Number >::n_array_elements > &mask=std::bitset< VectorizedArray< Number >::n_array_elements >().flip()) const
void evaluate(const bool evaluate_values, const bool evaluate_gradients)
value_type get_dof_value(const unsigned int dof) const
std::vector< unsigned int > dof_indices_contiguous[3]
void load(const Number *ptr)
AlignedVector< Tensor< 1, spacedim, VectorizedArray< Number > > > normal_vectors
const unsigned int n_q_points
std::vector< std::vector< unsigned int > > component_dof_indices_offset
VectorizedArray< Number > * values_dofs[n_components]
const VectorizedArray< Number > * begin_gradients() const
Tensor< 1, dim, VectorizedArray< Number > > get_normal_vector(const unsigned int q_point) const
const internal::MatrixFreeFunctions::FaceToCellTopology< VectorizedArray< Number >::n_array_elements > & get_face_info(const unsigned int face_batch_number) const
VectorizedArray< Number > read_cell_data(const AlignedVector< VectorizedArray< Number >> &array) const
unsigned int get_cell_data_number() const
unsigned int n_base_elements(const unsigned int dof_handler_index) const
static constexpr unsigned int static_dofs_per_component
const unsigned int n_quadrature_points
void gather(const Number *base_ptr, const unsigned int *offsets)
const unsigned int dofs_per_component
static ::ExceptionBase & ExcNotImplemented()
const Tensor< 1, dim, VectorizedArray< Number > > * normal_x_jacobian
std::vector< types::global_dof_index > local_dof_indices
value_type get_normal_derivative(const unsigned int q_point) const
void fill_JxW_values(AlignedVector< VectorizedArray< Number >> &JxW_values) const
bool indices_initialized() const
bool dof_values_initialized
void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
VectorizedArray< Number > * values_quad[n_components]
void submit_dof_value(const value_type val_in, const unsigned int dof)
bool gradients_quad_initialized
std::vector< unsigned int > start_components
void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector)
std::vector< unsigned int > lexicographic_numbering
FEEvaluation(const MatrixFree< dim, Number > &matrix_free, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
FEEvaluationAccess(const MatrixFree< dim, Number > &matrix_free, const unsigned int dof_no, const unsigned int first_selected_component, const unsigned int quad_no, const unsigned int fe_degree, const unsigned int n_q_points, const bool is_interior_face=true)
unsigned int face_orientation
static constexpr unsigned int static_n_q_points
AlignedVector< Tensor< 2, spacedim, VectorizedArray< Number > > > jacobians[2]
unsigned char interior_face_no
AlignedVector< VectorizedArray< Number > > JxW_values
const std::vector< unsigned int > & get_internal_dof_numbering() const
const unsigned int n_fe_components
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
Tensor< 1,(dim==2 ? 1 :dim), VectorizedArray< Number > > get_curl(const unsigned int q_point) const
void submit_gradient(const gradient_type grad_in, const unsigned int q_point)
const unsigned int first_selected_component
static ::ExceptionBase & ExcInternalError()
void release_scratch_data(const AlignedVector< VectorizedArray< Number >> *memory) const