16#ifndef dealii_matrix_free_fe_evaluation_h
17#define dealii_matrix_free_fe_evaluation_h
92 typename VectorizedArrayType>
99 std::conditional_t<n_components_ == 1,
106 n_components_ == dim,
113 n_components_ == dim,
118 static constexpr unsigned int n_lanes = VectorizedArrayType::size();
156 template <
typename VectorType>
159 const VectorType &src,
160 const unsigned int first_index = 0,
161 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip());
191 template <
typename VectorType>
194 const VectorType &src,
195 const unsigned int first_index = 0,
196 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip());
229 template <
typename VectorType>
233 const unsigned int first_index = 0,
234 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip())
const;
274 template <
typename VectorType>
278 const unsigned int first_index = 0,
279 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip())
const;
284 template <
typename VectorType>
288 const unsigned int first_index = 0,
289 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip())
const;
365 typename = std::enable_if_t<n_components == n_components_local>>
368 const unsigned int q_point);
419 template <
int dim_ = dim,
420 typename = std::enable_if_t<dim_ == 1 && n_components == dim_>>
423 const unsigned int q_point);
442 const unsigned int q_point);
496 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
515 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
518 const unsigned int q_point);
528 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
547 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
551 const unsigned int q_point);
561 template <
int dim_ = dim,
562 typename = std::enable_if_t<n_components_ == dim_ && dim_ != 1>>
563 Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
579 template <
int dim_ = dim,
580 typename = std::enable_if_t<n_components_ == dim_ && dim != 1>>
583 const unsigned int q_point);
624 const unsigned int dof_no,
627 const unsigned int fe_degree,
628 const unsigned int n_q_points,
632 const unsigned int face_type);
706 template <
typename VectorType,
typename VectorOperation>
710 const std::array<VectorType *, n_components_> &vectors,
713 n_components_> &vectors_sm,
714 const std::bitset<n_lanes> &mask,
715 const bool apply_constraints =
true)
const;
724 template <
typename VectorType,
typename VectorOperation>
728 const std::array<VectorType *, n_components_> &vectors,
731 n_components_> &vectors_sm,
732 const std::bitset<n_lanes> &mask)
const;
741 template <
typename VectorType,
typename VectorOperation>
745 const std::array<VectorType *, n_components_> &vectors)
const;
1349 typename VectorizedArrayType>
1354 VectorizedArrayType>
1357 std::is_same_v<Number, typename VectorizedArrayType::value_type>,
1358 "Type of Number and of VectorizedArrayType do not match.");
1400 static constexpr unsigned int n_lanes = VectorizedArrayType::size();
1485 const unsigned int dof_no = 0,
1486 const unsigned int quad_no = 0,
1499 const std::pair<unsigned int, unsigned int> &range,
1500 const unsigned int dof_no = 0,
1501 const unsigned int quad_no = 0,
1611 template <
bool level_dof_access>
1633 const unsigned int given_n_q_points_1d);
1676 template <
typename VectorType>
1706 VectorizedArrayType *values_array,
1707 const bool sum_into_values =
false);
1722 template <
typename VectorType>
1725 VectorType &output_vector);
1809 int n_q_points_1d = fe_degree + 1,
1810 int n_components_ = 1,
1811 typename Number = double,
1817 VectorizedArrayType>
1820 std::is_same_v<Number, typename VectorizedArrayType::value_type>,
1821 "Type of Number and of VectorizedArrayType do not match.");
1863 static constexpr unsigned int n_lanes = VectorizedArrayType::size();
1965 const unsigned int dof_no = 0,
1966 const unsigned int quad_no = 0,
1981 const std::pair<unsigned int, unsigned int> &range,
1983 const unsigned int dof_no = 0,
1984 const unsigned int quad_no = 0,
1998 reinit(
const unsigned int face_batch_number);
2008 reinit(
const unsigned int cell_batch_number,
const unsigned int face_number);
2015 const unsigned int given_n_q_points_1d);
2079 template <
typename VectorType>
2095 const bool sum_into_values =
false);
2108 VectorizedArrayType *values_array,
2109 const bool sum_into_values =
false);
2126 const bool sum_into_values =
false);
2134 VectorizedArrayType *values_array,
2135 const bool sum_into_values =
false);
2148 template <
typename VectorType>
2151 VectorType &output_vector);
2156 template <
typename VectorType>
2159 const bool integrate_gradients,
2160 VectorType &output_vector);
2236 namespace MatrixFreeFunctions
2240 template <
int dim,
int degree>
2249 template <
int degree>
2252 static constexpr unsigned int value = degree + 1;
2268 template <
bool is_face,
2271 typename VectorizedArrayType>
2274 extract_initialization_data(
2276 const unsigned int dof_no,
2277 const unsigned int first_selected_component,
2278 const unsigned int quad_no,
2279 const unsigned int fe_degree,
2280 const unsigned int n_q_points,
2281 const unsigned int active_fe_index_given,
2282 const unsigned int active_quad_index_given,
2283 const unsigned int face_type)
2286 InitializationData init_data;
2290 &internal::MatrixFreeFunctions::
2291 MappingInfoCellsOrFaces<dim, Number, is_face, VectorizedArrayType>::get(
2299 active_fe_index_given :
2305 active_quad_index_given :
2311 init_data.
mapping_data->quad_index_from_n_q_points(n_q_points);
2338 typename VectorizedArrayType>
2343 VectorizedArrayType>::
2346 const unsigned int dof_no,
2347 const unsigned int first_selected_component,
2348 const unsigned int quad_no,
2349 const unsigned int fe_degree,
2350 const unsigned int n_q_points,
2351 const bool is_interior_face,
2352 const unsigned int active_fe_index,
2353 const unsigned int active_quad_index,
2354 const unsigned int face_type)
2356 internal::extract_initialization_data<is_face>(matrix_free,
2358 first_selected_component,
2367 first_selected_component)
2368 , scratch_data_array(matrix_free.acquire_scratch_data())
2369 , matrix_free(&matrix_free)
2371 this->set_data_pointers(scratch_data_array, n_components_);
2373 this->dof_info->start_components.back() == 1 ||
2374 static_cast<int>(n_components_) <=
2376 this->dof_info->start_components
2377 [this->dof_info->component_to_base_index[first_selected_component] +
2379 first_selected_component,
2381 "You tried to construct a vector-valued evaluator with " +
2382 std::to_string(n_components) +
2383 " components. However, "
2384 "the current base element has only " +
2386 this->dof_info->start_components
2387 [this->dof_info->component_to_base_index[first_selected_component] +
2389 first_selected_component) +
2390 " components left when starting from local element index " +
2392 first_selected_component -
2393 this->dof_info->start_components
2394 [this->dof_info->component_to_base_index[first_selected_component]]) +
2395 " (global index " + std::to_string(first_selected_component) +
")"));
2407 typename VectorizedArrayType>
2412 VectorizedArrayType>::
2418 const unsigned int first_selected_component,
2422 other->mapped_geometry->get_quadrature() == quadrature ?
2423 other->mapped_geometry :
2425 MappingDataOnTheFly<dim, VectorizedArrayType>>(
2430 first_selected_component)
2431 , scratch_data_array(new
AlignedVector<VectorizedArrayType>())
2432 , matrix_free(nullptr)
2434 const unsigned int base_element_number =
2438 first_selected_component >=
2440 ExcMessage(
"The underlying element must at least contain as many "
2441 "components as requested by this class"));
2442 (void)base_element_number;
2446 Quadrature<(is_face ? dim - 1 : dim)>(quadrature),
2448 fe.component_to_base_index(first_selected_component).
first);
2450 this->set_data_pointers(scratch_data_array, n_components_);
2459 typename VectorizedArrayType>
2464 VectorizedArrayType>::
2469 VectorizedArrayType> &other)
2471 , scratch_data_array(other.matrix_free == nullptr ?
2473 other.matrix_free->acquire_scratch_data())
2474 , matrix_free(other.matrix_free)
2476 if (other.matrix_free ==
nullptr)
2483 this->mapped_geometry =
2484 std::make_shared<internal::MatrixFreeFunctions::
2485 MappingDataOnTheFly<dim, VectorizedArrayType>>(
2489 this->mapping_data = &this->mapped_geometry->get_data_storage();
2493 this->mapped_geometry->get_data_storage().jacobians[0].begin();
2495 this->mapped_geometry->get_data_storage().JxW_values.begin();
2496 this->jacobian_gradients =
2497 this->mapped_geometry->get_data_storage().jacobian_gradients[0].begin();
2498 this->jacobian_gradients_non_inverse =
2499 this->mapped_geometry->get_data_storage()
2500 .jacobian_gradients_non_inverse[0]
2503 this->mapped_geometry->get_data_storage().quadrature_points.begin();
2506 this->set_data_pointers(scratch_data_array, n_components_);
2515 typename VectorizedArrayType>
2520 VectorizedArrayType> &
2526 VectorizedArrayType> &other)
2529 if (matrix_free ==
nullptr)
2532 delete scratch_data_array;
2541 matrix_free = other.matrix_free;
2543 if (other.matrix_free ==
nullptr)
2551 this->mapped_geometry =
2552 std::make_shared<internal::MatrixFreeFunctions::
2553 MappingDataOnTheFly<dim, VectorizedArrayType>>(
2558 this->mapping_data = &this->mapped_geometry->get_data_storage();
2560 this->mapped_geometry->get_data_storage().jacobians[0].begin();
2562 this->mapped_geometry->get_data_storage().JxW_values.begin();
2563 this->jacobian_gradients =
2564 this->mapped_geometry->get_data_storage().jacobian_gradients[0].begin();
2565 this->jacobian_gradients_non_inverse =
2566 this->mapped_geometry->get_data_storage()
2567 .jacobian_gradients_non_inverse[0]
2570 this->mapped_geometry->get_data_storage().quadrature_points.begin();
2577 this->set_data_pointers(scratch_data_array, n_components_);
2588 typename VectorizedArrayType>
2593 VectorizedArrayType>::~FEEvaluationBase()
2595 if (matrix_free !=
nullptr)
2606 delete scratch_data_array;
2617 typename VectorizedArrayType>
2622 Assert(matrix_free !=
nullptr,
2624 "FEEvaluation was not initialized with a MatrixFree object!"));
2625 return *matrix_free;
2634 template <
typename VectorType,
bool>
2635 struct ConstBlockVectorSelector;
2637 template <
typename VectorType>
2638 struct ConstBlockVectorSelector<VectorType, true>
2640 using BaseVectorType =
const typename VectorType::BlockType;
2643 template <
typename VectorType>
2644 struct ConstBlockVectorSelector<VectorType, false>
2646 using BaseVectorType =
typename VectorType::BlockType;
2652 template <
typename VectorType,
bool>
2653 struct BlockVectorSelector;
2655 template <
typename VectorType>
2656 struct BlockVectorSelector<VectorType, true>
2658 using BaseVectorType =
typename ConstBlockVectorSelector<
2660 std::is_const_v<VectorType>>::BaseVectorType;
2662 static BaseVectorType *
2663 get_vector_component(VectorType &vec,
const unsigned int component)
2666 return &vec.block(component);
2670 template <
typename VectorType>
2671 struct BlockVectorSelector<VectorType, false>
2673 using BaseVectorType = VectorType;
2675 static BaseVectorType *
2676 get_vector_component(VectorType &vec,
const unsigned int component)
2695 template <
typename VectorType>
2696 struct BlockVectorSelector<
std::vector<VectorType>, false>
2698 using BaseVectorType = VectorType;
2700 static BaseVectorType *
2701 get_vector_component(std::vector<VectorType> &vec,
2702 const unsigned int component)
2705 return &vec[component];
2709 template <
typename VectorType>
2710 struct BlockVectorSelector<const
std::vector<VectorType>, false>
2712 using BaseVectorType =
const VectorType;
2714 static const BaseVectorType *
2715 get_vector_component(
const std::vector<VectorType> &vec,
2716 const unsigned int component)
2719 return &vec[component];
2723 template <
typename VectorType>
2724 struct BlockVectorSelector<
std::vector<VectorType *>, false>
2726 using BaseVectorType = VectorType;
2728 static BaseVectorType *
2729 get_vector_component(std::vector<VectorType *> &vec,
2730 const unsigned int component)
2733 return vec[component];
2737 template <
typename VectorType>
2738 struct BlockVectorSelector<const
std::vector<VectorType *>, false>
2740 using BaseVectorType =
const VectorType;
2742 static const BaseVectorType *
2743 get_vector_component(
const std::vector<VectorType *> &vec,
2744 const unsigned int component)
2747 return vec[component];
2751 template <
typename VectorType, std::
size_t N>
2752 struct BlockVectorSelector<
std::array<VectorType *, N>, false>
2754 using BaseVectorType = VectorType;
2756 static BaseVectorType *
2757 get_vector_component(std::array<VectorType *, N> &vec,
2758 const unsigned int component)
2761 return vec[component];
2772 typename VectorizedArrayType>
2773template <
typename VectorType,
typename VectorOperation>
2778 const std::array<VectorType *, n_components_> &src,
2781 n_components_> &src_sm,
2782 const std::bitset<n_lanes> &mask,
2783 const bool apply_constraints)
const
2788 if (this->matrix_free ==
nullptr)
2790 read_write_operation_global(operation, src);
2797 if (this->n_fe_components == 1)
2798 for (
unsigned int comp = 0; comp < n_components; ++comp)
2800 Assert(src[comp] !=
nullptr,
2801 ExcMessage(
"The finite element underlying this FEEvaluation "
2802 "object is scalar, but you requested " +
2803 std::to_string(n_components) +
2804 " components via the template argument in "
2805 "FEEvaluation. In that case, you must pass an "
2806 "std::vector<VectorType> or a BlockVector to " +
2807 "read_dof_values and distribute_local_to_global."));
2819 const bool accesses_exterior_dofs =
2820 this->dof_access_index ==
2822 this->is_interior_face() ==
false;
2832 bool is_contiguous =
true;
2834 if (accesses_exterior_dofs)
2836 const std::array<unsigned int, n_lanes> &cells = this->get_cell_ids();
2837 const unsigned int n_filled_lanes =
2842 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2843 if (mask[v] ==
true &&
2846 [cells[v] / n_lanes] <
2849 is_contiguous = false;
2853 this->dof_access_index :
2854 internal::MatrixFreeFunctions::DoFInfo::dof_access_cell]
2855 [this->cell] <
internal::MatrixFreeFunctions::DoFInfo::
2858 is_contiguous =
false;
2863 read_write_operation_contiguous(operation, src, src_sm, mask);
2870 std::array<unsigned int, n_lanes> cells = this->get_cell_ids();
2872 const bool masking_is_active =
mask.count() < n_lanes;
2873 if (masking_is_active)
2874 for (
unsigned int v = 0; v < n_lanes; ++v)
2875 if (mask[v] ==
false)
2878 bool has_hn_constraints =
false;
2880 if (is_face ==
false)
2886 [this->first_selected_component])
2887 for (
unsigned int v = 0; v < n_lanes; ++v)
2892 has_hn_constraints = true;
2895 std::bool_constant<internal::is_vectorizable<VectorType, Number>::value>
2898 const bool use_vectorized_path =
2899 !(masking_is_active || has_hn_constraints || accesses_exterior_dofs);
2901 const std::size_t dofs_per_component = this->data->dofs_per_component_on_cell;
2902 std::array<VectorizedArrayType *, n_components> values_dofs;
2903 for (
unsigned int c = 0; c < n_components; ++c)
2904 values_dofs[c] =
const_cast<VectorizedArrayType *
>(this->values_dofs) +
2905 c * dofs_per_component;
2909 [is_face ? this->dof_access_index :
2910 internal::MatrixFreeFunctions::DoFInfo::dof_access_cell]
2911 [this->cell] ==
internal::MatrixFreeFunctions::DoFInfo::
2912 IndexStorageVariants::interleaved &&
2913 use_vectorized_path)
2915 const unsigned int *dof_indices =
2917 dof_info.
row_starts[this->cell * this->n_fe_components * n_lanes]
2921 [this->first_selected_component] *
2924 std::array<typename VectorType::value_type *, n_components> src_ptrs;
2925 if (n_components == 1 || this->n_fe_components == 1)
2926 for (
unsigned int comp = 0; comp < n_components; ++comp)
2928 const_cast<typename VectorType::value_type *
>(src[comp]->
begin());
2931 const_cast<typename VectorType::value_type *
>(src[0]->begin());
2933 if (n_components == 1 || this->n_fe_components == 1)
2934 for (
unsigned int i = 0; i < dofs_per_component;
2935 ++i, dof_indices += n_lanes)
2936 for (
unsigned int comp = 0; comp < n_components; ++comp)
2937 operation.process_dof_gather(dof_indices,
2941 values_dofs[comp][i],
2944 for (
unsigned int comp = 0; comp < n_components; ++comp)
2945 for (
unsigned int i = 0; i < dofs_per_component;
2946 ++i, dof_indices += n_lanes)
2947 operation.process_dof_gather(dof_indices,
2951 values_dofs[comp][i],
2958 std::array<const unsigned int *, n_lanes> dof_indices;
2959 dof_indices.fill(
nullptr);
2964 bool has_constraints =
false;
2965 const unsigned int n_components_read =
2966 this->n_fe_components > 1 ? n_components : 1;
2970 for (
unsigned int v = 0; v < n_lanes; ++v)
2976 const std::pair<unsigned int, unsigned int> *my_index_start =
2977 &dof_info.
row_starts[cells[v] * this->n_fe_components +
2978 this->first_selected_component];
2983 if (my_index_start[n_components_read].
second !=
2984 my_index_start[0].
second)
2985 has_constraints =
true;
2988 dof_info.
dof_indices.data() + my_index_start[0].first;
2993 for (
unsigned int v = 0; v < n_lanes; ++v)
2998 const std::pair<unsigned int, unsigned int> *my_index_start =
2999 &dof_info.
row_starts[cells[v] * this->n_fe_components +
3000 this->first_selected_component];
3001 if (my_index_start[n_components_read].
second !=
3002 my_index_start[0].
second)
3003 has_constraints =
true;
3010 dof_info.hanging_node_constraint_masks_comp
3011 [this->active_fe_index][this->first_selected_component])
3012 has_hn_constraints = true;
3015 my_index_start[0].
first ||
3018 my_index_start[0].
first,
3021 dof_info.
dof_indices.data() + my_index_start[0].first;
3025 if (std::count_if(cells.begin(), cells.end(), [](
const auto i) {
3026 return i != numbers::invalid_unsigned_int;
3028 for (
unsigned int comp = 0; comp < n_components; ++comp)
3029 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3030 operation.process_empty(values_dofs[comp][i]);
3034 if (!has_constraints && apply_constraints)
3036 if (n_components == 1 || this->n_fe_components == 1)
3038 for (
unsigned int v = 0; v < n_lanes; ++v)
3043 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3044 for (
unsigned int comp = 0; comp < n_components; ++comp)
3045 operation.process_dof(dof_indices[v][i],
3047 values_dofs[comp][i][v]);
3052 for (
unsigned int comp = 0; comp < n_components; ++comp)
3053 for (
unsigned int v = 0; v < n_lanes; ++v)
3058 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3059 operation.process_dof(
3060 dof_indices[v][comp * dofs_per_component + i],
3062 values_dofs[comp][i][v]);
3074 for (
unsigned int v = 0; v < n_lanes; ++v)
3080 const unsigned int cell_dof_index =
3081 cell_index * this->n_fe_components + this->first_selected_component;
3082 const unsigned int n_components_read =
3083 this->n_fe_components > 1 ? n_components : 1;
3084 unsigned int index_indicators =
3086 unsigned int next_index_indicators =
3087 dof_info.
row_starts[cell_dof_index + 1].second;
3091 if (apply_constraints ==
false &&
3092 (dof_info.
row_starts[cell_dof_index].second !=
3093 dof_info.
row_starts[cell_dof_index + n_components_read].second ||
3099 dof_info.hanging_node_constraint_masks_comp
3100 [this->active_fe_index][this->first_selected_component])))
3109 [this->first_selected_component] +
3111 next_index_indicators = index_indicators;
3114 if (n_components == 1 || this->n_fe_components == 1)
3116 unsigned int ind_local = 0;
3117 for (; index_indicators != next_index_indicators; ++index_indicators)
3119 const std::pair<unsigned short, unsigned short> indicator =
3122 for (
unsigned int j = 0; j < indicator.first; ++j)
3123 for (
unsigned int comp = 0; comp < n_components; ++comp)
3124 operation.process_dof(dof_indices[v][j],
3126 values_dofs[comp][ind_local + j][v]);
3128 ind_local += indicator.first;
3129 dof_indices[v] += indicator.first;
3133 Number
value[n_components];
3134 for (
unsigned int comp = 0; comp < n_components; ++comp)
3135 operation.pre_constraints(values_dofs[comp][ind_local][v],
3138 const Number *data_val =
3140 const Number *end_pool =
3142 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
3143 for (
unsigned int comp = 0; comp < n_components; ++comp)
3144 operation.process_constraint(*dof_indices[v],
3149 for (
unsigned int comp = 0; comp < n_components; ++comp)
3150 operation.post_constraints(value[comp],
3151 values_dofs[comp][ind_local][v]);
3157 for (; ind_local < dofs_per_component; ++dof_indices[v], ++ind_local)
3158 for (
unsigned int comp = 0; comp < n_components; ++comp)
3159 operation.process_dof(*dof_indices[v],
3161 values_dofs[comp][ind_local][v]);
3170 for (
unsigned int comp = 0; comp < n_components; ++comp)
3172 unsigned int ind_local = 0;
3175 for (; index_indicators != next_index_indicators;
3178 const std::pair<unsigned short, unsigned short> indicator =
3182 for (
unsigned int j = 0; j < indicator.first; ++j)
3183 operation.process_dof(dof_indices[v][j],
3185 values_dofs[comp][ind_local + j][v]);
3186 ind_local += indicator.first;
3187 dof_indices[v] += indicator.first;
3192 operation.pre_constraints(values_dofs[comp][ind_local][v],
3195 const Number *data_val =
3197 const Number *end_pool =
3200 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
3201 operation.process_constraint(*dof_indices[v],
3206 operation.post_constraints(value,
3207 values_dofs[comp][ind_local][v]);
3214 for (; ind_local < dofs_per_component;
3215 ++dof_indices[v], ++ind_local)
3218 operation.process_dof(*dof_indices[v],
3220 values_dofs[comp][ind_local][v]);
3223 if (apply_constraints ==
true && comp + 1 < n_components)
3224 next_index_indicators =
3225 dof_info.
row_starts[cell_dof_index + comp + 2].second;
3237 typename VectorizedArrayType>
3238template <
typename VectorType,
typename VectorOperation>
3243 const std::array<VectorType *, n_components_> &src)
const
3247 const std::size_t dofs_per_component = this->data->dofs_per_component_on_cell;
3248 unsigned int index = this->first_selected_component * dofs_per_component;
3249 for (
unsigned int comp = 0; comp < n_components; ++comp)
3251 for (
unsigned int i = 0; i < dofs_per_component; ++i, ++
index)
3253 operation.process_empty(
3254 this->values_dofs[comp * dofs_per_component + i]);
3255 operation.process_dof_global(
3256 local_dof_indices[this->data->lexicographic_numbering[index]],
3258 this->values_dofs[comp * dofs_per_component + i][0]);
3269 typename VectorizedArrayType>
3270template <
typename VectorType,
typename VectorOperation>
3275 const std::array<VectorType *, n_components_> &src,
3278 n_components_> &vectors_sm,
3279 const std::bitset<n_lanes> &mask)
const
3288 std::bool_constant<internal::is_vectorizable<VectorType, Number>::value>
3291 is_face ? this->dof_access_index :
3293 const unsigned int n_active_lanes =
mask.count();
3296 const std::vector<unsigned int> &dof_indices_cont =
3299 const std::size_t dofs_per_component = this->data->dofs_per_component_on_cell;
3300 std::array<VectorizedArrayType *, n_components> values_dofs;
3301 for (
unsigned int c = 0; c < n_components; ++c)
3302 values_dofs[c] =
const_cast<VectorizedArrayType *
>(this->values_dofs) +
3303 c * dofs_per_component;
3307 const bool accesses_exterior_dofs =
3308 this->dof_access_index ==
3310 this->is_interior_face() ==
false;
3316 interleaved_contiguous &&
3317 n_active_lanes == n_lanes && !accesses_exterior_dofs)
3319 const unsigned int dof_index =
3320 dof_indices_cont[this->cell * n_lanes] +
3323 [this->first_selected_component] *
3325 if (n_components == 1 || this->n_fe_components == 1)
3326 for (
unsigned int comp = 0; comp < n_components; ++comp)
3327 operation.process_dofs_vectorized(dofs_per_component,
3333 operation.process_dofs_vectorized(dofs_per_component * n_components,
3341 const std::array<unsigned int, n_lanes> &cells = this->get_cell_or_face_ids();
3345 const unsigned int n_filled_lanes =
3348 const bool use_vectorized_path = n_filled_lanes == n_lanes &&
3349 n_active_lanes == n_lanes &&
3350 !accesses_exterior_dofs;
3352 if (vectors_sm[0] !=
nullptr)
3354 const auto compute_vector_ptrs = [&](
const unsigned int comp) {
3355 std::array<typename VectorType::value_type *, n_lanes> vector_ptrs = {};
3357 const auto upper_bound =
3359 for (
unsigned int v = 0; v < upper_bound; ++v)
3361 if (mask[v] ==
false)
3363 vector_ptrs[v] =
nullptr;
3383 vector_ptrs[v] =
const_cast<typename VectorType::value_type *
>(
3384 vectors_sm[comp]->operator[](temp.first).data() + temp.second +
3386 [this->active_fe_index][this->first_selected_component]);
3388 vector_ptrs[v] =
nullptr;
3390 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
3391 vector_ptrs[v] =
nullptr;
3396 if (use_vectorized_path)
3398 if (n_components == 1 || this->n_fe_components == 1)
3400 for (
unsigned int comp = 0; comp < n_components; ++comp)
3402 auto vector_ptrs = compute_vector_ptrs(comp);
3403 operation.process_dofs_vectorized_transpose(
3412 auto vector_ptrs = compute_vector_ptrs(0);
3413 operation.process_dofs_vectorized_transpose(dofs_per_component *
3421 for (
unsigned int comp = 0; comp < n_components; ++comp)
3423 auto vector_ptrs = compute_vector_ptrs(
3424 (n_components == 1 || this->n_fe_components == 1) ? comp : 0);
3426 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3427 operation.process_empty(values_dofs[comp][i]);
3429 if (n_components == 1 || this->n_fe_components == 1)
3431 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3432 if (mask[v] ==
true)
3433 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3434 operation.process_dof(vector_ptrs[v][i],
3435 values_dofs[comp][i][v]);
3439 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3440 if (mask[v] ==
true)
3441 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3442 operation.process_dof(
3443 vector_ptrs[v][i + comp * dofs_per_component],
3444 values_dofs[comp][i][v]);
3450 std::array<unsigned int, n_lanes> dof_indices;
3451 std::fill(dof_indices.begin(),
3456 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3460 if (mask[v] ==
true)
3462 dof_indices_cont[cells[v]] +
3465 [this->first_selected_component] *
3471 if (use_vectorized_path)
3477 if (n_components == 1 || this->n_fe_components == 1)
3478 for (
unsigned int comp = 0; comp < n_components; ++comp)
3479 operation.process_dofs_vectorized_transpose(dofs_per_component,
3485 operation.process_dofs_vectorized_transpose(dofs_per_component *
3494 interleaved_contiguous_strided)
3496 std::array<typename VectorType::value_type *, n_components> src_ptrs;
3497 if (n_components == 1 || this->n_fe_components == 1)
3498 for (
unsigned int comp = 0; comp < n_components; ++comp)
3499 src_ptrs[comp] =
const_cast<typename VectorType::value_type *
>(
3500 src[comp]->
begin());
3503 const_cast<typename VectorType::value_type *
>(src[0]->begin());
3505 if (n_components == 1 || this->n_fe_components == 1)
3506 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3508 for (
unsigned int comp = 0; comp < n_components; ++comp)
3509 operation.process_dof_gather(dof_indices.data(),
3512 src_ptrs[comp] + i * n_lanes,
3513 values_dofs[comp][i],
3517 for (
unsigned int comp = 0; comp < n_components; ++comp)
3518 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3520 operation.process_dof_gather(
3523 (comp * dofs_per_component + i) * n_lanes,
3524 src_ptrs[0] + (comp * dofs_per_component + i) * n_lanes,
3525 values_dofs[comp][i],
3533 IndexStorageVariants::interleaved_contiguous_mixed_strides,
3535 std::array<typename VectorType::value_type *, n_components> src_ptrs;
3536 if (n_components == 1 || this->n_fe_components == 1)
3537 for (
unsigned int comp = 0; comp < n_components; ++comp)
3538 src_ptrs[comp] =
const_cast<typename VectorType::value_type *
>(
3539 src[comp]->
begin());
3542 const_cast<typename VectorType::value_type *
>(src[0]->begin());
3544 const unsigned int *offsets =
3546 if (n_components == 1 || this->n_fe_components == 1)
3547 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3549 for (
unsigned int comp = 0; comp < n_components; ++comp)
3550 operation.process_dof_gather(dof_indices.data(),
3554 values_dofs[comp][i],
3557 for (
unsigned int v = 0; v < n_lanes; ++v)
3558 dof_indices[v] += offsets[v];
3561 for (
unsigned int comp = 0; comp < n_components; ++comp)
3562 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3564 operation.process_dof_gather(dof_indices.data(),
3568 values_dofs[comp][i],
3571 for (
unsigned int v = 0; v < n_lanes; ++v)
3572 dof_indices[v] += offsets[v];
3577 for (
unsigned int comp = 0; comp < n_components; ++comp)
3579 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3580 operation.process_empty(values_dofs[comp][i]);
3581 if (accesses_exterior_dofs)
3583 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3584 if (mask[v] ==
true)
3587 [ind][cells[v] / VectorizedArrayType::size()] ==
3591 if (n_components == 1 || this->n_fe_components == 1)
3593 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3594 operation.process_dof(dof_indices[v] + i,
3596 values_dofs[comp][i][v]);
3600 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3601 operation.process_dof(dof_indices[v] + i +
3602 comp * dofs_per_component,
3604 values_dofs[comp][i][v]);
3609 const unsigned int offset =
3612 if (n_components == 1 || this->n_fe_components == 1)
3614 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3615 operation.process_dof(dof_indices[v] + i * offset,
3617 values_dofs[comp][i][v]);
3621 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3622 operation.process_dof(
3624 (i + comp * dofs_per_component) * offset,
3626 values_dofs[comp][i][v]);
3637 if (n_components == 1 || this->n_fe_components == 1)
3639 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3640 if (mask[v] ==
true)
3641 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3642 operation.process_dof(dof_indices[v] + i,
3644 values_dofs[comp][i][v]);
3648 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3649 if (mask[v] ==
true)
3650 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3651 operation.process_dof(dof_indices[v] + i +
3652 comp * dofs_per_component,
3654 values_dofs[comp][i][v]);
3659 const unsigned int *offsets =
3661 [ind][VectorizedArrayType::size() * this->cell];
3662 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3664 if (n_components == 1 || this->n_fe_components == 1)
3665 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3667 if (mask[v] ==
true)
3668 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3669 operation.process_dof(dof_indices[v] + i * offsets[v],
3671 values_dofs[comp][i][v]);
3675 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3676 if (mask[v] ==
true)
3677 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3678 operation.process_dof(
3680 (i + comp * dofs_per_component) * offsets[v],
3682 values_dofs[comp][i][v]);
3693 typename VectorType,
3694 std::enable_if_t<!IsBlockVector<VectorType>::value, VectorType> * =
nullptr>
3695 decltype(std::declval<VectorType>().begin())
3696 get_beginning(VectorType &vec)
3703 typename VectorType,
3704 std::enable_if_t<IsBlockVector<VectorType>::value, VectorType> * =
nullptr>
3705 typename VectorType::value_type *
3706 get_beginning(VectorType &)
3711 template <
typename VectorType,
3712 std::enable_if_t<has_shared_vector_data<VectorType>, VectorType> * =
3714 const std::vector<ArrayView<const typename VectorType::value_type>> *
3715 get_shared_vector_data(VectorType *vec,
3716 const bool is_valid_mode_for_sm,
3717 const unsigned int active_fe_index,
3721 if (is_valid_mode_for_sm &&
3724 active_fe_index == 0)
3725 return &vec->shared_vector_data();
3730 template <
typename VectorType,
3731 std::enable_if_t<!has_shared_vector_data<VectorType>, VectorType>
3733 const std::vector<ArrayView<const typename VectorType::value_type>> *
3734 get_shared_vector_data(VectorType *,
3742 template <
int n_components,
typename VectorType>
3744 std::array<
typename internal::BlockVectorSelector<
3749 const std::vector<
ArrayView<
const typename internal::BlockVectorSelector<
3753 get_vector_data(VectorType &src,
3754 const unsigned int first_index,
3755 const bool is_valid_mode_for_sm,
3756 const unsigned int active_fe_index,
3762 std::array<
typename internal::BlockVectorSelector<
3768 ArrayView<
const typename internal::BlockVectorSelector<
3774 for (
unsigned int d = 0;
d < n_components; ++
d)
3775 src_data.first[d] = internal::BlockVectorSelector<
3781 for (
unsigned int d = 0;
d < n_components; ++
d)
3782 src_data.second[d] = get_shared_vector_data(
3783 const_cast<typename internal::BlockVectorSelector<
3784 std::remove_const_t<VectorType>,
3786 *>(src_data.first[d]),
3787 is_valid_mode_for_sm,
3801 typename VectorizedArrayType>
3806 if (this->dof_info ==
nullptr ||
3808 this->dof_info->hanging_node_constraint_masks_comp.empty() ||
3809 this->dof_info->hanging_node_constraint_masks_comp
3810 [this->active_fe_index][this->first_selected_component] ==
false)
3813 std::array<internal::MatrixFreeFunctions::compressed_constraint_kind, n_lanes>
3816 bool hn_available =
false;
3818 const std::array<unsigned int, n_lanes> &cells = this->get_cell_ids();
3820 for (
unsigned int v = 0; v < n_lanes; ++v)
3832 constraint_mask[v] =
mask;
3838 if (hn_available ==
false)
3843 this->data->data.front().fe_degree,
3844 this->get_shape_info(),
3856 typename VectorizedArrayType>
3857template <
typename VectorType>
3861 const unsigned int first_index,
3862 const std::bitset<n_lanes> &mask)
3864 const auto src_data = internal::get_vector_data<n_components_>(
3867 this->dof_access_index ==
3869 this->active_fe_index,
3873 read_write_operation(reader, src_data.first, src_data.second, mask,
true);
3875 apply_hanging_node_constraints(
false);
3878 this->dof_values_initialized =
true;
3888 typename VectorizedArrayType>
3889template <
typename VectorType>
3893 const unsigned int first_index,
3894 const std::bitset<n_lanes> &mask)
3896 const auto src_data = internal::get_vector_data<n_components_>(
3899 this->dof_access_index ==
3901 this->active_fe_index,
3905 read_write_operation(reader, src_data.first, src_data.second, mask,
false);
3908 this->dof_values_initialized =
true;
3918 typename VectorizedArrayType>
3919template <
typename VectorType>
3923 const unsigned int first_index,
3924 const std::bitset<n_lanes> &mask)
const
3927 Assert(this->dof_values_initialized ==
true,
3931 apply_hanging_node_constraints(
true);
3933 const auto dst_data = internal::get_vector_data<n_components_>(
3936 this->dof_access_index ==
3938 this->active_fe_index,
3943 read_write_operation(distributor, dst_data.first, dst_data.second, mask);
3952 typename VectorizedArrayType>
3953template <
typename VectorType>
3957 const unsigned int first_index,
3958 const std::bitset<n_lanes> &mask)
const
3961 Assert(this->dof_values_initialized ==
true,
3965 const auto dst_data = internal::get_vector_data<n_components_>(
3968 this->dof_access_index ==
3970 this->active_fe_index,
3974 read_write_operation(setter, dst_data.first, dst_data.second, mask);
3983 typename VectorizedArrayType>
3984template <
typename VectorType>
3988 const unsigned int first_index,
3989 const std::bitset<n_lanes> &mask)
const
3992 Assert(this->dof_values_initialized ==
true,
3996 const auto dst_data = internal::get_vector_data<n_components_>(
3999 this->dof_access_index ==
4001 this->active_fe_index,
4005 read_write_operation(setter, dst_data.first, dst_data.second, mask,
false);
4018 typename VectorizedArrayType>
4024 VectorizedArrayType>::value_type
4029 if constexpr (n_components == 1)
4030 return this->values_dofs[dof];
4033 const std::size_t dofs = this->data->dofs_per_component_on_cell;
4035 for (
unsigned int comp = 0; comp < n_components; ++comp)
4036 return_value[comp] = this->values_dofs[comp * dofs + dof];
4037 return return_value;
4047 typename VectorizedArrayType>
4053 VectorizedArrayType>::value_type
4055 get_value(
const unsigned int q_point)
const
4058 Assert(this->values_quad_initialized ==
true,
4063 if constexpr (n_components == 1)
4064 return this->values_quad[q_point];
4067 if (n_components == dim &&
4068 this->data->element_type ==
4073 Assert(this->values_quad_initialized ==
true,
4078 Assert(this->J_value !=
nullptr,
4081 const std::size_t nqp = this->n_quadrature_points;
4089 const VectorizedArrayType inv_det =
4090 (dim == 2) ? this->jacobian[0][0][0] * this->jacobian[0][1][1] :
4091 this->jacobian[0][0][0] * this->jacobian[0][1][1] *
4092 this->jacobian[0][2][2];
4095 for (
unsigned int comp = 0; comp < n_components; ++comp)
4096 value_out[comp] = this->values_quad[comp * nqp + q_point] *
4097 jac[comp][comp] * inv_det;
4104 this->jacobian[q_point] :
4113 const VectorizedArrayType inv_det =
4114 (is_face && dim == 2 && this->get_face_no() < 2) ?
4118 for (
unsigned int comp = 0; comp < n_components; ++comp)
4120 value_out[comp] = this->values_quad[q_point] * jac[comp][0];
4121 for (
unsigned int e = 1;
e < dim; ++
e)
4123 this->values_quad[e * nqp + q_point] * jac[comp][e];
4124 value_out[comp] *= inv_det;
4131 const std::size_t nqp = this->n_quadrature_points;
4133 for (
unsigned int comp = 0; comp < n_components; ++comp)
4134 return_value[comp] = this->values_quad[comp * nqp + q_point];
4135 return return_value;
4146 typename VectorizedArrayType>
4152 VectorizedArrayType>::gradient_type
4157 Assert(this->gradients_quad_initialized ==
true,
4162 Assert(this->jacobian !=
nullptr,
4164 "update_gradients"));
4165 const std::size_t nqp = this->n_quadrature_points;
4167 if constexpr (n_components == dim && dim > 1)
4169 if (this->data->element_type ==
4174 Assert(this->gradients_quad_initialized ==
true,
4179 Assert(this->jacobian !=
nullptr,
4181 "update_gradients"));
4182 const std::size_t nqp = this->n_quadrature_points;
4183 const std::size_t nqp_d = nqp * dim;
4186 this->gradients_quad + q_point * dim;
4197 const VectorizedArrayType inv_det =
4198 (dim == 2) ? this->jacobian[0][0][0] * this->jacobian[0][1][1] :
4199 this->jacobian[0][0][0] * this->jacobian[0][1][1] *
4200 this->jacobian[0][2][2];
4203 for (
unsigned int d = 0;
d < dim; ++
d)
4204 for (
unsigned int comp = 0; comp < n_components; ++comp)
4205 grad_out[comp][d] = gradients[comp * nqp_d + d] *
4207 (jac[comp][comp] * inv_det);
4219 const VectorizedArrayType inv_det =
4220 (is_face && dim == 2 && this->get_face_no() < 2) ?
4224 VectorizedArrayType tmp[dim][dim];
4226 for (
unsigned int d = 0;
d < dim; ++
d)
4227 for (
unsigned int e = 0;
e < dim; ++
e)
4230 for (
unsigned int f = 1; f < dim; ++f)
4231 tmp[d][e] += inv_t_jac[d][f] * gradients[e * nqp_d + f];
4233 for (
unsigned int comp = 0; comp < n_components; ++comp)
4234 for (
unsigned int d = 0;
d < dim; ++
d)
4236 VectorizedArrayType res = jac[comp][0] * tmp[
d][0];
4237 for (
unsigned int f = 1; f < dim; ++f)
4238 res += jac[comp][f] * tmp[d][f];
4240 grad_out[comp][
d] = res * inv_det;
4251 Assert(this->jacobian_gradients_non_inverse !=
nullptr,
4253 "update_hessians"));
4255 const auto jac_grad =
4256 this->jacobian_gradients_non_inverse[q_point];
4258 this->jacobian[q_point];
4262 const VectorizedArrayType inv_det =
4263 (is_face && dim == 2 && this->get_face_no() < 2) ?
4270 VectorizedArrayType tmp[dim][dim];
4271 for (
unsigned int d = 0;
d < dim; ++
d)
4272 for (
unsigned int e = 0;
e < dim; ++
e)
4275 for (
unsigned int f = 1; f < dim; ++f)
4276 tmp[e][d] += t_jac[f][d] * gradients[f * nqp_d + e];
4281 for (
unsigned int d = 0;
d < dim; ++
d)
4283 for (
unsigned int e = 0;
e < dim; ++
e)
4285 jac_grad[e][d] * this->values_quad[e * nqp + q_point];
4286 for (
unsigned int f = 0, r = dim; f < dim; ++f)
4287 for (
unsigned int k = f + 1; k < dim; ++k, ++r)
4290 jac_grad[r][
d] * this->values_quad[f * nqp + q_point];
4292 jac_grad[r][
d] * this->values_quad[k * nqp + q_point];
4297 for (
unsigned int d = 0;
d < dim; ++
d)
4298 for (
unsigned int e = 0;
e < dim; ++
e)
4300 VectorizedArrayType res = tmp[0][
d] * inv_t_jac[
e][0];
4301 for (
unsigned int f = 1; f < dim; ++f)
4302 res += tmp[f][d] * inv_t_jac[e][f];
4303 grad_out[
d][
e] = res;
4309 VectorizedArrayType tmp3[dim], tmp4[dim];
4310 for (
unsigned int d = 0;
d < dim; ++
d)
4312 tmp3[
d] = inv_t_jac[0][
d] * jac_grad[
d][0];
4313 for (
unsigned int e = 1;
e < dim; ++
e)
4314 tmp3[d] += inv_t_jac[e][d] * jac_grad[d][e];
4316 for (
unsigned int e = 0, k = dim;
e < dim; ++
e)
4317 for (
unsigned int f = e + 1; f < dim; ++k, ++f)
4318 for (
unsigned int d = 0;
d < dim; ++
d)
4320 tmp3[f] += inv_t_jac[
d][
e] * jac_grad[k][
d];
4321 tmp3[
e] += inv_t_jac[
d][f] * jac_grad[k][
d];
4323 for (
unsigned int d = 0;
d < dim; ++
d)
4325 tmp4[
d] = tmp3[0] * inv_t_jac[
d][0];
4326 for (
unsigned int e = 1;
e < dim; ++
e)
4327 tmp4[d] += tmp3[e] * inv_t_jac[d][e];
4330 VectorizedArrayType tmp2[dim];
4331 for (
unsigned int d = 0;
d < dim; ++
d)
4333 tmp2[
d] = t_jac[0][
d] * this->values_quad[q_point];
4334 for (
unsigned e = 1;
e < dim; ++
e)
4336 t_jac[e][d] * this->values_quad[e * nqp + q_point];
4339 for (
unsigned int d = 0;
d < dim; ++
d)
4340 for (
unsigned int e = 0;
e < dim; ++
e)
4342 grad_out[
d][
e] -= tmp4[
e] * tmp2[
d];
4346 grad_out[
d][
e] *= inv_det;
4357 for (
unsigned int comp = 0; comp < n_components; ++comp)
4358 for (
unsigned int d = 0;
d < dim; ++
d)
4360 this->gradients_quad[(comp * nqp + q_point) * dim +
d] *
4361 this->jacobian[0][
d][
d];
4370 for (
unsigned int comp = 0; comp < n_components; ++comp)
4371 for (
unsigned int d = 0;
d < dim; ++
d)
4374 jac[
d][0] * this->gradients_quad[(comp * nqp + q_point) * dim];
4375 for (
unsigned int e = 1;
e < dim; ++
e)
4376 grad_out[comp][d] +=
4378 this->gradients_quad[(comp * nqp + q_point) * dim +
e];
4381 if constexpr (n_components == 1)
4393 typename VectorizedArrayType>
4399 VectorizedArrayType>::value_type
4405 Assert(this->gradients_quad_initialized ==
true,
4409 Assert(this->normal_x_jacobian !=
nullptr,
4411 "update_gradients"));
4413 const std::size_t nqp = this->n_quadrature_points;
4417 for (
unsigned int comp = 0; comp < n_components; ++comp)
4419 this->gradients_quad[(comp * nqp + q_point) * dim + dim - 1] *
4420 (this->normal_x_jacobian[0][dim - 1]);
4423 const std::size_t
index =
4425 for (
unsigned int comp = 0; comp < n_components; ++comp)
4427 grad_out[comp] = this->gradients_quad[(comp * nqp + q_point) * dim] *
4428 this->normal_x_jacobian[index][0];
4429 for (
unsigned int d = 1;
d < dim; ++
d)
4431 this->gradients_quad[(comp * nqp + q_point) * dim +
d] *
4432 this->normal_x_jacobian[
index][
d];
4435 if constexpr (n_components == 1)
4447 template <
typename VectorizedArrayType>
4450 const VectorizedArrayType *
const hessians,
4452 VectorizedArrayType (&tmp)[1][1])
4454 tmp[0][0] = jac[0][0] *
hessians[0];
4457 template <
typename VectorizedArrayType>
4460 const VectorizedArrayType *
const hessians,
4461 const unsigned int nqp,
4462 VectorizedArrayType (&tmp)[2][2])
4464 for (
unsigned int d = 0;
d < 2; ++
d)
4472 template <
typename VectorizedArrayType>
4475 const VectorizedArrayType *
const hessians,
4476 const unsigned int nqp,
4477 VectorizedArrayType (&tmp)[3][3])
4479 for (
unsigned int d = 0;
d < 3; ++
d)
4500 typename VectorizedArrayType>
4505 VectorizedArrayType>::hessian_type
4510 Assert(this->hessians_quad_initialized ==
true,
4515 Assert(this->jacobian !=
nullptr,
4525 const std::size_t nqp = this->n_quadrature_points;
4526 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
4531 for (
unsigned int comp = 0; comp < n_components; ++comp)
4533 for (
unsigned int d = 0;
d < dim; ++
d)
4534 hessian_out[comp][d][d] =
4535 this->hessians_quad[(comp * hdim + d) * nqp + q_point] *
4536 (jac[
d][
d] * jac[
d][
d]);
4542 hessian_out[comp][0][1] =
4543 this->hessians_quad[(comp * hdim + 2) * nqp + q_point] *
4544 (jac[0][0] * jac[1][1]);
4547 hessian_out[comp][0][1] =
4548 this->hessians_quad[(comp * hdim + 3) * nqp + q_point] *
4549 (jac[0][0] * jac[1][1]);
4550 hessian_out[comp][0][2] =
4551 this->hessians_quad[(comp * hdim + 4) * nqp + q_point] *
4552 (jac[0][0] * jac[2][2]);
4553 hessian_out[comp][1][2] =
4554 this->hessians_quad[(comp * hdim + 5) * nqp + q_point] *
4555 (jac[1][1] * jac[2][2]);
4560 for (
unsigned int d = 0;
d < dim; ++
d)
4561 for (
unsigned int e = d + 1;
e < dim; ++
e)
4562 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4568 for (
unsigned int comp = 0; comp < n_components; ++comp)
4570 VectorizedArrayType tmp[dim][dim];
4571 internal::hessian_unit_times_jac(
4572 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4575 for (
unsigned int d = 0;
d < dim; ++
d)
4576 for (
unsigned int e = d;
e < dim; ++
e)
4578 hessian_out[comp][
d][
e] = jac[
d][0] * tmp[0][
e];
4579 for (
unsigned int f = 1; f < dim; ++f)
4580 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
4587 for (
unsigned int d = 0;
d < dim; ++
d)
4588 for (
unsigned int e = d + 1;
e < dim; ++
e)
4589 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4595 const auto &jac_grad = this->jacobian_gradients[q_point];
4596 for (
unsigned int comp = 0; comp < n_components; ++comp)
4598 VectorizedArrayType tmp[dim][dim];
4599 internal::hessian_unit_times_jac(
4600 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4603 for (
unsigned int d = 0;
d < dim; ++
d)
4604 for (
unsigned int e = d;
e < dim; ++
e)
4606 hessian_out[comp][
d][
e] = jac[
d][0] * tmp[0][
e];
4607 for (
unsigned int f = 1; f < dim; ++f)
4608 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
4612 for (
unsigned int d = 0;
d < dim; ++
d)
4613 for (
unsigned int e = 0;
e < dim; ++
e)
4614 hessian_out[comp][d][d] +=
4616 this->gradients_quad[(comp * nqp + q_point) * dim +
e];
4619 for (
unsigned int d = 0, count = dim;
d < dim; ++
d)
4620 for (
unsigned int e = d + 1;
e < dim; ++
e, ++count)
4621 for (
unsigned int f = 0; f < dim; ++f)
4622 hessian_out[comp][d][e] +=
4623 jac_grad[count][f] *
4624 this->gradients_quad[(comp * nqp + q_point) * dim + f];
4627 for (
unsigned int d = 0;
d < dim; ++
d)
4628 for (
unsigned int e = d + 1;
e < dim; ++
e)
4629 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4632 if constexpr (n_components == 1)
4633 return hessian_out[0];
4644 typename VectorizedArrayType>
4649 VectorizedArrayType>::gradient_type
4655 Assert(this->hessians_quad_initialized ==
true,
4666 const std::size_t nqp = this->n_quadrature_points;
4667 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
4673 for (
unsigned int comp = 0; comp < n_components; ++comp)
4674 for (
unsigned int d = 0;
d < dim; ++
d)
4675 hessian_out[comp][d] =
4676 this->hessians_quad[(comp * hdim + d) * nqp + q_point] *
4677 (jac[
d][
d] * jac[
d][
d]);
4682 for (
unsigned int comp = 0; comp < n_components; ++comp)
4686 VectorizedArrayType tmp[dim][dim];
4687 internal::hessian_unit_times_jac(
4688 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4692 for (
unsigned int d = 0;
d < dim; ++
d)
4694 hessian_out[comp][
d] = jac[
d][0] * tmp[0][
d];
4695 for (
unsigned int f = 1; f < dim; ++f)
4696 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
4703 const auto &jac_grad = this->jacobian_gradients[q_point];
4704 for (
unsigned int comp = 0; comp < n_components; ++comp)
4708 VectorizedArrayType tmp[dim][dim];
4709 internal::hessian_unit_times_jac(
4710 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4714 for (
unsigned int d = 0;
d < dim; ++
d)
4716 hessian_out[comp][
d] = jac[
d][0] * tmp[0][
d];
4717 for (
unsigned int f = 1; f < dim; ++f)
4718 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
4721 for (
unsigned int d = 0;
d < dim; ++
d)
4722 for (
unsigned int e = 0;
e < dim; ++
e)
4723 hessian_out[comp][d] +=
4725 this->gradients_quad[(comp * nqp + q_point) * dim +
e];
4729 if constexpr (n_components == 1)
4730 return hessian_out[0];
4741 typename VectorizedArrayType>
4746 VectorizedArrayType>::value_type
4752 Assert(this->hessians_quad_initialized ==
true,
4757 const gradient_type hess_diag = get_hessian_diagonal(q_point);
4758 if constexpr (n_components == 1)
4760 VectorizedArrayType
sum = hess_diag[0];
4761 for (
unsigned int d = 1;
d < dim; ++
d)
4762 sum += hess_diag[d];
4768 for (
unsigned int comp = 0; comp < n_components; ++comp)
4770 laplacian_out[comp] = hess_diag[comp][0];
4771 for (
unsigned int d = 1;
d < dim; ++
d)
4772 laplacian_out[comp] += hess_diag[comp][d];
4774 return laplacian_out;
4784 typename VectorizedArrayType>
4790 this->dof_values_initialized =
true;
4792 const std::size_t dofs = this->data->dofs_per_component_on_cell;
4794 for (
unsigned int comp = 0; comp < n_components; ++comp)
4795 if constexpr (n_components == 1)
4796 this->values_dofs[comp * dofs + dof] = val_in;
4798 this->values_dofs[comp * dofs + dof] = val_in[comp];
4807 typename VectorizedArrayType>
4810 submit_value(
const value_type val_in,
const unsigned int q_point)
4816 Assert(this->J_value !=
nullptr,
4820 this->values_quad_submitted =
true;
4823 const std::size_t nqp = this->n_quadrature_points;
4824 VectorizedArrayType *values = this->values_quad + q_point;
4826 const VectorizedArrayType JxW =
4828 this->J_value[0] * this->quadrature_weights[q_point] :
4829 this->J_value[q_point];
4830 if constexpr (n_components == 1)
4831 values[0] = val_in * JxW;
4834 if (n_components == dim &&
4835 this->data->element_type ==
4840 Assert(this->J_value !=
nullptr,
4845 this->values_quad_submitted =
true;
4848 VectorizedArrayType *values = this->values_quad + q_point;
4849 const std::size_t nqp = this->n_quadrature_points;
4855 const VectorizedArrayType weight =
4856 this->quadrature_weights[q_point];
4858 for (
unsigned int comp = 0; comp < n_components; ++comp)
4859 values[comp * nqp] = val_in[comp] * weight * jac[comp][comp];
4866 this->jacobian[q_point] :
4871 const VectorizedArrayType fac =
4873 this->quadrature_weights[q_point] :
4875 this->J_value[q_point] :
4876 this->J_value[0] * this->quadrature_weights[q_point]) *
4877 ((dim == 2 && this->get_face_no() < 2) ?
4886 for (
unsigned int comp = 0; comp < n_components; ++comp)
4888 values[comp * nqp] = val_in[0] * jac[0][comp];
4889 for (
unsigned int e = 1;
e < dim; ++
e)
4890 values[comp * nqp] += val_in[e] * jac[e][comp];
4891 values[comp * nqp] *= fac;
4896 for (
unsigned int comp = 0; comp < n_components; ++comp)
4897 values[comp * nqp] = val_in[comp] * JxW;
4907 typename VectorizedArrayType>
4908template <
int,
typename>
4912 const unsigned int q_point)
4914 static_assert(n_components == 1,
4915 "Do not try to modify the default template parameters used for"
4916 " selectively enabling this function via std::enable_if!");
4917 submit_value(val_in[0], q_point);
4926 typename VectorizedArrayType>
4929 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point)
4935 Assert(this->J_value !=
nullptr,
4937 "update_gradients"));
4938 Assert(this->jacobian !=
nullptr,
4940 "update_gradients"));
4942 this->gradients_quad_submitted =
true;
4945 if constexpr (dim > 1 && n_components == dim)
4947 if (this->data->element_type ==
4956 Assert(this->J_value !=
nullptr,
4958 "update_gradients"));
4959 Assert(this->jacobian !=
nullptr,
4961 "update_gradients"));
4963 this->gradients_quad_submitted =
true;
4966 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
4967 VectorizedArrayType *values =
4968 this->values_from_gradients_quad + q_point;
4969 const std::size_t nqp = this->n_quadrature_points;
4970 const std::size_t nqp_d = nqp * dim;
4980 const VectorizedArrayType weight =
4981 this->quadrature_weights[q_point];
4982 for (
unsigned int d = 0;
d < dim; ++
d)
4983 for (
unsigned int comp = 0; comp < n_components; ++comp)
4984 gradients[comp * nqp_d + d] = grad_in[comp][d] *
4986 (jac[comp][comp] * weight);
4998 const VectorizedArrayType fac =
5000 this->quadrature_weights[q_point] :
5001 this->J_value[0] * this->quadrature_weights[q_point] *
5002 ((dim == 2 && this->get_face_no() < 2) ?
5007 VectorizedArrayType tmp[dim][dim];
5008 for (
unsigned int d = 0;
d < dim; ++
d)
5009 for (
unsigned int e = 0;
e < dim; ++
e)
5011 tmp[
d][
e] = inv_t_jac[0][
d] * grad_in[
e][0];
5012 for (
unsigned int f = 1; f < dim; ++f)
5013 tmp[d][e] += inv_t_jac[f][d] * grad_in[e][f];
5015 for (
unsigned int comp = 0; comp < n_components; ++comp)
5016 for (
unsigned int d = 0;
d < dim; ++
d)
5018 VectorizedArrayType res = jac[0][comp] * tmp[
d][0];
5019 for (
unsigned int f = 1; f < dim; ++f)
5020 res += jac[f][comp] * tmp[d][f];
5029 const auto jac_grad =
5030 this->jacobian_gradients_non_inverse[q_point];
5032 this->jacobian[q_point];
5036 const VectorizedArrayType fac =
5037 (!is_face) ? this->quadrature_weights[q_point] :
5038 this->J_value[q_point] *
5039 ((dim == 2 && this->get_face_no() < 2) ?
5048 VectorizedArrayType tmp3[dim], tmp4[dim];
5049 for (
unsigned int d = 0;
d < dim; ++
d)
5051 tmp3[
d] = inv_t_jac[0][
d] * jac_grad[
d][0];
5052 for (
unsigned int e = 1;
e < dim; ++
e)
5053 tmp3[d] += inv_t_jac[e][d] * jac_grad[d][e];
5055 for (
unsigned int e = 0, k = dim;
e < dim; ++
e)
5056 for (
unsigned int f = e + 1; f < dim; ++k, ++f)
5057 for (
unsigned int d = 0;
d < dim; ++
d)
5059 tmp3[f] += inv_t_jac[
d][
e] * jac_grad[k][
d];
5060 tmp3[
e] += inv_t_jac[
d][f] * jac_grad[k][
d];
5062 for (
unsigned int d = 0;
d < dim; ++
d)
5064 tmp4[
d] = tmp3[0] * inv_t_jac[
d][0];
5065 for (
unsigned int e = 1;
e < dim; ++
e)
5066 tmp4[d] += tmp3[e] * inv_t_jac[d][e];
5072 VectorizedArrayType tmp[dim][dim];
5075 for (
unsigned int d = 0;
d < dim; ++
d)
5076 for (
unsigned int e = 0;
e < dim; ++
e)
5078 tmp[
d][
e] = inv_t_jac[0][
d] * grad_in_scaled[
e][0];
5079 for (
unsigned int f = 1; f < dim; ++f)
5080 tmp[d][e] += inv_t_jac[f][d] * grad_in_scaled[e][f];
5083 for (
unsigned int d = 0;
d < dim; ++
d)
5084 for (
unsigned int e = 0;
e < dim; ++
e)
5086 VectorizedArrayType res = t_jac[
d][0] * tmp[
e][0];
5087 for (
unsigned int f = 1; f < dim; ++f)
5088 res += t_jac[d][f] * tmp[e][f];
5095 VectorizedArrayType
value[dim];
5096 for (
unsigned int d = 0;
d < dim; ++
d)
5098 value[
d] = tmp[
d][0] * jac_grad[
d][0];
5099 for (
unsigned int e = 1;
e < dim; ++
e)
5100 value[d] += tmp[d][e] * jac_grad[d][e];
5102 for (
unsigned int e = 0, k = dim;
e < dim; ++
e)
5103 for (
unsigned int f = e + 1; f < dim; ++k, ++f)
5104 for (
unsigned int d = 0;
d < dim; ++
d)
5106 value[
e] += tmp[f][
d] * jac_grad[k][
d];
5107 value[f] += tmp[
e][
d] * jac_grad[k][
d];
5112 for (
unsigned int d = 0;
d < dim; ++
d)
5114 VectorizedArrayType tmp2 = grad_in_scaled[
d][0] * tmp4[0];
5115 for (
unsigned int e = 1;
e < dim; ++
e)
5116 tmp2 += grad_in_scaled[d][e] * tmp4[e];
5117 for (
unsigned int e = 0;
e < dim; ++
e)
5118 value[e] -= t_jac[e][d] * tmp2;
5121 for (
unsigned int d = 0;
d < dim; ++
d)
5122 values[d * nqp] = value[d];
5128 const std::size_t nqp_d = this->n_quadrature_points * dim;
5129 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
5133 const VectorizedArrayType JxW =
5134 this->J_value[0] * this->quadrature_weights[q_point];
5140 std::array<VectorizedArrayType, dim> jac;
5141 for (
unsigned int d = 0;
d < dim; ++
d)
5142 jac[d] = this->jacobian[0][d][d];
5144 for (
unsigned int d = 0;
d < dim; ++
d)
5146 const VectorizedArrayType factor = this->jacobian[0][
d][
d] * JxW;
5147 if constexpr (n_components == 1)
5148 gradients[d] = grad_in[d] * factor;
5150 for (
unsigned int comp = 0; comp < n_components; ++comp)
5151 gradients[comp * nqp_d + d] = grad_in[comp][d] * factor;
5158 this->jacobian[q_point] :
5160 const VectorizedArrayType JxW =
5162 this->J_value[q_point] :
5163 this->J_value[0] * this->quadrature_weights[q_point];
5164 if constexpr (n_components == 1)
5165 for (
unsigned int d = 0;
d < dim; ++
d)
5167 VectorizedArrayType new_val = jac[0][
d] * grad_in[0];
5168 for (
unsigned int e = 1;
e < dim; ++
e)
5169 new_val += (jac[e][d] * grad_in[e]);
5173 for (
unsigned int comp = 0; comp < n_components; ++comp)
5174 for (
unsigned int d = 0;
d < dim; ++
d)
5176 VectorizedArrayType new_val = jac[0][
d] * grad_in[comp][0];
5177 for (
unsigned int e = 1;
e < dim; ++
e)
5178 new_val += (jac[e][d] * grad_in[comp][e]);
5190 typename VectorizedArrayType>
5191template <
int,
typename>
5195 const unsigned int q_point)
5197 static_assert(n_components == 1 && dim == 1,
5198 "Do not try to modify the default template parameters used for"
5199 " selectively enabling this function via std::enable_if!");
5200 submit_gradient(grad_in[0], q_point);
5209 typename VectorizedArrayType>
5215 Assert(this->normal_x_jacobian !=
nullptr,
5217 "update_gradients"));
5219 this->gradients_quad_submitted =
true;
5222 const std::size_t nqp_d = this->n_quadrature_points * dim;
5223 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
5227 const VectorizedArrayType JxW_jac = this->J_value[0] *
5228 this->quadrature_weights[q_point] *
5229 this->normal_x_jacobian[0][dim - 1];
5230 for (
unsigned int comp = 0; comp < n_components; ++comp)
5232 for (
unsigned int d = 0;
d < dim - 1; ++
d)
5233 gradients[comp * nqp_d + d] = VectorizedArrayType();
5234 if constexpr (n_components == 1)
5235 gradients[dim - 1] = grad_in * JxW_jac;
5237 gradients[comp * nqp_d + dim - 1] = grad_in[comp] * JxW_jac;
5242 const unsigned int index =
5245 this->normal_x_jacobian[
index];
5246 const VectorizedArrayType JxW =
5248 this->J_value[index] * this->quadrature_weights[q_point] :
5249 this->J_value[
index];
5250 for (
unsigned int comp = 0; comp < n_components; ++comp)
5251 for (
unsigned int d = 0;
d < dim; ++
d)
5252 if constexpr (n_components == 1)
5255 gradients[comp * nqp_d +
d] = (grad_in[comp] * JxW) * jac[d];
5265 typename VectorizedArrayType>
5268 submit_hessian(
const hessian_type hessian_in,
const unsigned int q_point)
5274 Assert(this->J_value !=
nullptr,
5276 "update_hessians"));
5277 Assert(this->jacobian !=
nullptr,
5279 "update_hessians"));
5281 this->hessians_quad_submitted =
true;
5285 const std::size_t nqp = this->n_quadrature_points;
5286 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
5289 const VectorizedArrayType JxW =
5290 this->J_value[0] * this->quadrature_weights[q_point];
5293 for (
unsigned int d = 0;
d < dim; ++
d)
5295 const auto jac_d = this->jacobian[0][
d][
d];
5296 const VectorizedArrayType factor = jac_d * jac_d * JxW;
5297 for (
unsigned int comp = 0; comp < n_components; ++comp)
5298 if constexpr (n_components == 1)
5299 this->hessians_quad[
d * nqp + q_point] =
5300 hessian_in[
d][
d] * factor;
5302 this->hessians_quad[(comp * hdim +
d) * nqp + q_point] =
5303 hessian_in[comp][d][d] * factor;
5307 for (
unsigned int d = 1, off_dia = dim;
d < dim; ++
d)
5308 for (
unsigned int e = 0;
e <
d; ++
e, ++off_dia)
5310 const auto jac_d = this->jacobian[0][
d][
d];
5311 const auto jac_e = this->jacobian[0][
e][
e];
5312 const VectorizedArrayType factor = jac_d * jac_e * JxW;
5313 for (
unsigned int comp = 0; comp < n_components; ++comp)
5314 if constexpr (n_components == 1)
5315 this->hessians_quad[off_dia * nqp + q_point] =
5316 (hessian_in[
d][
e] + hessian_in[
e][
d]) * factor;
5318 this->hessians_quad[(comp * hdim + off_dia) * nqp + q_point] =
5319 (hessian_in[comp][d][e] + hessian_in[comp][e][d]) * factor;
5326 const VectorizedArrayType JxW =
5327 this->J_value[0] * this->quadrature_weights[q_point];
5328 for (
unsigned int comp = 0; comp < n_components; ++comp)
5331 if constexpr (n_components == 1)
5332 hessian_c = hessian_in;
5334 hessian_c = hessian_in[comp];
5337 VectorizedArrayType tmp[dim][dim];
5338 for (
unsigned int i = 0; i < dim; ++i)
5339 for (
unsigned int j = 0; j < dim; ++j)
5341 tmp[i][j] = hessian_c[i][0] * jac[0][j];
5342 for (
unsigned int k = 1; k < dim; ++k)
5343 tmp[i][j] += hessian_c[i][k] * jac[k][j];
5347 VectorizedArrayType tmp2[dim][dim];
5348 for (
unsigned int i = 0; i < dim; ++i)
5349 for (
unsigned int j = 0; j < dim; ++j)
5351 tmp2[i][j] = jac[0][i] * tmp[0][j];
5352 for (
unsigned int k = 1; k < dim; ++k)
5353 tmp2[i][j] += jac[k][i] * tmp[k][j];
5357 for (
unsigned int d = 0;
d < dim; ++
d)
5358 this->hessians_quad[(comp * hdim + d) * nqp + q_point] =
5362 for (
unsigned int d = 0, off_diag = dim;
d < dim; ++
d)
5363 for (
unsigned int e = d + 1;
e < dim; ++
e, ++off_diag)
5364 this->hessians_quad[(comp * hdim + off_diag) * nqp + q_point] =
5365 (tmp2[
d][
e] + tmp2[
e][
d]) * JxW;
5371 const VectorizedArrayType JxW = this->J_value[q_point];
5372 const auto &jac_grad = this->jacobian_gradients[q_point];
5373 for (
unsigned int comp = 0; comp < n_components; ++comp)
5376 if constexpr (n_components == 1)
5377 hessian_c = hessian_in;
5379 hessian_c = hessian_in[comp];
5382 VectorizedArrayType tmp[dim][dim];
5383 for (
unsigned int i = 0; i < dim; ++i)
5384 for (
unsigned int j = 0; j < dim; ++j)
5386 tmp[i][j] = hessian_c[i][0] * jac[0][j];
5387 for (
unsigned int k = 1; k < dim; ++k)
5388 tmp[i][j] += hessian_c[i][k] * jac[k][j];
5392 VectorizedArrayType tmp2[dim][dim];
5393 for (
unsigned int i = 0; i < dim; ++i)
5394 for (
unsigned int j = 0; j < dim; ++j)
5396 tmp2[i][j] = jac[0][i] * tmp[0][j];
5397 for (
unsigned int k = 1; k < dim; ++k)
5398 tmp2[i][j] += jac[k][i] * tmp[k][j];
5402 for (
unsigned int d = 0;
d < dim; ++
d)
5403 this->hessians_quad[(comp * hdim + d) * nqp + q_point] =
5407 for (
unsigned int d = 0, off_diag = dim;
d < dim; ++
d)
5408 for (
unsigned int e = d + 1;
e < dim; ++
e, ++off_diag)
5409 this->hessians_quad[(comp * hdim + off_diag) * nqp + q_point] =
5410 (tmp2[
d][
e] + tmp2[
e][
d]) * JxW;
5413 for (
unsigned int d = 0;
d < dim; ++
d)
5415 VectorizedArrayType
sum = 0;
5416 for (
unsigned int e = 0;
e < dim; ++
e)
5417 sum += hessian_c[e][e] * jac_grad[e][d];
5418 for (
unsigned int e = 0, count = dim;
e < dim; ++
e)
5419 for (
unsigned int f = e + 1; f < dim; ++f, ++count)
5421 (hessian_c[e][f] + hessian_c[f][e]) * jac_grad[count][
d];
5422 this->gradients_from_hessians_quad[(comp * nqp + q_point) * dim +
5435 typename VectorizedArrayType>
5440 VectorizedArrayType>::value_type
5446 Assert(this->values_quad_submitted ==
true,
5451 const std::size_t nqp = this->n_quadrature_points;
5452 for (
unsigned int q = 0; q < nqp; ++q)
5453 for (
unsigned int comp = 0; comp < n_components; ++comp)
5454 return_value[comp] += this->values_quad[comp * nqp + q];
5455 if constexpr (n_components == 1)
5456 return return_value[0];
5458 return return_value;
5467 typename VectorizedArrayType>
5468template <
int,
typename>
5473 static_assert(n_components == dim,
5474 "Do not try to modify the default template parameters used for"
5475 " selectively enabling this function via std::enable_if!");
5478 Assert(this->gradients_quad_initialized ==
true,
5482 Assert(this->jacobian !=
nullptr,
5484 "update_gradients"));
5486 VectorizedArrayType divergence;
5487 const std::size_t nqp = this->n_quadrature_points;
5490 this->data->element_type ==
5493 VectorizedArrayType inv_det =
5496 this->jacobian[0][0][0] *
5497 ((dim == 2) ? this->jacobian[0][1][1] :
5498 this->jacobian[0][1][1] * this->jacobian[0][2][2]) :
5506 if (is_face && dim == 2 && this->get_face_no() < 2)
5510 divergence = this->gradients_quad[q_point * dim];
5511 for (
unsigned int d = 1;
d < dim; ++
d)
5512 divergence += this->gradients_quad[(d * nqp + q_point) * dim +
d];
5513 divergence *= inv_det;
5522 this->gradients_quad[q_point * dim] * this->jacobian[0][0][0];
5523 for (
unsigned int d = 1;
d < dim; ++
d)
5524 divergence += this->gradients_quad[(d * nqp + q_point) * dim +
d] *
5525 this->jacobian[0][
d][
d];
5532 this->jacobian[q_point] :
5534 divergence = jac[0][0] * this->gradients_quad[q_point * dim];
5535 for (
unsigned int e = 1;
e < dim; ++
e)
5536 divergence += jac[0][e] * this->gradients_quad[q_point * dim + e];
5537 for (
unsigned int d = 1;
d < dim; ++
d)
5538 for (
unsigned int e = 0;
e < dim; ++
e)
5540 jac[d][e] * this->gradients_quad[(d * nqp + q_point) * dim +
e];
5552 typename VectorizedArrayType>
5553template <
int,
typename>
5558 static_assert(n_components == dim,
5559 "Do not try to modify the default template parameters used for"
5560 " selectively enabling this function via std::enable_if!");
5563 const auto grad = get_gradient(q_point);
5564 VectorizedArrayType symmetrized[(dim * dim + dim) / 2];
5565 VectorizedArrayType half = Number(0.5);
5566 for (
unsigned int d = 0;
d < dim; ++
d)
5567 symmetrized[d] = grad[d][d];
5573 symmetrized[2] = grad[0][1] + grad[1][0];
5574 symmetrized[2] *= half;
5577 symmetrized[3] = grad[0][1] + grad[1][0];
5578 symmetrized[3] *= half;
5579 symmetrized[4] = grad[0][2] + grad[2][0];
5580 symmetrized[4] *= half;
5581 symmetrized[5] = grad[1][2] + grad[2][1];
5582 symmetrized[5] *= half;
5596 typename VectorizedArrayType>
5597template <
int,
typename>
5599 Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
5601 get_curl(const unsigned
int q_point) const
5603 static_assert(dim > 1 && n_components == dim,
5604 "Do not try to modify the default template parameters used for"
5605 " selectively enabling this function via std::enable_if!");
5609 Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType> curl;
5613 curl[0] = grad[1][0] - grad[0][1];
5616 curl[0] = grad[2][1] - grad[1][2];
5617 curl[1] = grad[0][2] - grad[2][0];
5618 curl[2] = grad[1][0] - grad[0][1];
5632 typename VectorizedArrayType>
5633template <
int,
typename>
5637 const unsigned int q_point)
5639 static_assert(n_components == dim,
5640 "Do not try to modify the default template parameters used for"
5641 " selectively enabling this function via std::enable_if!");
5647 Assert(this->J_value !=
nullptr,
5649 "update_gradients"));
5650 Assert(this->jacobian !=
nullptr,
5652 "update_gradients"));
5654 this->gradients_quad_submitted =
true;
5657 const std::size_t nqp_d = this->n_quadrature_points * dim;
5658 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
5660 if (this->data->element_type ==
5667 const VectorizedArrayType fac =
5669 this->quadrature_weights[q_point] * div_in :
5671 this->J_value[q_point] :
5672 this->J_value[0] * this->quadrature_weights[q_point]) *
5675 this->jacobian[this->cell_type >
5679 Number((dim == 2 && this->get_face_no() < 2) ? -1 : 1);
5681 for (
unsigned int d = 0;
d < dim; ++
d)
5683 for (
unsigned int e = 0;
e < dim; ++
e)
5684 gradients[d * nqp_d + e] = (d == e) ? fac : 0.;
5686 this->divergence_is_requested =
true;
5693 const VectorizedArrayType fac =
5694 this->J_value[0] * this->quadrature_weights[q_point] * div_in;
5695 for (
unsigned int d = 0;
d < dim; ++
d)
5697 const VectorizedArrayType jac_dd = this->jacobian[0][
d][
d];
5698 for (
unsigned int e = 0;
e < dim; ++
e)
5699 gradients[d * nqp_d + e] = (d == e) ? fac * jac_dd : 0.;
5706 this->jacobian[q_point] :
5708 const VectorizedArrayType fac =
5710 this->J_value[q_point] :
5711 this->J_value[0] * this->quadrature_weights[q_point]) *
5713 for (
unsigned int d = 0;
d < dim; ++
d)
5715 for (
unsigned int e = 0;
e < dim; ++
e)
5716 gradients[d * nqp_d + e] = jac[d][e] * fac;
5728 typename VectorizedArrayType>
5729template <
int,
typename>
5734 const unsigned int q_point)
5736 static_assert(n_components == dim,
5737 "Do not try to modify the default template parameters used for"
5738 " selectively enabling this function via std::enable_if!");
5741 this->data->element_type !=
5752 Assert(this->J_value !=
nullptr,
5754 "update_gradients"));
5755 Assert(this->jacobian !=
nullptr,
5757 "update_gradients"));
5759 this->gradients_quad_submitted =
true;
5762 const std::size_t nqp_d = this->n_quadrature_points * dim;
5763 VectorizedArrayType *
gradients = this->gradients_quad + dim * q_point;
5766 const VectorizedArrayType JxW =
5767 this->J_value[0] * this->quadrature_weights[q_point];
5769 for (
unsigned int d = 0;
d < dim; ++
d)
5770 gradients[d * nqp_d + d] =
5772 for (
unsigned int e = 0, counter = dim;
e < dim; ++
e)
5773 for (
unsigned int d = e + 1;
d < dim; ++
d, ++counter)
5775 const VectorizedArrayType
value =
5784 const VectorizedArrayType JxW =
5786 this->J_value[q_point] :
5787 this->J_value[0] * this->quadrature_weights[q_point];
5790 this->jacobian[q_point] :
5792 VectorizedArrayType weighted[dim][dim];
5793 for (
unsigned int i = 0; i < dim; ++i)
5795 for (
unsigned int i = 0, counter = dim; i < dim; ++i)
5796 for (
unsigned int j = i + 1; j < dim; ++j, ++counter)
5798 const VectorizedArrayType
value =
5800 weighted[i][j] =
value;
5801 weighted[j][i] =
value;
5803 for (
unsigned int comp = 0; comp < dim; ++comp)
5804 for (
unsigned int d = 0;
d < dim; ++
d)
5806 VectorizedArrayType new_val = jac[0][
d] * weighted[comp][0];
5807 for (
unsigned int e = 1;
e < dim; ++
e)
5808 new_val += jac[e][d] * weighted[comp][e];
5820 typename VectorizedArrayType>
5821template <
int,
typename>
5825 const unsigned int q_point)
5827 static_assert(n_components == dim,
5828 "Do not try to modify the default template parameters used for"
5829 " selectively enabling this function via std::enable_if!");
5835 grad[1][0] = curl[0];
5836 grad[0][1] = -curl[0];
5839 grad[2][1] = curl[0];
5840 grad[1][2] = -curl[0];
5841 grad[0][2] = curl[1];
5842 grad[2][0] = -curl[1];
5843 grad[1][0] = curl[2];
5844 grad[0][1] = -curl[2];
5849 submit_gradient(grad, q_point);
5862 typename VectorizedArrayType>
5868 VectorizedArrayType>::
5870 const unsigned int fe_no,
5871 const unsigned int quad_no,
5872 const unsigned int first_selected_component,
5873 const unsigned int active_fe_index,
5874 const unsigned int active_quad_index)
5875 : BaseClass(matrix_free,
5877 first_selected_component,
5884 numbers::invalid_unsigned_int )
5885 , dofs_per_component(this->data->dofs_per_component_on_cell)
5886 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
5887 , n_q_points(this->data->n_q_points)
5889 check_template_arguments(fe_no, 0);
5899 typename VectorizedArrayType>
5905 VectorizedArrayType>::
5907 const std::pair<unsigned int, unsigned int> &range,
5908 const unsigned int dof_no,
5909 const unsigned int quad_no,
5910 const unsigned int first_selected_component)
5914 first_selected_component,
5915 matrix_free.get_cell_active_fe_index(range))
5925 typename VectorizedArrayType>
5931 VectorizedArrayType>::
5936 const unsigned int first_selected_component)
5937 : BaseClass(mapping,
5941 first_selected_component,
5943 , dofs_per_component(this->data->dofs_per_component_on_cell)
5944 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
5945 , n_q_points(this->data->n_q_points)
5957 typename VectorizedArrayType>
5963 VectorizedArrayType>::
5967 const unsigned int first_selected_component)
5972 first_selected_component,
5974 , dofs_per_component(this->data->dofs_per_component_on_cell)
5975 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
5976 , n_q_points(this->data->n_q_points)
5988 typename VectorizedArrayType>
5994 VectorizedArrayType>::
5997 const unsigned int first_selected_component)
5998 : BaseClass(other.mapped_geometry->get_fe_values().get_mapping(),
6000 other.mapped_geometry->get_quadrature(),
6001 other.mapped_geometry->get_fe_values().get_update_flags(),
6002 first_selected_component,
6004 , dofs_per_component(this->data->dofs_per_component_on_cell)
6005 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6006 , n_q_points(this->data->n_q_points)
6018 typename VectorizedArrayType>
6027 , dofs_per_component(this->data->dofs_per_component_on_cell)
6028 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6029 , n_q_points(this->data->n_q_points)
6041 typename VectorizedArrayType>
6047 VectorizedArrayType> &
6053 VectorizedArrayType>::operator=(
const FEEvaluation &other)
6055 BaseClass::operator=(other);
6067 typename VectorizedArrayType>
6074 VectorizedArrayType>::
6075 check_template_arguments(
const unsigned int dof_no,
6076 const unsigned int first_selected_component)
6079 (void)first_selected_component;
6082 this->data->dofs_per_component_on_cell > 0,
6084 "There is nothing useful you can do with an FEEvaluation object with "
6085 "FE_Nothing, i.e., without DoFs! If you have passed to "
6086 "MatrixFree::reinit() a collection of finite elements also containing "
6087 "FE_Nothing, please check - before creating FEEvaluation - the category "
6088 "of the current range by calling either "
6089 "MatrixFree::get_cell_range_category(range) or "
6090 "MatrixFree::get_face_range_category(range). The returned category "
6091 "is the index of the active FE, which you can use to exclude "
6098 static_cast<unsigned int>(fe_degree) !=
6099 this->data->data.front().fe_degree) ||
6100 n_q_points != this->n_quadrature_points)
6102 std::string message =
6103 "-------------------------------------------------------\n";
6104 message +=
"Illegal arguments in constructor/wrong template arguments!\n";
6105 message +=
" Called --> FEEvaluation<dim,";
6109 message +=
",Number>(data";
6125 if (
static_cast<unsigned int>(fe_degree) ==
6126 this->data->data.front().fe_degree)
6128 proposed_dof_comp = dof_no;
6129 proposed_fe_comp = first_selected_component;
6132 for (
unsigned int no = 0; no < this->matrix_free->
n_components();
6134 for (
unsigned int nf = 0;
6137 if (this->matrix_free
6138 ->get_shape_info(no, 0, nf, this->active_fe_index, 0)
6140 .fe_degree ==
static_cast<unsigned int>(fe_degree))
6142 proposed_dof_comp = no;
6143 proposed_fe_comp = nf;
6147 this->mapping_data->descriptor[this->active_quad_index]
6149 proposed_quad_comp = this->quad_no;
6151 for (
unsigned int no = 0;
6156 .descriptor[this->active_quad_index]
6157 .n_q_points == n_q_points)
6159 proposed_quad_comp = no;
6166 if (proposed_dof_comp != first_selected_component)
6167 message +=
"Wrong vector component selection:\n";
6169 message +=
"Wrong quadrature formula selection:\n";
6170 message +=
" Did you mean FEEvaluation<dim,";
6174 message +=
",Number>(data";
6183 std::string correct_pos;
6184 if (proposed_dof_comp != dof_no)
6185 correct_pos =
" ^ ";
6188 if (proposed_quad_comp != this->quad_no)
6189 correct_pos +=
" ^ ";
6192 if (proposed_fe_comp != first_selected_component)
6193 correct_pos +=
" ^\n";
6195 correct_pos +=
" \n";
6201 const unsigned int proposed_n_q_points_1d =
static_cast<unsigned int>(
6202 std::pow(1.001 * this->n_quadrature_points, 1. / dim));
6203 message +=
"Wrong template arguments:\n";
6204 message +=
" Did you mean FEEvaluation<dim,";
6209 message +=
",Number>(data";
6217 std::string correct_pos;
6218 if (this->data->data.front().fe_degree !=
6219 static_cast<unsigned int>(fe_degree))
6223 if (proposed_n_q_points_1d != n_q_points_1d)
6224 correct_pos +=
" ^\n";
6226 correct_pos +=
" \n";
6227 message +=
" " + correct_pos;
6229 Assert(
static_cast<unsigned int>(fe_degree) ==
6230 this->data->data.front().fe_degree &&
6231 n_q_points == this->n_quadrature_points,
6237 this->mapping_data->descriptor[this->active_quad_index].n_q_points);
6248 typename VectorizedArrayType>
6257 Assert(this->matrix_free !=
nullptr,
6258 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
6259 " Integer indexing is not possible."));
6267 const unsigned int offsets =
6268 this->mapping_data->data_index_offsets[
cell_index];
6269 this->jacobian = &this->mapping_data->jacobians[0][offsets];
6270 this->J_value = &this->mapping_data->JxW_values[offsets];
6271 if (!this->mapping_data->jacobian_gradients[0].empty())
6273 this->jacobian_gradients =
6274 this->mapping_data->jacobian_gradients[0].data() + offsets;
6275 this->jacobian_gradients_non_inverse =
6276 this->mapping_data->jacobian_gradients_non_inverse[0].data() + offsets;
6282 for (
unsigned int i = 0; i < n_lanes; ++i)
6283 this->cell_ids[i] =
cell_index * n_lanes + i;
6290 this->cell_ids[i] =
cell_index * n_lanes + i;
6291 for (; i < n_lanes; ++i)
6295 if (this->mapping_data->quadrature_points.empty() ==
false)
6297 &this->mapping_data->quadrature_points
6298 [this->mapping_data->quadrature_point_offsets[this->cell]];
6301 this->is_reinitialized =
true;
6302 this->dof_values_initialized =
false;
6303 this->values_quad_initialized =
false;
6304 this->gradients_quad_initialized =
false;
6305 this->hessians_quad_initialized =
false;
6316 typename VectorizedArrayType>
6323 VectorizedArrayType>
::reinit(
const std::array<
unsigned int,
6330 this->cell_ids = cell_ids;
6335 for (
unsigned int v = 0; v < n_lanes; ++v)
6349 if (this->mapped_geometry ==
nullptr)
6350 this->mapped_geometry =
6351 std::make_shared<internal::MatrixFreeFunctions::
6352 MappingDataOnTheFly<dim, VectorizedArrayType>>();
6354 auto &mapping_storage = this->mapped_geometry->get_data_storage();
6356 auto &this_jacobian_data = mapping_storage.jacobians[0];
6357 auto &this_J_value_data = mapping_storage.JxW_values;
6358 auto &this_jacobian_gradients_data = mapping_storage.jacobian_gradients[0];
6359 auto &this_jacobian_gradients_non_inverse_data =
6360 mapping_storage.jacobian_gradients_non_inverse[0];
6361 auto &this_quadrature_points_data = mapping_storage.quadrature_points;
6365 if (this_jacobian_data.size() != 2)
6366 this_jacobian_data.resize_fast(2);
6368 if (this_J_value_data.size() != 1)
6369 this_J_value_data.resize_fast(1);
6371 const auto &update_flags_cells =
6375 this_jacobian_gradients_data.size() != 1)
6377 this_jacobian_gradients_data.resize_fast(1);
6378 this_jacobian_gradients_non_inverse_data.resize_fast(1);
6382 this_quadrature_points_data.size() != 1)
6383 this_quadrature_points_data.resize_fast(1);
6387 if (this_jacobian_data.size() != this->n_quadrature_points)
6388 this_jacobian_data.resize_fast(this->n_quadrature_points);
6390 if (this_J_value_data.size() != this->n_quadrature_points)
6391 this_J_value_data.resize_fast(this->n_quadrature_points);
6393 const auto &update_flags_cells =
6397 this_jacobian_gradients_data.size() != this->n_quadrature_points)
6399 this_jacobian_gradients_data.resize_fast(this->n_quadrature_points);
6400 this_jacobian_gradients_non_inverse_data.resize_fast(
6401 this->n_quadrature_points);
6405 this_quadrature_points_data.size() != this->n_quadrature_points)
6406 this_quadrature_points_data.resize_fast(this->n_quadrature_points);
6410 this->jacobian = this_jacobian_data.data();
6411 this->J_value = this_J_value_data.data();
6412 this->jacobian_gradients = this_jacobian_gradients_data.data();
6413 this->jacobian_gradients_non_inverse =
6414 this_jacobian_gradients_non_inverse_data.data();
6418 for (
unsigned int v = 0; v < n_lanes; ++v)
6425 const unsigned int cell_batch_index =
cell_index / n_lanes;
6426 const unsigned int offsets =
6427 this->mapping_data->data_index_offsets[cell_batch_index];
6428 const unsigned int lane =
cell_index % n_lanes;
6430 if (this->cell_type <=
6434 for (
unsigned int q = 0; q < 2; ++q)
6435 for (
unsigned int i = 0; i < dim; ++i)
6436 for (
unsigned int j = 0; j < dim; ++j)
6437 this_jacobian_data[q][i][j][v] =
6438 this->mapping_data->jacobians[0][offsets + q][i][j][lane];
6440 const unsigned int q = 0;
6442 this_J_value_data[q][v] =
6443 this->mapping_data->JxW_values[offsets + q][lane];
6445 const auto &update_flags_cells =
6450 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
6451 for (
unsigned int j = 0; j < dim; ++j)
6452 this_jacobian_gradients_data[q][i][j][v] =
6454 ->jacobian_gradients[0][offsets + q][i][j][lane];
6456 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
6457 for (
unsigned int j = 0; j < dim; ++j)
6458 this_jacobian_gradients_non_inverse_data[q][i][j][v] =
6460 ->jacobian_gradients_non_inverse[0][offsets + q][i][j]
6465 for (
unsigned int i = 0; i < dim; ++i)
6466 this_quadrature_points_data[q][i][v] =
6467 this->mapping_data->quadrature_points
6469 ->quadrature_point_offsets[cell_batch_index] +
6475 const auto cell_type =
6479 for (
unsigned int q = 0; q < this->n_quadrature_points; ++q)
6481 const unsigned int q_src =
6487 this_J_value_data[q][v] =
6488 this->mapping_data->JxW_values[offsets + q_src][lane];
6490 for (
unsigned int i = 0; i < dim; ++i)
6491 for (
unsigned int j = 0; j < dim; ++j)
6492 this_jacobian_data[q][i][j][v] =
6494 ->jacobians[0][offsets + q_src][i][j][lane];
6496 const auto &update_flags_cells =
6501 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
6502 for (
unsigned int j = 0; j < dim; ++j)
6503 this_jacobian_gradients_data[q][i][j][v] =
6505 ->jacobian_gradients[0][offsets + q_src][i][j][lane];
6507 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
6508 for (
unsigned int j = 0; j < dim; ++j)
6509 this_jacobian_gradients_non_inverse_data[q][i][j][v] =
6511 ->jacobian_gradients_non_inverse[0][offsets + q_src]
6524 this->mapping_data->quadrature_points
6526 ->quadrature_point_offsets[cell_batch_index] +
6530 this->mapping_data->jacobians[0][offsets + 1];
6532 for (
unsigned int d = 0;
d < dim; ++
d)
6535 static_cast<Number
>(
6536 this->descriptor->quadrature.point(q)[
d]);
6538 for (
unsigned int d = 0;
d < dim; ++
d)
6539 for (
unsigned int e = 0;
e < dim; ++
e)
6542 static_cast<Number
>(
6543 this->descriptor->quadrature.point(q)[
e]);
6545 for (
unsigned int i = 0; i < dim; ++i)
6546 this_quadrature_points_data[q][i][v] = point[i][lane];
6551 for (
unsigned int i = 0; i < dim; ++i)
6552 this_quadrature_points_data[q][i][v] =
6553 this->mapping_data->quadrature_points
6555 ->quadrature_point_offsets[cell_batch_index] +
6564 this->is_reinitialized =
true;
6565 this->dof_values_initialized =
false;
6566 this->values_quad_initialized =
false;
6567 this->gradients_quad_initialized =
false;
6568 this->hessians_quad_initialized =
false;
6579 typename VectorizedArrayType>
6580template <
bool level_dof_access>
6587 VectorizedArrayType>
::
6590 Assert(this->matrix_free ==
nullptr,
6591 ExcMessage(
"Cannot use initialization from cell iterator if "
6592 "initialized from MatrixFree object. Use variant for "
6593 "on the fly computation with arguments as for FEValues "
6596 this->mapped_geometry->reinit(
6598 this->local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
6599 if (level_dof_access)
6600 cell->get_mg_dof_indices(this->local_dof_indices);
6602 cell->get_dof_indices(this->local_dof_indices);
6605 this->is_reinitialized =
true;
6616 typename VectorizedArrayType>
6623 VectorizedArrayType>
::
6626 Assert(this->matrix_free == 0,
6627 ExcMessage(
"Cannot use initialization from cell iterator if "
6628 "initialized from MatrixFree object. Use variant for "
6629 "on the fly computation with arguments as for FEValues "
6632 this->mapped_geometry->reinit(cell);
6635 this->is_reinitialized =
true;
6646 typename VectorizedArrayType>
6653 VectorizedArrayType>::
6657 Assert(this->dof_values_initialized ==
true,
6660 evaluate(this->values_dofs, evaluation_flags);
6670 typename VectorizedArrayType>
6677 VectorizedArrayType>::
6678 evaluate(
const VectorizedArrayType *values_array,
6681 const bool hessians_on_general_cells =
6685 if (hessians_on_general_cells)
6688 if (this->data->element_type ==
6694 if constexpr (fe_degree > -1)
6697 template run<fe_degree, n_q_points_1d>(n_components,
6698 evaluation_flag_actual,
6706 evaluation_flag_actual,
6707 const_cast<VectorizedArrayType *
>(values_array),
6712 this->values_quad_initialized =
6714 this->gradients_quad_initialized =
6716 this->hessians_quad_initialized =
6727 template <
typename Number,
6728 typename VectorizedArrayType,
6729 typename VectorType,
6730 typename EvaluatorType,
6731 std::enable_if_t<internal::has_begin<VectorType> &&
6733 VectorType> * =
nullptr>
6734 VectorizedArrayType *
6735 check_vector_access_inplace(
const EvaluatorType &fe_eval, VectorType &vector)
6741 const unsigned int cell = fe_eval.get_cell_or_face_batch_id();
6742 const auto &dof_info = fe_eval.get_dof_info();
6749 if (std::is_same_v<typename VectorType::value_type, Number> &&
6753 interleaved_contiguous &&
6754 reinterpret_cast<
std::size_t>(
6756 dof_info.dof_indices_contiguous
6757 [
internal::MatrixFreeFunctions::DoFInfo::dof_access_cell]
6758 [cell * VectorizedArrayType::size()]) %
6759 sizeof(VectorizedArrayType) ==
6762 return reinterpret_cast<VectorizedArrayType *
>(
6766 [cell * VectorizedArrayType::size()] +
6768 [fe_eval.get_active_fe_index()]
6769 [fe_eval.get_first_selected_component()] *
6770 VectorizedArrayType::size());
6779 template <
typename Number,
6780 typename VectorizedArrayType,
6781 typename VectorType,
6782 typename EvaluatorType,
6783 std::enable_if_t<!internal::has_begin<VectorType> ||
6785 VectorType> * =
nullptr>
6786 VectorizedArrayType *
6787 check_vector_access_inplace(
const EvaluatorType &, VectorType &)
6800 typename VectorizedArrayType>
6801template <
typename VectorType>
6808 VectorizedArrayType>::
6809 gather_evaluate(
const VectorType &input_vector,
6812 const VectorizedArrayType *src_ptr =
6813 internal::check_vector_access_inplace<Number, const VectorizedArrayType>(
6814 *
this, input_vector);
6815 if (src_ptr !=
nullptr)
6816 evaluate(src_ptr, evaluation_flag);
6819 this->read_dof_values(input_vector);
6820 evaluate(this->begin_dof_values(), evaluation_flag);
6831 typename VectorizedArrayType>
6838 VectorizedArrayType>::
6841 integrate(integration_flag, this->values_dofs);
6844 this->dof_values_initialized =
true;
6855 typename VectorizedArrayType>
6862 VectorizedArrayType>::
6864 VectorizedArrayType *values_array,
6865 const bool sum_into_values_array)
6869 Assert(this->values_quad_submitted ==
true,
6872 Assert(this->gradients_quad_submitted ==
true,
6875 Assert(this->hessians_quad_submitted ==
true,
6878 Assert(this->matrix_free !=
nullptr ||
6879 this->mapped_geometry->is_initialized(),
6885 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, and "
6886 "EvaluationFlags::hessians are supported."));
6892 unsigned int size = n_components * dim * n_q_points;
6895 for (
unsigned int i = 0; i < size; ++i)
6896 this->gradients_quad[i] += this->gradients_from_hessians_quad[i];
6900 for (
unsigned int i = 0; i < size; ++i)
6901 this->gradients_quad[i] = this->gradients_from_hessians_quad[i];
6906 if (n_components == dim &&
6907 this->data->element_type ==
6911 this->divergence_is_requested ==
false)
6913 unsigned int size = n_components * n_q_points;
6916 for (
unsigned int i = 0; i < size; ++i)
6917 this->values_quad[i] += this->values_from_gradients_quad[i];
6921 for (
unsigned int i = 0; i < size; ++i)
6922 this->values_quad[i] = this->values_from_gradients_quad[i];
6927 if constexpr (fe_degree > -1)
6930 template run<fe_degree, n_q_points_1d>(n_components,
6931 integration_flag_actual,
6934 sum_into_values_array);
6940 integration_flag_actual,
6943 sum_into_values_array);
6947 this->dof_values_initialized =
true;
6958 typename VectorizedArrayType>
6959template <
typename VectorType>
6966 VectorizedArrayType>::
6968 VectorType &destination)
6970 VectorizedArrayType *dst_ptr =
6971 internal::check_vector_access_inplace<Number, VectorizedArrayType>(
6972 *
this, destination);
6973 if (dst_ptr !=
nullptr)
6974 integrate(integration_flag, dst_ptr,
true);
6977 integrate(integration_flag, this->begin_dof_values());
6978 this->distribute_local_to_global(destination);
6989 typename VectorizedArrayType>
6996 VectorizedArrayType>::dof_indices()
const
6998 return {0U, dofs_per_cell};
7012 typename VectorizedArrayType>
7018 VectorizedArrayType>::
7021 const bool is_interior_face,
7022 const unsigned int dof_no,
7023 const unsigned int quad_no,
7024 const unsigned int first_selected_component,
7025 const unsigned int active_fe_index,
7026 const unsigned int active_quad_index,
7027 const unsigned int face_type)
7028 : BaseClass(matrix_free,
7030 first_selected_component,
7038 , dofs_per_component(this->data->dofs_per_component_on_cell)
7039 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
7040 , n_q_points(this->n_quadrature_points)
7050 typename VectorizedArrayType>
7056 VectorizedArrayType>::
7059 const std::pair<unsigned int, unsigned int> &range,
7060 const bool is_interior_face,
7061 const unsigned int dof_no,
7062 const unsigned int quad_no,
7063 const unsigned int first_selected_component)
7068 first_selected_component,
7069 matrix_free.get_face_active_fe_index(range,
7071 numbers::invalid_unsigned_int,
7072 matrix_free.get_face_info(range.
first).face_type)
7082 typename VectorizedArrayType>
7089 VectorizedArrayType>
::reinit(
const unsigned int face_index)
7091 Assert(this->mapped_geometry ==
nullptr,
7092 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
7093 " Integer indexing is not possible"));
7094 if (this->mapped_geometry !=
nullptr)
7097 this->cell = face_index;
7098 this->dof_access_index =
7099 this->is_interior_face() ?
7107 this->matrix_free->get_task_info().boundary_partition_data.back())
7108 Assert(this->is_interior_face(),
7110 "Boundary faces do not have a neighbor. When looping over "
7111 "boundary faces use FEFaceEvaluation with the parameter "
7112 "is_interior_face set to true. "));
7114 this->reinit_face(this->matrix_free->
get_face_info(face_index));
7119 this->face_ids[i] = face_index * n_lanes + i;
7120 for (; i < n_lanes; ++i)
7123 this->cell_type = this->matrix_free->
get_mapping_info().face_type[face_index];
7124 const unsigned int offsets =
7125 this->mapping_data->data_index_offsets[face_index];
7126 this->J_value = &this->mapping_data->JxW_values[offsets];
7127 this->normal_vectors = &this->mapping_data->normal_vectors[offsets];
7129 &this->mapping_data->jacobians[!this->is_interior_face()][offsets];
7130 this->normal_x_jacobian =
7132 ->normals_times_jacobians[!this->is_interior_face()][offsets];
7133 this->jacobian_gradients =
7134 this->mapping_data->jacobian_gradients[!this->is_interior_face()].data() +
7136 this->jacobian_gradients_non_inverse =
7138 ->jacobian_gradients_non_inverse[!this->is_interior_face()]
7142 if (this->mapping_data->quadrature_point_offsets.empty() ==
false)
7145 this->mapping_data->quadrature_point_offsets.size());
7147 this->mapping_data->quadrature_points.data() +
7148 this->mapping_data->quadrature_point_offsets[this->cell];
7152 this->is_reinitialized =
true;
7153 this->dof_values_initialized =
false;
7154 this->values_quad_initialized =
false;
7155 this->gradients_quad_initialized =
false;
7156 this->hessians_quad_initialized =
false;
7167 typename VectorizedArrayType>
7175 const unsigned int face_number)
7181 "You must set MatrixFree::AdditionalData::mapping_update_flags_faces_by_cells to use the present reinit method."));
7185 Assert(this->mapped_geometry ==
nullptr,
7186 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
7187 " Integer indexing is not possible"));
7188 if (this->mapped_geometry !=
nullptr)
7193 .faces_by_cells_type[
cell_index][face_number];
7196 this->dof_access_index =
7199 if (this->is_interior_face() ==
false)
7204 for (
unsigned int i = 0; i < n_lanes; ++i)
7207 const unsigned int cell_this =
cell_index * n_lanes + i;
7209 unsigned int face_index =
7214 this->face_ids[i] = face_index;
7219 this->face_numbers[i] =
static_cast<std::uint8_t
>(-1);
7220 this->face_orientations[i] =
static_cast<std::uint8_t
>(-1);
7227 auto cell_m = faces.cells_interior[face_index % n_lanes];
7228 auto cell_p = faces.cells_exterior[face_index % n_lanes];
7230 const bool face_identifies_as_interior = cell_m != cell_this;
7232 Assert(cell_m == cell_this || cell_p == cell_this,
7236 if (face_identifies_as_interior)
7238 this->cell_ids[i] = cell_m;
7239 this->face_numbers[i] = faces.interior_face_no;
7243 this->cell_ids[i] = cell_p;
7244 this->face_numbers[i] = faces.exterior_face_no;
7247 const bool orientation_interior_face = faces.face_orientation >= 8;
7248 unsigned int face_orientation = faces.face_orientation % 8;
7249 if (face_identifies_as_interior != orientation_interior_face)
7251 constexpr std::array<std::uint8_t, 8> table{
7252 {0, 1, 2, 3, 6, 5, 4, 7}};
7253 face_orientation = table[face_orientation];
7255 this->face_orientations[i] = face_orientation;
7260 this->face_orientations[0] = 0;
7261 this->face_numbers[0] = face_number;
7266 for (
unsigned int i = 0; i < n_lanes; ++i)
7267 this->cell_ids[i] =
cell_index * n_lanes + i;
7275 this->cell_ids[i] =
cell_index * n_lanes + i;
7276 for (; i < n_lanes; ++i)
7279 for (
unsigned int i = 0; i < n_lanes; ++i)
7286 const unsigned int offsets =
7288 .face_data_by_cells[this->quad_no]
7293 .face_data_by_cells[this->quad_no]
7294 .JxW_values.size());
7296 .face_data_by_cells[this->quad_no]
7297 .JxW_values[offsets];
7299 .face_data_by_cells[this->quad_no]
7300 .normal_vectors[offsets];
7302 .face_data_by_cells[this->quad_no]
7303 .jacobians[!this->is_interior_face()][offsets];
7304 this->normal_x_jacobian =
7306 .face_data_by_cells[this->quad_no]
7307 .normals_times_jacobians[!this->is_interior_face()][offsets];
7308 this->jacobian_gradients =
7309 this->mapping_data->jacobian_gradients[!this->is_interior_face()].data() +
7311 this->jacobian_gradients_non_inverse =
7313 ->jacobian_gradients_non_inverse[!this->is_interior_face()]
7318 .face_data_by_cells[this->quad_no]
7319 .quadrature_point_offsets.empty() ==
false)
7321 const unsigned int index =
7325 .face_data_by_cells[this->quad_no]
7326 .quadrature_point_offsets.size());
7328 .face_data_by_cells[this->quad_no]
7329 .quadrature_points.data() +
7331 .face_data_by_cells[this->quad_no]
7332 .quadrature_point_offsets[
index];
7336 this->is_reinitialized =
true;
7337 this->dof_values_initialized =
false;
7338 this->values_quad_initialized =
false;
7339 this->gradients_quad_initialized =
false;
7340 this->hessians_quad_initialized =
false;
7351 typename VectorizedArrayType>
7358 VectorizedArrayType>::
7365 evaluate(this->values_dofs, evaluation_flag);
7375 typename VectorizedArrayType>
7382 VectorizedArrayType>::
7383 evaluate(
const VectorizedArrayType *values_array,
7386 Assert((evaluation_flag &
7389 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7390 "and EvaluationFlags::hessians are supported."));
7392 const bool hessians_on_general_cells =
7396 if (hessians_on_general_cells)
7399 if (this->data->element_type ==
7405 if constexpr (fe_degree > -1)
7407 template
run<fe_degree, n_q_points_1d>(n_components,
7408 evaluation_flag_actual,
7413 n_components, evaluation_flag_actual, values_array, *
this);
7416 this->values_quad_initialized =
7418 this->gradients_quad_initialized =
7420 this->hessians_quad_initialized =
7432 typename VectorizedArrayType>
7439 VectorizedArrayType>::
7446 project_to_face(this->values_dofs, evaluation_flag);
7456 typename VectorizedArrayType>
7463 VectorizedArrayType>::
7464 project_to_face(
const VectorizedArrayType *values_array,
7467 Assert((evaluation_flag &
7470 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7471 "and EvaluationFlags::hessians are supported."));
7473 const bool hessians_on_general_cells =
7477 if (hessians_on_general_cells)
7480 if (this->data->element_type ==
7486 if constexpr (fe_degree > -1)
7489 VectorizedArrayType>::template run<fe_degree>(n_components,
7490 evaluation_flag_actual,
7496 evaluation_flag_actual,
7510 typename VectorizedArrayType>
7517 VectorizedArrayType>::
7520 Assert((evaluation_flag &
7523 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7524 "and EvaluationFlags::hessians are supported."));
7526 const bool hessians_on_general_cells =
7530 if (hessians_on_general_cells)
7533 if (this->data->element_type ==
7539 if constexpr (fe_degree > -1)
7542 VectorizedArrayType>::template run<fe_degree>(n_components,
7543 evaluation_flag_actual,
7550 this->values_quad_initialized =
7552 this->gradients_quad_initialized =
7554 this->hessians_quad_initialized =
7566 typename VectorizedArrayType>
7573 VectorizedArrayType>::
7575 const bool sum_into_values)
7577 integrate(integration_flag, this->values_dofs, sum_into_values);
7580 this->dof_values_initialized =
true;
7591 typename VectorizedArrayType>
7598 VectorizedArrayType>::
7600 VectorizedArrayType *values_array,
7601 const bool sum_into_values)
7603 Assert((integration_flag &
7606 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7607 "and EvaluationFlags::hessians are supported."));
7613 unsigned int size = n_components * dim * n_q_points;
7616 for (
unsigned int i = 0; i < size; ++i)
7617 this->gradients_quad[i] += this->gradients_from_hessians_quad[i];
7621 for (
unsigned int i = 0; i < size; ++i)
7622 this->gradients_quad[i] = this->gradients_from_hessians_quad[i];
7627 if (this->data->element_type ==
7631 this->divergence_is_requested ==
false)
7633 unsigned int size = n_components * n_q_points;
7636 for (
unsigned int i = 0; i < size; ++i)
7637 this->values_quad[i] += this->values_from_gradients_quad[i];
7641 for (
unsigned int i = 0; i < size; ++i)
7642 this->values_quad[i] = this->values_from_gradients_quad[i];
7647 if constexpr (fe_degree > -1)
7649 template
run<fe_degree, n_q_points_1d>(n_components,
7650 integration_flag_actual,
7657 integration_flag_actual,
7670 typename VectorizedArrayType>
7677 VectorizedArrayType>::
7680 Assert((integration_flag &
7683 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7684 "and EvaluationFlags::hessians are supported."));
7690 unsigned int size = n_components * dim * n_q_points;
7693 for (
unsigned int i = 0; i < size; ++i)
7694 this->gradients_quad[i] += this->gradients_from_hessians_quad[i];
7698 for (
unsigned int i = 0; i < size; ++i)
7699 this->gradients_quad[i] = this->gradients_from_hessians_quad[i];
7704 if (this->data->element_type ==
7708 this->divergence_is_requested ==
false)
7710 unsigned int size = n_components * n_q_points;
7713 for (
unsigned int i = 0; i < size; ++i)
7714 this->values_quad[i] += this->values_from_gradients_quad[i];
7718 for (
unsigned int i = 0; i < size; ++i)
7719 this->values_quad[i] = this->values_from_gradients_quad[i];
7724 if constexpr (fe_degree > -1)
7727 VectorizedArrayType>::template run<fe_degree>(n_components,
7728 integration_flag_actual,
7744 typename VectorizedArrayType>
7751 VectorizedArrayType>::
7753 const bool sum_into_values)
7755 collect_from_face(integration_flag, this->values_dofs, sum_into_values);
7758 this->dof_values_initialized =
true;
7769 typename VectorizedArrayType>
7776 VectorizedArrayType>::
7778 VectorizedArrayType *values_array,
7779 const bool sum_into_values)
7781 Assert((integration_flag &
7784 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7785 "and EvaluationFlags::hessians are supported."));
7792 if (this->data->element_type ==
7796 this->divergence_is_requested ==
false)
7799 if constexpr (fe_degree > -1)
7802 VectorizedArrayType>::template run<fe_degree>(n_components,
7803 integration_flag_actual,
7810 integration_flag_actual,
7823 typename VectorizedArrayType>
7824template <
typename VectorType>
7831 VectorizedArrayType>::
7832 gather_evaluate(
const VectorType &input_vector,
7835 Assert((evaluation_flag &
7838 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7839 "and EvaluationFlags::hessians are supported."));
7841 const auto shared_vector_data = internal::get_shared_vector_data(
7843 this->dof_access_index ==
7845 this->active_fe_index,
7848 if (this->data->data.front().fe_degree > 0 &&
7849 fast_evaluation_supported(this->data->data.front().fe_degree,
7850 this->data->data.front().n_q_points_1d) &&
7853 typename VectorType::value_type,
7854 VectorizedArrayType>::
7855 supports(evaluation_flag,
7857 internal::get_beginning<typename VectorType::value_type>(
7859 this->dof_info->index_storage_variants[this->dof_access_index]
7862 if constexpr (fe_degree > -1)
7866 typename VectorType::value_type,
7867 VectorizedArrayType>::template
run<fe_degree,
7871 internal::get_beginning<typename VectorType::value_type>(
7880 typename VectorType::value_type,
7881 VectorizedArrayType>::evaluate(n_components,
7883 internal::get_beginning<
7884 typename VectorType::value_type>(
7892 this->read_dof_values(input_vector);
7893 this->evaluate(evaluation_flag);
7898 this->gradients_quad_initialized =
7911 typename VectorizedArrayType>
7912template <
typename VectorType>
7920 VectorizedArrayType>::integrate_scatter(
const bool integrate_values,
7921 const bool integrate_gradients,
7922 VectorType &destination)
7929 integrate_scatter(flag, destination);
7939 typename VectorizedArrayType>
7940template <
typename VectorType>
7947 VectorizedArrayType>::
7949 VectorType &destination)
7951 Assert((this->dof_access_index ==
7953 this->is_interior_face() ==
false) ==
false,
7956 const auto shared_vector_data = internal::get_shared_vector_data(
7958 this->dof_access_index ==
7960 this->active_fe_index,
7963 if (this->data->data.front().fe_degree > 0 &&
7964 fast_evaluation_supported(this->data->data.front().fe_degree,
7965 this->data->data.front().n_q_points_1d) &&
7968 typename VectorType::value_type,
7969 VectorizedArrayType>::
7970 supports(integration_flag,
7972 internal::get_beginning<typename VectorType::value_type>(
7974 this->dof_info->index_storage_variants[this->dof_access_index]
7977 if constexpr (fe_degree > -1)
7981 typename VectorType::value_type,
7982 VectorizedArrayType>::template
run<fe_degree,
7986 internal::get_beginning<typename VectorType::value_type>(
7995 typename VectorType::value_type,
7996 VectorizedArrayType>::integrate(n_components,
7998 internal::get_beginning<
7999 typename VectorType::value_type>(
8007 integrate(integration_flag);
8008 this->distribute_local_to_global(destination);
8019 typename VectorizedArrayType>
8026 VectorizedArrayType>::dof_indices()
const
8028 return {0U, dofs_per_cell};
8038 typename VectorizedArrayType>
8045 VectorizedArrayType>::
8046 fast_evaluation_supported(
const unsigned int given_degree,
8047 const unsigned int given_n_q_points_1d)
8049 return fe_degree == -1 ?
8062 typename VectorizedArrayType>
8069 VectorizedArrayType>::
8070 fast_evaluation_supported(
const unsigned int given_degree,
8071 const unsigned int given_n_q_points_1d)
8073 return fe_degree == -1 ?
8086 typename VectorizedArrayType>
8093 VectorizedArrayType>::at_boundary()
const
8095 Assert(this->dof_access_index !=
8099 if (this->is_interior_face() ==
false)
8104 this->matrix_free->n_boundary_face_batches()))
8117 typename VectorizedArrayType>
8124 VectorizedArrayType>::boundary_id()
const
8126 Assert(this->dof_access_index !=
8143 typename VectorizedArrayType>
8151 VectorizedArrayType>::get_dofs_per_component_projected_to_face()
8153 return this->data->dofs_per_component_on_face;
8163 typename VectorizedArrayType>
8170 VectorizedArrayType>::get_dofs_projected_to_face()
8172 return this->data->dofs_per_component_on_face * n_components_;
value_type get_dof_value(const unsigned int dof) const
void read_write_operation_global(const VectorOperation &operation, const std::array< VectorType *, n_components_ > &vectors) const
value_type get_laplacian(const unsigned int q_point) const
AlignedVector< VectorizedArrayType > * scratch_data_array
gradient_type get_gradient(const unsigned int q_point) const
void submit_gradient(const Tensor< 2, 1, VectorizedArrayType > val_in, const unsigned int q_point)
static constexpr unsigned int dimension
void read_write_operation(const VectorOperation &operation, const std::array< VectorType *, n_components_ > &vectors, const std::array< const std::vector< ArrayView< const typename VectorType::value_type > > *, n_components_ > &vectors_sm, const std::bitset< n_lanes > &mask, const bool apply_constraints=true) const
void submit_gradient(const gradient_type grad_in, const unsigned int q_point)
void submit_curl(const Tensor< 1, dim==2 ? 1 :dim, VectorizedArrayType > curl_in, const unsigned int q_point)
void submit_value(const value_type val_in, const unsigned int q_point)
void submit_divergence(const VectorizedArrayType div_in, const unsigned int q_point)
void submit_dof_value(const value_type val_in, const unsigned int dof)
std::vector< types::global_dof_index > local_dof_indices
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip()) const
void read_dof_values_plain(const VectorType &src, const unsigned int first_index=0, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
VectorizedArrayType get_divergence(const unsigned int q_point) const
hessian_type get_hessian(const unsigned int q_point) const
FEEvaluationBase(const Mapping< dim > &mapping, const FiniteElement< dim > &fe, const Quadrature< 1 > &quadrature, const UpdateFlags update_flags, const unsigned int first_selected_component, const FEEvaluationData< dim, VectorizedArrayType, is_face > *other)
FEEvaluationBase & operator=(const FEEvaluationBase &other)
Tensor< 1,(dim==2 ? 1 :dim), VectorizedArrayType > get_curl(const unsigned int q_point) const
SymmetricTensor< 2, dim, VectorizedArrayType > get_symmetric_gradient(const unsigned int q_point) const
static constexpr unsigned int n_components
void submit_symmetric_gradient(const SymmetricTensor< 2, dim, VectorizedArrayType > grad_in, const unsigned int q_point)
gradient_type get_hessian_diagonal(const unsigned int q_point) const
std::conditional_t< n_components_==1, Tensor< 1, dim, VectorizedArrayType >, std::conditional_t< n_components_==dim, Tensor< 2, dim, VectorizedArrayType >, Tensor< 1, n_components_, Tensor< 1, dim, VectorizedArrayType > > > > gradient_type
std::conditional_t< n_components_==1, VectorizedArrayType, Tensor< 1, n_components_, VectorizedArrayType > > value_type
void submit_value(const Tensor< 1, 1, VectorizedArrayType > val_in, const unsigned int q_point)
const MatrixFree< dim, Number, VectorizedArrayType > & get_matrix_free() const
void apply_hanging_node_constraints(const bool transpose) const
void set_dof_values_plain(VectorType &dst, const unsigned int first_index=0, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip()) const
FEEvaluationBase(const MatrixFree< dim, Number, VectorizedArrayType > &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, const unsigned int active_fe_index, const unsigned int active_quad_index, const unsigned int face_type)
void submit_normal_derivative(const value_type grad_in, const unsigned int q_point)
void read_write_operation_contiguous(const VectorOperation &operation, const std::array< VectorType *, n_components_ > &vectors, const std::array< const std::vector< ArrayView< const typename VectorType::value_type > > *, n_components_ > &vectors_sm, const std::bitset< n_lanes > &mask) const
value_type integrate_value() const
FEEvaluationBase(const FEEvaluationBase &other)
void submit_hessian(const hessian_type hessian_in, const unsigned int q_point)
std::conditional_t< n_components_==1, Tensor< 2, dim, VectorizedArrayType >, std::conditional_t< n_components_==dim, Tensor< 3, dim, VectorizedArrayType >, Tensor< 1, n_components_, Tensor< 2, dim, VectorizedArrayType > > > > hessian_type
void set_dof_values(VectorType &dst, const unsigned int first_index=0, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip()) const
static constexpr unsigned int n_lanes
const MatrixFree< dim, Number, VectorizedArrayType > * matrix_free
value_type get_normal_derivative(const unsigned int q_point) const
value_type get_value(const unsigned int q_point) const
void read_dof_values(const VectorType &src, const unsigned int first_index=0, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
const unsigned int quad_no
const MappingInfoStorageType::QuadratureDescriptor * descriptor
const MappingInfoStorageType * mapping_data
const ShapeInfoType * data
std::shared_ptr< internal::MatrixFreeFunctions::MappingDataOnTheFly< dim, Number > > mapped_geometry
const unsigned int active_fe_index
std::array< unsigned int, n_lanes > cell_ids
const unsigned int active_quad_index
bool is_interior_face() const
FEEvaluationData & operator=(const FEEvaluationData &other)
const unsigned int first_selected_component
FEEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const std::pair< unsigned int, unsigned int > &range, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
const unsigned int dofs_per_component
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
FEEvaluation(const Mapping< dim > &mapping, const FiniteElement< dim > &fe, const Quadrature< 1 > &quadrature, const UpdateFlags update_flags, const unsigned int first_selected_component=0)
const unsigned int n_q_points
FEEvaluation(const FiniteElement< dim > &fe, const Quadrature< 1 > &quadrature, const UpdateFlags update_flags, const unsigned int first_selected_component=0)
void reinit(const typename Triangulation< dim >::cell_iterator &cell)
static bool fast_evaluation_supported(const unsigned int given_degree, const unsigned int given_n_q_points_1d)
void integrate_scatter(const EvaluationFlags::EvaluationFlags integration_flag, VectorType &output_vector)
void reinit(const unsigned int cell_batch_index)
void reinit(const std::array< unsigned int, n_lanes > &cell_ids)
FEEvaluation(const FiniteElement< dim > &fe, const FEEvaluationData< dim, VectorizedArrayType, false > &other, const unsigned int first_selected_component=0)
void reinit(const TriaIterator< DoFCellAccessor< dim, dim, level_dof_access > > &cell)
void evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag)
static constexpr unsigned int tensor_dofs_per_cell
void evaluate(const VectorizedArrayType *values_array, const EvaluationFlags::EvaluationFlags evaluation_flag)
typename BaseClass::gradient_type gradient_type
void integrate(const EvaluationFlags::EvaluationFlags integration_flag, VectorizedArrayType *values_array, const bool sum_into_values=false)
static constexpr unsigned int dimension
void gather_evaluate(const VectorType &input_vector, const EvaluationFlags::EvaluationFlags evaluation_flag)
const unsigned int dofs_per_cell
static constexpr unsigned int static_dofs_per_cell
typename BaseClass::value_type value_type
FEEvaluation & operator=(const FEEvaluation &other)
void integrate(const EvaluationFlags::EvaluationFlags integration_flag)
static constexpr unsigned int n_components
FEEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0, const unsigned int active_fe_index=numbers::invalid_unsigned_int, const unsigned int active_quad_index=numbers::invalid_unsigned_int)
static constexpr unsigned int static_n_q_points
static constexpr unsigned int n_lanes
FEEvaluation(const FEEvaluation &other)
void check_template_arguments(const unsigned int fe_no, const unsigned int first_selected_component)
static constexpr unsigned int static_dofs_per_component
typename BaseClass::value_type value_type
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
void integrate(const EvaluationFlags::EvaluationFlags integration_flag, VectorizedArrayType *values_array, const bool sum_into_values=false)
void collect_from_face(const EvaluationFlags::EvaluationFlags integration_flag, VectorizedArrayType *values_array, const bool sum_into_values=false)
void integrate_scatter(const EvaluationFlags::EvaluationFlags integration_flag, VectorType &output_vector)
static constexpr unsigned int static_n_q_points_cell
void project_to_face(const EvaluationFlags::EvaluationFlags evaluation_flag)
static constexpr unsigned int tensor_dofs_per_cell
unsigned int get_dofs_per_component_projected_to_face()
void project_to_face(const VectorizedArrayType *values_array, const EvaluationFlags::EvaluationFlags evaluation_flag)
const unsigned int dofs_per_component
void reinit(const unsigned int face_batch_number)
const unsigned int n_q_points
void gather_evaluate(const VectorType &input_vector, const EvaluationFlags::EvaluationFlags evaluation_flag)
void reinit(const unsigned int cell_batch_number, const unsigned int face_number)
static bool fast_evaluation_supported(const unsigned int given_degree, const unsigned int given_n_q_points_1d)
void evaluate(const VectorizedArrayType *values_array, const EvaluationFlags::EvaluationFlags evaluation_flag)
const unsigned int dofs_per_cell
static constexpr unsigned int n_components
void evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag)
FEFaceEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const std::pair< unsigned int, unsigned int > &range, const bool is_interior_face=true, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
void collect_from_face(const EvaluationFlags::EvaluationFlags integration_flag, const bool sum_into_values=false)
static constexpr unsigned int static_dofs_per_component
static constexpr unsigned int n_lanes
static constexpr unsigned int static_n_q_points
unsigned int get_dofs_projected_to_face()
FEFaceEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &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, const unsigned int active_fe_index=numbers::invalid_unsigned_int, const unsigned int active_quad_index=numbers::invalid_unsigned_int, const unsigned int face_type=numbers::invalid_unsigned_int)
static constexpr unsigned int dimension
typename BaseClass::gradient_type gradient_type
types::boundary_id boundary_id() const
void integrate(const EvaluationFlags::EvaluationFlags integration_flag, const bool sum_into_values=false)
void evaluate_in_face(const EvaluationFlags::EvaluationFlags evaluation_flag)
void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector)
static constexpr unsigned int static_dofs_per_cell
void integrate_in_face(const EvaluationFlags::EvaluationFlags integration_flag)
std::pair< unsigned int, unsigned int > component_to_base_index(const unsigned int component) const
unsigned int element_multiplicity(const unsigned int index) const
Abstract base class for mapping classes.
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
types::boundary_id get_boundary_id(const unsigned int face_batch_index) const
const Table< 3, unsigned int > & get_cell_and_face_to_plain_faces() const
unsigned int n_inner_face_batches() const
unsigned int n_active_entries_per_cell_batch(const unsigned int cell_batch_index) const
const internal::MatrixFreeFunctions::FaceToCellTopology< VectorizedArrayType::size()> & get_face_info(const unsigned int face_batch_index) const
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info(const unsigned int dof_handler_index_component=0) const
AlignedVector< VectorizedArrayType > * acquire_scratch_data() const
const Number * constraint_pool_begin(const unsigned int pool_index) const
void release_scratch_data(const AlignedVector< VectorizedArrayType > *memory) const
const internal::MatrixFreeFunctions::MappingInfo< dim, Number, VectorizedArrayType > & get_mapping_info() const
bool indices_initialized() const
const Number * constraint_pool_end(const unsigned int pool_index) const
unsigned int n_components() const
unsigned int n_active_entries_per_face_batch(const unsigned int face_batch_index) const
const internal::MatrixFreeFunctions::ShapeInfo< Number > & get_shape_info(const unsigned int dof_handler_index_component=0, const unsigned int quad_index=0, const unsigned int fe_base_element=0, const unsigned int hp_active_fe_index=0, const unsigned int hp_active_quad_index=0) const
unsigned int n_base_elements(const unsigned int dof_handler_index) const
DEAL_II_HOST constexpr const Number & access_raw_entry(const unsigned int unrolled_index) const
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_OPENMP_SIMD_PRAGMA
#define DEAL_II_DEPRECATED
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcAccessToUninitializedField()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMatrixFreeAccessToUninitializedMappingField(std::string arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ update_jacobian_grads
Gradient of volume element.
@ update_quadrature_points
Transformed quadrature points.
#define DEAL_II_NOT_IMPLEMENTED()
The namespace for the EvaluationFlags enum.
EvaluationFlags
The EvaluationFlags enum.
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
void quadrature_points(const Triangulation< dim, spacedim > &triangulation, const Quadrature< dim > &quadrature, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bounding_boxes, ParticleHandler< dim, spacedim > &particle_handler, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()), const std::vector< std::vector< double > > &properties={})
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
VectorType::value_type * begin(VectorType &V)
T sum(const T &t, const MPI_Comm mpi_communicator)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
constexpr T pow(const T base, const int iexp)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
constexpr compressed_constraint_kind unconstrained_compressed_constraint_kind
void check_vector_compatibility(const VectorType &vec, const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const internal::MatrixFreeFunctions::DoFInfo &dof_info)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
const types::boundary_id internal_face_boundary_id
static const unsigned int invalid_unsigned_int
boost::integer_range< IncrementableType > iota_view
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
static bool fast_evaluation_supported(const unsigned int given_degree, const unsigned int n_q_points_1d)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval)
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, false > &fe_eval, const bool sum_into_values_array)
static void apply(const unsigned int n_components, const unsigned int fe_degree, const MatrixFreeFunctions::ShapeInfo< Number > &shape_info, const bool transpose, const std::array< MatrixFreeFunctions::compressed_constraint_kind, VectorizedArrayType::size()> &c_mask, VectorizedArrayType *values)
static void integrate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, const bool sum_into_values)
static void evaluate(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval)
static bool fast_evaluation_supported(const unsigned int given_degree, const unsigned int n_q_points_1d)
static void evaluate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, FEEvaluationData< dim, Number, true > &fe_eval)
static void integrate_in_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, FEEvaluationData< dim, Number, true > &fe_eval)
static void collect_from_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags integration_flag, Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval, const bool sum_into_values)
static void project_to_face(const unsigned int n_components, const EvaluationFlags::EvaluationFlags evaluation_flag, const Number *values_dofs, FEEvaluationData< dim, Number, true > &fe_eval)
static constexpr unsigned int value
@ dof_access_face_exterior
@ dof_access_face_interior
std::vector< std::pair< unsigned short, unsigned short > > constraint_indicator
std::vector< std::pair< unsigned int, unsigned int > > row_starts
std::vector< std::vector< unsigned int > > component_dof_indices_offset
std::vector< std::vector< bool > > hanging_node_constraint_masks_comp
unsigned int fe_index_from_degree(const unsigned int first_selected_component, const unsigned int fe_degree) const
std::vector< unsigned int > dof_indices
std::vector< compressed_constraint_kind > hanging_node_constraint_masks
std::array< std::vector< unsigned int >, 3 > dof_indices_interleave_strides
std::array< std::vector< std::pair< unsigned int, unsigned int > >, 3 > dof_indices_contiguous_sm
std::vector< unsigned int > row_starts_plain_indices
std::vector< unsigned int > component_to_base_index
std::array< std::vector< unsigned int >, 3 > dof_indices_contiguous
std::vector< unsigned int > plain_dof_indices
std::array< std::vector< unsigned char >, 3 > n_vectorization_lanes_filled
std::vector< unsigned int > dof_indices_interleaved
std::array< std::vector< IndexStorageVariants >, 3 > index_storage_variants
std::vector< unsigned int > face_partition_data
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)