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_;
174 template <
typename VectorType>
176 read_dof_values(
const VectorType &src,
const unsigned int first_index = 0);
206 template <
typename VectorType>
209 const unsigned int first_index = 0);
241 template <
typename VectorType>
245 const unsigned int first_index = 0,
281 template <
typename VectorType>
285 const unsigned int first_index = 0,
339 get_value(
const unsigned int q_point)
const;
417 const unsigned int q_point);
477 get_curl(
const unsigned int q_point)
const;
489 const unsigned int q_point);
503 const unsigned int q_point);
517 const unsigned int q_point);
545 JxW(
const unsigned int q_index)
const;
552 DEAL_II_DEPRECATED
void 705 const std::vector<unsigned int> &
729 const unsigned int dof_no,
732 const unsigned int fe_degree,
733 const unsigned int n_q_points,
770 template <
int n_components_other>
802 template <
typename VectorType,
typename VectorOperation>
806 VectorType * vectors[],
808 const bool apply_constraints =
true)
const;
817 template <
typename VectorType,
typename VectorOperation>
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;
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,
1151 const unsigned int fe_degree,
1152 const unsigned int n_q_points,
1159 template <
int n_components_other>
1192 template <
int dim,
typename Number,
bool is_face>
1197 using number_type = Number;
1200 static constexpr
unsigned int dimension = dim;
1216 get_value(
const unsigned int q_point)
const;
1227 const unsigned int q_point);
1248 const unsigned int q_point);
1279 const unsigned int dof_no,
1282 const unsigned int fe_degree,
1283 const unsigned int n_q_points,
1290 template <
int n_components_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;
1362 get_curl(
const unsigned int q_point)
const;
1390 const unsigned int q_point);
1402 const unsigned int q_point);
1415 const unsigned int q_point);
1424 const unsigned int q_point);
1435 const unsigned int dof_no,
1438 const unsigned int dofs_per_cell,
1439 const unsigned int n_q_points,
1446 template <
int n_components_other>
1479 template <
typename Number,
bool is_face>
1484 using number_type = Number;
1487 static constexpr
unsigned int dimension = 1;
1503 get_value(
const unsigned int q_point)
const;
1539 const unsigned int q_point);
1545 const unsigned int q_point);
1576 const unsigned int dof_no,
1579 const unsigned int fe_degree,
1580 const unsigned int n_q_points,
1587 template <
int n_components_other>
2176 using number_type = Number;
2268 const unsigned int dof_no = 0,
2269 const unsigned int quad_no = 0,
2324 template <
int n_components_other>
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>
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);
2465 const bool integrate_gradients,
2481 template <
typename VectorType>
2484 const bool integrate_gradients,
2485 VectorType &output_vector);
2564 int n_q_points_1d = fe_degree + 1,
2565 int n_components_ = 1,
2566 typename Number =
double>
2579 using number_type = Number;
2683 const unsigned int dof_no = 0,
2684 const unsigned int quad_no = 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>
2754 const bool evaluate_values,
2755 const bool evaluate_gradients);
2767 integrate(
const bool integrate_values,
const bool integrate_gradients);
2779 const bool integrate_gradients,
2793 template <
typename VectorType>
2796 const bool integrate_gradients,
2797 VectorType &output_vector);
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 " +
2975 " components left when starting from local element index " +
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,
2999 , quad_no(
numbers::invalid_unsigned_int)
3000 , n_fe_components(n_components_)
3001 , active_fe_index(
numbers::invalid_unsigned_int)
3002 , active_quad_index(
numbers::invalid_unsigned_int)
3003 , n_quadrature_points(
3005 , matrix_info(nullptr)
3007 , mapping_data(nullptr)
3013 fe.component_to_base_index(first_selected_component).first))
3016 , normal_vectors(nullptr)
3017 , normal_x_jacobian(nullptr)
3018 , quadrature_weights(nullptr)
3021 , is_interior_face(true)
3022 , dof_access_index(
internal::MatrixFreeFunctions::DoFInfo::dof_access_cell)
3023 , dof_values_initialized(false)
3024 , values_quad_initialized(false)
3025 , gradients_quad_initialized(false)
3026 , hessians_quad_initialized(false)
3027 , values_quad_submitted(false)
3028 , gradients_quad_submitted(false)
3032 first_selected_component(first_selected_component)
3038 if (other !=
nullptr &&
3044 mapping, quadrature, update_flags);
3051 const unsigned int base_element_number =
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>
3067 : scratch_data_array(other.matrix_info == nullptr ?
3069 other.matrix_info->acquire_scratch_data())
3070 , quad_no(other.quad_no)
3071 , n_fe_components(other.n_fe_components)
3072 , active_fe_index(other.active_fe_index)
3073 , active_quad_index(other.active_quad_index)
3074 , n_quadrature_points(other.n_quadrature_points)
3075 , matrix_info(other.matrix_info)
3076 , dof_info(other.dof_info)
3077 , mapping_data(other.mapping_data)
3079 other.matrix_info == nullptr ?
3085 , normal_vectors(nullptr)
3086 , normal_x_jacobian(nullptr)
3087 , quadrature_weights(
3088 other.matrix_info == nullptr ?
3090 mapping_data->descriptor[active_quad_index].quadrature_weights.begin())
3091 , cell(
numbers::invalid_unsigned_int)
3093 , is_interior_face(other.is_interior_face)
3094 , dof_access_index(other.dof_access_index)
3095 , dof_values_initialized(false)
3096 , values_quad_initialized(false)
3097 , gradients_quad_initialized(false)
3098 , hessians_quad_initialized(false)
3099 , values_quad_submitted(false)
3100 , gradients_quad_submitted(false)
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)
3138 delete scratch_data_array;
3160 set_data_pointers();
3162 quadrature_weights =
3163 (mapping_data !=
nullptr ?
3164 mapping_data->descriptor[active_quad_index].quadrature_weights.begin() :
3174 mapped_geometry.reset(
3180 mapping_data = &mapped_geometry->get_data_storage();
3181 jacobian = mapped_geometry->get_data_storage().jacobians[0].begin();
3182 J_value = mapped_geometry->get_data_storage().JxW_values.begin();
3190 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3194 if (matrix_info !=
nullptr)
3205 delete scratch_data_array;
3209 scratch_data_array =
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);
3222 const unsigned int dofs_per_component =
3224 const unsigned int n_quadrature_points =
3227 const unsigned int shift =
3228 std::max(tensor_dofs_per_component + 1, dofs_per_component) *
3230 2 * n_quadrature_points;
3231 const unsigned int allocated_size =
3232 shift + n_components_ * dofs_per_component +
3233 (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3234 scratch_data_array->resize_fast(allocated_size);
3237 for (
unsigned int c = 0; c < n_components_; ++c)
3239 this->values_dofs[c] =
3240 scratch_data_array->begin() + c * dofs_per_component;
3241 this->values_quad[c] = scratch_data_array->begin() +
3243 c * n_quadrature_points;
3244 for (
unsigned int d = 0;
d < dim; ++
d)
3245 this->gradients_quad[c][d] =
3246 scratch_data_array->begin() +
3247 n_components * (dofs_per_component + n_quadrature_points) +
3248 (c * dim + d) * n_quadrature_points;
3249 for (
unsigned int d = 0;
d < (dim * dim + dim) / 2; ++
d)
3250 this->hessians_quad[c][d] =
3251 scratch_data_array->begin() +
3253 ((dim + 1) * n_quadrature_points + dofs_per_component) +
3254 (c * (dim * dim + dim) + d) * n_quadrature_points;
3257 scratch_data_array->begin() + n_components_ * 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>
3268 return get_mapping_data_index_offset();
3273 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3278 if (matrix_info ==
nullptr)
3283 return this->mapping_data->data_index_offsets[cell];
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>
3319 for (
unsigned int q = 0; q < this->n_quadrature_points; ++q)
3320 JxW_values[q] = J * this->quadrature_weights[q];
3323 for (
unsigned int q = 0; q < n_quadrature_points; ++q)
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 3354 return J_value[0] * this->quadrature_weights[q_index];
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>
3606 process_dofs_vectorized(
const unsigned int dofs_per_cell,
3607 const unsigned int dof_index,
3610 std::integral_constant<bool, true>)
const 3612 const Number *vec_ptr = vec.begin() + dof_index;
3613 for (
unsigned int i = 0; i < dofs_per_cell;
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 3628 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
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 3661 for (
unsigned int d = 0;
d < dofs_per_cell; ++
d)
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;
3772 for (
unsigned int i = 0; i < dofs_per_cell;
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 3792 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
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 3825 for (
unsigned int d = 0;
d < dofs_per_cell; ++
d)
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;
3941 for (
unsigned int i = 0; i < dofs_per_cell;
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 3956 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
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 3989 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
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)
4155 read_write_operation_global(operation, src);
4161 if (n_fe_components == 1)
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);
4174 [is_face ? dof_access_index :
4179 read_write_operation_contiguous(operation, src, mask);
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 =
4198 [is_face ? dof_access_index :
4203 const unsigned int *dof_indices =
4205 dof_info->
row_starts[cell * n_fe_components * n_vectorization].first +
4207 [first_selected_component] *
4210 for (
unsigned int i = 0; i < dofs_per_component;
4211 ++i, dof_indices += n_vectorization)
4212 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4213 operation.process_dof_gather(dof_indices,
4216 values_dofs[comp][i],
4219 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4220 for (
unsigned int i = 0; i < dofs_per_component;
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;
4238 if (dof_access_index ==
4240 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4243 cells = dof_access_index ==
4249 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4260 first_selected_component]
4265 first_selected_component]
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]
4284 ->
row_starts[(cell * n_vectorization + v) * n_fe_components +
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]
4311 ->
row_starts[(cell * n_vectorization + v) * n_fe_components +
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)
4325 for (
unsigned int i = 0; i < dofs_per_component; ++i)
4326 operation.process_empty(values_dofs[comp][i]);
4329 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4330 for (
unsigned int i = 0; i < dofs_per_component; ++i)
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)
4340 for (
unsigned int i = 0; i < dofs_per_component; ++i)
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)
4356 for (
unsigned int i = 0; i < dofs_per_component; ++i)
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
4367 first_selected_component]
4369 next_index_indicators = dof_info
4371 first_selected_component + 1]
4378 ->
row_starts[(cell * n_vectorization + v) * n_fe_components +
4379 first_selected_component]
4381 next_index_indicators =
4383 ->
row_starts[(cell * n_vectorization + v) * n_fe_components +
4384 first_selected_component + 1]
4388 if (apply_constraints ==
false &&
4390 ->row_starts[(cell * n_vectorization + v) * n_fe_components +
4391 first_selected_component]
4394 ->
row_starts[(cell * n_vectorization + v) * n_fe_components +
4395 first_selected_component + n_components_read]
4405 [first_selected_component] +
4409 next_index_indicators = index_indicators;
4415 Assert(src[c] !=
nullptr,
4417 "The finite element underlying this FEEvaluation " 4418 "object is scalar, but you requested " +
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]);
4466 for (; ind_local < dofs_per_component; ++dof_indices[v], ++ind_local)
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]);
4523 for (; ind_local < dofs_per_component;
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>
4602 is_face ? dof_access_index :
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 =
4619 [first_selected_component] *
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;
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)
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 =
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]);
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)
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;
4845 read_write_operation(
4852 dof_values_initialized =
true;
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;
4877 read_write_operation(
4884 dof_values_initialized =
true;
4890 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4891 template <
typename VectorType>
4896 const unsigned int first_index,
4899 Assert(dof_values_initialized ==
true,
4904 typename internal::BlockVectorSelector<
4908 dst_data[d] = internal::BlockVectorSelector<
4913 internal::VectorDistributorLocalToGlobal<Number> distributor;
4914 read_write_operation(distributor, dst_data, mask);
4919 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4920 template <
typename VectorType>
4924 const unsigned int first_index,
4927 Assert(dof_values_initialized ==
true,
4932 typename internal::BlockVectorSelector<
4936 dst_data[d] = internal::BlockVectorSelector<
4941 internal::VectorSetter<Number> setter;
4942 read_write_operation(setter, dst_data, mask);
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>
4965 scratch_data_array->end() - scratch_data);
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>
4984 dof_values_initialized =
true;
4986 return &values_dofs[0][0];
4991 template <
int dim,
int n_components,
typename Number,
bool is_face>
4996 return &values_quad[0][0];
5001 template <
int dim,
int n_components,
typename Number,
bool is_face>
5006 values_quad_initialized =
true;
5007 values_quad_submitted =
true;
5009 return &values_quad[0][0];
5014 template <
int dim,
int n_components,
typename Number,
bool is_face>
5018 Assert(gradients_quad_initialized || gradients_quad_submitted,
5020 return &gradients_quad[0][0][0];
5025 template <
int dim,
int n_components,
typename Number,
bool is_face>
5030 gradients_quad_submitted =
true;
5031 gradients_quad_initialized =
true;
5033 return &gradients_quad[0][0][0];
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>
5053 hessians_quad_initialized =
true;
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 5079 Assert(this->values_quad_initialized ==
true,
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 5096 Assert(this->gradients_quad_initialized ==
true,
5107 for (
unsigned int comp = 0; comp <
n_components; comp++)
5108 for (
unsigned int d = 0;
d < dim; ++
d)
5110 (this->gradients_quad[comp][d][q_point] * jacobian[0][d][d]);
5119 for (
unsigned int comp = 0; comp <
n_components; comp++)
5120 for (
unsigned int d = 0;
d < dim; ++
d)
5123 jac[
d][0] * this->gradients_quad[comp][0][q_point];
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 5140 Assert(this->gradients_quad_initialized ==
true,
5147 for (
unsigned int comp = 0; comp <
n_components; comp++)
5148 grad_out[comp] = this->gradients_quad[comp][dim - 1][q_point] *
5149 (this->normal_x_jacobian[0][dim - 1]);
5152 const unsigned int index =
5154 for (
unsigned int comp = 0; comp <
n_components; comp++)
5156 grad_out[comp] = this->gradients_quad[comp][0][q_point] *
5157 this->normal_x_jacobian[index][0];
5158 for (
unsigned int d = 1;
d < dim; ++
d)
5159 grad_out[comp] += this->gradients_quad[comp][d][q_point] *
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 5228 Assert(this->hessians_quad_initialized ==
true,
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];
5312 mapping_data->jacobian_gradients
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] +=
5338 (jac_grad[d][e] * this->gradients_quad[comp][e][q_point]);
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] +=
5345 (jac_grad[count][f] * this->gradients_quad[comp][f][q_point]);
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 5365 Assert(this->hessians_quad_initialized ==
true,
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];
5414 mapping_data->jacobian_gradients
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] +=
5438 (jac_grad[d][e] * this->gradients_quad[comp][e][q_point]);
5446 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5449 const unsigned int q_point)
const 5452 Assert(this->hessians_quad_initialized ==
true,
5458 hess_diag = get_hessian_diagonal(q_point);
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)
5477 this->dof_values_initialized =
true;
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)
5496 this->values_quad_submitted =
true;
5502 J_value[0] * quadrature_weights[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)
5526 this->gradients_quad_submitted =
true;
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)
5537 this->gradients_quad[comp][d][q_point] =
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]);
5556 this->gradients_quad[comp][
d][q_point] = new_val * JxW;
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)
5571 this->gradients_quad_submitted =
true;
5576 for (
unsigned int comp = 0; comp <
n_components; comp++)
5578 for (
unsigned int d = 0;
d < dim - 1; ++
d)
5580 this->gradients_quad[comp][dim - 1][q_point] =
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)
5595 this->gradients_quad[comp][d][q_point] =
5596 factor * this->normal_x_jacobian[index][d];
5603 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5609 Assert(this->values_quad_submitted ==
true,
5613 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5614 return_value[comp] = this->values_quad[comp][0];
5615 const unsigned int n_q_points = this->n_quadrature_points;
5616 for (
unsigned int q = 1; q < n_q_points; ++q)
5617 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5618 return_value[comp] += this->values_quad[comp][q];
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)
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,
6632 const unsigned int quad_no,
6633 const unsigned int first_selected_component)
6634 : BaseClass(data_in,
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)
6660 : BaseClass(mapping,
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)
6710 : BaseClass(other.mapped_geometry->get_fe_values().get_mapping(),
6712 other.mapped_geometry->get_quadrature(),
6713 other.mapped_geometry->get_fe_values().get_update_flags(),
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)
6751 BaseClass::operator=(other);
6766 const unsigned int first_selected_component)
6769 (void)first_selected_component;
6775 static_cast<unsigned int>(fe_degree) != this->data->
fe_degree) ||
6776 n_q_points != this->n_quadrature_points)
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;
6804 proposed_fe_comp = first_selected_component;
6807 for (
unsigned int no = 0; no < this->matrix_info->
n_components();
6809 for (
unsigned int nf = 0;
6812 if (this->matrix_info
6813 ->get_shape_info(no, 0, nf, this->active_fe_index, 0)
6814 .fe_degree ==
static_cast<unsigned int>(fe_degree))
6816 proposed_dof_comp = no;
6817 proposed_fe_comp = nf;
6821 this->mapping_data->descriptor[this->active_quad_index]
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()
6830 .descriptor[this->active_quad_index]
6831 .n_q_points == n_q_points)
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>(
6876 std::pow(1.001 * this->n_quadrature_points, 1. / dim));
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,
6908 this->mapping_data->descriptor[this->active_quad_index].n_q_points);
6921 const unsigned int cell_index)
6923 Assert(this->mapped_geometry ==
nullptr,
6924 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 6925 " Integer indexing is not possible"));
6926 if (this->mapped_geometry !=
nullptr)
6931 this->cell = cell_index;
6933 this->matrix_info->get_mapping_info().get_cell_type(cell_index);
6935 const unsigned int offsets =
6936 this->mapping_data->data_index_offsets[cell_index];
6937 this->jacobian = &this->mapping_data->jacobians[0][offsets];
6938 this->J_value = &this->mapping_data->JxW_values[offsets];
6941 this->dof_values_initialized =
false;
6942 this->values_quad_initialized =
false;
6943 this->gradients_quad_initialized =
false;
6944 this->hessians_quad_initialized =
false;
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 " 6966 this->mapped_geometry->reinit(
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 " 6992 this->mapped_geometry->reinit(cell);
7006 if (this->matrix_info ==
nullptr)
7008 Assert((this->mapped_geometry->get_fe_values().get_update_flags() |
7014 Assert(this->mapping_data->quadrature_point_offsets.empty() ==
false,
7020 const unsigned int n_q_points_1d_actual =
7021 fe_degree == -1 ? this->data->
n_q_points_1d : n_q_points_1d;
7027 &this->mapping_data->quadrature_points
7028 [this->mapping_data->quadrature_point_offsets[this->cell]];
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)
7070 Assert(this->dof_values_initialized ==
true,
7072 evaluate(this->values_dofs[0],
7088 const bool evaluate_values,
7089 const bool evaluate_gradients,
7090 const bool evaluate_hessians)
7100 this->values_quad[0],
7101 this->gradients_quad[0][0],
7102 this->hessians_quad[0][0],
7109 if (evaluate_values ==
true)
7110 this->values_quad_initialized =
true;
7111 if (evaluate_gradients ==
true)
7112 this->gradients_quad_initialized =
true;
7113 if (evaluate_hessians ==
true)
7114 this->hessians_quad_initialized =
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() +
7158 [this->first_selected_component] *
7161 evaluate(vec_values,
7168 this->read_dof_values(input_vector);
7169 evaluate(this->begin_dof_values(),
7185 const bool integrate_values,
7186 const bool integrate_gradients)
7188 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7191 this->dof_values_initialized =
true;
7204 const bool integrate_values,
7205 const bool integrate_gradients,
7208 if (integrate_values ==
true)
7209 Assert(this->values_quad_submitted ==
true,
7211 if (integrate_gradients ==
true)
7212 Assert(this->gradients_quad_submitted ==
true,
7214 Assert(this->matrix_info !=
nullptr ||
7215 this->mapped_geometry->is_initialized(),
7224 this->values_quad[0],
7226 ->gradients_quad[0][0],
7229 integrate_gradients,
7233 this->dof_values_initialized =
true;
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() +
7277 [this->first_selected_component] *
7286 this->values_quad[0],
7287 this->gradients_quad[0][0],
7290 integrate_gradients,
7295 integrate(integrate_values,
7296 integrate_gradients,
7297 this->begin_dof_values());
7298 this->distribute_local_to_global(destination);
7315 const bool is_interior_face,
7316 const unsigned int dof_no,
7317 const unsigned int quad_no,
7318 const unsigned int first_selected_component)
7319 : BaseClass(matrix_free,
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)
7342 Assert(this->mapped_geometry ==
nullptr,
7343 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 7344 " Integer indexing is not possible"));
7345 if (this->mapped_geometry !=
nullptr)
7348 this->cell = face_index;
7349 this->dof_access_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)
7373 this->face_orientation = 0;
7380 this->face_orientation = 0;
7383 this->values_quad_submitted =
false;
7385 this->cell_type = this->matrix_info->get_mapping_info().face_type[face_index];
7386 const unsigned int offsets =
7387 this->mapping_data->data_index_offsets[face_index];
7388 this->J_value = &this->mapping_data->JxW_values[offsets];
7389 this->normal_vectors = &this->mapping_data->normal_vectors[offsets];
7391 &this->mapping_data->jacobians[!this->is_interior_face][offsets];
7392 this->normal_x_jacobian =
7394 ->normals_times_jacobians[!this->is_interior_face][offsets];
7397 this->dof_values_initialized =
false;
7398 this->values_quad_initialized =
false;
7399 this->gradients_quad_initialized =
false;
7400 this->hessians_quad_initialized =
false;
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());
7424 Assert(this->mapped_geometry ==
nullptr,
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"));
7431 if (this->mapped_geometry !=
nullptr)
7435 this->cell_type = this->matrix_info->get_mapping_info().cell_type[cell_index];
7436 this->cell = cell_index;
7437 this->face_orientation = 0;
7439 this->face_no = face_number;
7440 this->dof_access_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];
7466 this->dof_values_initialized =
false;
7467 this->values_quad_initialized =
false;
7468 this->gradients_quad_initialized =
false;
7469 this->hessians_quad_initialized =
false;
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 ?
7526 if (static_dofs_per_face < stack_array_size_threshold)
7527 temp1 = &temp_data[0];
7529 temp1 = this->scratch_data;
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,
7551 this->begin_values(),
7552 this->begin_gradients(),
7553 this->scratch_data +
7558 this->subface_index);
7560 internal::FEFaceEvaluationImpl<
7564 n_q_points_1d_actual,
7568 this->begin_values(),
7569 this->begin_gradients(),
7570 this->scratch_data +
7575 this->subface_index);
7577 if (this->face_orientation)
7578 adjust_for_face_orientation(
false, evaluate_values, evaluate_gradients);
7581 if (evaluate_values ==
true)
7582 this->values_quad_initialized =
true;
7583 if (evaluate_gradients ==
true)
7584 this->gradients_quad_initialized =
true;
7597 integrate(
const bool integrate_values,
const bool integrate_gradients)
7599 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7602 this->dof_values_initialized =
true;
7616 const bool integrate_gradients,
7619 if (!(integrate_values + integrate_gradients))
7622 if (this->face_orientation)
7623 adjust_for_face_orientation(
true, 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 ?
7639 if (static_dofs_per_face < stack_array_size_threshold)
7640 temp1 = &temp_data[0];
7642 temp1 = this->scratch_data;
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,
7657 this->begin_values(),
7658 this->begin_gradients(),
7659 this->scratch_data +
7663 integrate_gradients,
7664 this->subface_index);
7666 internal::FEFaceEvaluationImpl<
7670 n_q_points_1d_actual,
7674 this->begin_values(),
7675 this->begin_gradients(),
7676 this->scratch_data +
7680 integrate_gradients,
7681 this->subface_index);
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];
7724 temp1 = this->scratch_data;
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)
7744 ->n_vectorization_lanes_filled[this->dof_access_index][this->cell],
7746 const unsigned int dof_index =
7753 [this->first_selected_component] *
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(
7777 dof_index + (ind1 + comp * static_dofs_per_component) *
7780 temp1 + i + 2 * comp * dofs_per_face,
7782 reader.process_dofs_vectorized(
7784 dof_index + (ind2 + comp * static_dofs_per_component) *
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(
7808 dof_index + (ind + comp * static_dofs_per_component) *
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)
7830 ->n_vectorization_lanes_filled[this->dof_access_index][this->cell],
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] *
7856 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7858 reader.process_dof_gather(
7862 comp * static_dofs_per_component *
7865 [this->active_fe_index]
7866 [this->first_selected_component] *
7868 temp1[i + 2 * comp * dofs_per_face],
7871 reader.process_dof_gather(
7875 comp * static_dofs_per_component *
7878 [this->active_fe_index]
7879 [this->first_selected_component] *
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 =
7898 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7899 reader.process_dof_gather(
7903 comp * static_dofs_per_component *
7905 this->dof_info->component_dof_indices_offset
7906 [this->active_fe_index]
7907 [this->first_selected_component] *
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 =
7928 [this->dof_access_index]
7931 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
7935 [this->dof_access_index]
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);
7958 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7959 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7962 DEAL_II_OPENMP_SIMD_PRAGMA
7963 for (
unsigned int v = 0;
7964 v < VectorizedArray<Number>::n_array_elements;
7966 ind1[v] = indices[v] + (comp * static_dofs_per_component +
7967 index_array[2 * i]) *
7970 DEAL_II_OPENMP_SIMD_PRAGMA
7971 for (
unsigned int v = 0;
7972 v < VectorizedArray<Number>::n_array_elements;
7974 ind2[v] = indices[v] + (comp * static_dofs_per_component +
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 =
7998 indices[v] + (comp * static_dofs_per_component +
7999 index_array[2 * i]) *
8001 const unsigned int ind2 =
8002 indices[v] + (comp * static_dofs_per_component +
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);
8026 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8027 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8030 DEAL_II_OPENMP_SIMD_PRAGMA
8031 for (
unsigned int v = 0;
8032 v < VectorizedArray<Number>::n_array_elements;
8034 ind[v] = indices[v] + (comp * static_dofs_per_component +
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 =
8053 (comp * static_dofs_per_component + index_array[i]) *
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]
8078 const unsigned int *indices =
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(
8106 ind1 + comp * static_dofs_per_component +
8108 [this->active_fe_index][this->first_selected_component],
8109 temp1[i + 2 * comp * dofs_per_face],
8112 reader.process_dof_gather(
8115 ind2 + comp * static_dofs_per_component +
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(
8138 ind + comp * static_dofs_per_component +
8140 [this->active_fe_index][this->first_selected_component],
8141 temp1[i + comp * 2 * dofs_per_face],
8150 this->read_dof_values(input_vector);
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<
8174 this->values_quad[0],
8175 this->gradients_quad[0][0],
8176 this->scratch_data +
8181 this->subface_index);
8183 internal::FEFaceEvaluationImpl<
8191 this->values_quad[0],
8192 this->gradients_quad[0][0],
8193 this->scratch_data +
8198 this->subface_index);
8200 if (this->face_orientation)
8201 adjust_for_face_orientation(
false, evaluate_values, evaluate_gradients);
8204 if (evaluate_values ==
true)
8205 this->values_quad_initialized =
true;
8206 if (evaluate_gradients ==
true)
8207 this->gradients_quad_initialized =
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 =
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];
8239 temp1 = this->scratch_data;
8241 if (this->face_orientation)
8242 adjust_for_face_orientation(
true, integrate_values, integrate_gradients);
8243 if (fe_degree > -1 &&
8245 this->data->element_type <=
8247 internal::FEFaceEvaluationImpl<
8255 this->values_quad[0],
8256 this->gradients_quad[0][0],
8257 this->scratch_data +
8261 integrate_gradients,
8262 this->subface_index);
8264 internal::FEFaceEvaluationImpl<
8272 this->values_quad[0],
8273 this->gradients_quad[0][0],
8274 this->scratch_data +
8278 integrate_gradients,
8279 this->subface_index);
8282 this->dof_values_initialized =
true;
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)
8303 ->n_vectorization_lanes_filled[this->dof_access_index][this->cell],
8305 const unsigned int dof_index =
8312 [this->first_selected_component] *
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(
8343 dof_index + (ind1 + comp * static_dofs_per_component) *
8348 writer.process_dofs_vectorized(
8350 dof_index + (ind2 + comp * static_dofs_per_component) *
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(
8370 dof_index + (ind + comp * static_dofs_per_component) *
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)
8392 ->n_vectorization_lanes_filled[this->dof_access_index][this->cell],
8394 const unsigned int *indices =
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 =
8415 const unsigned int ind2 =
8416 index_array[2 * i + 1] *
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(
8431 comp * static_dofs_per_component *
8434 [this->active_fe_index]
8435 [this->first_selected_component] *
8439 writer.process_dof_gather(
8443 comp * static_dofs_per_component *
8446 [this->active_fe_index]
8447 [this->first_selected_component] *
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 =
8464 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8465 writer.process_dof_gather(
8469 comp * static_dofs_per_component *
8471 this->dof_info->component_dof_indices_offset
8472 [this->active_fe_index]
8473 [this->first_selected_component] *
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 =
8494 [this->dof_access_index]
8497 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
8501 [this->dof_access_index]
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);
8524 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8525 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8528 DEAL_II_OPENMP_SIMD_PRAGMA
8529 for (
unsigned int v = 0;
8530 v < VectorizedArray<Number>::n_array_elements;
8532 ind1[v] = indices[v] + (comp * static_dofs_per_component +
8533 index_array[2 * i]) *
8536 DEAL_II_OPENMP_SIMD_PRAGMA
8537 for (
unsigned int v = 0;
8538 v < VectorizedArray<Number>::n_array_elements;
8540 ind2[v] = indices[v] + (comp * static_dofs_per_component +
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 =
8562 indices[v] + (comp * static_dofs_per_component +
8563 index_array[2 * i]) *
8565 const unsigned int ind2 =
8566 indices[v] + (comp * static_dofs_per_component +
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);
8588 for (
unsigned int comp = 0; comp < n_components_; ++comp)
8589 for (
unsigned int i = 0; i < dofs_per_face; ++i)
8592 DEAL_II_OPENMP_SIMD_PRAGMA
8593 for (
unsigned int v = 0;
8594 v < VectorizedArray<Number>::n_array_elements;
8596 ind[v] = indices[v] + (comp * static_dofs_per_component +
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 =
8613 (comp * static_dofs_per_component + index_array[i]) *
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]
8638 const unsigned int *indices =
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(
8673 comp * static_dofs_per_component + ind1 +
8675 [this->active_fe_index][this->first_selected_component],
8678 writer.process_dof_gather(
8681 comp * static_dofs_per_component + ind2 +
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(
8702 comp * static_dofs_per_component + ind +
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,
8723 this->distribute_local_to_global(destination);
8738 const bool gradients)
8741 const unsigned int * orientations =
8742 &this->mapping_data->descriptor[this->active_fe_index]
8743 .face_orientations[this->face_orientation][0];
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)
8755 this->values_quad[c][q] = tmp_values[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)
8762 tmp_values[q] = this->gradients_quad[c][d][orientations[q]];
8764 for (
unsigned int q = 0; q < n_q_points; ++q)
8765 tmp_values[orientations[q]] = this->gradients_quad[c][d][q];
8766 for (
unsigned int q = 0; q < n_q_points; ++q)
8767 this->gradients_quad[c][d][q] = tmp_values[q];
8784 if (this->dof_access_index < 2)
8786 Assert(this->mapping_data->quadrature_point_offsets.empty() ==
false,
8789 this->mapping_data->quadrature_point_offsets.size());
8790 return this->mapping_data->quadrature_points
8791 [this->mapping_data->quadrature_point_offsets[this->cell] + 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
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
#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)
internal::MatrixFreeFunctions::GeometryType get_cell_type() const
internal::MatrixFreeFunctions::GeometryType cell_type
static ::ExceptionBase & ExcAccessToUninitializedField()
std::vector< unsigned int > component_to_base_index
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
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)
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)
static constexpr unsigned int static_dofs_per_cell
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
static constexpr unsigned int n_components
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
const Tensor< 1, dim, VectorizedArray< Number > > * normal_vectors
const Number * quadrature_weights
static constexpr unsigned int tensor_dofs_per_cell
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)
const unsigned int n_q_points
gradient_type get_hessian_diagonal(const unsigned int q_point) const
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
T sum(const T &t, const MPI_Comm &mpi_communicator)
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]
VectorizedArray< Number > pow(const ::VectorizedArray< Number > &x, const Number p)
void submit_curl(const Tensor< 1, dim==2 ? 1 :dim, VectorizedArray< Number >> curl_in, const unsigned int q_point)
static constexpr unsigned int static_dofs_per_cell
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 hessians_quad_initialized
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
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
static constexpr unsigned int static_n_q_points_cell
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)
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)
VectorizedArray< Number > * hessians_quad[n_components][(dim *(dim+1))/2]
value_type get_dof_value(const unsigned int dof) const
static constexpr unsigned int static_n_q_points
std::vector< unsigned int > dof_indices_contiguous[3]
void load(const Number *ptr)
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
static constexpr unsigned int tensor_dofs_per_cell
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
static constexpr unsigned int dimension
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
static constexpr unsigned int dimension
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)
static constexpr unsigned int static_dofs_per_component
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
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
unsigned char interior_face_no
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