14#ifndef dealii_matrix_free_fe_evaluation_h
15#define dealii_matrix_free_fe_evaluation_h
92 typename VectorizedArrayType>
99 std::conditional_t<n_components_ == 1,
106 n_components_ == dim,
114 n_components_ == dim,
119 static constexpr unsigned int n_lanes = VectorizedArrayType::size();
158 template <
typename VectorType>
161 const VectorType &src,
162 const unsigned int first_index = 0,
163 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip());
196 template <
typename VectorType>
199 const VectorType &src,
200 const unsigned int first_index = 0,
201 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip());
234 template <
typename VectorType>
238 const unsigned int first_index = 0,
239 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip())
const;
279 template <
typename VectorType>
283 const unsigned int first_index = 0,
284 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip())
const;
289 template <
typename VectorType>
293 const unsigned int first_index = 0,
294 const std::bitset<n_lanes> &mask = std::bitset<n_lanes>().flip())
const;
370 typename = std::enable_if_t<n_components == n_components_local>>
373 const unsigned int q_point);
424 template <
int dim_ = dim,
425 typename = std::enable_if_t<dim_ == 1 && n_components == dim_>>
428 const unsigned int q_point);
447 const unsigned int q_point);
523 const unsigned int q_point);
532 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
551 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
554 const unsigned int q_point);
564 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
583 template <
int dim_ = dim,
typename = std::enable_if_t<n_components_ == dim_>>
587 const unsigned int q_point);
597 template <
int dim_ = dim,
598 typename = std::enable_if_t<n_components_ == dim_ && dim_ != 1>>
615 template <
int dim_ = dim,
616 typename = std::enable_if_t<n_components_ == dim_ && dim != 1>>
658 const unsigned int dof_handler_index,
661 const unsigned int fe_degree,
666 const unsigned int face_type);
708 const UpdateFlags update_flags,
740 template <
typename VectorType,
typename VectorOperation>
744 const std::array<VectorType *, n_components_> &vectors,
747 n_components_> &vectors_sm,
748 const std::bitset<n_lanes> &mask,
749 const bool apply_constraints =
true)
const;
758 template <
typename VectorType,
typename VectorOperation>
762 const std::array<VectorType *, n_components_> &vectors,
765 n_components_> &vectors_sm,
766 const std::bitset<n_lanes> &mask)
const;
775 template <
typename VectorType,
typename VectorOperation>
779 const std::array<VectorType *, n_components_> &vectors)
const;
1374 typename VectorizedArrayType>
1379 VectorizedArrayType>
1382 std::is_same_v<Number, typename VectorizedArrayType::value_type>,
1383 "Type of Number and of VectorizedArrayType do not match.");
1425 static constexpr unsigned int n_lanes = VectorizedArrayType::size();
1510 const unsigned int dof_handler_index = 0,
1524 const std::pair<unsigned int, unsigned int> &range,
1525 const unsigned int dof_handler_index = 0,
1560 const UpdateFlags update_flags,
1570 const UpdateFlags update_flags,
1636 template <
bool level_dof_access>
1658 const unsigned int given_n_q_points_1d);
1701 template <
typename VectorType>
1731 VectorizedArrayType *values_array,
1732 const bool sum_into_values =
false);
1747 template <
typename VectorType>
1750 VectorType &output_vector);
1757 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
1834 int n_q_points_1d = fe_degree + 1,
1835 int n_components_ = 1,
1836 typename Number = double,
1842 VectorizedArrayType>
1845 std::is_same_v<Number, typename VectorizedArrayType::value_type>,
1846 "Type of Number and of VectorizedArrayType do not match.");
1888 static constexpr unsigned int n_lanes = VectorizedArrayType::size();
1990 const unsigned int dof_handler_index = 0,
2006 const std::pair<unsigned int, unsigned int> &range,
2008 const unsigned int dof_handler_index = 0,
2023 reinit(
const unsigned int face_batch_number);
2033 reinit(
const unsigned int cell_batch_number,
const unsigned int face_number);
2040 const unsigned int given_n_q_points_1d);
2104 template <
typename VectorType>
2120 const bool sum_into_values =
false);
2133 VectorizedArrayType *values_array,
2134 const bool sum_into_values =
false);
2151 const bool sum_into_values =
false);
2159 VectorizedArrayType *values_array,
2160 const bool sum_into_values =
false);
2173 template <
typename VectorType>
2176 VectorType &output_vector);
2181 template <
typename VectorType>
2184 const bool integrate_gradients,
2185 VectorType &output_vector);
2192 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
2261 namespace MatrixFreeFunctions
2265 template <
int dim,
int degree>
2274 template <
int degree>
2277 static constexpr unsigned int value = degree + 1;
2293 template <
bool is_face,
2296 typename VectorizedArrayType>
2299 extract_initialization_data(
2301 const unsigned int dof_handler_index,
2302 const unsigned int first_selected_component,
2303 const unsigned int quadrature_index,
2304 const unsigned int fe_degree,
2306 const unsigned int active_fe_index_given,
2307 const unsigned int active_quad_index_given,
2308 const unsigned int face_type)
2311 InitializationData init_data;
2315 &internal::MatrixFreeFunctions::
2316 MappingInfoCellsOrFaces<dim, Number, is_face, VectorizedArrayType>::get(
2324 active_fe_index_given :
2330 active_quad_index_given :
2363 typename VectorizedArrayType>
2368 VectorizedArrayType>::
2371 const unsigned int dof_handler_index,
2372 const unsigned int first_selected_component,
2373 const unsigned int quadrature_index,
2374 const unsigned int fe_degree,
2376 const bool is_interior_face,
2377 const unsigned int active_fe_index,
2378 const unsigned int active_quad_index,
2379 const unsigned int face_type)
2381 internal::extract_initialization_data<is_face>(matrix_free,
2383 first_selected_component,
2392 first_selected_component)
2393 , scratch_data_array(matrix_free.acquire_scratch_data())
2394 , matrix_free(&matrix_free)
2396 this->set_data_pointers(scratch_data_array, n_components_);
2398 this->dof_info->start_components.back() == 1 ||
2399 static_cast<int>(n_components_) <=
2401 this->dof_info->start_components
2402 [this->dof_info->component_to_base_index[first_selected_component] +
2404 first_selected_component,
2406 "You tried to construct a vector-valued evaluator with " +
2407 std::to_string(n_components) +
2408 " components. However, "
2409 "the current base element has only " +
2411 this->dof_info->start_components
2412 [this->dof_info->component_to_base_index[first_selected_component] +
2414 first_selected_component) +
2415 " components left when starting from local element index " +
2417 first_selected_component -
2418 this->dof_info->start_components
2419 [this->dof_info->component_to_base_index[first_selected_component]]) +
2420 " (global index " + std::to_string(first_selected_component) +
")"));
2432 typename VectorizedArrayType>
2433inline FEEvaluationBase<dim,
2437 VectorizedArrayType>::
2440 const FiniteElement<dim> &fe,
2441 const Quadrature<1> &quadrature,
2443 const unsigned int first_selected_component,
2444 const FEEvaluationData<dim, VectorizedArrayType, is_face> *other)
2445 : FEEvaluationData<dim, VectorizedArrayType, is_face>(
2447 other->mapped_geometry->get_quadrature() == quadrature ?
2448 other->mapped_geometry :
2449 std::make_shared<
internal::MatrixFreeFunctions::
2455 first_selected_component)
2456 , scratch_data_array(new AlignedVector<VectorizedArrayType>())
2457 , matrix_free(nullptr)
2459 const unsigned int base_element_number =
2463 first_selected_component >=
2465 ExcMessage(
"The underlying element must at least contain as many "
2466 "components as requested by this class"));
2467 (void)base_element_number;
2470 this->data =
new internal::MatrixFreeFunctions::ShapeInfo<Number>(
2471 Quadrature<(is_face ? dim - 1 : dim)>(quadrature),
2475 this->set_data_pointers(scratch_data_array, n_components_);
2484 typename VectorizedArrayType>
2485inline FEEvaluationBase<dim,
2489 VectorizedArrayType>::
2490 FEEvaluationBase(
const FEEvaluationBase<dim,
2494 VectorizedArrayType> &other)
2495 : FEEvaluationData<dim, VectorizedArrayType, is_face>(other)
2496 , scratch_data_array(other.matrix_free == nullptr ?
2497 new AlignedVector<VectorizedArrayType>() :
2498 other.matrix_free->acquire_scratch_data())
2499 , matrix_free(other.matrix_free)
2501 if (other.matrix_free ==
nullptr)
2503 Assert(other.mapped_geometry.get() != nullptr, ExcInternalError());
2505 new internal::MatrixFreeFunctions::ShapeInfo<Number>(*other.data);
2508 this->mapped_geometry =
2509 std::make_shared<internal::MatrixFreeFunctions::
2510 MappingDataOnTheFly<dim, VectorizedArrayType>>(
2511 other.mapped_geometry->get_fe_values().get_mapping(),
2512 other.mapped_geometry->get_quadrature(),
2513 other.mapped_geometry->get_fe_values().get_update_flags());
2515 if constexpr (is_face == false)
2516 this->mapping_data = &this->mapped_geometry->get_data_storage();
2519 ExcNotImplemented(
"On-the-fly geometry evaluation with "
2520 "face evaluators is not currently "
2526 this->mapped_geometry->get_data_storage().jacobians[0].begin();
2528 this->mapped_geometry->get_data_storage().JxW_values.begin();
2529 this->jacobian_gradients =
2530 this->mapped_geometry->get_data_storage().jacobian_gradients[0].begin();
2531 this->jacobian_gradients_non_inverse =
2532 this->mapped_geometry->get_data_storage()
2533 .jacobian_gradients_non_inverse[0]
2535 this->quadrature_points =
2536 this->mapped_geometry->get_data_storage().quadrature_points.begin();
2539 this->set_data_pointers(scratch_data_array, n_components_);
2548 typename VectorizedArrayType>
2549inline FEEvaluationBase<dim,
2553 VectorizedArrayType> &
2559 VectorizedArrayType> &other)
2562 if (matrix_free ==
nullptr)
2565 delete scratch_data_array;
2574 matrix_free = other.matrix_free;
2576 if (other.matrix_free ==
nullptr)
2580 new internal::MatrixFreeFunctions::ShapeInfo<Number>(*other.
data);
2581 scratch_data_array =
new AlignedVector<VectorizedArrayType>();
2584 this->mapped_geometry =
2585 std::make_shared<internal::MatrixFreeFunctions::
2586 MappingDataOnTheFly<dim, VectorizedArrayType>>(
2591 if constexpr (is_face ==
false)
2592 this->mapping_data = &this->mapped_geometry->get_data_storage();
2596 "face evaluators is not currently "
2601 this->mapped_geometry->get_data_storage().jacobians[0].begin();
2603 this->mapped_geometry->get_data_storage().JxW_values.begin();
2604 this->jacobian_gradients =
2605 this->mapped_geometry->get_data_storage().jacobian_gradients[0].begin();
2606 this->jacobian_gradients_non_inverse =
2607 this->mapped_geometry->get_data_storage()
2608 .jacobian_gradients_non_inverse[0]
2611 this->mapped_geometry->get_data_storage().quadrature_points.begin();
2618 this->set_data_pointers(scratch_data_array, n_components_);
2629 typename VectorizedArrayType>
2630inline FEEvaluationBase<dim,
2634 VectorizedArrayType>::~FEEvaluationBase()
2636 if (matrix_free !=
nullptr)
2647 delete scratch_data_array;
2658 typename VectorizedArrayType>
2659inline const MatrixFree<dim, Number, VectorizedArrayType> &
2663 Assert(matrix_free !=
nullptr,
2665 "FEEvaluation was not initialized with a MatrixFree object!"));
2666 return *matrix_free;
2675 template <
typename VectorType,
bool>
2676 struct ConstBlockVectorSelector;
2678 template <
typename VectorType>
2679 struct ConstBlockVectorSelector<
VectorType, true>
2681 using BaseVectorType =
const typename VectorType::BlockType;
2684 template <
typename VectorType>
2685 struct ConstBlockVectorSelector<
VectorType, false>
2687 using BaseVectorType =
typename VectorType::BlockType;
2693 template <
typename VectorType,
bool>
2694 struct BlockVectorSelector;
2696 template <
typename VectorType>
2699 using BaseVectorType =
typename ConstBlockVectorSelector<
2701 std::is_const_v<VectorType>>::BaseVectorType;
2703 static BaseVectorType *
2704 get_vector_component(VectorType &vec,
const unsigned int component)
2707 return &vec.block(component);
2711 template <
typename VectorType>
2712 struct BlockVectorSelector<
VectorType, false>
2716 static BaseVectorType *
2717 get_vector_component(VectorType &vec,
const unsigned int component)
2736 template <
typename VectorType>
2737 struct BlockVectorSelector<std::vector<VectorType>, false>
2741 static BaseVectorType *
2742 get_vector_component(std::vector<VectorType> &vec,
2743 const unsigned int component)
2750 template <
typename VectorType>
2751 struct BlockVectorSelector<
const std::vector<VectorType>, false>
2755 static const BaseVectorType *
2756 get_vector_component(
const std::vector<VectorType> &vec,
2757 const unsigned int component)
2764 template <
typename VectorType>
2765 struct BlockVectorSelector<std::vector<VectorType *>, false>
2769 static BaseVectorType *
2770 get_vector_component(std::vector<VectorType *> &vec,
2771 const unsigned int component)
2778 template <
typename VectorType>
2779 struct BlockVectorSelector<
const std::vector<VectorType *>, false>
2783 static const BaseVectorType *
2784 get_vector_component(
const std::vector<VectorType *> &vec,
2785 const unsigned int component)
2792 template <
typename VectorType, std::
size_t N>
2793 struct BlockVectorSelector<std::array<VectorType *, N>, false>
2797 static BaseVectorType *
2798 get_vector_component(std::array<VectorType *, N> &vec,
2799 const unsigned int component)
2813 typename VectorizedArrayType>
2814template <
typename VectorType,
typename VectorOperation>
2818 const VectorOperation &operation,
2819 const std::array<VectorType *, n_components_> &src,
2821 const std::vector<ArrayView<const typename VectorType::value_type>> *,
2822 n_components_> &src_sm,
2823 const std::bitset<n_lanes> &mask,
2824 const bool apply_constraints)
const
2829 if (this->matrix_free ==
nullptr)
2831 read_write_operation_global(operation, src);
2836 const internal::MatrixFreeFunctions::DoFInfo &dof_info = *this->dof_info;
2838 if (this->n_fe_components == 1)
2839 for (
unsigned int comp = 0; comp < n_components; ++comp)
2841 Assert(src[comp] !=
nullptr,
2842 ExcMessage(
"The finite element underlying this FEEvaluation "
2843 "object is scalar, but you requested " +
2844 std::to_string(n_components) +
2845 " components via the template argument in "
2846 "FEEvaluation. In that case, you must pass an "
2847 "std::vector<VectorType> or a BlockVector to " +
2848 "read_dof_values and distribute_local_to_global."));
2860 const bool accesses_exterior_dofs =
2861 this->dof_access_index ==
2863 this->is_interior_face() ==
false;
2873 bool is_contiguous =
true;
2875 if (accesses_exterior_dofs)
2877 const std::array<unsigned int, n_lanes> &cells = this->get_cell_ids();
2878 const unsigned int n_filled_lanes =
2883 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
2884 if (mask[v] ==
true &&
2887 [cells[v] / n_lanes] <
2890 is_contiguous =
false;
2894 this->dof_access_index :
2896 [this->cell] < internal::MatrixFreeFunctions::DoFInfo::
2897 IndexStorageVariants::contiguous)
2899 is_contiguous =
false;
2904 read_write_operation_contiguous(operation, src, src_sm, mask);
2911 std::array<unsigned int, n_lanes> cells = this->get_cell_ids();
2913 const bool masking_is_active =
mask.count() < n_lanes;
2914 if (masking_is_active)
2915 for (
unsigned int v = 0; v < n_lanes; ++v)
2916 if (mask[v] ==
false)
2919 std::bool_constant<internal::is_vectorizable<VectorType, Number>::value>
2922 const bool use_vectorized_path =
2923 !(masking_is_active || accesses_exterior_dofs);
2925 const std::size_t dofs_per_component = this->data->dofs_per_component_on_cell;
2929 [is_face ? this->dof_access_index :
2931 [this->cell] == internal::MatrixFreeFunctions::DoFInfo::
2932 IndexStorageVariants::interleaved &&
2933 use_vectorized_path)
2935 const unsigned int *dof_indices =
2937 dof_info.
row_starts[this->cell * this->n_fe_components * n_lanes]
2941 [this->first_selected_component] *
2944 std::array<typename VectorType::value_type *, n_components> src_ptrs;
2945 if (n_components == 1 || this->n_fe_components == 1)
2946 for (
unsigned int comp = 0; comp < n_components; ++comp)
2948 const_cast<typename VectorType::value_type *
>(src[comp]->
begin());
2951 const_cast<typename VectorType::value_type *
>(src[0]->begin());
2953 if (n_components == 1 || this->n_fe_components == 1)
2954 for (
unsigned int i = 0; i < dofs_per_component;
2955 ++i, dof_indices += n_lanes)
2956 for (
unsigned int comp = 0; comp < n_components; ++comp)
2957 operation.process_dof_gather(
2962 this->values_dofs[comp * dofs_per_component + i],
2965 for (
unsigned int comp = 0; comp < n_components; ++comp)
2966 for (
unsigned int i = 0; i < dofs_per_component;
2967 ++i, dof_indices += n_lanes)
2968 operation.process_dof_gather(
2973 this->values_dofs[comp * dofs_per_component + i],
2978 std::array<VectorizedArrayType *, n_components> values_dofs;
2979 for (
unsigned int c = 0; c < n_components; ++c)
2980 values_dofs[c] =
const_cast<VectorizedArrayType *
>(this->values_dofs) +
2981 c * dofs_per_component;
2985 std::array<const unsigned int *, n_lanes> dof_indices;
2986 dof_indices.fill(
nullptr);
2991 bool has_constraints =
false;
2992 const unsigned int n_components_read =
2993 this->n_fe_components > 1 ? n_components : 1;
2997 for (
unsigned int v = 0; v < n_lanes; ++v)
3003 const std::pair<unsigned int, unsigned int> *my_index_start =
3004 &dof_info.
row_starts[cells[v] * this->n_fe_components +
3005 this->first_selected_component];
3010 if (my_index_start[n_components_read].second !=
3011 my_index_start[0].second)
3012 has_constraints =
true;
3015 dof_info.
dof_indices.data() + my_index_start[0].first;
3020 for (
unsigned int v = 0; v < n_lanes; ++v)
3025 const std::pair<unsigned int, unsigned int> *my_index_start =
3026 &dof_info.
row_starts[cells[v] * this->n_fe_components +
3027 this->first_selected_component];
3028 if (my_index_start[n_components_read].second !=
3029 my_index_start[0].second)
3030 has_constraints =
true;
3032 Assert(my_index_start[n_components_read].first ==
3033 my_index_start[0].first ||
3034 my_index_start[0].first < dof_info.
dof_indices.size(),
3036 my_index_start[0].first,
3039 dof_info.
dof_indices.data() + my_index_start[0].first;
3043 for (
unsigned int comp = 0; comp < n_components; ++comp)
3044 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3045 operation.process_empty(values_dofs[comp][i]);
3049 if (!has_constraints && apply_constraints)
3051 if (n_components == 1 || this->n_fe_components == 1)
3053 for (
unsigned int v = 0; v < n_lanes; ++v)
3058 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3060 for (
unsigned int comp = 0; comp < n_components; ++comp)
3061 operation.process_dof(dof_indices[v][i],
3063 values_dofs[comp][i][v]);
3068 for (
unsigned int comp = 0; comp < n_components; ++comp)
3069 for (
unsigned int v = 0; v < n_lanes; ++v)
3074 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3075 if (dof_indices[v][comp * dofs_per_component + i] !=
3077 operation.process_dof(
3078 dof_indices[v][comp * dofs_per_component + i],
3080 values_dofs[comp][i][v]);
3092 for (
unsigned int v = 0; v < n_lanes; ++v)
3097 const unsigned int cell_index = cells[v];
3098 const unsigned int cell_dof_index =
3099 cell_index * this->n_fe_components + this->first_selected_component;
3100 unsigned int index_indicators =
3102 unsigned int next_index_indicators =
3103 dof_info.
row_starts[cell_dof_index + 1].second;
3107 if (apply_constraints ==
false &&
3115 [this->first_selected_component] +
3117 next_index_indicators = index_indicators;
3120 if (n_components == 1 || this->n_fe_components == 1)
3122 unsigned int ind_local = 0;
3123 for (; index_indicators != next_index_indicators; ++index_indicators)
3125 const std::pair<unsigned short, unsigned short> indicator =
3128 for (
unsigned int j = 0; j < indicator.first; ++j)
3130 for (
unsigned int comp = 0; comp < n_components; ++comp)
3131 operation.process_dof(dof_indices[v][j],
3133 values_dofs[comp][ind_local + j][v]);
3135 ind_local += indicator.first;
3136 dof_indices[v] += indicator.first;
3141 for (
unsigned int comp = 0; comp < n_components; ++comp)
3142 operation.pre_constraints(values_dofs[comp][ind_local][v],
3149 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
3151 for (
unsigned int comp = 0; comp < n_components; ++comp)
3152 operation.process_constraint(*dof_indices[v],
3157 for (
unsigned int comp = 0; comp < n_components; ++comp)
3158 operation.post_constraints(
value[comp],
3159 values_dofs[comp][ind_local][v]);
3165 for (; ind_local < dofs_per_component; ++dof_indices[v], ++ind_local)
3167 for (
unsigned int comp = 0; comp < n_components; ++comp)
3168 operation.process_dof(*dof_indices[v],
3170 values_dofs[comp][ind_local][v]);
3179 for (
unsigned int comp = 0; comp < n_components; ++comp)
3181 unsigned int ind_local = 0;
3184 for (; index_indicators != next_index_indicators;
3187 const std::pair<unsigned short, unsigned short> indicator =
3191 for (
unsigned int j = 0; j < indicator.first; ++j)
3193 operation.process_dof(
3196 values_dofs[comp][ind_local + j][v]);
3197 ind_local += indicator.first;
3198 dof_indices[v] += indicator.first;
3203 operation.pre_constraints(values_dofs[comp][ind_local][v],
3211 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
3213 operation.process_constraint(*dof_indices[v],
3218 operation.post_constraints(
value,
3219 values_dofs[comp][ind_local][v]);
3226 for (; ind_local < dofs_per_component;
3227 ++dof_indices[v], ++ind_local)
3231 operation.process_dof(*dof_indices[v],
3233 values_dofs[comp][ind_local][v]);
3236 if (apply_constraints ==
true && comp + 1 < n_components)
3237 next_index_indicators =
3238 dof_info.
row_starts[cell_dof_index + comp + 2].second;
3250 typename VectorizedArrayType>
3251template <
typename VectorType,
typename VectorOperation>
3255 const VectorOperation &operation,
3256 const std::array<VectorType *, n_components_> &src)
const
3260 const std::size_t dofs_per_component = this->data->dofs_per_component_on_cell;
3261 unsigned int index = this->first_selected_component * dofs_per_component;
3262 for (
unsigned int comp = 0; comp < n_components; ++comp)
3264 for (
unsigned int i = 0; i < dofs_per_component; ++i, ++
index)
3266 operation.process_empty(
3267 this->values_dofs[comp * dofs_per_component + i]);
3268 operation.process_dof_global(
3269 local_dof_indices[this->data->lexicographic_numbering[index]],
3271 this->values_dofs[comp * dofs_per_component + i][0]);
3282 typename VectorizedArrayType>
3283template <
typename VectorType,
typename VectorOperation>
3287 const VectorOperation &operation,
3288 const std::array<VectorType *, n_components_> &src,
3290 const std::vector<ArrayView<const typename VectorType::value_type>> *,
3291 n_components_> &vectors_sm,
3292 const std::bitset<n_lanes> &mask)
const
3301 std::bool_constant<internal::is_vectorizable<VectorType, Number>::value>
3304 is_face ? this->dof_access_index :
3306 const unsigned int n_active_lanes =
mask.count();
3308 const internal::MatrixFreeFunctions::DoFInfo &dof_info = *this->dof_info;
3309 const std::vector<unsigned int> &dof_indices_cont =
3312 const std::size_t dofs_per_component = this->data->dofs_per_component_on_cell;
3313 std::array<VectorizedArrayType *, n_components> values_dofs{{
nullptr}};
3314 for (
unsigned int c = 0; c < n_components; ++c)
3315 values_dofs[c] =
const_cast<VectorizedArrayType *
>(this->values_dofs) +
3316 c * dofs_per_component;
3320 const bool accesses_exterior_dofs =
3321 this->dof_access_index ==
3323 this->is_interior_face() ==
false;
3329 interleaved_contiguous &&
3330 n_active_lanes == n_lanes && !accesses_exterior_dofs)
3332 const unsigned int dof_index =
3333 dof_indices_cont[this->cell * n_lanes] +
3336 [this->first_selected_component] *
3338 if (n_components == 1 || this->n_fe_components == 1)
3339 for (
unsigned int comp = 0; comp < n_components; ++comp)
3340 operation.process_dofs_vectorized(dofs_per_component,
3346 operation.process_dofs_vectorized(dofs_per_component * n_components,
3354 const std::array<unsigned int, n_lanes> &cells = this->get_cell_or_face_ids();
3358 const unsigned int n_filled_lanes =
3361 const bool use_vectorized_path = n_filled_lanes == n_lanes &&
3362 n_active_lanes == n_lanes &&
3363 !accesses_exterior_dofs;
3365 if (vectors_sm[0] !=
nullptr)
3367 const auto compute_vector_ptrs = [&](
const unsigned int comp) {
3368 std::array<typename VectorType::value_type *, n_lanes> vector_ptrs{
3371 const auto upper_bound =
3373 for (
unsigned int v = 0; v < upper_bound; ++v)
3375 if (mask[v] ==
false)
3377 vector_ptrs[v] =
nullptr;
3397 vector_ptrs[v] =
const_cast<typename VectorType::value_type *
>(
3398 vectors_sm[comp]->operator[](temp.first).data() + temp.second +
3400 [this->active_fe_index][this->first_selected_component]);
3402 vector_ptrs[v] =
nullptr;
3404 for (
unsigned int v = n_filled_lanes; v < n_lanes; ++v)
3405 vector_ptrs[v] =
nullptr;
3410 if (use_vectorized_path)
3412 if (n_components == 1 || this->n_fe_components == 1)
3414 for (
unsigned int comp = 0; comp < n_components; ++comp)
3416 auto vector_ptrs = compute_vector_ptrs(comp);
3417 operation.process_dofs_vectorized_transpose(
3426 auto vector_ptrs = compute_vector_ptrs(0);
3427 operation.process_dofs_vectorized_transpose(dofs_per_component *
3435 for (
unsigned int comp = 0; comp < n_components; ++comp)
3437 auto vector_ptrs = compute_vector_ptrs(
3438 (n_components == 1 || this->n_fe_components == 1) ? comp : 0);
3440 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3441 operation.process_empty(values_dofs[comp][i]);
3443 if (n_components == 1 || this->n_fe_components == 1)
3445 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3446 if (mask[v] ==
true)
3447 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3448 operation.process_dof(vector_ptrs[v][i],
3449 values_dofs[comp][i][v]);
3453 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3454 if (mask[v] ==
true)
3455 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3456 operation.process_dof(
3457 vector_ptrs[v][i + comp * dofs_per_component],
3458 values_dofs[comp][i][v]);
3464 std::array<unsigned int, n_lanes> dof_indices{
3467 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3471 if (mask[v] ==
true)
3473 dof_indices_cont[cells[v]] +
3476 [this->first_selected_component] *
3482 if (use_vectorized_path)
3488 if (n_components == 1 || this->n_fe_components == 1)
3489 for (
unsigned int comp = 0; comp < n_components; ++comp)
3490 operation.process_dofs_vectorized_transpose(dofs_per_component,
3496 operation.process_dofs_vectorized_transpose(dofs_per_component *
3505 interleaved_contiguous_strided)
3507 std::array<typename VectorType::value_type *, n_components> src_ptrs{
3509 if (n_components == 1 || this->n_fe_components == 1)
3510 for (
unsigned int comp = 0; comp < n_components; ++comp)
3511 src_ptrs[comp] =
const_cast<typename VectorType::value_type *
>(
3512 src[comp]->
begin());
3515 const_cast<typename VectorType::value_type *
>(src[0]->begin());
3517 if (n_components == 1 || this->n_fe_components == 1)
3518 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3520 for (
unsigned int comp = 0; comp < n_components; ++comp)
3521 operation.process_dof_gather(dof_indices.data(),
3524 src_ptrs[comp] + i * n_lanes,
3525 values_dofs[comp][i],
3529 for (
unsigned int comp = 0; comp < n_components; ++comp)
3530 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3532 operation.process_dof_gather(
3535 (comp * dofs_per_component + i) * n_lanes,
3536 src_ptrs[0] + (comp * dofs_per_component + i) * n_lanes,
3537 values_dofs[comp][i],
3544 internal::MatrixFreeFunctions::DoFInfo::
3545 IndexStorageVariants::interleaved_contiguous_mixed_strides,
3547 std::array<typename VectorType::value_type *, n_components> src_ptrs{
3549 if (n_components == 1 || this->n_fe_components == 1)
3550 for (
unsigned int comp = 0; comp < n_components; ++comp)
3551 src_ptrs[comp] =
const_cast<typename VectorType::value_type *
>(
3552 src[comp]->
begin());
3555 const_cast<typename VectorType::value_type *
>(src[0]->begin());
3557 const unsigned int *offsets =
3559 if (n_components == 1 || this->n_fe_components == 1)
3560 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3562 for (
unsigned int comp = 0; comp < n_components; ++comp)
3563 operation.process_dof_gather(dof_indices.data(),
3567 values_dofs[comp][i],
3570 for (
unsigned int v = 0; v < n_lanes; ++v)
3571 dof_indices[v] += offsets[v];
3574 for (
unsigned int comp = 0; comp < n_components; ++comp)
3575 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3577 operation.process_dof_gather(dof_indices.data(),
3581 values_dofs[comp][i],
3584 for (
unsigned int v = 0; v < n_lanes; ++v)
3585 dof_indices[v] += offsets[v];
3590 for (
unsigned int comp = 0; comp < n_components; ++comp)
3592 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3593 operation.process_empty(values_dofs[comp][i]);
3594 if (accesses_exterior_dofs)
3596 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3597 if (mask[v] ==
true)
3600 [ind][cells[v] / VectorizedArrayType::size()] ==
3601 internal::MatrixFreeFunctions::DoFInfo::
3602 IndexStorageVariants::contiguous)
3604 if (n_components == 1 || this->n_fe_components == 1)
3606 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3607 operation.process_dof(dof_indices[v] + i,
3609 values_dofs[comp][i][v]);
3613 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3614 operation.process_dof(dof_indices[v] + i +
3615 comp * dofs_per_component,
3617 values_dofs[comp][i][v]);
3622 const unsigned int offset =
3625 if (n_components == 1 || this->n_fe_components == 1)
3627 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3628 operation.process_dof(dof_indices[v] + i * offset,
3630 values_dofs[comp][i][v]);
3634 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3635 operation.process_dof(
3637 (i + comp * dofs_per_component) * offset,
3639 values_dofs[comp][i][v]);
3650 if (n_components == 1 || this->n_fe_components == 1)
3652 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3653 if (mask[v] ==
true)
3654 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3655 operation.process_dof(dof_indices[v] + i,
3657 values_dofs[comp][i][v]);
3661 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3662 if (mask[v] ==
true)
3663 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3664 operation.process_dof(dof_indices[v] + i +
3665 comp * dofs_per_component,
3667 values_dofs[comp][i][v]);
3672 const unsigned int *offsets =
3674 [ind][VectorizedArrayType::size() * this->cell];
3675 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3677 if (n_components == 1 || this->n_fe_components == 1)
3678 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3680 if (mask[v] ==
true)
3681 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3682 operation.process_dof(dof_indices[v] + i * offsets[v],
3684 values_dofs[comp][i][v]);
3688 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
3689 if (mask[v] ==
true)
3690 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3691 operation.process_dof(
3693 (i + comp * dofs_per_component) * offsets[v],
3695 values_dofs[comp][i][v]);
3707 std::enable_if_t<!IsBlockVector<VectorType>::value,
VectorType> * =
nullptr>
3708 decltype(std::declval<VectorType>().begin())
3709 get_beginning(VectorType &vec)
3717 std::enable_if_t<IsBlockVector<VectorType>::value,
VectorType> * =
nullptr>
3718 typename VectorType::value_type *
3719 get_beginning(VectorType &)
3725 std::enable_if_t<has_shared_vector_data<VectorType>,
VectorType> * =
3727 const std::vector<ArrayView<const typename VectorType::value_type>> *
3728 get_shared_vector_data(VectorType *vec,
3729 const bool is_valid_mode_for_sm,
3730 const unsigned int active_fe_index,
3731 const internal::MatrixFreeFunctions::DoFInfo *dof_info)
3734 if (is_valid_mode_for_sm &&
3737 active_fe_index == 0)
3738 return &vec->shared_vector_data();
3744 std::enable_if_t<!has_shared_vector_data<VectorType>,
VectorType>
3746 const std::vector<ArrayView<const typename VectorType::value_type>> *
3747 get_shared_vector_data(VectorType *,
3750 const internal::MatrixFreeFunctions::DoFInfo *)
3755 template <
int n_components,
typename VectorType>
3757 std::array<
typename internal::BlockVectorSelector<
3762 const std::vector<ArrayView<
const typename internal::BlockVectorSelector<
3766 get_vector_data(VectorType &src,
3767 const unsigned int first_index,
3768 const bool is_valid_mode_for_sm,
3769 const unsigned int active_fe_index,
3770 const internal::MatrixFreeFunctions::DoFInfo *dof_info)
3775 std::array<
typename internal::BlockVectorSelector<
3781 ArrayView<
const typename internal::BlockVectorSelector<
3787 for (
unsigned int d = 0;
d < n_components; ++
d)
3788 src_data.first[d] = internal::BlockVectorSelector<
3794 for (
unsigned int d = 0;
d < n_components; ++
d)
3795 src_data.second[d] = get_shared_vector_data(
3796 const_cast<typename internal::BlockVectorSelector<
3797 std::remove_const_t<VectorType>,
3798 IsBlockVector<std::remove_const_t<VectorType>
>::value>::BaseVectorType
3799 *>(src_data.first[d]),
3800 is_valid_mode_for_sm,
3814 typename VectorizedArrayType>
3819 if (this->dof_info ==
nullptr ||
3821 this->dof_info->hanging_node_constraint_masks_comp.empty() ||
3822 this->dof_info->hanging_node_constraint_masks_comp
3823 [this->active_fe_index][this->first_selected_component] ==
false)
3826 std::array<internal::MatrixFreeFunctions::compressed_constraint_kind, n_lanes>
3827 constraint_mask{{internal::MatrixFreeFunctions::
3828 unconstrained_compressed_constraint_kind}};
3830 bool hn_available =
false;
3832 const std::array<unsigned int, n_lanes> &cells = this->get_cell_ids();
3834 for (
unsigned int v = 0; v < n_lanes; ++v)
3838 constraint_mask[v] = internal::MatrixFreeFunctions::
3839 unconstrained_compressed_constraint_kind;
3843 const unsigned int cell_index = cells[v];
3846 constraint_mask[v] =
mask;
3848 hn_available |= (
mask != internal::MatrixFreeFunctions::
3849 unconstrained_compressed_constraint_kind);
3852 if (hn_available ==
false)
3857 this->data->data.front().fe_degree,
3858 this->get_shape_info(),
3870 typename VectorizedArrayType>
3871template <
typename VectorType>
3875 const unsigned int first_index,
3876 const std::bitset<n_lanes> &mask)
3878 const auto src_data = internal::get_vector_data<n_components_>(
3881 this->dof_info !=
nullptr &&
3882 this->dof_access_index ==
3884 this->active_fe_index,
3887 internal::VectorReader<Number, VectorizedArrayType> reader;
3888 read_write_operation(reader, src_data.first, src_data.second, mask,
true);
3890 apply_hanging_node_constraints(
false);
3894 this->dof_values_initialized =
true;
3904 typename VectorizedArrayType>
3905template <
typename VectorType>
3909 const unsigned int first_index,
3910 const std::bitset<n_lanes> &mask)
3912 const auto src_data = internal::get_vector_data<n_components_>(
3915 this->dof_info !=
nullptr &&
3916 this->dof_access_index ==
3918 this->active_fe_index,
3921 internal::VectorReader<Number, VectorizedArrayType> reader;
3922 read_write_operation(reader, src_data.first, src_data.second, mask,
false);
3926 this->dof_values_initialized =
true;
3936 typename VectorizedArrayType>
3937template <
typename VectorType>
3941 const unsigned int first_index,
3942 const std::bitset<n_lanes> &mask)
const
3946 Assert(this->dof_values_initialized ==
true,
3950 apply_hanging_node_constraints(
true);
3952 const auto dst_data = internal::get_vector_data<n_components_>(
3955 this->dof_info !=
nullptr &&
3956 this->dof_access_index ==
3958 this->active_fe_index,
3961 internal::VectorDistributorLocalToGlobal<Number, VectorizedArrayType>
3963 read_write_operation(distributor, dst_data.first, dst_data.second, mask);
3972 typename VectorizedArrayType>
3973template <
typename VectorType>
3977 const unsigned int first_index,
3978 const std::bitset<n_lanes> &mask)
const
3982 Assert(this->dof_values_initialized ==
true,
3986 const auto dst_data = internal::get_vector_data<n_components_>(
3989 this->dof_info !=
nullptr &&
3990 this->dof_access_index ==
3992 this->active_fe_index,
3995 internal::VectorSetter<Number, VectorizedArrayType> setter;
3996 read_write_operation(setter, dst_data.first, dst_data.second, mask);
4005 typename VectorizedArrayType>
4006template <
typename VectorType>
4010 const unsigned int first_index,
4011 const std::bitset<n_lanes> &mask)
const
4015 Assert(this->dof_values_initialized ==
true,
4019 const auto dst_data = internal::get_vector_data<n_components_>(
4022 this->dof_access_index ==
4024 this->active_fe_index,
4027 internal::VectorSetter<Number, VectorizedArrayType> setter;
4028 read_write_operation(setter, dst_data.first, dst_data.second, mask,
false);
4041 typename VectorizedArrayType>
4043 typename FEEvaluationBase<dim,
4052 if constexpr (n_components == 1)
4053 return this->values_dofs[dof];
4056 const std::size_t dofs = this->data->dofs_per_component_on_cell;
4057 Tensor<1, n_components_, VectorizedArrayType> return_value;
4058 for (
unsigned int comp = 0; comp < n_components; ++comp)
4059 return_value[comp] = this->values_dofs[comp * dofs + dof];
4060 return return_value;
4070 typename VectorizedArrayType>
4072 typename FEEvaluationBase<dim,
4078 get_value(
const unsigned int q_point)
const
4082 Assert(this->values_quad_initialized ==
true,
4087 if constexpr (n_components == 1)
4088 return this->values_quad[q_point];
4091 if (n_components == dim &&
4092 this->data->element_type ==
4098 Assert(this->values_quad_initialized ==
true,
4103 Assert(this->J_value !=
nullptr,
4106 const std::size_t nqp = this->n_quadrature_points;
4107 Tensor<1, n_components, VectorizedArrayType> value_out;
4113 const Tensor<2, dim, VectorizedArrayType> jac = this->jacobian[1];
4114 const VectorizedArrayType inv_det =
4115 (dim == 2) ? this->jacobian[0][0][0] * this->jacobian[0][1][1] :
4116 this->jacobian[0][0][0] * this->jacobian[0][1][1] *
4117 this->jacobian[0][2][2];
4120 for (
unsigned int comp = 0; comp < n_components; ++comp)
4121 value_out[comp] = this->values_quad[comp * nqp + q_point] *
4122 jac[comp][comp] * inv_det;
4127 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
4129 this->jacobian[q_point] :
4131 const Tensor<2, dim, VectorizedArrayType> jac =
4138 const VectorizedArrayType inv_det =
4139 (is_face && dim == 2 && this->get_face_no() < 2) ?
4143 for (
unsigned int comp = 0; comp < n_components; ++comp)
4145 value_out[comp] = this->values_quad[q_point] * jac[comp][0];
4146 for (
unsigned int e = 1;
e < dim; ++
e)
4148 this->values_quad[e * nqp + q_point] * jac[comp][e];
4149 value_out[comp] *= inv_det;
4154 else if (n_components == dim &&
4155 this->data->element_type ==
4161 Assert(this->values_quad_initialized ==
true,
4166 Assert(this->J_value !=
nullptr,
4169 const std::size_t nqp = this->n_quadrature_points;
4170 Tensor<1, n_components, VectorizedArrayType> value_out;
4176 const Tensor<2, dim, VectorizedArrayType> inv_transp_jac =
4181 for (
unsigned int comp = 0; comp < n_components; ++comp)
4182 value_out[comp] = this->values_quad[comp * nqp + q_point] *
4183 inv_transp_jac[comp][comp];
4188 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
4190 this->jacobian[q_point] :
4194 for (
unsigned int comp = 0; comp < n_components; ++comp)
4197 this->values_quad[q_point] * inv_t_jac[comp][0];
4198 for (
unsigned int e = 1;
e < dim; ++
e)
4200 this->values_quad[e * nqp + q_point] * inv_t_jac[comp][e];
4207 const std::size_t nqp = this->n_quadrature_points;
4208 Tensor<1, n_components_, VectorizedArrayType> return_value;
4209 for (
unsigned int comp = 0; comp < n_components; ++comp)
4210 return_value[comp] = this->values_quad[comp * nqp + q_point];
4211 return return_value;
4222 typename VectorizedArrayType>
4224 typename FEEvaluationBase<dim,
4228 VectorizedArrayType>::gradient_type
4234 Assert(this->gradients_quad_initialized ==
true,
4239 Assert(this->jacobian !=
nullptr,
4241 "update_gradients"));
4242 const std::size_t nqp = this->n_quadrature_points;
4244 if constexpr (n_components == dim && dim > 1)
4246 if (this->data->element_type ==
4252 Assert(this->gradients_quad_initialized ==
true,
4257 Assert(this->jacobian !=
nullptr,
4259 "update_gradients"));
4260 const std::size_t nqp = this->n_quadrature_points;
4261 const std::size_t nqp_d = nqp * dim;
4262 Tensor<1, dim, Tensor<1, dim, VectorizedArrayType>> grad_out;
4264 this->gradients_quad + q_point * dim;
4271 const Tensor<2, dim, VectorizedArrayType> &inv_t_jac =
4273 const Tensor<2, dim, VectorizedArrayType> &jac =
4275 const VectorizedArrayType inv_det =
4276 (dim == 2) ? this->jacobian[0][0][0] * this->jacobian[0][1][1] :
4277 this->jacobian[0][0][0] * this->jacobian[0][1][1] *
4278 this->jacobian[0][2][2];
4281 for (
unsigned int d = 0;
d < dim; ++
d)
4282 for (
unsigned int comp = 0; comp < n_components; ++comp)
4283 grad_out[comp][d] = gradients[comp * nqp_d + d] *
4285 (jac[comp][comp] * inv_det);
4290 const Tensor<2, dim, VectorizedArrayType> &inv_t_jac =
4292 const Tensor<2, dim, VectorizedArrayType> &jac =
4297 const VectorizedArrayType inv_det =
4298 (is_face && dim == 2 && this->get_face_no() < 2) ?
4302 VectorizedArrayType tmp[dim][dim];
4304 for (
unsigned int d = 0;
d < dim; ++
d)
4305 for (
unsigned int e = 0;
e < dim; ++
e)
4308 for (
unsigned int f = 1; f < dim; ++f)
4309 tmp[d][e] += inv_t_jac[d][f] * gradients[e * nqp_d + f];
4311 for (
unsigned int comp = 0; comp < n_components; ++comp)
4312 for (
unsigned int d = 0;
d < dim; ++
d)
4314 VectorizedArrayType res = jac[comp][0] * tmp[
d][0];
4315 for (
unsigned int f = 1; f < dim; ++f)
4316 res += jac[comp][f] * tmp[d][f];
4318 grad_out[comp][
d] = res * inv_det;
4329 Assert(this->jacobian_gradients_non_inverse !=
nullptr,
4331 "update_hessians"));
4333 const auto jac_grad =
4334 this->jacobian_gradients_non_inverse[q_point];
4335 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
4336 this->jacobian[q_point];
4340 const VectorizedArrayType inv_det =
4341 (is_face && dim == 2 && this->get_face_no() < 2) ?
4344 const Tensor<2, dim, VectorizedArrayType> t_jac =
4348 VectorizedArrayType tmp[dim][dim];
4349 for (
unsigned int d = 0;
d < dim; ++
d)
4350 for (
unsigned int e = 0;
e < dim; ++
e)
4353 for (
unsigned int f = 1; f < dim; ++f)
4354 tmp[e][d] += t_jac[f][d] * gradients[f * nqp_d + e];
4359 for (
unsigned int d = 0;
d < dim; ++
d)
4361 for (
unsigned int e = 0;
e < dim; ++
e)
4363 jac_grad[e][d] * this->values_quad[e * nqp + q_point];
4364 for (
unsigned int f = 0, r = dim; f < dim; ++f)
4365 for (
unsigned int k = f + 1; k < dim; ++k, ++r)
4368 jac_grad[r][
d] * this->values_quad[f * nqp + q_point];
4370 jac_grad[r][
d] * this->values_quad[k * nqp + q_point];
4375 for (
unsigned int d = 0;
d < dim; ++
d)
4376 for (
unsigned int e = 0;
e < dim; ++
e)
4378 VectorizedArrayType res = tmp[0][
d] * inv_t_jac[
e][0];
4379 for (
unsigned int f = 1; f < dim; ++f)
4380 res += tmp[f][d] * inv_t_jac[e][f];
4381 grad_out[
d][
e] = res;
4387 VectorizedArrayType tmp3[dim], tmp4[dim];
4388 for (
unsigned int d = 0;
d < dim; ++
d)
4390 tmp3[
d] = inv_t_jac[0][
d] * jac_grad[
d][0];
4391 for (
unsigned int e = 1;
e < dim; ++
e)
4392 tmp3[d] += inv_t_jac[e][d] * jac_grad[d][e];
4394 for (
unsigned int e = 0, k = dim;
e < dim; ++
e)
4395 for (
unsigned int f = e + 1; f < dim; ++k, ++f)
4396 for (
unsigned int d = 0;
d < dim; ++
d)
4398 tmp3[f] += inv_t_jac[
d][
e] * jac_grad[k][
d];
4399 tmp3[
e] += inv_t_jac[
d][f] * jac_grad[k][
d];
4401 for (
unsigned int d = 0;
d < dim; ++
d)
4403 tmp4[
d] = tmp3[0] * inv_t_jac[
d][0];
4404 for (
unsigned int e = 1;
e < dim; ++
e)
4405 tmp4[d] += tmp3[e] * inv_t_jac[d][e];
4408 VectorizedArrayType tmp2[dim];
4409 for (
unsigned int d = 0;
d < dim; ++
d)
4411 tmp2[
d] = t_jac[0][
d] * this->values_quad[q_point];
4412 for (
unsigned e = 1;
e < dim; ++
e)
4414 t_jac[e][d] * this->values_quad[e * nqp + q_point];
4417 for (
unsigned int d = 0;
d < dim; ++
d)
4418 for (
unsigned int e = 0;
e < dim; ++
e)
4420 grad_out[
d][
e] -= tmp4[
e] * tmp2[
d];
4424 grad_out[
d][
e] *= inv_det;
4430 Tensor<1, n_components_, Tensor<1, dim, VectorizedArrayType>> grad_out;
4435 for (
unsigned int comp = 0; comp < n_components; ++comp)
4436 for (
unsigned int d = 0;
d < dim; ++
d)
4438 this->gradients_quad[(comp * nqp + q_point) * dim +
d] *
4439 this->jacobian[0][
d][
d];
4444 const Tensor<2, dim, VectorizedArrayType> &jac =
4448 for (
unsigned int comp = 0; comp < n_components; ++comp)
4449 for (
unsigned int d = 0;
d < dim; ++
d)
4452 jac[
d][0] * this->gradients_quad[(comp * nqp + q_point) * dim];
4453 for (
unsigned int e = 1;
e < dim; ++
e)
4454 grad_out[comp][d] +=
4456 this->gradients_quad[(comp * nqp + q_point) * dim +
e];
4459 if constexpr (n_components == 1)
4471 typename VectorizedArrayType>
4473 typename FEEvaluationBase<dim,
4484 Assert(this->gradients_quad_initialized ==
true,
4488 Assert(this->normal_x_jacobian !=
nullptr,
4490 "update_gradients"));
4492 const std::size_t nqp = this->n_quadrature_points;
4493 Tensor<1, n_components, VectorizedArrayType> grad_out;
4496 for (
unsigned int comp = 0; comp < n_components; ++comp)
4498 this->gradients_quad[(comp * nqp + q_point) * dim + dim - 1] *
4499 (this->normal_x_jacobian[0][dim - 1]);
4502 const std::size_t
index =
4504 for (
unsigned int comp = 0; comp < n_components; ++comp)
4506 grad_out[comp] = this->gradients_quad[(comp * nqp + q_point) * dim] *
4507 this->normal_x_jacobian[index][0];
4508 for (
unsigned int d = 1;
d < dim; ++
d)
4510 this->gradients_quad[(comp * nqp + q_point) * dim +
d] *
4511 this->normal_x_jacobian[
index][
d];
4514 if constexpr (n_components == 1)
4526 template <
typename VectorizedArrayType>
4528 hessian_unit_times_jac(
const Tensor<2, 1, VectorizedArrayType> &jac,
4529 const VectorizedArrayType *
const hessians,
4531 VectorizedArrayType (&tmp)[1][1])
4533 tmp[0][0] = jac[0][0] *
hessians[0];
4536 template <
typename VectorizedArrayType>
4538 hessian_unit_times_jac(
const Tensor<2, 2, VectorizedArrayType> &jac,
4539 const VectorizedArrayType *
const hessians,
4540 const unsigned int nqp,
4541 VectorizedArrayType (&tmp)[2][2])
4543 for (
unsigned int d = 0;
d < 2; ++
d)
4551 template <
typename VectorizedArrayType>
4553 hessian_unit_times_jac(
const Tensor<2, 3, VectorizedArrayType> &jac,
4554 const VectorizedArrayType *
const hessians,
4555 const unsigned int nqp,
4556 VectorizedArrayType (&tmp)[3][3])
4558 for (
unsigned int d = 0;
d < 3; ++
d)
4579 typename VectorizedArrayType>
4580inline typename FEEvaluationBase<dim,
4584 VectorizedArrayType>::hessian_type
4590 Assert(this->hessians_quad_initialized ==
true,
4595 Assert(this->jacobian !=
nullptr,
4598 const Tensor<2, dim, VectorizedArrayType> &jac =
4603 Tensor<1, n_components, Tensor<2, dim, VectorizedArrayType>> hessian_out;
4605 const std::size_t nqp = this->n_quadrature_points;
4606 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
4611 for (
unsigned int comp = 0; comp < n_components; ++comp)
4613 for (
unsigned int d = 0;
d < dim; ++
d)
4614 hessian_out[comp][d][d] =
4615 this->hessians_quad[(comp * hdim + d) * nqp + q_point] *
4616 (jac[
d][
d] * jac[
d][
d]);
4622 hessian_out[comp][0][1] =
4623 this->hessians_quad[(comp * hdim + 2) * nqp + q_point] *
4624 (jac[0][0] * jac[1][1]);
4627 hessian_out[comp][0][1] =
4628 this->hessians_quad[(comp * hdim + 3) * nqp + q_point] *
4629 (jac[0][0] * jac[1][1]);
4630 hessian_out[comp][0][2] =
4631 this->hessians_quad[(comp * hdim + 4) * nqp + q_point] *
4632 (jac[0][0] * jac[2][2]);
4633 hessian_out[comp][1][2] =
4634 this->hessians_quad[(comp * hdim + 5) * nqp + q_point] *
4635 (jac[1][1] * jac[2][2]);
4640 for (
unsigned int d = 0;
d < dim; ++
d)
4641 for (
unsigned int e = d + 1;
e < dim; ++
e)
4642 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4648 for (
unsigned int comp = 0; comp < n_components; ++comp)
4650 VectorizedArrayType tmp[dim][dim];
4651 internal::hessian_unit_times_jac(
4652 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4655 for (
unsigned int d = 0;
d < dim; ++
d)
4656 for (
unsigned int e = d;
e < dim; ++
e)
4658 hessian_out[comp][
d][
e] = jac[
d][0] * tmp[0][
e];
4659 for (
unsigned int f = 1; f < dim; ++f)
4660 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
4667 for (
unsigned int d = 0;
d < dim; ++
d)
4668 for (
unsigned int e = d + 1;
e < dim; ++
e)
4669 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4675 const auto &jac_grad = this->jacobian_gradients[q_point];
4676 for (
unsigned int comp = 0; comp < n_components; ++comp)
4678 VectorizedArrayType tmp[dim][dim];
4679 internal::hessian_unit_times_jac(
4680 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4683 for (
unsigned int d = 0;
d < dim; ++
d)
4684 for (
unsigned int e = d;
e < dim; ++
e)
4686 hessian_out[comp][
d][
e] = jac[
d][0] * tmp[0][
e];
4687 for (
unsigned int f = 1; f < dim; ++f)
4688 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
4692 for (
unsigned int d = 0;
d < dim; ++
d)
4693 for (
unsigned int e = 0;
e < dim; ++
e)
4694 hessian_out[comp][d][d] +=
4696 this->gradients_quad[(comp * nqp + q_point) * dim +
e];
4699 for (
unsigned int d = 0, count = dim;
d < dim; ++
d)
4700 for (
unsigned int e = d + 1;
e < dim; ++
e, ++count)
4701 for (
unsigned int f = 0; f < dim; ++f)
4702 hessian_out[comp][d][e] +=
4703 jac_grad[count][f] *
4704 this->gradients_quad[(comp * nqp + q_point) * dim + f];
4707 for (
unsigned int d = 0;
d < dim; ++
d)
4708 for (
unsigned int e = d + 1;
e < dim; ++
e)
4709 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4712 if constexpr (n_components == 1)
4713 return hessian_out[0];
4724 typename VectorizedArrayType>
4725inline typename FEEvaluationBase<dim,
4729 VectorizedArrayType>::gradient_type
4736 Assert(this->hessians_quad_initialized ==
true,
4742 const Tensor<2, dim, VectorizedArrayType> &jac =
4747 const std::size_t nqp = this->n_quadrature_points;
4748 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
4749 Tensor<1, n_components_, Tensor<1, dim, VectorizedArrayType>> hessian_out;
4754 for (
unsigned int comp = 0; comp < n_components; ++comp)
4755 for (
unsigned int d = 0;
d < dim; ++
d)
4756 hessian_out[comp][d] =
4757 this->hessians_quad[(comp * hdim + d) * nqp + q_point] *
4758 (jac[
d][
d] * jac[
d][
d]);
4763 for (
unsigned int comp = 0; comp < n_components; ++comp)
4767 VectorizedArrayType tmp[dim][dim];
4768 internal::hessian_unit_times_jac(
4769 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4773 for (
unsigned int d = 0;
d < dim; ++
d)
4775 hessian_out[comp][
d] = jac[
d][0] * tmp[0][
d];
4776 for (
unsigned int f = 1; f < dim; ++f)
4777 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
4784 const auto &jac_grad = this->jacobian_gradients[q_point];
4785 for (
unsigned int comp = 0; comp < n_components; ++comp)
4789 VectorizedArrayType tmp[dim][dim];
4790 internal::hessian_unit_times_jac(
4791 jac, this->hessians_quad + comp * hdim * nqp + q_point, nqp, tmp);
4795 for (
unsigned int d = 0;
d < dim; ++
d)
4797 hessian_out[comp][
d] = jac[
d][0] * tmp[0][
d];
4798 for (
unsigned int f = 1; f < dim; ++f)
4799 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
4802 for (
unsigned int d = 0;
d < dim; ++
d)
4803 for (
unsigned int e = 0;
e < dim; ++
e)
4804 hessian_out[comp][d] +=
4806 this->gradients_quad[(comp * nqp + q_point) * dim +
e];
4810 if constexpr (n_components == 1)
4811 return hessian_out[0];
4822 typename VectorizedArrayType>
4823inline typename FEEvaluationBase<dim,
4834 Assert(this->hessians_quad_initialized ==
true,
4839 const gradient_type hess_diag = get_hessian_diagonal(q_point);
4840 if constexpr (n_components == 1)
4842 VectorizedArrayType
sum = hess_diag[0];
4843 for (
unsigned int d = 1;
d < dim; ++
d)
4844 sum += hess_diag[d];
4849 Tensor<1, n_components_, VectorizedArrayType> laplacian_out;
4850 for (
unsigned int comp = 0; comp < n_components; ++comp)
4852 laplacian_out[comp] = hess_diag[comp][0];
4853 for (
unsigned int d = 1;
d < dim; ++
d)
4854 laplacian_out[comp] += hess_diag[comp][d];
4856 return laplacian_out;
4866 typename VectorizedArrayType>
4867inline typename FEEvaluationBase<dim,
4877 Assert(this->hessians_quad_initialized ==
true,
4882 Assert(this->normal_x_jacobian !=
nullptr,
4884 "update_hessians"));
4886 Tensor<1, n_components, VectorizedArrayType> hessian_out;
4888 const std::size_t nqp = this->n_quadrature_points;
4889 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
4893 const auto nxj = this->normal_x_jacobian[0];
4895 for (
unsigned int comp = 0; comp < n_components; ++comp)
4897 for (
unsigned int d = 0;
d < dim; ++
d)
4898 hessian_out[comp] +=
4899 this->hessians_quad[(comp * hdim + d) * nqp + q_point] *
4900 (nxj[
d]) * (nxj[d]);
4907 hessian_out[comp] +=
4908 this->hessians_quad[(comp * hdim + 2) * nqp + q_point] *
4912 hessian_out[comp] +=
4913 2. * this->hessians_quad[(comp * hdim + 3) * nqp + q_point] *
4915 hessian_out[comp] +=
4916 2. * this->hessians_quad[(comp * hdim + 4) * nqp + q_point] *
4918 hessian_out[comp] +=
4919 2. * this->hessians_quad[(comp * hdim + 5) * nqp + q_point] *
4930 const auto normal = this->normal_vector(q_point);
4931 const auto hessian = get_hessian(q_point);
4933 if constexpr (n_components == 1)
4934 hessian_out[0] = hessian * normal * normal;
4936 for (
unsigned int comp = 0; comp < n_components; ++comp)
4937 hessian_out[comp] = hessian[comp] * normal * normal;
4939 if constexpr (n_components == 1)
4940 return hessian_out[0];
4951 typename VectorizedArrayType>
4958 this->dof_values_initialized =
true;
4960 const std::size_t dofs = this->data->dofs_per_component_on_cell;
4962 for (
unsigned int comp = 0; comp < n_components; ++comp)
4963 if constexpr (n_components == 1)
4964 this->values_dofs[comp * dofs + dof] = val_in;
4966 this->values_dofs[comp * dofs + dof] = val_in[comp];
4975 typename VectorizedArrayType>
4985 Assert(this->J_value !=
nullptr,
4990 this->values_quad_submitted =
true;
4993 const std::size_t nqp = this->n_quadrature_points;
4994 VectorizedArrayType *
values = this->values_quad + q_point;
4996 const VectorizedArrayType JxW =
4998 this->J_value[0] * this->quadrature_weights[q_point] :
4999 this->J_value[q_point];
5000 if constexpr (n_components == 1)
5001 values[0] = val_in * JxW;
5004 if (n_components == dim &&
5005 this->data->element_type ==
5010 Assert(this->J_value !=
nullptr,
5016 this->values_quad_submitted =
true;
5019 VectorizedArrayType *
values = this->values_quad + q_point;
5020 const std::size_t nqp = this->n_quadrature_points;
5025 const Tensor<2, dim, VectorizedArrayType> jac = this->jacobian[1];
5026 const VectorizedArrayType weight =
5027 this->quadrature_weights[q_point];
5029 for (
unsigned int comp = 0; comp < n_components; ++comp)
5030 values[comp * nqp] = val_in[comp] * weight * jac[comp][comp];
5035 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
5037 this->jacobian[q_point] :
5042 const VectorizedArrayType fac =
5044 this->quadrature_weights[q_point] :
5045 (((this->cell_type > internal::MatrixFreeFunctions::
affine) ?
5046 this->J_value[q_point] :
5047 this->J_value[0] * this->quadrature_weights[q_point]) *
5048 ((dim == 2 && this->get_face_no() < 2) ?
5051 const Tensor<2, dim, VectorizedArrayType> jac =
5057 for (
unsigned int comp = 0; comp < n_components; ++comp)
5059 values[comp * nqp] = val_in[0] * jac[0][comp];
5060 for (
unsigned int e = 1;
e < dim; ++
e)
5061 values[comp * nqp] += val_in[e] * jac[e][comp];
5062 values[comp * nqp] *= fac;
5066 else if (n_components == dim &&
5067 this->data->element_type ==
5072 Assert(this->J_value !=
nullptr,
5078 this->values_quad_submitted =
true;
5081 VectorizedArrayType *
values = this->values_quad + q_point;
5082 const std::size_t nqp = this->n_quadrature_points;
5087 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
5089 const VectorizedArrayType det_jac =
5090 (dim == 2) ? this->jacobian[1][0][0] * this->jacobian[1][1][1] :
5091 this->jacobian[1][0][0] * this->jacobian[1][1][1] *
5092 this->jacobian[1][2][2];
5094 const VectorizedArrayType weight =
5095 this->quadrature_weights[q_point];
5098 for (
unsigned int comp = 0; comp < n_components; ++comp)
5099 values[comp * nqp] =
5100 val_in[comp] * weight * inv_t_jac[comp][comp] * det_jac;
5105 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
5107 this->jacobian[q_point] :
5110 const VectorizedArrayType fac =
5112 this->J_value[q_point] :
5113 this->J_value[0] * this->quadrature_weights[q_point]);
5116 for (
unsigned int comp = 0; comp < n_components; ++comp)
5118 values[comp * nqp] = val_in[0] * inv_t_jac[0][comp];
5119 for (
unsigned int e = 1;
e < dim; ++
e)
5120 values[comp * nqp] += val_in[e] * inv_t_jac[e][comp];
5121 values[comp * nqp] *= fac;
5126 for (
unsigned int comp = 0; comp < n_components; ++comp)
5127 values[comp * nqp] = val_in[comp] * JxW;
5137 typename VectorizedArrayType>
5138template <
int,
typename>
5141 submit_value(
const Tensor<1, 1, VectorizedArrayType> val_in,
5142 const unsigned int q_point)
5144 static_assert(n_components == 1,
5145 "Do not try to modify the default template parameters used for"
5146 " selectively enabling this function via std::enable_if!");
5147 submit_value(val_in[0], q_point);
5156 typename VectorizedArrayType>
5159 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point)
5166 Assert(this->J_value !=
nullptr,
5168 "update_gradients"));
5169 Assert(this->jacobian !=
nullptr,
5171 "update_gradients"));
5174 this->gradients_quad_submitted =
true;
5177 if constexpr (dim > 1 && n_components == dim)
5179 if (this->data->element_type ==
5189 Assert(this->J_value !=
nullptr,
5191 "update_gradients"));
5192 Assert(this->jacobian !=
nullptr,
5194 "update_gradients"));
5197 this->gradients_quad_submitted =
true;
5200 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
5201 VectorizedArrayType *
values =
5202 this->values_from_gradients_quad + q_point;
5203 const std::size_t nqp = this->n_quadrature_points;
5204 const std::size_t nqp_d = nqp * dim;
5210 const Tensor<2, dim, VectorizedArrayType> &inv_t_jac =
5212 const Tensor<2, dim, VectorizedArrayType> &jac =
5214 const VectorizedArrayType weight =
5215 this->quadrature_weights[q_point];
5216 for (
unsigned int d = 0;
d < dim; ++
d)
5217 for (
unsigned int comp = 0; comp < n_components; ++comp)
5218 gradients[comp * nqp_d + d] = grad_in[comp][d] *
5220 (jac[comp][comp] * weight);
5225 const Tensor<2, dim, VectorizedArrayType> &inv_t_jac =
5227 const Tensor<2, dim, VectorizedArrayType> &jac =
5232 const VectorizedArrayType fac =
5234 this->quadrature_weights[q_point] :
5235 this->J_value[0] * this->quadrature_weights[q_point] *
5236 ((dim == 2 && this->get_face_no() < 2) ?
5241 VectorizedArrayType tmp[dim][dim];
5242 for (
unsigned int d = 0;
d < dim; ++
d)
5243 for (
unsigned int e = 0;
e < dim; ++
e)
5245 tmp[
d][
e] = inv_t_jac[0][
d] * grad_in[
e][0];
5246 for (
unsigned int f = 1; f < dim; ++f)
5247 tmp[d][e] += inv_t_jac[f][d] * grad_in[e][f];
5249 for (
unsigned int comp = 0; comp < n_components; ++comp)
5250 for (
unsigned int d = 0;
d < dim; ++
d)
5252 VectorizedArrayType res = jac[0][comp] * tmp[
d][0];
5253 for (
unsigned int f = 1; f < dim; ++f)
5254 res += jac[f][comp] * tmp[d][f];
5263 const auto jac_grad =
5264 this->jacobian_gradients_non_inverse[q_point];
5265 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
5266 this->jacobian[q_point];
5270 const VectorizedArrayType fac =
5271 (!is_face) ? this->quadrature_weights[q_point] :
5272 this->J_value[q_point] *
5273 ((dim == 2 && this->get_face_no() < 2) ?
5276 const Tensor<2, dim, VectorizedArrayType> t_jac =
5282 VectorizedArrayType tmp3[dim], tmp4[dim];
5283 for (
unsigned int d = 0;
d < dim; ++
d)
5285 tmp3[
d] = inv_t_jac[0][
d] * jac_grad[
d][0];
5286 for (
unsigned int e = 1;
e < dim; ++
e)
5287 tmp3[d] += inv_t_jac[e][d] * jac_grad[d][e];
5289 for (
unsigned int e = 0, k = dim;
e < dim; ++
e)
5290 for (
unsigned int f = e + 1; f < dim; ++k, ++f)
5291 for (
unsigned int d = 0;
d < dim; ++
d)
5293 tmp3[f] += inv_t_jac[
d][
e] * jac_grad[k][
d];
5294 tmp3[
e] += inv_t_jac[
d][f] * jac_grad[k][
d];
5296 for (
unsigned int d = 0;
d < dim; ++
d)
5298 tmp4[
d] = tmp3[0] * inv_t_jac[
d][0];
5299 for (
unsigned int e = 1;
e < dim; ++
e)
5300 tmp4[d] += tmp3[e] * inv_t_jac[d][e];
5303 const Tensor<2, dim, VectorizedArrayType> grad_in_scaled =
5306 VectorizedArrayType tmp[dim][dim];
5309 for (
unsigned int d = 0;
d < dim; ++
d)
5310 for (
unsigned int e = 0;
e < dim; ++
e)
5312 tmp[
d][
e] = inv_t_jac[0][
d] * grad_in_scaled[
e][0];
5313 for (
unsigned int f = 1; f < dim; ++f)
5314 tmp[d][e] += inv_t_jac[f][d] * grad_in_scaled[e][f];
5317 for (
unsigned int d = 0;
d < dim; ++
d)
5318 for (
unsigned int e = 0;
e < dim; ++
e)
5320 VectorizedArrayType res = t_jac[
d][0] * tmp[
e][0];
5321 for (
unsigned int f = 1; f < dim; ++f)
5322 res += t_jac[d][f] * tmp[e][f];
5329 VectorizedArrayType
value[dim];
5330 for (
unsigned int d = 0;
d < dim; ++
d)
5332 value[
d] = tmp[
d][0] * jac_grad[
d][0];
5333 for (
unsigned int e = 1;
e < dim; ++
e)
5334 value[d] += tmp[d][e] * jac_grad[d][e];
5336 for (
unsigned int e = 0, k = dim;
e < dim; ++
e)
5337 for (
unsigned int f = e + 1; f < dim; ++k, ++f)
5338 for (
unsigned int d = 0;
d < dim; ++
d)
5340 value[
e] += tmp[f][
d] * jac_grad[k][
d];
5341 value[f] += tmp[
e][
d] * jac_grad[k][
d];
5346 for (
unsigned int d = 0;
d < dim; ++
d)
5348 VectorizedArrayType tmp2 = grad_in_scaled[
d][0] * tmp4[0];
5349 for (
unsigned int e = 1;
e < dim; ++
e)
5350 tmp2 += grad_in_scaled[d][e] * tmp4[e];
5351 for (
unsigned int e = 0;
e < dim; ++
e)
5352 value[e] -= t_jac[e][d] * tmp2;
5355 for (
unsigned int d = 0;
d < dim; ++
d)
5356 values[d * nqp] =
value[d];
5362 const std::size_t nqp_d = this->n_quadrature_points * dim;
5363 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
5367 const VectorizedArrayType JxW =
5368 this->J_value[0] * this->quadrature_weights[q_point];
5374 std::array<VectorizedArrayType, dim> jac;
5375 for (
unsigned int d = 0;
d < dim; ++
d)
5376 jac[d] = this->jacobian[0][d][d];
5378 for (
unsigned int d = 0;
d < dim; ++
d)
5380 const VectorizedArrayType factor = this->jacobian[0][
d][
d] * JxW;
5381 if constexpr (n_components == 1)
5382 gradients[d] = grad_in[d] * factor;
5384 for (
unsigned int comp = 0; comp < n_components; ++comp)
5385 gradients[comp * nqp_d + d] = grad_in[comp][d] * factor;
5390 const Tensor<2, dim, VectorizedArrayType> jac =
5392 this->jacobian[q_point] :
5394 const VectorizedArrayType JxW =
5396 this->J_value[q_point] :
5397 this->J_value[0] * this->quadrature_weights[q_point];
5398 if constexpr (n_components == 1)
5399 for (
unsigned int d = 0;
d < dim; ++
d)
5401 VectorizedArrayType new_val = jac[0][
d] * grad_in[0];
5402 for (
unsigned int e = 1;
e < dim; ++
e)
5403 new_val += (jac[e][d] * grad_in[e]);
5407 for (
unsigned int comp = 0; comp < n_components; ++comp)
5408 for (
unsigned int d = 0;
d < dim; ++
d)
5410 VectorizedArrayType new_val = jac[0][
d] * grad_in[comp][0];
5411 for (
unsigned int e = 1;
e < dim; ++
e)
5412 new_val += (jac[e][d] * grad_in[comp][e]);
5424 typename VectorizedArrayType>
5425template <
int,
typename>
5429 const unsigned int q_point)
5431 static_assert(n_components == 1 && dim == 1,
5432 "Do not try to modify the default template parameters used for"
5433 " selectively enabling this function via std::enable_if!");
5434 submit_gradient(grad_in[0], q_point);
5443 typename VectorizedArrayType>
5449 Assert(this->normal_x_jacobian !=
nullptr,
5451 "update_gradients"));
5454 this->gradients_quad_submitted =
true;
5457 const std::size_t nqp_d = this->n_quadrature_points * dim;
5458 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
5462 const VectorizedArrayType JxW_jac = this->J_value[0] *
5463 this->quadrature_weights[q_point] *
5464 this->normal_x_jacobian[0][dim - 1];
5465 for (
unsigned int comp = 0; comp < n_components; ++comp)
5467 for (
unsigned int d = 0;
d < dim - 1; ++
d)
5468 gradients[comp * nqp_d + d] = VectorizedArrayType();
5469 if constexpr (n_components == 1)
5470 gradients[dim - 1] = grad_in * JxW_jac;
5472 gradients[comp * nqp_d + dim - 1] = grad_in[comp] * JxW_jac;
5477 const unsigned int index =
5479 const Tensor<1, dim, VectorizedArrayType> jac =
5480 this->normal_x_jacobian[
index];
5481 const VectorizedArrayType JxW =
5483 this->J_value[index] * this->quadrature_weights[q_point] :
5484 this->J_value[
index];
5485 for (
unsigned int comp = 0; comp < n_components; ++comp)
5486 for (
unsigned int d = 0;
d < dim; ++
d)
5487 if constexpr (n_components == 1)
5490 gradients[comp * nqp_d +
d] = (grad_in[comp] * JxW) * jac[d];
5500 typename VectorizedArrayType>
5503 submit_hessian(
const hessian_type hessian_in,
const unsigned int q_point)
5510 Assert(this->J_value !=
nullptr,
5512 "update_hessians"));
5513 Assert(this->jacobian !=
nullptr,
5515 "update_hessians"));
5518 this->hessians_quad_submitted =
true;
5522 const std::size_t nqp = this->n_quadrature_points;
5523 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
5526 const VectorizedArrayType JxW =
5527 this->J_value[0] * this->quadrature_weights[q_point];
5530 for (
unsigned int d = 0;
d < dim; ++
d)
5532 const auto jac_d = this->jacobian[0][
d][
d];
5533 const VectorizedArrayType factor = jac_d * jac_d * JxW;
5534 for (
unsigned int comp = 0; comp < n_components; ++comp)
5535 if constexpr (n_components == 1)
5536 this->hessians_quad[
d * nqp + q_point] =
5537 hessian_in[
d][
d] * factor;
5539 this->hessians_quad[(comp * hdim +
d) * nqp + q_point] =
5540 hessian_in[comp][d][d] * factor;
5544 for (
unsigned int d = 1, off_dia = dim;
d < dim; ++
d)
5545 for (
unsigned int e = 0;
e <
d; ++
e, ++off_dia)
5547 const auto jac_d = this->jacobian[0][
d][
d];
5548 const auto jac_e = this->jacobian[0][
e][
e];
5549 const VectorizedArrayType factor = jac_d * jac_e * JxW;
5550 for (
unsigned int comp = 0; comp < n_components; ++comp)
5551 if constexpr (n_components == 1)
5552 this->hessians_quad[off_dia * nqp + q_point] =
5553 (hessian_in[
d][
e] + hessian_in[
e][
d]) * factor;
5555 this->hessians_quad[(comp * hdim + off_dia) * nqp + q_point] =
5556 (hessian_in[comp][d][e] + hessian_in[comp][e][d]) * factor;
5562 const Tensor<2, dim, VectorizedArrayType> jac = this->jacobian[0];
5563 const VectorizedArrayType JxW =
5564 this->J_value[0] * this->quadrature_weights[q_point];
5565 for (
unsigned int comp = 0; comp < n_components; ++comp)
5567 Tensor<2, dim, VectorizedArrayType> hessian_c;
5568 if constexpr (n_components == 1)
5569 hessian_c = hessian_in;
5571 hessian_c = hessian_in[comp];
5574 VectorizedArrayType tmp[dim][dim];
5575 for (
unsigned int i = 0; i < dim; ++i)
5576 for (
unsigned int j = 0; j < dim; ++j)
5578 tmp[i][j] = hessian_c[i][0] * jac[0][j];
5579 for (
unsigned int k = 1; k < dim; ++k)
5580 tmp[i][j] += hessian_c[i][k] * jac[k][j];
5584 VectorizedArrayType tmp2[dim][dim];
5585 for (
unsigned int i = 0; i < dim; ++i)
5586 for (
unsigned int j = 0; j < dim; ++j)
5588 tmp2[i][j] = jac[0][i] * tmp[0][j];
5589 for (
unsigned int k = 1; k < dim; ++k)
5590 tmp2[i][j] += jac[k][i] * tmp[k][j];
5594 for (
unsigned int d = 0;
d < dim; ++
d)
5595 this->hessians_quad[(comp * hdim + d) * nqp + q_point] =
5599 for (
unsigned int d = 0, off_diag = dim;
d < dim; ++
d)
5600 for (
unsigned int e = d + 1;
e < dim; ++
e, ++off_diag)
5601 this->hessians_quad[(comp * hdim + off_diag) * nqp + q_point] =
5602 (tmp2[
d][
e] + tmp2[
e][
d]) * JxW;
5607 const Tensor<2, dim, VectorizedArrayType> jac = this->jacobian[q_point];
5608 const VectorizedArrayType JxW = this->J_value[q_point];
5609 const auto &jac_grad = this->jacobian_gradients[q_point];
5610 for (
unsigned int comp = 0; comp < n_components; ++comp)
5612 Tensor<2, dim, VectorizedArrayType> hessian_c;
5613 if constexpr (n_components == 1)
5614 hessian_c = hessian_in;
5616 hessian_c = hessian_in[comp];
5619 VectorizedArrayType tmp[dim][dim];
5620 for (
unsigned int i = 0; i < dim; ++i)
5621 for (
unsigned int j = 0; j < dim; ++j)
5623 tmp[i][j] = hessian_c[i][0] * jac[0][j];
5624 for (
unsigned int k = 1; k < dim; ++k)
5625 tmp[i][j] += hessian_c[i][k] * jac[k][j];
5629 VectorizedArrayType tmp2[dim][dim];
5630 for (
unsigned int i = 0; i < dim; ++i)
5631 for (
unsigned int j = 0; j < dim; ++j)
5633 tmp2[i][j] = jac[0][i] * tmp[0][j];
5634 for (
unsigned int k = 1; k < dim; ++k)
5635 tmp2[i][j] += jac[k][i] * tmp[k][j];
5639 for (
unsigned int d = 0;
d < dim; ++
d)
5640 this->hessians_quad[(comp * hdim + d) * nqp + q_point] =
5644 for (
unsigned int d = 0, off_diag = dim;
d < dim; ++
d)
5645 for (
unsigned int e = d + 1;
e < dim; ++
e, ++off_diag)
5646 this->hessians_quad[(comp * hdim + off_diag) * nqp + q_point] =
5647 (tmp2[
d][
e] + tmp2[
e][
d]) * JxW;
5650 for (
unsigned int d = 0;
d < dim; ++
d)
5652 VectorizedArrayType
sum = 0;
5653 for (
unsigned int e = 0;
e < dim; ++
e)
5654 sum += hessian_c[e][e] * jac_grad[e][d];
5655 for (
unsigned int e = 0, count = dim;
e < dim; ++
e)
5656 for (
unsigned int f = e + 1; f < dim; ++f, ++count)
5658 (hessian_c[e][f] + hessian_c[f][e]) * jac_grad[count][
d];
5659 this->gradients_from_hessians_quad[(comp * nqp + q_point) * dim +
5672 typename VectorizedArrayType>
5676 const unsigned int q_point)
5683 Assert(this->J_value !=
nullptr,
5685 "update_hessians"));
5686 Assert(this->jacobian !=
nullptr,
5688 "update_hessians"));
5691 this->hessians_quad_submitted =
true;
5695 const std::size_t nqp = this->n_quadrature_points;
5696 constexpr unsigned int hdim = (dim * (dim + 1)) / 2;
5699 const VectorizedArrayType JxW =
5700 this->J_value[0] * this->quadrature_weights[q_point];
5702 const auto nxj = this->normal_x_jacobian[0];
5705 for (
unsigned int d = 0;
d < dim; ++
d)
5707 const auto nxj_d = nxj[
d];
5708 const VectorizedArrayType factor = nxj_d * nxj_d * JxW;
5709 for (
unsigned int comp = 0; comp < n_components; ++comp)
5710 if constexpr (n_components == 1)
5711 this->hessians_quad[
d * nqp + q_point] =
5712 normal_hessian_in * factor;
5714 this->hessians_quad[(comp * hdim +
d) * nqp + q_point] =
5715 normal_hessian_in[comp] * factor;
5719 for (
unsigned int d = 1, off_dia = dim;
d < dim; ++
d)
5720 for (
unsigned int e = 0;
e <
d; ++
e, ++off_dia)
5722 const auto jac_d = nxj[
d];
5723 const auto jac_e = nxj[
e];
5724 const VectorizedArrayType factor = jac_d * jac_e * JxW;
5725 for (
unsigned int comp = 0; comp < n_components; ++comp)
5726 if constexpr (n_components == 1)
5727 this->hessians_quad[off_dia * nqp + q_point] =
5728 2. * normal_hessian_in * factor;
5730 this->hessians_quad[(comp * hdim + off_dia) * nqp + q_point] =
5731 2. * normal_hessian_in[comp] * factor;
5736 const auto normal = this->normal_vector(q_point);
5737 const auto normal_projector =
outer_product(normal, normal);
5738 if constexpr (n_components == 1)
5739 submit_hessian(normal_hessian_in * normal_projector, q_point);
5743 for (
unsigned int comp = 0; comp < n_components; ++comp)
5744 tmp[comp] = normal_hessian_in[comp] * normal_projector;
5745 submit_hessian(tmp, q_point);
5756 typename VectorizedArrayType>
5757inline typename FEEvaluationBase<dim,
5768 Assert(this->values_quad_submitted ==
true,
5772 Tensor<1, n_components, VectorizedArrayType> return_value;
5773 const std::size_t nqp = this->n_quadrature_points;
5774 for (
unsigned int q = 0; q < nqp; ++q)
5775 for (
unsigned int comp = 0; comp < n_components; ++comp)
5776 return_value[comp] += this->values_quad[comp * nqp + q];
5777 if constexpr (n_components == 1)
5778 return return_value[0];
5780 return return_value;
5789 typename VectorizedArrayType>
5790template <
int,
typename>
5795 static_assert(n_components == dim,
5796 "Do not try to modify the default template parameters used for"
5797 " selectively enabling this function via std::enable_if!");
5801 Assert(this->gradients_quad_initialized ==
true,
5805 Assert(this->jacobian !=
nullptr,
5807 "update_gradients"));
5809 VectorizedArrayType divergence;
5810 const std::size_t nqp = this->n_quadrature_points;
5813 this->data->element_type ==
5816 VectorizedArrayType inv_det =
5819 this->jacobian[0][0][0] *
5820 ((dim == 2) ? this->jacobian[0][1][1] :
5821 this->jacobian[0][1][1] * this->jacobian[0][2][2]) :
5829 if (is_face && dim == 2 && this->get_face_no() < 2)
5833 divergence = this->gradients_quad[q_point * dim];
5834 for (
unsigned int d = 1;
d < dim; ++
d)
5835 divergence += this->gradients_quad[(d * nqp + q_point) * dim +
d];
5836 divergence *= inv_det;
5845 this->gradients_quad[q_point * dim] * this->jacobian[0][0][0];
5846 for (
unsigned int d = 1;
d < dim; ++
d)
5847 divergence += this->gradients_quad[(d * nqp + q_point) * dim +
d] *
5848 this->jacobian[0][
d][
d];
5853 const Tensor<2, dim, VectorizedArrayType> &jac =
5855 this->jacobian[q_point] :
5857 divergence = jac[0][0] * this->gradients_quad[q_point * dim];
5858 for (
unsigned int e = 1;
e < dim; ++
e)
5859 divergence += jac[0][e] * this->gradients_quad[q_point * dim + e];
5860 for (
unsigned int d = 1;
d < dim; ++
d)
5861 for (
unsigned int e = 0;
e < dim; ++
e)
5863 jac[d][e] * this->gradients_quad[(d * nqp + q_point) * dim +
e];
5875 typename VectorizedArrayType>
5876template <
int,
typename>
5881 static_assert(n_components == dim,
5882 "Do not try to modify the default template parameters used for"
5883 " selectively enabling this function via std::enable_if!");
5886 const auto grad = get_gradient(q_point);
5887 VectorizedArrayType symmetrized[(dim * dim + dim) / 2];
5888 VectorizedArrayType half =
Number(0.5);
5889 for (
unsigned int d = 0;
d < dim; ++
d)
5890 symmetrized[d] = grad[d][d];
5896 symmetrized[2] = grad[0][1] + grad[1][0];
5897 symmetrized[2] *= half;
5900 symmetrized[3] = grad[0][1] + grad[1][0];
5901 symmetrized[3] *= half;
5902 symmetrized[4] = grad[0][2] + grad[2][0];
5903 symmetrized[4] *= half;
5904 symmetrized[5] = grad[1][2] + grad[2][1];
5905 symmetrized[5] *= half;
5910 return SymmetricTensor<2, dim, VectorizedArrayType>(symmetrized);
5919 typename VectorizedArrayType>
5920template <
int,
typename>
5922 typename FEEvaluationBase<dim,
5926 VectorizedArrayType>::curl_type
5928 get_curl(
const unsigned int q_point)
const
5930 static_assert(dim > 1 && n_components == dim,
5931 "Do not try to modify the default template parameters used for"
5932 " selectively enabling this function via std::enable_if!");
5934 if (dim > 1 && this->data->element_type ==
5942 Assert(this->gradients_quad_initialized ==
true,
5946 Assert(this->jacobian !=
nullptr,
5948 "update_gradients"));
5950 const std::size_t nqp = this->n_quadrature_points;
5951 const std::size_t nqp_d = nqp * dim;
5953 this->gradients_quad + q_point * dim;
5954 if constexpr (dim == 2)
5955 curl = gradients[1 * nqp_d + 0] - gradients[0 * nqp_d + 1];
5956 else if constexpr (dim == 3)
5968 VectorizedArrayType inv_det =
5969 this->jacobian[0][0][0] *
5970 ((dim == 2) ? this->jacobian[0][1][1] :
5971 this->jacobian[0][1][1] * this->jacobian[0][2][2]);
5973 const Tensor<2, dim, VectorizedArrayType> jac = this->jacobian[1];
5976 if constexpr (dim == 2)
5979 for (
unsigned int d = 0;
d < (dim == 2 ? 1 : dim); ++
d)
5980 curl[d] *= jac[d][d] * inv_det;
5985 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
5987 this->jacobian[q_point] :
5989 const Tensor<2, dim, VectorizedArrayType> jac =
5994 VectorizedArrayType inv_det =
determinant(inv_t_jac);
5998 if (is_face && dim == 2 && this->get_face_no() < 2)
6003 if constexpr (dim == 2)
6007 Tensor<1, dim, VectorizedArrayType> curl_temp;
6008 for (
unsigned int comp = 0; comp < dim; ++comp)
6010 curl_temp[comp] = curl[0] * jac[comp][0];
6011 for (
unsigned int e = 1;
e < dim; ++
e)
6012 curl_temp[comp] += jac[comp][e] * curl[e];
6014 for (
unsigned int comp = 0; comp < dim; ++comp)
6015 curl[comp] = curl_temp[comp] * inv_det;
6022 const Tensor<2, dim, VectorizedArrayType> grad = get_gradient(q_point);
6024 if constexpr (dim == 2)
6025 curl = grad[1][0] - grad[0][1];
6026 else if constexpr (dim == 3)
6028 curl[0] = grad[2][1] - grad[1][2];
6029 curl[1] = grad[0][2] - grad[2][0];
6030 curl[2] = grad[1][0] - grad[0][1];
6044 typename VectorizedArrayType>
6045template <
int,
typename>
6049 const unsigned int q_point)
6051 static_assert(n_components == dim,
6052 "Do not try to modify the default template parameters used for"
6053 " selectively enabling this function via std::enable_if!");
6060 Assert(this->J_value !=
nullptr,
6062 "update_gradients"));
6063 Assert(this->jacobian !=
nullptr,
6065 "update_gradients"));
6068 this->gradients_quad_submitted =
true;
6071 const std::size_t nqp_d = this->n_quadrature_points * dim;
6072 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
6074 if (this->data->element_type ==
6081 const VectorizedArrayType fac =
6083 this->quadrature_weights[q_point] * div_in :
6084 (this->cell_type > internal::MatrixFreeFunctions::
affine ?
6085 this->J_value[q_point] :
6086 this->J_value[0] * this->quadrature_weights[q_point]) *
6089 this->jacobian[this->cell_type >
6090 internal::MatrixFreeFunctions::
affine ?
6093 Number((dim == 2 && this->get_face_no() < 2) ? -1 : 1);
6095 for (
unsigned int d = 0;
d < dim; ++
d)
6097 for (
unsigned int e = 0;
e < dim; ++
e)
6098 gradients[d * nqp_d + e] = (d == e) ? fac : 0.;
6100 this->divergence_is_requested =
true;
6107 const VectorizedArrayType fac =
6108 this->J_value[0] * this->quadrature_weights[q_point] * div_in;
6109 for (
unsigned int d = 0;
d < dim; ++
d)
6111 const VectorizedArrayType jac_dd = this->jacobian[0][
d][
d];
6112 for (
unsigned int e = 0;
e < dim; ++
e)
6113 gradients[d * nqp_d + e] = (d == e) ? fac * jac_dd : 0.;
6118 const Tensor<2, dim, VectorizedArrayType> jac =
6120 this->jacobian[q_point] :
6122 const VectorizedArrayType fac =
6124 this->J_value[q_point] :
6125 this->J_value[0] * this->quadrature_weights[q_point]) *
6127 for (
unsigned int d = 0;
d < dim; ++
d)
6129 for (
unsigned int e = 0;
e < dim; ++
e)
6130 gradients[d * nqp_d + e] = jac[d][e] * fac;
6142 typename VectorizedArrayType>
6143template <
int,
typename>
6147 const SymmetricTensor<2, dim, VectorizedArrayType> sym_grad,
6148 const unsigned int q_point)
6150 static_assert(n_components == dim,
6151 "Do not try to modify the default template parameters used for"
6152 " selectively enabling this function via std::enable_if!");
6155 this->data->element_type !=
6167 Assert(this->J_value !=
nullptr,
6169 "update_gradients"));
6170 Assert(this->jacobian !=
nullptr,
6172 "update_gradients"));
6175 this->gradients_quad_submitted =
true;
6178 const std::size_t nqp_d = this->n_quadrature_points * dim;
6179 VectorizedArrayType *
gradients = this->gradients_quad + dim * q_point;
6182 const VectorizedArrayType JxW =
6183 this->J_value[0] * this->quadrature_weights[q_point];
6184 const Tensor<2, dim, VectorizedArrayType> jac = this->jacobian[0];
6185 for (
unsigned int d = 0;
d < dim; ++
d)
6186 gradients[d * nqp_d + d] =
6188 for (
unsigned int e = 0, counter = dim;
e < dim; ++
e)
6189 for (
unsigned int d = e + 1;
d < dim; ++
d, ++counter)
6191 const VectorizedArrayType
value =
6200 const VectorizedArrayType JxW =
6202 this->J_value[q_point] :
6203 this->J_value[0] * this->quadrature_weights[q_point];
6204 const Tensor<2, dim, VectorizedArrayType> jac =
6206 this->jacobian[q_point] :
6208 VectorizedArrayType weighted[dim][dim];
6209 for (
unsigned int i = 0; i < dim; ++i)
6211 for (
unsigned int i = 0, counter = dim; i < dim; ++i)
6212 for (
unsigned int j = i + 1; j < dim; ++j, ++counter)
6214 const VectorizedArrayType
value =
6216 weighted[i][j] =
value;
6217 weighted[j][i] =
value;
6219 for (
unsigned int comp = 0; comp < dim; ++comp)
6220 for (
unsigned int d = 0;
d < dim; ++
d)
6222 VectorizedArrayType new_val = jac[0][
d] * weighted[comp][0];
6223 for (
unsigned int e = 1;
e < dim; ++
e)
6224 new_val += jac[e][d] * weighted[comp][e];
6236 typename VectorizedArrayType>
6237template <
int,
typename>
6241 const typename FEEvaluationBase<dim,
6245 VectorizedArrayType>::curl_type curl,
6246 const unsigned int q_point)
6248 static_assert(n_components == dim,
6249 "Do not try to modify the default template parameters used for"
6250 " selectively enabling this function via std::enable_if!");
6252 Tensor<2, dim, VectorizedArrayType> grad;
6254 if (this->data->element_type ==
6257 curl_type curl_temp;
6261 Assert(this->J_value !=
nullptr,
6266 this->gradients_quad_submitted =
true;
6269 const std::size_t nqp_d = this->n_quadrature_points * dim;
6270 VectorizedArrayType *
gradients = this->gradients_quad + q_point * dim;
6275 const Tensor<2, dim, VectorizedArrayType> jac = this->jacobian[1];
6276 const VectorizedArrayType weight = this->quadrature_weights[q_point];
6278 if constexpr (dim == 2)
6280 curl_temp = curl * weight;
6282 else if constexpr (dim == 3)
6284 for (
unsigned int comp = 0; comp < dim; ++comp)
6286 curl_temp[comp] = curl[comp] * jac[comp][comp] * weight;
6295 const Tensor<2, dim, VectorizedArrayType> inv_t_jac =
6297 this->jacobian[q_point] :
6302 const VectorizedArrayType fac =
6304 this->quadrature_weights[q_point] :
6305 (((this->cell_type > internal::MatrixFreeFunctions::
affine) ?
6306 this->J_value[q_point] :
6307 this->J_value[0] * this->quadrature_weights[q_point]) *
6308 ((dim == 2 && this->get_face_no() < 2) ?
6311 const Tensor<2, dim, VectorizedArrayType> jac =
6316 if constexpr (dim == 2)
6318 curl_temp = curl * fac;
6320 else if constexpr (dim == 3)
6323 for (
unsigned int comp = 0; comp < n_components; ++comp)
6325 curl_temp[comp] = curl[0] * jac[0][comp];
6326 for (
unsigned int e = 1;
e < dim; ++
e)
6327 curl_temp[comp] += curl[e] * jac[e][comp];
6328 curl_temp[comp] *= fac;
6337 grad[1][0] = curl_temp[0];
6338 grad[0][1] = -curl_temp[0];
6343 grad[2][1] = curl_temp[0];
6344 grad[1][2] = -curl_temp[0];
6345 grad[0][2] = curl_temp[1];
6346 grad[2][0] = -curl_temp[1];
6347 grad[1][0] = curl_temp[2];
6348 grad[0][1] = -curl_temp[2];
6356 for (
unsigned int d = 0;
d < dim; ++
d)
6358 for (
unsigned int comp = 0; comp < n_components; ++comp)
6359 gradients[comp * nqp_d + d] = grad[comp][d];
6364 if constexpr (dim == 2)
6369 else if constexpr (dim == 3)
6371 grad[2][1] = curl[0];
6372 grad[1][2] = -curl[0];
6373 grad[0][2] = curl[1];
6374 grad[2][0] = -curl[1];
6375 grad[1][0] = curl[2];
6376 grad[0][1] = -curl[2];
6381 submit_gradient(grad, q_point);
6394 typename VectorizedArrayType>
6395inline FEEvaluation<dim,
6400 VectorizedArrayType>::
6401 FEEvaluation(
const MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
6402 const unsigned int fe_no,
6403 const unsigned int quadrature_index,
6404 const unsigned int first_selected_component,
6405 const unsigned int active_fe_index,
6406 const unsigned int active_quad_index)
6407 : BaseClass(matrix_free,
6409 first_selected_component,
6417 , dofs_per_component(this->data->dofs_per_component_on_cell)
6418 ,
dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6421 check_template_arguments(fe_no, 0);
6431 typename VectorizedArrayType>
6432inline FEEvaluation<dim,
6437 VectorizedArrayType>::
6438 FEEvaluation(
const MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
6439 const std::pair<unsigned int, unsigned int> &range,
6440 const unsigned int dof_handler_index,
6441 const unsigned int quadrature_index,
6442 const unsigned int first_selected_component)
6443 : FEEvaluation(matrix_free,
6446 first_selected_component,
6447 matrix_free.get_cell_active_fe_index(range, dof_handler_index))
6457 typename VectorizedArrayType>
6458inline FEEvaluation<dim,
6463 VectorizedArrayType>::
6464 FEEvaluation(
const Mapping<dim> &
mapping,
6465 const FiniteElement<dim> &fe,
6466 const Quadrature<1> &quadrature,
6468 const unsigned int first_selected_component)
6473 first_selected_component,
6475 , dofs_per_component(this->data->dofs_per_component_on_cell)
6476 ,
dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6489 typename VectorizedArrayType>
6490inline FEEvaluation<dim,
6495 VectorizedArrayType>::
6496 FEEvaluation(
const FiniteElement<dim> &fe,
6497 const Quadrature<1> &quadrature,
6499 const unsigned int first_selected_component)
6500 : BaseClass(StaticMappingQ1<dim>::
mapping,
6504 first_selected_component,
6506 , dofs_per_component(this->data->dofs_per_component_on_cell)
6507 ,
dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6520 typename VectorizedArrayType>
6521inline FEEvaluation<dim,
6526 VectorizedArrayType>::
6527 FEEvaluation(
const FiniteElement<dim> &fe,
6528 const FEEvaluationData<dim, VectorizedArrayType, false> &other,
6529 const unsigned int first_selected_component)
6530 : BaseClass(other.mapped_geometry->get_fe_values().get_mapping(),
6532 other.mapped_geometry->get_quadrature(),
6534 first_selected_component,
6536 , dofs_per_component(this->data->dofs_per_component_on_cell)
6537 ,
dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6550 typename VectorizedArrayType>
6551inline FEEvaluation<dim,
6556 VectorizedArrayType>::FEEvaluation(
const FEEvaluation
6559 , dofs_per_component(this->data->dofs_per_component_on_cell)
6560 ,
dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6573 typename VectorizedArrayType>
6574inline FEEvaluation<dim,
6579 VectorizedArrayType> &
6585 VectorizedArrayType>::operator=(
const FEEvaluation &other)
6587 BaseClass::operator=(other);
6599 typename VectorizedArrayType>
6606 VectorizedArrayType>::
6607 check_template_arguments(
const unsigned int dof_handler_index,
6608 const unsigned int first_selected_component)
6610 (void)dof_handler_index;
6611 (void)first_selected_component;
6614 this->data->dofs_per_component_on_cell > 0,
6616 "There is nothing useful you can do with an FEEvaluation object with "
6617 "FE_Nothing, i.e., without DoFs! If you have passed to "
6618 "MatrixFree::reinit() a collection of finite elements also containing "
6619 "FE_Nothing, please check - before creating FEEvaluation - the category "
6620 "of the current range by calling either "
6621 "MatrixFree::get_cell_range_category(range) or "
6622 "MatrixFree::get_face_range_category(range). The returned category "
6623 "is the index of the active FE, which you can use to exclude "
6630 if ((
static_cast<unsigned int>(fe_degree) !=
6632 static_cast<unsigned int>(fe_degree) !=
6633 this->data->data.front().fe_degree) ||
6636 std::string message =
6637 "-------------------------------------------------------\n";
6639 "Illegal arguments in constructor/wrong template arguments!\n";
6640 message +=
" Called --> FEEvaluation<dim,";
6644 message +=
",Number>(data";
6662 if (
static_cast<unsigned int>(fe_degree) ==
6663 this->data->data.front().fe_degree)
6665 proposed_dof_comp = dof_handler_index;
6666 proposed_fe_comp = first_selected_component;
6669 for (
unsigned int no = 0;
6672 for (
unsigned int nf = 0;
6675 if (this->matrix_free
6676 ->get_shape_info(no, 0, nf, this->active_fe_index, 0)
6678 .fe_degree ==
static_cast<unsigned int>(fe_degree))
6680 proposed_dof_comp = no;
6681 proposed_fe_comp = nf;
6685 this->mapping_data->descriptor[this->active_quad_index]
6687 proposed_quad_comp = this->quadrature_index;
6689 for (
unsigned int no = 0;
6695 .descriptor[this->active_quad_index]
6698 proposed_quad_comp = no;
6705 if (proposed_dof_comp != first_selected_component)
6706 message +=
"Wrong vector component selection:\n";
6708 message +=
"Wrong quadrature formula selection:\n";
6709 message +=
" Did you mean FEEvaluation<dim,";
6713 message +=
",Number>(data";
6723 std::string correct_pos;
6724 if (proposed_dof_comp != dof_handler_index)
6725 correct_pos =
" ^ ";
6728 if (proposed_quad_comp != this->quadrature_index)
6729 correct_pos +=
" ^ ";
6732 if (proposed_fe_comp != first_selected_component)
6733 correct_pos +=
" ^\n";
6735 correct_pos +=
" \n";
6742 const unsigned int proposed_n_q_points_1d =
static_cast<unsigned int>(
6743 std::pow(1.001 * this->n_quadrature_points, 1. / dim));
6744 message +=
"Wrong template arguments:\n";
6745 message +=
" Did you mean FEEvaluation<dim,";
6750 message +=
",Number>(data";
6760 std::string correct_pos;
6761 if (this->data->data.front().fe_degree !=
6762 static_cast<unsigned int>(fe_degree))
6766 if (proposed_n_q_points_1d != n_q_points_1d)
6767 correct_pos +=
" ^\n";
6769 correct_pos +=
" \n";
6770 message +=
" " + correct_pos;
6772 Assert(
static_cast<unsigned int>(fe_degree) ==
6773 this->data->data.front().fe_degree &&
6780 this->mapping_data->descriptor[this->active_quad_index].n_q_points);
6791 typename VectorizedArrayType>
6798 VectorizedArrayType>
::reinit(
const unsigned int cell_index)
6800 Assert(this->matrix_free !=
nullptr,
6801 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
6802 " Integer indexing is not possible."));
6806 this->cell = cell_index;
6810 const unsigned int offsets =
6811 this->mapping_data->data_index_offsets[cell_index];
6812 this->jacobian = &this->mapping_data->jacobians[0][offsets];
6813 this->J_value = &this->mapping_data->JxW_values[offsets];
6814 if (!this->mapping_data->jacobian_gradients[0].empty())
6816 this->jacobian_gradients =
6817 this->mapping_data->jacobian_gradients[0].data() + offsets;
6818 this->jacobian_gradients_non_inverse =
6819 this->mapping_data->jacobian_gradients_non_inverse[0].data() + offsets;
6825 for (
unsigned int i = 0; i < n_lanes; ++i)
6826 this->cell_ids[i] = cell_index * n_lanes + i;
6833 this->cell_ids[i] = cell_index * n_lanes + i;
6834 for (; i < n_lanes; ++i)
6838 if (this->mapping_data->quadrature_points.empty() ==
false)
6840 &this->mapping_data->quadrature_points
6841 [this->mapping_data->quadrature_point_offsets[this->cell]];
6845 this->is_reinitialized =
true;
6846 this->dof_values_initialized =
false;
6847 this->values_quad_initialized =
false;
6848 this->gradients_quad_initialized =
false;
6849 this->hessians_quad_initialized =
false;
6860 typename VectorizedArrayType>
6867 VectorizedArrayType>
::reinit(
const std::array<
unsigned int,
6874 this->cell_ids = cell_ids;
6879 for (
unsigned int v = 0; v < n_lanes; ++v)
6881 const unsigned int cell_index = cell_ids[v];
6889 cell_index / n_lanes));
6893 if (this->mapped_geometry ==
nullptr)
6894 this->mapped_geometry =
6895 std::make_shared<internal::MatrixFreeFunctions::
6896 MappingDataOnTheFly<dim, VectorizedArrayType>>();
6898 auto &mapping_storage = this->mapped_geometry->get_data_storage();
6900 auto &this_jacobian_data = mapping_storage.jacobians[0];
6901 auto &this_J_value_data = mapping_storage.JxW_values;
6902 auto &this_jacobian_gradients_data = mapping_storage.jacobian_gradients[0];
6903 auto &this_jacobian_gradients_non_inverse_data =
6904 mapping_storage.jacobian_gradients_non_inverse[0];
6905 auto &this_quadrature_points_data = mapping_storage.quadrature_points;
6909 if (this_jacobian_data.size() != 2)
6910 this_jacobian_data.resize_fast(2);
6912 if (this_J_value_data.size() != 1)
6913 this_J_value_data.resize_fast(1);
6915 const auto &update_flags_cells =
6919 this_jacobian_gradients_data.size() != 1)
6921 this_jacobian_gradients_data.resize_fast(1);
6922 this_jacobian_gradients_non_inverse_data.resize_fast(1);
6926 this_quadrature_points_data.size() != 1)
6927 this_quadrature_points_data.resize_fast(1);
6931 if (this_jacobian_data.size() != this->n_quadrature_points)
6932 this_jacobian_data.resize_fast(this->n_quadrature_points);
6934 if (this_J_value_data.size() != this->n_quadrature_points)
6935 this_J_value_data.resize_fast(this->n_quadrature_points);
6937 const auto &update_flags_cells =
6941 this_jacobian_gradients_data.size() != this->n_quadrature_points)
6943 this_jacobian_gradients_data.resize_fast(this->n_quadrature_points);
6944 this_jacobian_gradients_non_inverse_data.resize_fast(
6945 this->n_quadrature_points);
6949 this_quadrature_points_data.size() != this->n_quadrature_points)
6950 this_quadrature_points_data.resize_fast(this->n_quadrature_points);
6954 this->jacobian = this_jacobian_data.data();
6955 this->J_value = this_J_value_data.data();
6956 this->jacobian_gradients = this_jacobian_gradients_data.data();
6957 this->jacobian_gradients_non_inverse =
6958 this_jacobian_gradients_non_inverse_data.data();
6962 for (
unsigned int v = 0; v < n_lanes; ++v)
6964 const unsigned int cell_index = cell_ids[v];
6969 const unsigned int cell_batch_index = cell_index / n_lanes;
6970 const unsigned int offsets =
6971 this->mapping_data->data_index_offsets[cell_batch_index];
6972 const unsigned int lane = cell_index % n_lanes;
6974 if (this->cell_type <=
6978 for (
unsigned int q = 0; q < 2; ++q)
6979 for (
unsigned int i = 0; i < dim; ++i)
6980 for (
unsigned int j = 0; j < dim; ++j)
6981 this_jacobian_data[q][i][j][v] =
6982 this->mapping_data->jacobians[0][offsets + q][i][j][lane];
6984 const unsigned int q = 0;
6986 this_J_value_data[q][v] =
6987 this->mapping_data->JxW_values[offsets + q][lane];
6989 const auto &update_flags_cells =
6994 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
6995 for (
unsigned int j = 0; j < dim; ++j)
6996 this_jacobian_gradients_data[q][i][j][v] =
6998 ->jacobian_gradients[0][offsets + q][i][j][lane];
7000 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
7001 for (
unsigned int j = 0; j < dim; ++j)
7002 this_jacobian_gradients_non_inverse_data[q][i][j][v] =
7004 ->jacobian_gradients_non_inverse[0][offsets + q][i][j]
7009 for (
unsigned int i = 0; i < dim; ++i)
7010 this_quadrature_points_data[q][i][v] =
7011 this->mapping_data->quadrature_points
7013 ->quadrature_point_offsets[cell_batch_index] +
7019 const auto cell_type =
7023 for (
unsigned int q = 0; q < this->n_quadrature_points; ++q)
7025 const unsigned int q_src =
7031 this_J_value_data[q][v] =
7032 this->mapping_data->JxW_values[offsets + q_src][lane];
7034 for (
unsigned int i = 0; i < dim; ++i)
7035 for (
unsigned int j = 0; j < dim; ++j)
7036 this_jacobian_data[q][i][j][v] =
7038 ->jacobians[0][offsets + q_src][i][j][lane];
7040 const auto &update_flags_cells =
7045 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
7046 for (
unsigned int j = 0; j < dim; ++j)
7047 this_jacobian_gradients_data[q][i][j][v] =
7049 ->jacobian_gradients[0][offsets + q_src][i][j][lane];
7051 for (
unsigned int i = 0; i < dim * (dim + 1) / 2; ++i)
7052 for (
unsigned int j = 0; j < dim; ++j)
7053 this_jacobian_gradients_non_inverse_data[q][i][j][v] =
7055 ->jacobian_gradients_non_inverse[0][offsets + q_src]
7067 Point<dim, VectorizedArrayType>
point =
7068 this->mapping_data->quadrature_points
7070 ->quadrature_point_offsets[cell_batch_index] +
7073 const Tensor<2, dim, VectorizedArrayType> &jac =
7074 this->mapping_data->jacobians[0][offsets + 1];
7076 for (
unsigned int d = 0;
d < dim; ++
d)
7080 this->descriptor->quadrature.point(q)[d]);
7082 for (
unsigned int d = 0;
d < dim; ++
d)
7083 for (
unsigned int e = 0;
e < dim; ++
e)
7087 this->descriptor->quadrature.point(q)[e]);
7089 for (
unsigned int i = 0; i < dim; ++i)
7090 this_quadrature_points_data[q][i][v] = point[i][lane];
7095 for (
unsigned int i = 0; i < dim; ++i)
7096 this_quadrature_points_data[q][i][v] =
7097 this->mapping_data->quadrature_points
7099 ->quadrature_point_offsets[cell_batch_index] +
7109 this->is_reinitialized =
true;
7110 this->dof_values_initialized =
false;
7111 this->values_quad_initialized =
false;
7112 this->gradients_quad_initialized =
false;
7113 this->hessians_quad_initialized =
false;
7124 typename VectorizedArrayType>
7125template <
bool level_dof_access>
7132 VectorizedArrayType>
::
7133 reinit(
const TriaIterator<DoFCellAccessor<dim, dim, level_dof_access>> &cell)
7135 Assert(this->matrix_free ==
nullptr,
7136 ExcMessage(
"Cannot use initialization from cell iterator if "
7137 "initialized from MatrixFree object. Use variant for "
7138 "on the fly computation with arguments as for FEValues "
7141 this->mapped_geometry->reinit(
7143 this->local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
7144 if (level_dof_access)
7145 cell->get_mg_dof_indices(this->local_dof_indices);
7147 cell->get_dof_indices(this->local_dof_indices);
7151 this->is_reinitialized =
true;
7162 typename VectorizedArrayType>
7169 VectorizedArrayType>
::
7172 Assert(this->matrix_free == 0,
7173 ExcMessage(
"Cannot use initialization from cell iterator if "
7174 "initialized from MatrixFree object. Use variant for "
7175 "on the fly computation with arguments as for FEValues "
7178 this->mapped_geometry->reinit(cell);
7182 this->is_reinitialized =
true;
7193 typename VectorizedArrayType>
7200 VectorizedArrayType>::
7205 Assert(this->dof_values_initialized ==
true,
7208 evaluate(this->values_dofs, evaluation_flags);
7218 typename VectorizedArrayType>
7225 VectorizedArrayType>::
7226 evaluate(
const VectorizedArrayType *values_array,
7229 const bool hessians_on_general_cells =
7233 if (hessians_on_general_cells)
7236 if (this->data->element_type ==
7242 if constexpr (fe_degree > -1)
7244 internal::FEEvaluationImplSelector<dim, VectorizedArrayType, false>::
7245 template run<fe_degree, n_q_points_1d>(n_components,
7246 evaluation_flag_actual,
7254 evaluation_flag_actual,
7255 const_cast<VectorizedArrayType *
>(values_array),
7261 this->values_quad_initialized =
7263 this->gradients_quad_initialized =
7265 this->hessians_quad_initialized =
7276 template <
typename Number,
7277 typename VectorizedArrayType,
7279 typename EvaluatorType,
7280 std::enable_if_t<internal::has_begin<VectorType> &&
7283 VectorizedArrayType *
7284 check_vector_access_inplace(
const EvaluatorType &fe_eval, VectorType &vector)
7290 const unsigned int cell = fe_eval.get_cell_or_face_batch_id();
7291 const auto &dof_info = fe_eval.get_dof_info();
7298 if (std::is_same_v<typename VectorType::value_type, Number> &&
7302 interleaved_contiguous &&
7303 reinterpret_cast<std::size_t
>(
7307 [cell * VectorizedArrayType::size()]) %
7308 sizeof(VectorizedArrayType) ==
7311 return reinterpret_cast<VectorizedArrayType *
>(
7315 [cell * VectorizedArrayType::size()] +
7317 [fe_eval.get_active_fe_index()]
7318 [fe_eval.get_first_selected_component()] *
7319 VectorizedArrayType::size());
7328 template <
typename Number,
7329 typename VectorizedArrayType,
7331 typename EvaluatorType,
7332 std::enable_if_t<!internal::has_begin<VectorType> ||
7335 VectorizedArrayType *
7336 check_vector_access_inplace(
const EvaluatorType &, VectorType &)
7349 typename VectorizedArrayType>
7350template <
typename VectorType>
7357 VectorizedArrayType>::
7358 gather_evaluate(
const VectorType &input_vector,
7361 const VectorizedArrayType *src_ptr =
7362 internal::check_vector_access_inplace<Number, const VectorizedArrayType>(
7363 *
this, input_vector);
7364 if (src_ptr !=
nullptr)
7365 evaluate(src_ptr, evaluation_flag);
7368 this->read_dof_values(input_vector);
7369 evaluate(this->begin_dof_values(), evaluation_flag);
7380 typename VectorizedArrayType>
7387 VectorizedArrayType>::
7390 integrate(integration_flag, this->values_dofs);
7394 this->dof_values_initialized =
true;
7405 typename VectorizedArrayType>
7412 VectorizedArrayType>::
7414 VectorizedArrayType *values_array,
7415 const bool sum_into_values_array)
7420 Assert(this->values_quad_submitted ==
true,
7423 Assert(this->gradients_quad_submitted ==
true,
7426 Assert(this->hessians_quad_submitted ==
true,
7429 Assert(this->matrix_free !=
nullptr ||
7430 this->mapped_geometry->is_initialized(),
7436 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, and "
7437 "EvaluationFlags::hessians are supported."));
7443 unsigned int size = n_components * dim *
n_q_points;
7446 for (
unsigned int i = 0; i < size; ++i)
7447 this->gradients_quad[i] += this->gradients_from_hessians_quad[i];
7451 for (
unsigned int i = 0; i < size; ++i)
7452 this->gradients_quad[i] = this->gradients_from_hessians_quad[i];
7457 if (n_components == dim &&
7458 this->data->element_type ==
7462 this->divergence_is_requested ==
false)
7464 unsigned int size = n_components *
n_q_points;
7467 for (
unsigned int i = 0; i < size; ++i)
7468 this->values_quad[i] += this->values_from_gradients_quad[i];
7472 for (
unsigned int i = 0; i < size; ++i)
7473 this->values_quad[i] = this->values_from_gradients_quad[i];
7478 if constexpr (fe_degree > -1)
7480 internal::FEEvaluationImplSelector<dim, VectorizedArrayType, true>::
7481 template run<fe_degree, n_q_points_1d>(n_components,
7482 integration_flag_actual,
7485 sum_into_values_array);
7491 integration_flag_actual,
7494 sum_into_values_array);
7499 this->dof_values_initialized =
true;
7510 typename VectorizedArrayType>
7511template <
typename VectorType>
7518 VectorizedArrayType>::
7520 VectorType &destination)
7522 VectorizedArrayType *dst_ptr =
7523 internal::check_vector_access_inplace<Number, VectorizedArrayType>(
7524 *
this, destination);
7525 if (dst_ptr !=
nullptr)
7526 integrate(integration_flag, dst_ptr,
true);
7529 integrate(integration_flag, this->begin_dof_values());
7530 this->distribute_local_to_global(destination);
7541 typename VectorizedArrayType>
7542inline std_cxx20::ranges::iota_view<unsigned int, unsigned int>
7548 VectorizedArrayType>::dof_indices()
const
7550 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(
7565 typename VectorizedArrayType>
7566inline FEFaceEvaluation<dim,
7571 VectorizedArrayType>::
7573 const MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
7574 const bool is_interior_face,
7575 const unsigned int dof_handler_index,
7576 const unsigned int quadrature_index,
7577 const unsigned int first_selected_component,
7578 const unsigned int active_fe_index,
7579 const unsigned int active_quad_index,
7580 const unsigned int face_type)
7581 : BaseClass(matrix_free,
7583 first_selected_component,
7591 , dofs_per_component(this->data->dofs_per_component_on_cell)
7592 ,
dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
7603 typename VectorizedArrayType>
7604inline FEFaceEvaluation<dim,
7609 VectorizedArrayType>::
7611 const MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
7612 const std::pair<unsigned int, unsigned int> &range,
7613 const bool is_interior_face,
7614 const unsigned int dof_handler_index,
7615 const unsigned int quadrature_index,
7616 const unsigned int first_selected_component)
7617 : FEFaceEvaluation(matrix_free,
7621 first_selected_component,
7622 matrix_free.get_face_active_fe_index(range,
7625 matrix_free.get_face_info(range.first).face_type)
7635 typename VectorizedArrayType>
7637FEFaceEvaluation<dim,
7642 VectorizedArrayType>
::reinit(
const unsigned int face_index)
7644 Assert(this->mapped_geometry ==
nullptr,
7645 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
7646 " Integer indexing is not possible"));
7647 if (this->mapped_geometry !=
nullptr)
7650 this->cell = face_index;
7651 this->dof_access_index =
7652 this->is_interior_face() ?
7660 this->matrix_free->get_task_info().boundary_partition_data.back())
7661 Assert(this->is_interior_face(),
7663 "Boundary faces do not have a neighbor. When looping over "
7664 "boundary faces use FEFaceEvaluation with the parameter "
7665 "is_interior_face set to true. "));
7667 this->reinit_face(this->matrix_free->
get_face_info(face_index));
7672 this->face_ids[i] = face_index * n_lanes + i;
7673 for (; i < n_lanes; ++i)
7676 this->cell_type = this->matrix_free->
get_mapping_info().face_type[face_index];
7677 const unsigned int offsets =
7678 this->mapping_data->data_index_offsets[face_index];
7679 this->J_value = &this->mapping_data->JxW_values[offsets];
7680 this->normal_vectors = &this->mapping_data->normal_vectors[offsets];
7682 &this->mapping_data->jacobians[!this->is_interior_face()][offsets];
7683 this->normal_x_jacobian =
7685 ->normals_times_jacobians[!this->is_interior_face()][offsets];
7686 this->jacobian_gradients =
7687 this->mapping_data->jacobian_gradients[!this->is_interior_face()].data() +
7689 this->jacobian_gradients_non_inverse =
7691 ->jacobian_gradients_non_inverse[!this->is_interior_face()]
7695 if (this->mapping_data->quadrature_point_offsets.empty() ==
false)
7698 this->mapping_data->quadrature_point_offsets.size());
7700 this->mapping_data->quadrature_points.data() +
7701 this->mapping_data->quadrature_point_offsets[this->cell];
7706 this->is_reinitialized =
true;
7707 this->dof_values_initialized =
false;
7708 this->values_quad_initialized =
false;
7709 this->gradients_quad_initialized =
false;
7710 this->hessians_quad_initialized =
false;
7721 typename VectorizedArrayType>
7723FEFaceEvaluation<dim,
7728 VectorizedArrayType>
::reinit(
const unsigned int cell_index,
7729 const unsigned int face_number)
7732 this->quadrature_index <
7735 "You must set MatrixFree::AdditionalData::mapping_update_flags_faces_by_cells to use the present reinit method."));
7739 Assert(this->mapped_geometry ==
nullptr,
7740 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
7741 " Integer indexing is not possible"));
7742 if (this->mapped_geometry !=
nullptr)
7747 .faces_by_cells_type[cell_index][face_number];
7748 this->cell = cell_index;
7750 this->dof_access_index =
7753 if (this->is_interior_face() ==
false)
7758 for (
unsigned int i = 0; i < n_lanes; ++i)
7761 const unsigned int cell_this = cell_index * n_lanes + i;
7763 unsigned int face_index =
7768 this->face_ids[i] = face_index;
7773 this->face_numbers[i] =
static_cast<std::uint8_t
>(-1);
7774 this->face_orientations[i] =
7782 auto cell_m = faces.cells_interior[face_index % n_lanes];
7783 auto cell_p = faces.cells_exterior[face_index % n_lanes];
7785 const bool face_identifies_as_interior = cell_m != cell_this;
7787 Assert(cell_m == cell_this || cell_p == cell_this,
7791 if (face_identifies_as_interior)
7793 this->cell_ids[i] = cell_m;
7794 this->face_numbers[i] = faces.interior_face_no;
7798 this->cell_ids[i] = cell_p;
7799 this->face_numbers[i] = faces.exterior_face_no;
7802 const bool orientation_interior_face = faces.face_orientation >= 8;
7804 faces.face_orientation % 8;
7805 if (face_identifies_as_interior != orientation_interior_face)
7808 ->reference_cell() ==
7813 .get_inverse_combined_orientation(face_orientation);
7815 this->face_orientations[i] = face_orientation;
7821 this->face_numbers[0] = face_number;
7826 for (
unsigned int i = 0; i < n_lanes; ++i)
7827 this->cell_ids[i] = cell_index * n_lanes + i;
7835 this->cell_ids[i] = cell_index * n_lanes + i;
7836 for (; i < n_lanes; ++i)
7839 for (
unsigned int i = 0; i < n_lanes; ++i)
7846 const unsigned int offsets =
7848 .face_data_by_cells[this->quadrature_index]
7853 .face_data_by_cells[this->quadrature_index]
7854 .JxW_values.size());
7856 .face_data_by_cells[this->quadrature_index]
7857 .JxW_values[offsets];
7859 .face_data_by_cells[this->quadrature_index]
7860 .normal_vectors[offsets];
7862 .face_data_by_cells[this->quadrature_index]
7863 .jacobians[!this->is_interior_face()][offsets];
7864 this->normal_x_jacobian =
7866 .face_data_by_cells[this->quadrature_index]
7867 .normals_times_jacobians[!this->is_interior_face()][offsets];
7868 this->jacobian_gradients =
7869 this->mapping_data->jacobian_gradients[!this->is_interior_face()].data() +
7871 this->jacobian_gradients_non_inverse =
7873 ->jacobian_gradients_non_inverse[!this->is_interior_face()]
7878 .face_data_by_cells[this->quadrature_index]
7879 .quadrature_point_offsets.empty() ==
false)
7881 const unsigned int index =
7885 .face_data_by_cells[this->quadrature_index]
7886 .quadrature_point_offsets.size());
7888 .face_data_by_cells[this->quadrature_index]
7889 .quadrature_points.data() +
7891 .face_data_by_cells[this->quadrature_index]
7892 .quadrature_point_offsets[
index];
7897 this->is_reinitialized =
true;
7898 this->dof_values_initialized =
false;
7899 this->values_quad_initialized =
false;
7900 this->gradients_quad_initialized =
false;
7901 this->hessians_quad_initialized =
false;
7912 typename VectorizedArrayType>
7914FEFaceEvaluation<dim,
7919 VectorizedArrayType>::
7927 evaluate(this->values_dofs, evaluation_flag);
7937 typename VectorizedArrayType>
7939FEFaceEvaluation<dim,
7944 VectorizedArrayType>::
7945 evaluate(
const VectorizedArrayType *values_array,
7948 Assert((evaluation_flag &
7951 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
7952 "and EvaluationFlags::hessians are supported."));
7954 const bool hessians_on_general_cells =
7958 if (hessians_on_general_cells)
7961 if (this->data->element_type ==
7967 if constexpr (fe_degree > -1)
7968 internal::FEFaceEvaluationImplEvaluateSelector<dim, VectorizedArrayType>::
7969 template
run<fe_degree, n_q_points_1d>(n_components,
7970 evaluation_flag_actual,
7975 n_components, evaluation_flag_actual, values_array, *
this);
7979 this->values_quad_initialized =
7981 this->gradients_quad_initialized =
7983 this->hessians_quad_initialized =
7995 typename VectorizedArrayType>
7997FEFaceEvaluation<dim,
8002 VectorizedArrayType>::
8010 project_to_face(this->values_dofs, evaluation_flag);
8020 typename VectorizedArrayType>
8022FEFaceEvaluation<dim,
8027 VectorizedArrayType>::
8028 project_to_face(
const VectorizedArrayType *values_array,
8031 Assert((evaluation_flag &
8034 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
8035 "and EvaluationFlags::hessians are supported."));
8037 const bool hessians_on_general_cells =
8041 if (hessians_on_general_cells)
8044 if (this->data->element_type ==
8050 if constexpr (fe_degree > -1)
8051 internal::FEFaceEvaluationImplProjectToFaceSelector<
8053 VectorizedArrayType>::template run<fe_degree>(n_components,
8054 evaluation_flag_actual,
8060 evaluation_flag_actual,
8074 typename VectorizedArrayType>
8076FEFaceEvaluation<dim,
8081 VectorizedArrayType>::
8084 Assert((evaluation_flag &
8087 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
8088 "and EvaluationFlags::hessians are supported."));
8090 const bool hessians_on_general_cells =
8094 if (hessians_on_general_cells)
8097 if (this->data->element_type ==
8103 if constexpr (fe_degree > -1)
8104 internal::FEFaceEvaluationImplEvaluateInFaceSelector<
8106 VectorizedArrayType>::template run<fe_degree>(n_components,
8107 evaluation_flag_actual,
8115 this->values_quad_initialized =
8117 this->gradients_quad_initialized =
8119 this->hessians_quad_initialized =
8131 typename VectorizedArrayType>
8133FEFaceEvaluation<dim,
8138 VectorizedArrayType>::
8140 const bool sum_into_values)
8142 integrate(integration_flag, this->values_dofs, sum_into_values);
8146 this->dof_values_initialized =
true;
8157 typename VectorizedArrayType>
8159FEFaceEvaluation<dim,
8164 VectorizedArrayType>::
8166 VectorizedArrayType *values_array,
8167 const bool sum_into_values)
8169 Assert((integration_flag &
8172 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
8173 "and EvaluationFlags::hessians are supported."));
8179 unsigned int size = n_components * dim *
n_q_points;
8182 for (
unsigned int i = 0; i < size; ++i)
8183 this->gradients_quad[i] += this->gradients_from_hessians_quad[i];
8187 for (
unsigned int i = 0; i < size; ++i)
8188 this->gradients_quad[i] = this->gradients_from_hessians_quad[i];
8193 if (this->data->element_type ==
8197 this->divergence_is_requested ==
false)
8199 unsigned int size = n_components *
n_q_points;
8202 for (
unsigned int i = 0; i < size; ++i)
8203 this->values_quad[i] += this->values_from_gradients_quad[i];
8207 for (
unsigned int i = 0; i < size; ++i)
8208 this->values_quad[i] = this->values_from_gradients_quad[i];
8213 if constexpr (fe_degree > -1)
8214 internal::FEFaceEvaluationImplIntegrateSelector<dim, VectorizedArrayType>::
8215 template
run<fe_degree, n_q_points_1d>(n_components,
8216 integration_flag_actual,
8223 integration_flag_actual,
8236 typename VectorizedArrayType>
8238FEFaceEvaluation<dim,
8243 VectorizedArrayType>::
8246 Assert((integration_flag &
8249 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
8250 "and EvaluationFlags::hessians are supported."));
8256 unsigned int size = n_components * dim *
n_q_points;
8259 for (
unsigned int i = 0; i < size; ++i)
8260 this->gradients_quad[i] += this->gradients_from_hessians_quad[i];
8264 for (
unsigned int i = 0; i < size; ++i)
8265 this->gradients_quad[i] = this->gradients_from_hessians_quad[i];
8270 if (this->data->element_type ==
8274 this->divergence_is_requested ==
false)
8276 unsigned int size = n_components *
n_q_points;
8279 for (
unsigned int i = 0; i < size; ++i)
8280 this->values_quad[i] += this->values_from_gradients_quad[i];
8284 for (
unsigned int i = 0; i < size; ++i)
8285 this->values_quad[i] = this->values_from_gradients_quad[i];
8290 if constexpr (fe_degree > -1)
8291 internal::FEFaceEvaluationImplIntegrateInFaceSelector<
8293 VectorizedArrayType>::template run<fe_degree>(n_components,
8294 integration_flag_actual,
8310 typename VectorizedArrayType>
8312FEFaceEvaluation<dim,
8317 VectorizedArrayType>::
8319 const bool sum_into_values)
8321 collect_from_face(integration_flag, this->values_dofs, sum_into_values);
8325 this->dof_values_initialized =
true;
8336 typename VectorizedArrayType>
8338FEFaceEvaluation<dim,
8343 VectorizedArrayType>::
8345 VectorizedArrayType *values_array,
8346 const bool sum_into_values)
8348 Assert((integration_flag &
8351 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
8352 "and EvaluationFlags::hessians are supported."));
8359 if (this->data->element_type ==
8363 this->divergence_is_requested ==
false)
8366 if constexpr (fe_degree > -1)
8367 internal::FEFaceEvaluationImplCollectFromFaceSelector<
8369 VectorizedArrayType>::template run<fe_degree>(n_components,
8370 integration_flag_actual,
8377 integration_flag_actual,
8390 typename VectorizedArrayType>
8391template <
typename VectorType>
8393FEFaceEvaluation<dim,
8398 VectorizedArrayType>::
8399 gather_evaluate(
const VectorType &input_vector,
8402 Assert((evaluation_flag &
8405 ExcMessage(
"Only EvaluationFlags::values, EvaluationFlags::gradients, "
8406 "and EvaluationFlags::hessians are supported."));
8408 const auto shared_vector_data = internal::get_shared_vector_data(
8410 this->dof_access_index ==
8412 this->active_fe_index,
8415 if (this->data->data.front().fe_degree > 0 &&
8416 fast_evaluation_supported(this->data->data.front().fe_degree,
8417 this->data->data.front().n_q_points_1d) &&
8418 internal::FEFaceEvaluationImplGatherEvaluateSelector<
8420 typename VectorType::value_type,
8421 VectorizedArrayType>::
8422 supports(evaluation_flag,
8424 internal::get_beginning<typename VectorType::value_type>(
8429 if constexpr (fe_degree > -1)
8431 internal::FEFaceEvaluationImplGatherEvaluateSelector<
8433 typename VectorType::value_type,
8434 VectorizedArrayType>::template
run<fe_degree,
8438 internal::get_beginning<typename VectorType::value_type>(
8445 internal::FEFaceEvaluationGatherFactory<
8447 typename VectorType::value_type,
8448 VectorizedArrayType>::evaluate(n_components,
8450 internal::get_beginning<
8451 typename VectorType::value_type>(
8459 this->read_dof_values(input_vector);
8460 this->evaluate(evaluation_flag);
8466 this->gradients_quad_initialized =
8468 this->hessians_quad_initialized =
8480 typename VectorizedArrayType>
8481template <
typename VectorType>
8489 VectorizedArrayType>::integrate_scatter(
const bool integrate_values,
8490 const bool integrate_gradients,
8491 VectorType &destination)
8498 integrate_scatter(flag, destination);
8508 typename VectorizedArrayType>
8509template <
typename VectorType>
8511FEFaceEvaluation<dim,
8516 VectorizedArrayType>::
8518 VectorType &destination)
8520 Assert((this->dof_access_index ==
8522 this->is_interior_face() ==
false) ==
false,
8525 const auto shared_vector_data = internal::get_shared_vector_data(
8527 this->dof_access_index ==
8529 this->active_fe_index,
8532 if (this->data->data.front().fe_degree > 0 &&
8533 fast_evaluation_supported(this->data->data.front().fe_degree,
8534 this->data->data.front().n_q_points_1d) &&
8535 internal::FEFaceEvaluationImplGatherEvaluateSelector<
8537 typename VectorType::value_type,
8538 VectorizedArrayType>::
8539 supports(integration_flag,
8541 internal::get_beginning<typename VectorType::value_type>(
8546 if constexpr (fe_degree > -1)
8548 internal::FEFaceEvaluationImplIntegrateScatterSelector<
8550 typename VectorType::value_type,
8551 VectorizedArrayType>::template
run<fe_degree,
8555 internal::get_beginning<typename VectorType::value_type>(
8562 internal::FEFaceEvaluationGatherFactory<
8564 typename VectorType::value_type,
8565 VectorizedArrayType>::integrate(n_components,
8567 internal::get_beginning<
8568 typename VectorType::value_type>(
8576 integrate(integration_flag);
8577 this->distribute_local_to_global(destination);
8588 typename VectorizedArrayType>
8589inline std_cxx20::ranges::iota_view<unsigned int, unsigned int>
8590FEFaceEvaluation<dim,
8595 VectorizedArrayType>::dof_indices()
const
8597 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(
8608 typename VectorizedArrayType>
8615 VectorizedArrayType>::
8616 fast_evaluation_supported(
const unsigned int given_degree,
8617 const unsigned int given_n_q_points_1d)
8619 return fe_degree == -1 ?
8632 typename VectorizedArrayType>
8634FEFaceEvaluation<dim,
8639 VectorizedArrayType>::
8640 fast_evaluation_supported(
const unsigned int given_degree,
8641 const unsigned int given_n_q_points_1d)
8643 return fe_degree == -1 ?
8656 typename VectorizedArrayType>
8658FEFaceEvaluation<dim,
8663 VectorizedArrayType>::at_boundary()
const
8665 Assert(this->dof_access_index !=
8669 if (this->is_interior_face() ==
false)
8674 this->matrix_free->n_boundary_face_batches()))
8687 typename VectorizedArrayType>
8689FEFaceEvaluation<dim,
8694 VectorizedArrayType>::boundary_id()
const
8696 Assert(this->dof_access_index !=
8713 typename VectorizedArrayType>
8721 VectorizedArrayType>::get_dofs_per_component_projected_to_face()
8723 return this->data->dofs_per_component_on_face;
8733 typename VectorizedArrayType>
8735FEFaceEvaluation<dim,
8740 VectorizedArrayType>::get_dofs_projected_to_face()
8742 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)
void submit_normal_hessian(const value_type normal_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
internal::CurlType< dim, VectorizedArrayType > curl_type
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_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
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
FEEvaluationBase(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const unsigned int dof_handler_index, const unsigned int first_selected_component, const unsigned int quadrature_index, 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 read_dof_values_plain(const VectorType &src, const unsigned int first_index=0, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
curl_type get_curl(const unsigned int q_point) const
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)
void submit_curl(const curl_type curl_in, const unsigned int q_point)
FEEvaluationBase & operator=(const FEEvaluationBase &other)
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
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
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)
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
std::conditional_t< n_components_==1, VectorizedArrayType, Tensor< 1, n_components_, VectorizedArrayType > > value_type
value_type get_normal_hessian(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 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
const unsigned int quadrature_index
bool is_interior_face() const
FEEvaluationData & operator=(const FEEvaluationData &other)
FEEvaluationData(const ShapeInfoType &shape_info, const bool is_interior_face=true)
const unsigned int first_selected_component
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)
FEEvaluationBase< dim, n_components_, Number, false, VectorizedArrayType > BaseClass
void evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag)
FEEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const unsigned int dof_handler_index=0, const unsigned int quadrature_index=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 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)
FEEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const std::pair< unsigned int, unsigned int > &range, const unsigned int dof_handler_index=0, const unsigned int quadrature_index=0, const unsigned int first_selected_component=0)
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
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)
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_handler_index=0, const unsigned int quadrature_index=0, const unsigned int first_selected_component=0)
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
FEFaceEvaluation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const bool is_interior_face=true, const unsigned int dof_handler_index=0, const unsigned int quadrature_index=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)
void evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag)
FEEvaluationBase< dim, n_components_, Number, true, VectorizedArrayType > BaseClass
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()
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 internal::MatrixFreeFunctions::MappingInfo< dim, Number, VectorizedArrayType > & get_mapping_info() const
const Number * constraint_pool_begin(const unsigned int pool_index) const
void release_scratch_data(const AlignedVector< VectorizedArrayType > *memory) const
DoFHandler< dim >::cell_iterator get_cell_iterator(const unsigned int cell_batch_index, const unsigned int lane_index, const unsigned int dof_handler_index=0) 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
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_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
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)
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
const bool IsBlockVector< VectorType >::value
@ update_jacobian_grads
Gradient of volume element.
@ update_quadrature_points
Transformed quadrature points.
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
EvaluationFlags
The EvaluationFlags enum.
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
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< 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)
* * * ScaleZFunction< dim, Number, components >::ScaleZFunction * component(component)
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
* * * * * * TimeRateUpdateFlags TimeRateRequest< ValueType, dim, Number > get_update_flags() const
* * * * std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters const
constexpr const ReferenceCell< dim > & get_hypercube()
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)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
void check_vector_compatibility(const VectorType &vec, const MatrixFree< dim, Number, VectorizedArrayType > &, const internal::MatrixFreeFunctions::DoFInfo &dof_info)
std::conditional_t< dim==3, Tensor< 1, 3, NumberType >, std::conditional_t< dim==2, NumberType, std::monostate > > CurlType
constexpr types::geometric_orientation invalid_geometric_orientation
constexpr unsigned int invalid_unsigned_int
constexpr types::boundary_id internal_face_boundary_id
constexpr types::geometric_orientation default_geometric_orientation
::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)
std::uint8_t geometric_orientation
* const unsigned int dofs_per_cell
* const unsigned int n_q_points
static constexpr unsigned int faces_per_cell
static constexpr unsigned int max_children_per_cell
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
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
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
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)