17 #ifndef dealii_matrix_free_fe_evaluation_h 18 #define dealii_matrix_free_fe_evaluation_h 21 #include <deal.II/base/config.h> 23 #include <deal.II/base/array_view.h> 24 #include <deal.II/base/exceptions.h> 25 #include <deal.II/base/smartpointer.h> 27 #include <deal.II/base/template_constraints.h> 28 #include <deal.II/base/vectorization.h> 30 #include <deal.II/lac/vector_operation.h> 32 #include <deal.II/matrix_free/evaluation_kernels.h> 33 #include <deal.II/matrix_free/evaluation_selector.h> 34 #include <deal.II/matrix_free/mapping_data_on_the_fly.h> 35 #include <deal.II/matrix_free/matrix_free.h> 36 #include <deal.II/matrix_free/shape_info.h> 37 #include <deal.II/matrix_free/tensor_product_kernels.h> 39 DEAL_II_NAMESPACE_OPEN
59 int n_q_points_1d = fe_degree + 1,
60 int n_components_ = 1,
61 typename Number =
double>
90 template <
int dim,
int n_components_,
typename Number,
bool is_face = false>
94 using number_type = Number;
98 static constexpr
unsigned int dimension = dim;
99 static constexpr
unsigned int n_components = n_components_;
115 get_cell_data_number()
const;
126 get_mapping_data_index_offset()
const;
135 get_cell_type()
const;
141 get_shape_info()
const;
181 template <
typename VectorType>
183 read_dof_values(
const VectorType &src,
const unsigned int first_index = 0);
213 template <
typename VectorType>
215 read_dof_values_plain(
const VectorType & src,
216 const unsigned int first_index = 0);
241 template <
typename VectorType>
243 distribute_local_to_global(VectorType & dst,
244 const unsigned int first_index = 0)
const;
272 template <
typename VectorType>
274 set_dof_values(VectorType &dst,
const unsigned int first_index = 0)
const;
299 get_dof_value(
const unsigned int dof)
const;
312 submit_dof_value(
const value_type val_in,
const unsigned int dof);
326 get_value(
const unsigned int q_point)
const;
340 submit_value(
const value_type val_in,
const unsigned int q_point);
352 get_gradient(
const unsigned int q_point)
const;
368 get_normal_derivative(
const unsigned int q_point)
const;
383 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
403 submit_normal_derivative(
const value_type grad_in,
404 const unsigned int q_point);
417 get_hessian(
const unsigned int q_point)
const;
428 get_hessian_diagonal(
const unsigned int q_point)
const;
441 get_laplacian(
const unsigned int q_point)
const;
452 get_divergence(
const unsigned int q_point)
const;
458 get_symmetric_gradient(
const unsigned int q_point)
const;
464 get_curl(
const unsigned int q_point)
const;
476 const unsigned int q_point);
488 submit_symmetric_gradient(
490 const unsigned int q_point);
504 const unsigned int q_point);
525 integrate_value()
const;
532 JxW(
const unsigned int q_index)
const;
547 inverse_jacobian(
const unsigned int q_index)
const;
562 get_normal_vector(
const unsigned int q_point)
const;
588 begin_dof_values()
const;
612 begin_values()
const;
639 begin_gradients()
const;
668 begin_hessians()
const;
690 const std::vector<unsigned int> &
691 get_internal_dof_numbering()
const;
700 get_scratch_data()
const;
714 const unsigned int dof_no,
715 const unsigned int first_selected_component,
716 const unsigned int quad_no,
717 const unsigned int fe_degree,
718 const unsigned int n_q_points,
719 const bool is_interior_face);
755 template <
int n_components_other>
761 const unsigned int first_selected_component,
770 FEEvaluationBase(
const FEEvaluationBase &other);
779 operator=(
const FEEvaluationBase &other);
787 template <
typename VectorType,
typename VectorOperation>
790 VectorType * vectors[],
791 const bool apply_constraints =
true)
const;
800 template <
typename VectorType,
typename VectorOperation>
803 VectorType * vectors[])
const;
812 template <
typename VectorType,
typename VectorOperation>
815 VectorType * vectors[])
const;
1085 set_data_pointers();
1090 template <
int,
int,
typename,
bool>
1092 template <
int,
int,
int,
int,
typename>
1107 template <
int dim,
int n_components_,
typename Number,
bool is_face>
1112 using number_type = Number;
1116 static constexpr
unsigned int dimension = dim;
1117 static constexpr
unsigned int n_components = n_components_;
1129 const unsigned int dof_no,
1130 const unsigned int first_selected_component,
1131 const unsigned int quad_no,
1132 const unsigned int fe_degree,
1133 const unsigned int n_q_points,
1134 const bool is_interior_face =
true);
1140 template <
int n_components_other>
1146 const unsigned int first_selected_component,
1152 FEEvaluationAccess(
const FEEvaluationAccess &other);
1157 FEEvaluationAccess &
1158 operator=(
const FEEvaluationAccess &other);
1173 template <
int dim,
typename Number,
bool is_face>
1178 using number_type = Number;
1181 static constexpr
unsigned int dimension = dim;
1187 get_dof_value(
const unsigned int dof)
const;
1192 submit_dof_value(
const value_type val_in,
const unsigned int dof);
1197 get_value(
const unsigned int q_point)
const;
1202 submit_value(
const value_type val_in,
const unsigned int q_point);
1208 const unsigned int q_point);
1213 get_gradient(
const unsigned int q_point)
const;
1218 get_normal_derivative(
const unsigned int q_point)
const;
1223 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
1228 submit_normal_derivative(
const value_type grad_in,
1229 const unsigned int q_point);
1234 get_hessian(
unsigned int q_point)
const;
1239 get_hessian_diagonal(
const unsigned int q_point)
const;
1244 get_laplacian(
const unsigned int q_point)
const;
1249 integrate_value()
const;
1260 const unsigned int dof_no,
1261 const unsigned int first_selected_component,
1262 const unsigned int quad_no,
1263 const unsigned int fe_degree,
1264 const unsigned int n_q_points,
1265 const bool is_interior_face =
true);
1271 template <
int n_components_other>
1277 const unsigned int first_selected_component,
1283 FEEvaluationAccess(
const FEEvaluationAccess &other);
1288 FEEvaluationAccess &
1289 operator=(
const FEEvaluationAccess &other);
1305 template <
int dim,
typename Number,
bool is_face>
1310 using number_type = Number;
1313 static constexpr
unsigned int dimension = dim;
1314 static constexpr
unsigned int n_components = dim;
1320 get_gradient(
const unsigned int q_point)
const;
1327 get_divergence(
const unsigned int q_point)
const;
1336 get_symmetric_gradient(
const unsigned int q_point)
const;
1343 get_curl(
const unsigned int q_point)
const;
1348 get_hessian(
const unsigned int q_point)
const;
1353 get_hessian_diagonal(
const unsigned int q_point)
const;
1358 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
1371 const unsigned int q_point);
1383 const unsigned int q_point);
1394 submit_symmetric_gradient(
1396 const unsigned int q_point);
1405 const unsigned int q_point);
1416 const unsigned int dof_no,
1417 const unsigned int first_selected_component,
1418 const unsigned int quad_no,
1419 const unsigned int dofs_per_cell,
1420 const unsigned int n_q_points,
1421 const bool is_interior_face =
true);
1427 template <
int n_components_other>
1433 const unsigned int first_selected_component,
1439 FEEvaluationAccess(
const FEEvaluationAccess &other);
1444 FEEvaluationAccess &
1445 operator=(
const FEEvaluationAccess &other);
1460 template <
typename Number,
bool is_face>
1465 using number_type = Number;
1468 static constexpr
unsigned int dimension = 1;
1474 get_dof_value(
const unsigned int dof)
const;
1479 submit_dof_value(
const value_type val_in,
const unsigned int dof);
1484 get_value(
const unsigned int q_point)
const;
1489 submit_value(
const value_type val_in,
const unsigned int q_point);
1494 submit_value(
const gradient_type val_in,
const unsigned int q_point);
1499 get_gradient(
const unsigned int q_point)
const;
1504 get_normal_derivative(
const unsigned int q_point)
const;
1509 submit_gradient(
const gradient_type grad_in,
const unsigned int q_point);
1514 submit_gradient(
const value_type grad_in,
const unsigned int q_point);
1519 submit_normal_derivative(
const value_type grad_in,
1520 const unsigned int q_point);
1526 const unsigned int q_point);
1531 get_hessian(
unsigned int q_point)
const;
1536 get_hessian_diagonal(
const unsigned int q_point)
const;
1541 get_laplacian(
const unsigned int q_point)
const;
1546 integrate_value()
const;
1557 const unsigned int dof_no,
1558 const unsigned int first_selected_component,
1559 const unsigned int quad_no,
1560 const unsigned int fe_degree,
1561 const unsigned int n_q_points,
1562 const bool is_interior_face =
true);
1568 template <
int n_components_other>
1574 const unsigned int first_selected_component,
1580 FEEvaluationAccess(
const FEEvaluationAccess &other);
1585 FEEvaluationAccess &
1586 operator=(
const FEEvaluationAccess &other);
2157 using number_type = Number;
2176 static constexpr
unsigned int dimension = dim;
2182 static constexpr
unsigned int n_components = n_components_;
2190 static constexpr
unsigned int static_n_q_points =
2200 static constexpr
unsigned int static_dofs_per_component =
2210 static constexpr
unsigned int tensor_dofs_per_cell =
2211 static_dofs_per_component * n_components;
2220 static constexpr
unsigned int static_dofs_per_cell =
2221 static_dofs_per_component * n_components;
2249 const unsigned int dof_no = 0,
2250 const unsigned int quad_no = 0,
2251 const unsigned int first_selected_component = 0);
2283 const unsigned int first_selected_component = 0);
2293 const unsigned int first_selected_component = 0);
2305 template <
int n_components_other>
2308 const unsigned int first_selected_component = 0);
2336 reinit(
const unsigned int cell_batch_index);
2350 template <
typename DoFHandlerType,
bool level_dof_access>
2378 evaluate(
const bool evaluate_values,
2379 const bool evaluate_gradients,
2380 const bool evaluate_hessians =
false);
2396 const bool evaluate_values,
2397 const bool evaluate_gradients,
2398 const bool evaluate_hessians =
false);
2413 template <
typename VectorType>
2415 gather_evaluate(
const VectorType &input_vector,
2416 const bool evaluate_values,
2417 const bool evaluate_gradients,
2418 const bool evaluate_hessians =
false);
2431 integrate(
const bool integrate_values,
const bool integrate_gradients);
2445 integrate(
const bool integrate_values,
2446 const bool integrate_gradients,
2462 template <
typename VectorType>
2464 integrate_scatter(
const bool integrate_values,
2465 const bool integrate_gradients,
2466 VectorType &output_vector);
2473 quadrature_point(
const unsigned int q_point)
const;
2506 check_template_arguments(
const unsigned int fe_no,
2507 const unsigned int first_selected_component);
2545 int n_q_points_1d = fe_degree + 1,
2546 int n_components_ = 1,
2547 typename Number =
double>
2560 using number_type = Number;
2579 static constexpr
unsigned int dimension = dim;
2585 static constexpr
unsigned int n_components = n_components_;
2594 static constexpr
unsigned int static_n_q_points =
2603 static constexpr
unsigned int static_n_q_points_cell =
2612 static constexpr
unsigned int static_dofs_per_component =
2621 static constexpr
unsigned int tensor_dofs_per_cell =
2622 static_dofs_per_component * n_components;
2630 static constexpr
unsigned int static_dofs_per_cell =
2631 static_dofs_per_component * n_components;
2663 const bool is_interior_face =
true,
2664 const unsigned int dof_no = 0,
2665 const unsigned int quad_no = 0,
2666 const unsigned int first_selected_component = 0);
2684 reinit(
const unsigned int face_batch_number);
2694 reinit(
const unsigned int cell_batch_number,
const unsigned int face_number);
2707 evaluate(
const bool evaluate_values,
const bool evaluate_gradients);
2723 const bool evaluate_values,
2724 const bool evaluate_gradients);
2737 template <
typename VectorType>
2739 gather_evaluate(
const VectorType &input_vector,
2740 const bool evaluate_values,
2741 const bool evaluate_gradients);
2753 integrate(
const bool integrate_values,
const bool integrate_gradients);
2764 integrate(
const bool integrate_values,
2765 const bool integrate_gradients,
2779 template <
typename VectorType>
2781 integrate_scatter(
const bool integrate_values,
2782 const bool integrate_gradients,
2783 VectorType &output_vector);
2790 quadrature_point(
const unsigned int q_point)
const;
2824 adjust_for_face_orientation(
const bool integrate,
2826 const bool gradients);
2833 namespace MatrixFreeFunctions
2837 template <
int dim,
int degree>
2838 struct DGP_dofs_per_component
2841 static constexpr
unsigned int value =
2842 (DGP_dofs_per_component<dim - 1, degree>::value * (degree + dim)) / dim;
2846 template <
int degree>
2847 struct DGP_dofs_per_component<1, degree>
2849 static constexpr
unsigned int value = degree + 1;
2863 template <
int dim,
int n_components_,
typename Number,
bool is_face>
2866 const unsigned int dof_no,
2867 const unsigned int first_selected_component,
2868 const unsigned int quad_no_in,
2869 const unsigned int fe_degree,
2870 const unsigned int n_q_points,
2871 const bool is_interior_face)
2872 : scratch_data_array(data_in.acquire_scratch_data())
2873 , quad_no(quad_no_in)
2874 , n_fe_components(data_in.get_dof_info(dof_no).start_components.back())
2875 , active_fe_index(fe_degree !=
numbers::invalid_unsigned_int ?
2876 data_in.get_dof_info(dof_no).fe_index_from_degree(
2877 first_selected_component,
2880 , active_quad_index(fe_degree !=
numbers::invalid_unsigned_int ?
2881 (is_face ? data_in.get_mapping_info()
2882 .face_data[quad_no_in]
2883 .quad_index_from_n_q_points(n_q_points) :
2884 data_in.get_mapping_info()
2885 .cell_data[quad_no_in]
2886 .quad_index_from_n_q_points(n_q_points)) :
2888 , n_quadrature_points(fe_degree !=
numbers::invalid_unsigned_int ?
2891 .get_shape_info(dof_no,
2897 .get_shape_info(dof_no,
2902 , matrix_info(&data_in)
2903 , dof_info(&data_in.get_dof_info(dof_no))
2904 , mapping_data(
internal::MatrixFreeFunctions::
2905 MappingInfoCellsOrFaces<dim, Number, is_face>::get(
2906 data_in.get_mapping_info(),
2908 , data(&data_in.get_shape_info(
2911 dof_info->component_to_base_index[first_selected_component],
2916 , normal_vectors(nullptr)
2917 , normal_x_jacobian(nullptr)
2918 , quadrature_weights(
2919 mapping_data->descriptor[active_quad_index].quadrature_weights.begin())
2920 , cell(
numbers::invalid_unsigned_int)
2921 , is_interior_face(is_interior_face)
2925 internal::MatrixFreeFunctions::DoFInfo::dof_access_face_interior :
2926 internal::MatrixFreeFunctions::DoFInfo::dof_access_face_exterior) :
2927 internal::MatrixFreeFunctions::DoFInfo::dof_access_cell)
2929 , dof_values_initialized(false)
2930 , values_quad_initialized(false)
2931 , gradients_quad_initialized(false)
2932 , hessians_quad_initialized(false)
2933 , values_quad_submitted(false)
2934 , gradients_quad_submitted(false)
2935 , first_selected_component(first_selected_component)
2947 (int)n_components_ <=
2952 "You tried to construct a vector-valued evaluator with " +
2954 " components. However, " 2955 "the current base element has only " +
2959 first_selected_component) +
2960 " components left when starting from local element index " +
2962 first_selected_component -
2974 template <
int dim,
int n_components_,
typename Number,
bool is_face>
2975 template <
int n_components_other>
2981 const unsigned int first_selected_component,
2989 Utilities::fixed_power < is_face ? dim - 1 : dim > (quadrature.size()))
2990 , matrix_info(nullptr)
2998 fe.component_to_base_index(first_selected_component).first))
3001 , normal_vectors(nullptr)
3002 , normal_x_jacobian(nullptr)
3006 , is_interior_face(true)
3017 first_selected_component(first_selected_component)
3023 if (other !=
nullptr &&
3029 mapping, quadrature, update_flags);
3036 const unsigned int base_element_number =
3040 first_selected_component >=
3042 ExcMessage(
"The underlying element must at least contain as many " 3043 "components as requested by this class"));
3044 (void)base_element_number;
3049 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3054 other.matrix_info->acquire_scratch_data())
3060 , matrix_info(other.matrix_info)
3061 , dof_info(other.dof_info)
3064 other.matrix_info == nullptr ?
3070 , normal_vectors(nullptr)
3071 , normal_x_jacobian(nullptr)
3073 other.matrix_info == nullptr ?
3078 , is_interior_face(other.is_interior_face)
3086 , first_selected_component(other.first_selected_component)
3108 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3120 if (matrix_info ==
nullptr)
3175 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3179 if (matrix_info !=
nullptr)
3199 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3205 const unsigned int tensor_dofs_per_component =
3206 Utilities::fixed_power<dim>(this->data->
fe_degree + 1);
3212 const unsigned int shift =
3213 std::max(tensor_dofs_per_component + 1, dofs_per_component) *
3216 const unsigned int allocated_size =
3217 shift + n_components_ * dofs_per_component +
3218 (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3222 for (
unsigned int c = 0; c < n_components_; ++c)
3229 for (
unsigned int d = 0; d < dim; ++d)
3234 for (
unsigned int d = 0; d < (dim * dim + dim) / 2; ++d)
3235 this->hessians_quad[c][d] =
3238 ((dim + 1) * n_quadrature_points + dofs_per_component) +
3243 (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3248 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3258 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3263 if (matrix_info == 0)
3274 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3284 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3294 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3309 JxW_values[q] = J_value[q];
3314 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3317 const unsigned int q_index)
const 3322 return normal_vectors[0];
3324 return normal_vectors[q_index];
3329 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3332 const unsigned int q_index)
const 3342 return J_value[q_index];
3347 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3350 const unsigned int q_index)
const 3357 return jacobian[q_index];
3362 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3373 const unsigned int * cells =
3377 for (
unsigned int i = 0; i < VectorizedArray<Number>::n_array_elements;
3393 template <
typename VectorType>
3394 inline typename VectorType::value_type &
3395 vector_access(VectorType &vec,
const unsigned int entry)
3405 template <
typename Number>
3408 const unsigned int entry)
3418 template <
typename VectorType>
3420 check_vector_compatibility(
3421 const VectorType & vec,
3430 template <
typename Number>
3432 check_vector_compatibility(
3440 "The parallel layout of the given vector is not " 3441 "compatible with the parallel partitioning in MatrixFree. " 3442 "Use MatrixFree::initialize_dof_vector to get a " 3443 "compatible vector."));
3447 template <
typename Number>
3450 template <
typename VectorType>
3452 process_dof(
const unsigned int index, VectorType &vec, Number &res)
const 3454 res = vector_access(vec, index);
3457 template <
typename VectorType>
3459 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3460 const unsigned int * dof_indices,
3463 std::integral_constant<bool, true>)
const 3465 ::vectorized_load_and_transpose(dofs_per_cell,
3472 template <
typename VectorType>
3474 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3475 const unsigned int * dof_indices,
3478 std::integral_constant<bool, false>)
const 3481 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3483 dof_values[d][v] = vector_access(vec, dof_indices[v] + d);
3488 template <
typename VectorType>
3490 process_dof_gather(
const unsigned int * indices,
3492 const unsigned int constant_offset,
3494 std::integral_constant<bool, true>)
const 3496 res.
gather(vec.begin() + constant_offset, indices);
3501 template <
typename VectorType>
3503 process_dof_gather(
const unsigned int * indices,
3505 const unsigned int constant_offset,
3507 std::integral_constant<bool, false>)
const 3509 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3511 res[v] = vector_access(vec, indices[v] + constant_offset);
3514 template <
typename VectorType>
3520 res =
const_cast<const VectorType &
>(vec)(index);
3524 pre_constraints(
const Number &, Number &res)
const 3529 template <
typename VectorType>
3531 process_constraint(
const unsigned int index,
3532 const Number weight,
3536 res += weight * vector_access(vec, index);
3540 post_constraints(
const Number &sum, Number &write_pos)
const 3553 template <
typename Number>
3554 struct VectorDistributorLocalToGlobal
3556 template <
typename VectorType>
3558 process_dof(
const unsigned int index, VectorType &vec, Number &res)
const 3560 vector_access(vec, index) += res;
3563 template <
typename VectorType>
3565 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3566 const unsigned int * dof_indices,
3569 std::integral_constant<bool, true>)
const 3571 vectorized_transpose_and_store(
3572 true, dofs_per_cell, dof_values, dof_indices, vec.begin());
3575 template <
typename VectorType>
3577 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3578 const unsigned int * dof_indices,
3581 std::integral_constant<bool, false>)
const 3584 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3586 vector_access(vec, dof_indices[v] + d) += dof_values[d][v];
3591 template <
typename VectorType>
3593 process_dof_gather(
const unsigned int * indices,
3595 const unsigned int constant_offset,
3597 std::integral_constant<bool, true>)
const 3599 # if DEAL_II_COMPILER_VECTORIZATION_LEVEL < 3 3600 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3602 vector_access(vec, indices[v] + constant_offset) += res[v];
3606 tmp.
gather(vec.begin() + constant_offset, indices);
3608 tmp.
scatter(indices, vec.begin() + constant_offset);
3614 template <
typename VectorType>
3616 process_dof_gather(
const unsigned int * indices,
3618 const unsigned int constant_offset,
3620 std::integral_constant<bool, false>)
const 3622 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3624 vector_access(vec, indices[v] + constant_offset) += res[v];
3627 template <
typename VectorType>
3637 pre_constraints(
const Number &input, Number &res)
const 3642 template <
typename VectorType>
3644 process_constraint(
const unsigned int index,
3645 const Number weight,
3649 vector_access(vec, index) += weight * res;
3653 post_constraints(
const Number &, Number &)
const 3663 template <
typename Number>
3666 template <
typename VectorType>
3668 process_dof(
const unsigned int index, VectorType &vec, Number &res)
const 3670 vector_access(vec, index) = res;
3673 template <
typename VectorType>
3675 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3676 const unsigned int * dof_indices,
3679 std::integral_constant<bool, true>)
const 3681 vectorized_transpose_and_store(
3682 false, dofs_per_cell, dof_values, dof_indices, vec.begin());
3685 template <
typename VectorType,
bool booltype>
3687 process_dofs_vectorized_transpose(
const unsigned int dofs_per_cell,
3688 const unsigned int * dof_indices,
3691 std::integral_constant<bool, false>)
const 3694 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3696 vector_access(vec, dof_indices[v] + i) = dof_values[i][v];
3699 template <
typename VectorType>
3701 process_dof_gather(
const unsigned int * indices,
3703 const unsigned int constant_offset,
3705 std::integral_constant<bool, true>)
const 3707 res.
scatter(indices, vec.begin() + constant_offset);
3710 template <
typename VectorType>
3712 process_dof_gather(
const unsigned int * indices,
3714 const unsigned int constant_offset,
3716 std::integral_constant<bool, false>)
const 3718 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
3720 vector_access(vec, indices[v] + constant_offset) = res[v];
3723 template <
typename VectorType>
3733 pre_constraints(
const Number &, Number &)
const 3736 template <
typename VectorType>
3738 process_constraint(
const unsigned int,
3745 post_constraints(
const Number &, Number &)
const 3756 template <
typename VectorType,
bool>
3757 struct BlockVectorSelector
3760 template <
typename VectorType>
3761 struct BlockVectorSelector<VectorType, true>
3763 using BaseVectorType =
typename VectorType::BlockType;
3765 static BaseVectorType *
3766 get_vector_component(VectorType &vec,
const unsigned int component)
3769 return &vec.block(component);
3773 template <
typename VectorType>
3774 struct BlockVectorSelector<VectorType, false>
3776 using BaseVectorType = VectorType;
3778 static BaseVectorType *
3779 get_vector_component(VectorType &vec,
const unsigned int component)
3798 template <
typename VectorType>
3799 struct BlockVectorSelector<
std::vector<VectorType>, false>
3801 using BaseVectorType = VectorType;
3803 static BaseVectorType *
3804 get_vector_component(std::vector<VectorType> &vec,
3805 const unsigned int component)
3808 return &vec[component];
3812 template <
typename VectorType>
3813 struct BlockVectorSelector<
std::vector<VectorType *>, false>
3815 using BaseVectorType = VectorType;
3817 static BaseVectorType *
3818 get_vector_component(std::vector<VectorType *> &vec,
3819 const unsigned int component)
3822 return vec[component];
3829 template <
int dim,
int n_components_,
typename Number,
bool is_face>
3830 template <
typename VectorType,
typename VectorOperation>
3835 const bool apply_constraints)
const 3840 if (matrix_info ==
nullptr)
3849 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3850 internal::check_vector_compatibility(*src[comp], *dof_info);
3853 internal::check_vector_compatibility(*src[0], *dof_info);
3873 constexpr
unsigned int n_vectorization =
3875 const unsigned int dofs_per_component =
3883 const unsigned int *dof_indices =
3891 ++i, dof_indices += n_vectorization)
3892 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3893 operation.process_dof_gather(
3898 std::integral_constant<
3900 std::is_same<
typename VectorType::value_type,
3903 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3905 ++i, dof_indices += n_vectorization)
3906 operation.process_dof_gather(
3911 std::integral_constant<
3913 std::is_same<
typename VectorType::value_type,
3918 const unsigned int * dof_indices[n_vectorization];
3922 unsigned int cells_copied[n_vectorization];
3923 const unsigned int *cells;
3924 unsigned int n_vectorization_actual =
3926 bool has_constraints =
false;
3931 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3940 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3959 for (
unsigned int v = n_vectorization_actual; v < n_vectorization; ++v)
3960 dof_indices[v] =
nullptr;
3966 const unsigned int n_components_read =
3967 n_fe_components > 1 ? n_components : 1;
3968 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3971 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
3972 first_selected_component + n_components_read]
3976 first_selected_component]
3978 has_constraints =
true;
3981 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
3982 first_selected_component + n_components_read]
3985 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
3986 first_selected_component]
3989 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
3990 first_selected_component]
3991 .first < dof_info->dof_indices.size(),
3995 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
3996 first_selected_component]
4003 first_selected_component]
4006 for (
unsigned int v = n_vectorization_actual; v < n_vectorization; ++v)
4007 dof_indices[v] =
nullptr;
4012 if (!has_constraints)
4014 if (n_vectorization_actual < n_vectorization)
4015 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4017 operation.process_empty(values_dofs[comp][i]);
4018 if (n_components == 1 || n_fe_components == 1)
4020 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4022 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4023 operation.process_dof(dof_indices[v][i],
4025 values_dofs[comp][i][v]);
4029 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4030 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4032 operation.process_dof(
4033 dof_indices[v][comp * dofs_per_component + i],
4035 values_dofs[comp][i][v]);
4045 if (n_vectorization_actual < n_vectorization)
4046 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4048 operation.process_empty(values_dofs[comp][i]);
4049 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
4051 unsigned int index_indicators, next_index_indicators;
4052 const unsigned int n_components_read =
4053 n_fe_components > 1 ? n_components : 1;
4056 index_indicators = dof_info
4060 next_index_indicators = dof_info
4062 first_selected_component + 1]
4070 first_selected_component]
4072 next_index_indicators =
4075 first_selected_component + 1]
4079 if (apply_constraints ==
false &&
4081 ->row_starts[(
cell * n_vectorization + v) * n_fe_components +
4086 first_selected_component + n_components_read]
4100 next_index_indicators = index_indicators;
4103 if (n_components == 1 || n_fe_components == 1)
4106 Assert(src[c] !=
nullptr,
4108 "The finite element underlying this FEEvaluation " 4109 "object is scalar, but you requested " +
4110 std::to_string(n_components) +
4111 " components via the template argument in " 4112 "FEEvaluation. In that case, you must pass an " 4113 "std::vector<VectorType> or a BlockVector to " +
4114 "read_dof_values and distribute_local_to_global."));
4116 unsigned int ind_local = 0;
4117 for (; index_indicators != next_index_indicators; ++index_indicators)
4119 const std::pair<unsigned short, unsigned short> indicator =
4122 for (
unsigned int j = 0; j < indicator.first; ++j)
4123 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4124 operation.process_dof(dof_indices[v][j],
4126 values_dofs[comp][ind_local + j][v]);
4128 ind_local += indicator.first;
4129 dof_indices[v] += indicator.first;
4134 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4135 operation.pre_constraints(values_dofs[comp][ind_local][v],
4138 const Number *data_val =
4140 const Number *end_pool =
4142 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4143 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4144 operation.process_constraint(*dof_indices[v],
4149 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4150 operation.post_constraints(value[comp],
4151 values_dofs[comp][ind_local][v]);
4158 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4159 operation.process_dof(*dof_indices[v],
4161 values_dofs[comp][ind_local][v]);
4170 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4172 unsigned int ind_local = 0;
4175 for (; index_indicators != next_index_indicators;
4178 const std::pair<unsigned short, unsigned short> indicator =
4182 for (
unsigned int j = 0; j < indicator.first; ++j)
4183 operation.process_dof(dof_indices[v][j],
4185 values_dofs[comp][ind_local + j][v]);
4186 ind_local += indicator.first;
4187 dof_indices[v] += indicator.first;
4192 operation.pre_constraints(values_dofs[comp][ind_local][v],
4195 const Number *data_val =
4197 const Number *end_pool =
4200 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4201 operation.process_constraint(*dof_indices[v],
4206 operation.post_constraints(value,
4207 values_dofs[comp][ind_local][v]);
4215 ++dof_indices[v], ++ind_local)
4218 operation.process_dof(*dof_indices[v],
4220 values_dofs[comp][ind_local][v]);
4223 if (apply_constraints ==
true && comp + 1 < n_components)
4226 next_index_indicators =
4229 first_selected_component + comp + 2]
4232 next_index_indicators =
4236 first_selected_component + comp + 2]
4246 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4247 template <
typename VectorType,
typename VectorOperation>
4251 VectorType * src[])
const 4255 unsigned int index =
4257 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4262 operation.process_empty(values_dofs[comp][i]);
4263 operation.process_dof_global(
4266 values_dofs[comp][i][0]);
4273 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4274 template <
typename VectorType,
typename VectorOperation>
4278 VectorType * src[])
const 4287 std::integral_constant<
4289 std::is_same<typename VectorType::value_type, Number>::value>
4295 const std::vector<unsigned int> &dof_indices_cont =
4297 const unsigned int vectorization_populated =
4300 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4304 [first_selected_component];
4305 for (
unsigned int v = vectorization_populated;
4306 v < VectorizedArray<Number>::n_array_elements;
4314 if (n_components == 1 || n_fe_components == 1)
4315 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4316 operation.process_dofs_vectorized_transpose(
4323 operation.process_dofs_vectorized_transpose(
4331 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4334 operation.process_empty(values_dofs[comp][i]);
4335 if (n_components == 1 || n_fe_components == 1)
4336 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4338 operation.process_dof(dof_indices[v] + i,
4340 values_dofs[comp][i][v]);
4342 for (
unsigned int v = 0; v < vectorization_populated; ++v)
4344 operation.process_dof(dof_indices[v] + i +
4347 values_dofs[comp][i][v]);
4353 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4354 template <
typename VectorType>
4357 const VectorType & src,
4358 const unsigned int first_index)
4362 typename internal::BlockVectorSelector<
4367 internal::BlockVectorSelector<VectorType,
4369 get_vector_component(const_cast<VectorType &>(src), d + first_index);
4371 internal::VectorReader<Number> reader;
4381 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4382 template <
typename VectorType>
4385 const VectorType & src,
4386 const unsigned int first_index)
4390 typename internal::BlockVectorSelector<
4395 internal::BlockVectorSelector<VectorType,
4397 get_vector_component(const_cast<VectorType &>(src), d + first_index);
4399 internal::VectorReader<Number> reader;
4409 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4410 template <
typename VectorType>
4414 const unsigned int first_index)
const 4421 typename internal::BlockVectorSelector<
4425 dst_data[d] = internal::BlockVectorSelector<
4430 internal::VectorDistributorLocalToGlobal<Number> distributor;
4436 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4437 template <
typename VectorType>
4441 const unsigned int first_index)
const 4448 typename internal::BlockVectorSelector<
4452 dst_data[d] = internal::BlockVectorSelector<
4457 internal::VectorSetter<Number> setter;
4465 template <
int dim,
int n_components,
typename Number,
bool is_face>
4466 inline const std::vector<unsigned int> &
4475 template <
int dim,
int n_components,
typename Number,
bool is_face>
4486 template <
int dim,
int n_components,
typename Number,
bool is_face>
4490 return &values_dofs[0][0];
4495 template <
int dim,
int n_components,
typename Number,
bool is_face>
4502 return &values_dofs[0][0];
4507 template <
int dim,
int n_components,
typename Number,
bool is_face>
4517 template <
int dim,
int n_components,
typename Number,
bool is_face>
4530 template <
int dim,
int n_components,
typename Number,
bool is_face>
4541 template <
int dim,
int n_components,
typename Number,
bool is_face>
4554 template <
int dim,
int n_components,
typename Number,
bool is_face>
4559 return &hessians_quad[0][0][0];
4564 template <
int dim,
int n_components,
typename Number,
bool is_face>
4571 return &hessians_quad[0][0][0];
4576 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4579 const unsigned int dof)
const 4583 for (
unsigned int comp = 0; comp <
n_components; comp++)
4584 return_value[comp] = this->values_dofs[comp][dof];
4585 return return_value;
4590 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4593 const unsigned int q_point)
const 4599 for (
unsigned int comp = 0; comp <
n_components; comp++)
4600 return_value[comp] = this->
values_quad[comp][q_point];
4601 return return_value;
4606 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4607 inline DEAL_II_ALWAYS_INLINE
4610 const unsigned int q_point)
const 4623 for (
unsigned int comp = 0; comp <
n_components; comp++)
4624 for (
unsigned int d = 0; d < dim; ++d)
4635 for (
unsigned int comp = 0; comp <
n_components; comp++)
4636 for (
unsigned int d = 0; d < dim; ++d)
4640 for (
unsigned int e = 1; e < dim; ++e)
4641 grad_out[comp][d] +=
4642 jac[d][e] * this->gradients_quad[comp][e][q_point];
4650 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4653 const unsigned int q_point)
const 4663 for (
unsigned int comp = 0; comp <
n_components; comp++)
4665 (this->normal_x_jacobian[0][dim - 1]);
4668 const unsigned int index =
4670 for (
unsigned int comp = 0; comp <
n_components; comp++)
4673 this->normal_x_jacobian[index][0];
4674 for (
unsigned int d = 1; d < dim; ++d)
4676 this->normal_x_jacobian[index][d];
4688 template <
typename Number>
4692 const unsigned int q_point,
4695 tmp[0][0] = jac[0][0] * hessians_quad[0][q_point];
4698 template <
typename Number>
4702 const unsigned int q_point,
4705 for (
unsigned int d = 0; d < 2; ++d)
4707 tmp[0][d] = (jac[d][0] * hessians_quad[0][q_point] +
4708 jac[d][1] * hessians_quad[2][q_point]);
4709 tmp[1][d] = (jac[d][0] * hessians_quad[2][q_point] +
4710 jac[d][1] * hessians_quad[1][q_point]);
4714 template <
typename Number>
4718 const unsigned int q_point,
4721 for (
unsigned int d = 0; d < 3; ++d)
4723 tmp[0][d] = (jac[d][0] * hessians_quad[0][q_point] +
4724 jac[d][1] * hessians_quad[3][q_point] +
4725 jac[d][2] * hessians_quad[4][q_point]);
4726 tmp[1][d] = (jac[d][0] * hessians_quad[3][q_point] +
4727 jac[d][1] * hessians_quad[1][q_point] +
4728 jac[d][2] * hessians_quad[5][q_point]);
4729 tmp[2][d] = (jac[d][0] * hessians_quad[4][q_point] +
4730 jac[d][1] * hessians_quad[5][q_point] +
4731 jac[d][2] * hessians_quad[2][q_point]);
4738 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4741 const unsigned int q_point)
const 4759 for (
unsigned int comp = 0; comp <
n_components; comp++)
4760 for (
unsigned int d = 0; d < dim; ++d)
4762 hessian_out[comp][d][d] =
4763 (this->hessians_quad[comp][d][q_point] * jac[d][d] * jac[d][d]);
4769 hessian_out[comp][0][1] =
4770 (this->hessians_quad[comp][2][q_point] * jac[0][0] *
4774 hessian_out[comp][0][1] =
4775 (this->hessians_quad[comp][3][q_point] * jac[0][0] *
4777 hessian_out[comp][0][2] =
4778 (this->hessians_quad[comp][4][q_point] * jac[0][0] *
4780 hessian_out[comp][1][2] =
4781 (this->hessians_quad[comp][5][q_point] * jac[1][1] *
4787 for (
unsigned int e = d + 1; e < dim; ++e)
4788 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4794 for (
unsigned int comp = 0; comp <
n_components; comp++)
4799 internal::hessian_unit_times_jac(jac,
4800 this->hessians_quad[comp],
4805 for (
unsigned int d = 0; d < dim; ++d)
4806 for (
unsigned int e = d; e < dim; ++e)
4808 hessian_out[comp][d][e] = jac[d][0] * tmp[0][e];
4809 for (
unsigned int f = 1; f < dim; ++f)
4810 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
4817 for (
unsigned int d = 0; d < dim; ++d)
4818 for (
unsigned int e = d + 1; e < dim; ++e)
4819 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4829 [1 - this->is_interior_face]
4830 [this->mapping_data->data_index_offsets[this->cell] + q_point];
4831 for (
unsigned int comp = 0; comp <
n_components; comp++)
4836 internal::hessian_unit_times_jac(jac,
4837 this->hessians_quad[comp],
4842 for (
unsigned int d = 0; d < dim; ++d)
4843 for (
unsigned int e = d; e < dim; ++e)
4845 hessian_out[comp][d][e] = jac[d][0] * tmp[0][e];
4846 for (
unsigned int f = 1; f < dim; ++f)
4847 hessian_out[comp][d][e] += jac[d][f] * tmp[f][e];
4851 for (
unsigned int d = 0; d < dim; ++d)
4852 for (
unsigned int e = 0; e < dim; ++e)
4853 hessian_out[comp][d][d] +=
4857 for (
unsigned int d = 0, count = dim; d < dim; ++d)
4858 for (
unsigned int e = d + 1; e < dim; ++e, ++count)
4859 for (
unsigned int f = 0; f < dim; ++f)
4860 hessian_out[comp][d][e] +=
4864 for (
unsigned int d = 0; d < dim; ++d)
4865 for (
unsigned int e = d + 1; e < dim; ++e)
4866 hessian_out[comp][e][d] = hessian_out[comp][d][e];
4875 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4878 const unsigned int q_point)
const 4896 for (
unsigned int comp = 0; comp <
n_components; comp++)
4897 for (
unsigned int d = 0; d < dim; ++d)
4898 hessian_out[comp][d] =
4899 (this->hessians_quad[comp][d][q_point] * jac[d][d] * jac[d][d]);
4904 for (
unsigned int comp = 0; comp <
n_components; comp++)
4909 internal::hessian_unit_times_jac(jac,
4910 this->hessians_quad[comp],
4916 for (
unsigned int d = 0; d < dim; ++d)
4918 hessian_out[comp][d] = jac[d][0] * tmp[0][d];
4919 for (
unsigned int f = 1; f < dim; ++f)
4920 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
4931 [0][this->mapping_data->data_index_offsets[this->cell] + q_point];
4932 for (
unsigned int comp = 0; comp <
n_components; comp++)
4937 internal::hessian_unit_times_jac(jac,
4938 this->hessians_quad[comp],
4944 for (
unsigned int d = 0; d < dim; ++d)
4946 hessian_out[comp][d] = jac[d][0] * tmp[0][d];
4947 for (
unsigned int f = 1; f < dim; ++f)
4948 hessian_out[comp][d] += jac[d][f] * tmp[f][d];
4951 for (
unsigned int d = 0; d < dim; ++d)
4952 for (
unsigned int e = 0; e < dim; ++e)
4953 hessian_out[comp][d] +=
4962 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4965 const unsigned int q_point)
const 4975 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4977 laplacian_out[comp] = hess_diag[comp][0];
4978 for (
unsigned int d = 1; d < dim; ++d)
4979 laplacian_out[comp] += hess_diag[comp][d];
4981 return laplacian_out;
4986 template <
int dim,
int n_components_,
typename Number,
bool is_face>
4987 inline DEAL_II_ALWAYS_INLINE
void 4990 const unsigned int dof)
4996 for (
unsigned int comp = 0; comp <
n_components; comp++)
4997 this->values_dofs[comp][dof] = val_in[comp];
5002 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5003 inline DEAL_II_ALWAYS_INLINE
void 5006 const unsigned int q_point)
5019 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5020 this->
values_quad[comp][q_point] = val_in[comp] * JxW;
5025 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5026 this->
values_quad[comp][q_point] = val_in[comp] * JxW;
5032 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5033 inline DEAL_II_ALWAYS_INLINE
void 5037 const unsigned int q_point)
5050 J_value[0] * quadrature_weights[q_point];
5051 for (
unsigned int comp = 0; comp <
n_components; comp++)
5052 for (
unsigned int d = 0; d < dim; ++d)
5054 (grad_in[comp][d] * jacobian[0][d][d] * JxW);
5065 J_value[0] * quadrature_weights[q_point];
5066 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5067 for (
unsigned int d = 0; d < dim; ++d)
5070 for (
unsigned int e = 1; e < dim; ++e)
5071 new_val += (jac[e][d] * grad_in[comp][e]);
5079 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5080 inline DEAL_II_ALWAYS_INLINE
void 5083 const unsigned int q_point)
5092 for (
unsigned int comp = 0; comp <
n_components; comp++)
5094 for (
unsigned int d = 0; d < dim - 1; ++d)
5098 (this->normal_x_jacobian[0][dim - 1] * this->J_value[0] *
5099 this->quadrature_weights[q_point]);
5103 const unsigned int index =
5105 for (
unsigned int comp = 0; comp <
n_components; comp++)
5109 factor = factor * this->quadrature_weights[q_point];
5110 for (
unsigned int d = 0; d < dim; ++d)
5112 factor * this->normal_x_jacobian[index][d];
5119 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5129 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5132 for (
unsigned int q = 1; q <
n_q_points; ++q)
5133 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5135 return (return_value);
5143 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5146 const unsigned int dof_no,
5147 const unsigned int first_selected_component,
5148 const unsigned int quad_no_in,
5149 const unsigned int fe_degree,
5150 const unsigned int n_q_points,
5151 const bool is_interior_face)
5155 first_selected_component,
5164 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5165 template <
int n_components_other>
5172 const unsigned int first_selected_component,
5179 first_selected_component,
5185 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5194 template <
int dim,
int n_components_,
typename Number,
bool is_face>
5208 template <
int dim,
typename Number,
bool is_face>
5211 const unsigned int dof_no,
5212 const unsigned int first_selected_component,
5213 const unsigned int quad_no_in,
5214 const unsigned int fe_degree,
5215 const unsigned int n_q_points,
5216 const bool is_interior_face)
5219 first_selected_component,
5228 template <
int dim,
typename Number,
bool is_face>
5229 template <
int n_components_other>
5235 const unsigned int first_selected_component,
5241 first_selected_component,
5247 template <
int dim,
typename Number,
bool is_face>
5255 template <
int dim,
typename Number,
bool is_face>
5266 template <
int dim,
typename Number,
bool is_face>
5269 const unsigned int dof)
const 5272 return this->values_dofs[0][dof];
5277 template <
int dim,
typename Number,
bool is_face>
5280 const unsigned int q_point)
const 5290 template <
int dim,
typename Number,
bool is_face>
5293 const unsigned int q_point)
const 5300 template <
int dim,
typename Number,
bool is_face>
5303 const unsigned int q_point)
const 5318 for (
unsigned int d = 0; d < dim; ++d)
5329 for (
unsigned int d = 0; d < dim; ++d)
5332 for (
unsigned int e = 1; e < dim; ++e)
5333 grad_out[d] += jac[d][e] * this->gradients_quad[0][e][q_point];
5341 template <
int dim,
typename Number,
bool is_face>
5344 const unsigned int q_point)
const 5351 template <
int dim,
typename Number,
bool is_face>
5354 const unsigned int q_point)
const 5361 template <
int dim,
typename Number,
bool is_face>
5364 const unsigned int q_point)
const 5371 template <
int dim,
typename Number,
bool is_face>
5372 inline void DEAL_II_ALWAYS_INLINE
5375 const unsigned int dof)
5381 this->values_dofs[0][dof] = val_in;
5386 template <
int dim,
typename Number,
bool is_face>
5387 inline void DEAL_II_ALWAYS_INLINE
5390 const unsigned int q_index)
5401 this->J_value[0] * this->quadrature_weights[q_index];
5406 this->
values_quad[0][q_index] = val_in * this->J_value[q_index];
5412 template <
int dim,
typename Number,
bool is_face>
5413 inline DEAL_II_ALWAYS_INLINE
void 5416 const unsigned int q_point)
5423 template <
int dim,
typename Number,
bool is_face>
5424 inline DEAL_II_ALWAYS_INLINE
void 5427 const unsigned int q_point)
5436 template <
int dim,
typename Number,
bool is_face>
5437 inline DEAL_II_ALWAYS_INLINE
void 5440 const unsigned int q_index)
5453 this->J_value[0] * this->quadrature_weights[q_index];
5454 for (
unsigned int d = 0; d < dim; ++d)
5456 (grad_in[d] * this->jacobian[0][d][d] * JxW);
5463 this->jacobian[q_index] :
5467 this->J_value[q_index] :
5468 this->J_value[0] * this->quadrature_weights[q_index];
5469 for (
unsigned int d = 0; d < dim; ++d)
5472 for (
unsigned int e = 1; e < dim; ++e)
5473 new_val += jac[e][d] * grad_in[e];
5481 template <
int dim,
typename Number,
bool is_face>
5493 template <
int dim,
typename Number,
bool is_face>
5496 const unsigned int dof_no,
5497 const unsigned int first_selected_component,
5498 const unsigned int quad_no_in,
5499 const unsigned int fe_degree,
5500 const unsigned int n_q_points,
5501 const bool is_interior_face)
5504 first_selected_component,
5513 template <
int dim,
typename Number,
bool is_face>
5514 template <
int n_components_other>
5520 const unsigned int first_selected_component,
5526 first_selected_component,
5532 template <
int dim,
typename Number,
bool is_face>
5540 template <
int dim,
typename Number,
bool is_face>
5551 template <
int dim,
typename Number,
bool is_face>
5554 const unsigned int q_point)
const 5561 template <
int dim,
typename Number,
bool is_face>
5564 const unsigned int q_point)
const 5578 for (
unsigned int d = 1; d < dim; ++d)
5587 this->jacobian[q_point] :
5590 for (
unsigned int e = 1; e < dim; ++e)
5592 for (
unsigned int d = 1; d < dim; ++d)
5593 for (
unsigned int e = 0; e < dim; ++e)
5601 template <
int dim,
typename Number,
bool is_face>
5604 const unsigned int q_point)
const 5610 for (
unsigned int d = 0; d < dim; ++d)
5611 symmetrized[d] = grad[d][d];
5617 symmetrized[2] = grad[0][1] + grad[1][0];
5618 symmetrized[2] *= half;
5621 symmetrized[3] = grad[0][1] + grad[1][0];
5622 symmetrized[3] *= half;
5623 symmetrized[4] = grad[0][2] + grad[2][0];
5624 symmetrized[4] *= half;
5625 symmetrized[5] = grad[1][2] + grad[2][1];
5626 symmetrized[5] *= half;
5636 template <
int dim,
typename Number,
bool is_face>
5637 inline DEAL_II_ALWAYS_INLINE
5640 const unsigned int q_point)
const 5650 "Computing the curl in 1d is not a useful operation"));
5653 curl[0] = grad[1][0] - grad[0][1];
5656 curl[0] = grad[2][1] - grad[1][2];
5657 curl[1] = grad[0][2] - grad[2][0];
5658 curl[2] = grad[1][0] - grad[0][1];
5668 template <
int dim,
typename Number,
bool is_face>
5671 const unsigned int q_point)
const 5678 template <
int dim,
typename Number,
bool is_face>
5681 const unsigned int q_point)
const 5691 template <
int dim,
typename Number,
bool is_face>
5692 inline DEAL_II_ALWAYS_INLINE
void 5695 const unsigned int q_point)
5702 template <
int dim,
typename Number,
bool is_face>
5703 inline DEAL_II_ALWAYS_INLINE
void 5706 const unsigned int q_point)
5713 template <
int dim,
typename Number,
bool is_face>
5714 inline DEAL_II_ALWAYS_INLINE
void 5717 const unsigned int q_point)
5730 this->J_value[0] * this->quadrature_weights[q_point] * div_in;
5731 for (
unsigned int d = 0; d < dim; ++d)
5733 this->
gradients_quad[d][d][q_point] = (fac * this->jacobian[0][d][d]);
5734 for (
unsigned int e = d + 1; e < dim; ++e)
5745 this->jacobian[q_point] :
5749 this->J_value[q_point] :
5750 this->J_value[0] * this->quadrature_weights[q_point]) *
5752 for (
unsigned int d = 0; d < dim; ++d)
5754 for (
unsigned int e = 0; e < dim; ++e)
5762 template <
int dim,
typename Number,
bool is_face>
5763 inline DEAL_II_ALWAYS_INLINE
void 5766 const unsigned int q_point)
5782 this->J_value[0] * this->quadrature_weights[q_point];
5783 for (
unsigned int d = 0; d < dim; ++d)
5785 (sym_grad.access_raw_entry(d) * JxW * this->jacobian[0][d][d]);
5786 for (
unsigned int e = 0, counter = dim; e < dim; ++e)
5787 for (
unsigned int d = e + 1; d < dim; ++d, ++counter)
5790 sym_grad.access_raw_entry(counter) *
JxW;
5792 (value * this->jacobian[0][d][d]);
5794 (value * this->jacobian[0][e][e]);
5802 this->J_value[q_point] :
5803 this->J_value[0] * this->quadrature_weights[q_point];
5806 this->jacobian[q_point] :
5809 for (
unsigned int i = 0; i < dim; ++i)
5810 weighted[i][i] = sym_grad.access_raw_entry(i) *
JxW;
5811 for (
unsigned int i = 0, counter = dim; i < dim; ++i)
5812 for (
unsigned int j = i + 1; j < dim; ++j, ++counter)
5815 sym_grad.access_raw_entry(counter) *
JxW;
5816 weighted[i][j] = value;
5817 weighted[j][i] = value;
5819 for (
unsigned int comp = 0; comp < dim; ++comp)
5820 for (
unsigned int d = 0; d < dim; ++d)
5823 for (
unsigned int e = 1; e < dim; ++e)
5824 new_val += jac[e][d] * weighted[comp][e];
5832 template <
int dim,
typename Number,
bool is_face>
5833 inline DEAL_II_ALWAYS_INLINE
void 5836 const unsigned int q_point)
5844 "Testing by the curl in 1d is not a useful operation"));
5847 grad[1][0] = curl[0];
5848 grad[0][1] = -curl[0];
5851 grad[2][1] = curl[0];
5852 grad[1][2] = -curl[0];
5853 grad[0][2] = curl[1];
5854 grad[2][0] = -curl[1];
5855 grad[1][0] = curl[2];
5856 grad[0][1] = -curl[2];
5868 template <
typename Number,
bool is_face>
5871 const unsigned int dof_no,
5872 const unsigned int first_selected_component,
5873 const unsigned int quad_no_in,
5874 const unsigned int fe_degree,
5875 const unsigned int n_q_points,
5876 const bool is_interior_face)
5879 first_selected_component,
5888 template <
typename Number,
bool is_face>
5889 template <
int n_components_other>
5895 const unsigned int first_selected_component,
5901 first_selected_component,
5907 template <
typename Number,
bool is_face>
5915 template <
typename Number,
bool is_face>
5926 template <
typename Number,
bool is_face>
5929 const unsigned int dof)
const 5932 return this->values_dofs[0][dof];
5937 template <
typename Number,
bool is_face>
5940 const unsigned int q_point)
const 5950 template <
typename Number,
bool is_face>
5953 const unsigned int q_point)
const 5964 this->jacobian[q_point] :
5975 template <
typename Number,
bool is_face>
5978 const unsigned int q_point)
const 5985 template <
typename Number,
bool is_face>
5988 const unsigned int q_point)
const 5995 template <
typename Number,
bool is_face>
5998 const unsigned int q_point)
const 6005 template <
typename Number,
bool is_face>
6008 const unsigned int q_point)
const 6015 template <
typename Number,
bool is_face>
6016 inline DEAL_II_ALWAYS_INLINE
void DEAL_II_ALWAYS_INLINE
6019 const unsigned int dof)
6025 this->values_dofs[0][dof] = val_in;
6030 template <
typename Number,
bool is_face>
6031 inline DEAL_II_ALWAYS_INLINE
void 6034 const unsigned int q_point)
6049 this->J_value[0] * this->quadrature_weights[q_point];
6056 template <
typename Number,
bool is_face>
6057 inline DEAL_II_ALWAYS_INLINE
void 6060 const unsigned int q_point)
6067 template <
typename Number,
bool is_face>
6068 inline DEAL_II_ALWAYS_INLINE
void 6071 const unsigned int q_point)
6078 template <
typename Number,
bool is_face>
6079 inline DEAL_II_ALWAYS_INLINE
void 6082 const unsigned int q_point)
6092 this->jacobian[q_point] :
6096 this->J_value[q_point] :
6097 this->J_value[0] * this->quadrature_weights[q_point];
6104 template <
typename Number,
bool is_face>
6105 inline DEAL_II_ALWAYS_INLINE
void 6108 const unsigned int q_point)
6117 template <
typename Number,
bool is_face>
6118 inline DEAL_II_ALWAYS_INLINE
void 6121 const unsigned int q_point)
6128 template <
typename Number,
bool is_face>
6147 const unsigned int fe_no,
6149 const unsigned int first_selected_component)
6152 first_selected_component,
6156 , dofs_per_component(this->data->dofs_per_component_on_cell)
6157 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6158 , n_q_points(this->data->n_q_points)
6160 check_template_arguments(fe_no, 0);
6175 const unsigned int first_selected_component)
6180 first_selected_component,
6182 , dofs_per_component(this->data->dofs_per_component_on_cell)
6183 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6184 , n_q_points(this->data->n_q_points)
6200 const unsigned int first_selected_component)
6205 first_selected_component,
6207 , dofs_per_component(this->data->dofs_per_component_on_cell)
6208 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6209 , n_q_points(this->data->n_q_points)
6221 template <
int n_components_other>
6225 const unsigned int first_selected_component)
6230 first_selected_component,
6232 , dofs_per_component(this->data->dofs_per_component_on_cell)
6233 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6234 , n_q_points(this->data->n_q_points)
6249 , dofs_per_component(this->data->dofs_per_component_on_cell)
6250 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6251 , n_q_points(this->data->n_q_points)
6282 const unsigned int first_selected_component)
6285 (void)first_selected_component;
6291 static_cast<unsigned int>(fe_degree) != this->data->
fe_degree) ||
6294 std::string message =
6295 "-------------------------------------------------------\n";
6296 message +=
"Illegal arguments in constructor/wrong template arguments!\n";
6297 message +=
" Called --> FEEvaluation<dim,";
6301 message +=
",Number>(data";
6317 if (static_cast<unsigned int>(fe_degree) == this->data->
fe_degree)
6319 proposed_dof_comp = dof_no;
6323 for (
unsigned int no = 0; no < this->matrix_info->
n_components();
6325 for (
unsigned int nf = 0;
6328 if (this->matrix_info
6330 .
fe_degree ==
static_cast<unsigned int>(fe_degree))
6332 proposed_dof_comp = no;
6333 proposed_fe_comp = nf;
6339 proposed_quad_comp = this->
quad_no;
6341 for (
unsigned int no = 0;
6342 no < this->matrix_info->get_mapping_info().cell_data.size();
6344 if (this->matrix_info->get_mapping_info()
6349 proposed_quad_comp = no;
6356 if (proposed_dof_comp != first_selected_component)
6357 message +=
"Wrong vector component selection:\n";
6359 message +=
"Wrong quadrature formula selection:\n";
6360 message +=
" Did you mean FEEvaluation<dim,";
6364 message +=
",Number>(data";
6373 std::string correct_pos;
6374 if (proposed_dof_comp != dof_no)
6375 correct_pos =
" ^ ";
6378 if (proposed_quad_comp != this->
quad_no)
6379 correct_pos +=
" ^ ";
6382 if (proposed_fe_comp != first_selected_component)
6383 correct_pos +=
" ^\n";
6385 correct_pos +=
" \n";
6391 const unsigned int proposed_n_q_points_1d =
static_cast<unsigned int>(
6393 message +=
"Wrong template arguments:\n";
6394 message +=
" Did you mean FEEvaluation<dim,";
6398 message +=
",Number>(data";
6406 std::string correct_pos;
6407 if (this->data->
fe_degree != static_cast<unsigned int>(fe_degree))
6411 if (proposed_n_q_points_1d != n_q_points_1d)
6412 correct_pos +=
" ^\n";
6414 correct_pos +=
" \n";
6415 message +=
" " + correct_pos;
6417 Assert(static_cast<unsigned int>(fe_degree) == this->data->
fe_degree &&
6418 n_q_points == this->n_quadrature_points,
6437 const unsigned int cell_index)
6440 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 6441 " Integer indexing is not possible"));
6447 this->
cell = cell_index;
6449 this->matrix_info->get_mapping_info().get_cell_type(cell_index);
6451 const unsigned int offsets =
6471 template <
typename DoFHandlerType,
bool level_dof_access>
6476 Assert(this->matrix_info ==
nullptr,
6477 ExcMessage(
"Cannot use initialization from cell iterator if " 6478 "initialized from MatrixFree object. Use variant for " 6479 "on the fly computation with arguments as for FEValues " 6484 this->local_dof_indices.resize(
cell->get_fe().dofs_per_cell);
6485 if (level_dof_access)
6486 cell->get_mg_dof_indices(this->local_dof_indices);
6488 cell->get_dof_indices(this->local_dof_indices);
6502 Assert(this->matrix_info == 0,
6503 ExcMessage(
"Cannot use initialization from cell iterator if " 6504 "initialized from MatrixFree object. Use variant for " 6505 "on the fly computation with arguments as for FEValues " 6522 if (this->matrix_info ==
nullptr)
6536 const unsigned int n_q_points_1d_actual =
6537 fe_degree == -1 ? this->data->
n_q_points_1d : n_q_points_1d;
6551 return quadrature_points[q];
6553 point[0] = quadrature_points[q % n_q_points_1d_actual][0];
6554 point[1] = quadrature_points[q / n_q_points_1d_actual][1];
6557 point[0] = quadrature_points[q % n_q_points_1d_actual][0];
6558 point[1] = quadrature_points[(q / n_q_points_1d_actual) %
6559 n_q_points_1d_actual][1];
6560 point[2] = quadrature_points[q / (n_q_points_1d_actual *
6561 n_q_points_1d_actual)][2];
6570 return quadrature_points[q];
6582 const bool evaluate_values,
6583 const bool evaluate_gradients,
6584 const bool evaluate_hessians)
6604 const bool evaluate_values,
6605 const bool evaluate_gradients,
6606 const bool evaluate_hessians)
6618 this->hessians_quad[0][0],
6625 if (evaluate_values ==
true)
6627 if (evaluate_gradients ==
true)
6629 if (evaluate_hessians ==
true)
6641 template <
typename VectorType>
6645 const bool evaluate_values,
6646 const bool evaluate_gradients,
6647 const bool evaluate_hessians)
6665 const bool integrate_values,
6666 const bool integrate_gradients)
6668 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
6684 const bool integrate_values,
6685 const bool integrate_gradients,
6688 if (integrate_values ==
true)
6691 if (integrate_gradients ==
true)
6694 Assert(this->matrix_info !=
nullptr ||
6709 integrate_gradients);
6723 template <
typename VectorType>
6727 const bool integrate_gradients,
6728 VectorType &destination)
6747 const bool is_interior_face,
6748 const unsigned int dof_no,
6750 const unsigned int first_selected_component)
6753 first_selected_component,
6758 , dofs_per_component(this->data->dofs_per_component_on_cell)
6759 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6760 , n_q_points(this->data->n_q_points_face)
6783 const unsigned int face_index)
6786 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 6787 " Integer indexing is not possible"));
6791 this->cell = face_index;
6793 this->is_interior_face ?
6804 Assert(this->is_interior_face,
6805 ExcMessage(
"Boundary faces do not have a neighbor"));
6810 if (this->is_interior_face ==
true)
6828 this->cell_type = this->matrix_info->get_mapping_info().face_type[face_index];
6829 const unsigned int offsets =
6835 this->normal_x_jacobian =
6856 const unsigned int cell_index,
6857 const unsigned int face_number)
6861 this->matrix_info->get_mapping_info().face_data_by_cells.size(),
6863 "You must set MatrixFree::AdditionalData::mapping_update_flags_faces_by_cells to use the present reinit method."));
6866 this->matrix_info->get_mapping_info().cell_type.size());
6868 ExcMessage(
"FEEvaluation was initialized without a matrix-free object." 6869 " Integer indexing is not possible"));
6870 Assert(this->is_interior_face ==
true,
6872 "Cell-based FEFaceEvaluation::reinit only possible for the " 6873 "interior face with second argument to constructor as true"));
6878 this->cell_type = this->matrix_info->get_mapping_info().cell_type[cell_index];
6879 this->cell = cell_index;
6886 const unsigned int offsets =
6887 this->matrix_info->get_mapping_info()
6888 .face_data_by_cells[this->
quad_no]
6892 this->matrix_info->get_mapping_info()
6893 .face_data_by_cells[this->
quad_no]
6894 .JxW_values.size());
6895 this->J_value = &this->matrix_info->get_mapping_info()
6896 .face_data_by_cells[this->
quad_no]
6897 .JxW_values[offsets];
6898 this->normal_vectors = &this->matrix_info->get_mapping_info()
6899 .face_data_by_cells[this->
quad_no]
6900 .normal_vectors[offsets];
6901 this->jacobian = &this->matrix_info->get_mapping_info()
6902 .face_data_by_cells[this->
quad_no]
6903 .jacobians[0][offsets];
6904 this->normal_x_jacobian = &this->matrix_info->get_mapping_info()
6905 .face_data_by_cells[this->
quad_no]
6906 .normals_times_jacobians[0][offsets];
6925 const bool evaluate_values,
6926 const bool evaluate_gradients)
6930 evaluate(this->values_dofs[0], evaluate_values, evaluate_gradients);
6943 const bool evaluate_values,
6944 const bool evaluate_gradients)
6946 if (!(evaluate_values + evaluate_gradients))
6949 constexpr
unsigned int static_dofs_per_face =
6951 numbers::invalid_unsigned_int;
6952 const unsigned int dofs_per_face =
6953 fe_degree > -1 ? static_dofs_per_face :
6962 constexpr
unsigned int stack_array_size_threshold = 100;
6965 temp_data[static_dofs_per_face < stack_array_size_threshold ?
6966 n_components * 2 * static_dofs_per_face :
6969 if (static_dofs_per_face < stack_array_size_threshold)
6970 temp1 = &temp_data[0];
6974 internal::FEFaceNormalEvaluationImpl<dim,
6978 template interpolate<true, false>(
6979 *this->
data, values_array, temp1, evaluate_gradients, this->
face_no);
6981 const unsigned int n_q_points_1d_actual = fe_degree > -1 ? n_q_points_1d : 0;
6982 if (fe_degree > -1 &&
6984 this->data->element_type <=
6985 internal::MatrixFreeFunctions::tensor_symmetric)
6986 internal::FEFaceEvaluationImpl<
6990 n_q_points_1d_actual,
7003 internal::FEFaceEvaluationImpl<
7007 n_q_points_1d_actual,
7024 if (evaluate_values ==
true)
7026 if (evaluate_gradients ==
true)
7040 integrate(
const bool integrate_values,
const bool integrate_gradients)
7042 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7059 const bool integrate_gradients,
7062 if (!(integrate_values + integrate_gradients))
7068 constexpr
unsigned int static_dofs_per_face =
7070 numbers::invalid_unsigned_int;
7071 const unsigned int dofs_per_face =
7072 fe_degree > -1 ? static_dofs_per_face :
7075 constexpr
unsigned int stack_array_size_threshold = 100;
7078 temp_data[static_dofs_per_face < stack_array_size_threshold ?
7079 n_components * 2 * static_dofs_per_face :
7082 if (static_dofs_per_face < stack_array_size_threshold)
7083 temp1 = &temp_data[0];
7087 const unsigned int n_q_points_1d_actual = fe_degree > -1 ? n_q_points_1d : 0;
7088 if (fe_degree > -1 &&
7090 this->data->element_type <=
7091 internal::MatrixFreeFunctions::tensor_symmetric)
7092 internal::FEFaceEvaluationImpl<
7096 n_q_points_1d_actual,
7106 integrate_gradients,
7109 internal::FEFaceEvaluationImpl<
7113 n_q_points_1d_actual,
7123 integrate_gradients,
7126 internal::FEFaceNormalEvaluationImpl<dim,
7130 template interpolate<false, false>(
7131 *this->
data, temp1, values_array, integrate_gradients, this->
face_no);
7141 template <
typename VectorType>
7145 const bool evaluate_values,
7146 const bool evaluate_gradients)
7148 const unsigned int side = this->
face_no % 2;
7150 constexpr
unsigned int static_dofs_per_face =
7152 numbers::invalid_unsigned_int;
7153 const unsigned int dofs_per_face =
7154 fe_degree > -1 ? static_dofs_per_face :
7157 constexpr
unsigned int stack_array_size_threshold = 100;
7160 temp_data[static_dofs_per_face < stack_array_size_threshold ?
7161 n_components_ * 2 * dofs_per_face :
7164 if (static_dofs_per_face < stack_array_size_threshold)
7165 temp1 = &temp_data[0];
7169 internal::VectorReader<Number> reader;
7178 ((evaluate_gradients ==
false &&
7179 this->data->nodal_at_cell_boundaries ==
true) ||
7180 (this->data->element_type ==
7181 internal::MatrixFreeFunctions::tensor_symmetric_hermite &&
7184 const unsigned int *indices =
7189 if (evaluate_gradients ==
true &&
7190 this->data->element_type ==
7191 internal::MatrixFreeFunctions::tensor_symmetric_hermite)
7198 this->data->shape_data_on_face[0][fe_degree + 1];
7201 this->data->shape_data_on_face[0][fe_degree + 2];
7205 const unsigned int *index_array =
7206 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
7207 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7209 const unsigned int ind1 = index_array[2 * i];
7210 const unsigned int ind2 = index_array[2 * i + 1];
7211 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7213 reader.process_dof_gather(
7218 [this->active_fe_index][this->first_selected_component],
7219 temp1[i + 2 * comp * dofs_per_face],
7220 std::integral_constant<
7222 std::is_same<
typename VectorType::value_type,
7225 reader.process_dof_gather(
7230 [this->active_fe_index][this->first_selected_component],
7232 std::integral_constant<
7234 std::is_same<
typename VectorType::value_type,
7236 temp1[i + dofs_per_face + 2 * comp * dofs_per_face] =
7237 grad_weight0 * temp1[i + 2 * comp * dofs_per_face] +
7238 grad_weight1 * grad;
7246 const unsigned int *index_array =
7247 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
7248 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7249 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7251 const unsigned int ind = index_array[i];
7252 reader.process_dof_gather(
7257 [this->active_fe_index][this->first_selected_component],
7258 temp1[i + comp * 2 * dofs_per_face],
7259 std::integral_constant<
7261 std::is_same<
typename VectorType::value_type,
7269 internal::FEFaceNormalEvaluationImpl<dim,
7273 template interpolate<true, false>(*this->
data,
7274 this->values_dofs[0],
7280 if (fe_degree > -1 &&
7282 this->data->element_type <=
7283 internal::MatrixFreeFunctions::tensor_symmetric)
7284 internal::FEFaceEvaluationImpl<
7301 internal::FEFaceEvaluationImpl<
7322 if (evaluate_values ==
true)
7324 if (evaluate_gradients ==
true)
7336 template <
typename VectorType>
7340 const bool integrate_gradients,
7341 VectorType &destination)
7343 const unsigned int side = this->
face_no % 2;
7344 const unsigned int dofs_per_face =
7346 Utilities::pow(this->data->fe_degree + 1, dim - 1);
7348 constexpr
unsigned int stack_array_size_threshold = 100;
7351 n_components_ * 2 * dofs_per_face :
7354 if (dofs_per_face < stack_array_size_threshold)
7355 temp1 = &temp_data[0];
7361 if (fe_degree > -1 &&
7363 this->data->element_type <=
7364 internal::MatrixFreeFunctions::tensor_symmetric)
7365 internal::FEFaceEvaluationImpl<
7379 integrate_gradients,
7382 internal::FEFaceEvaluationImpl<
7396 integrate_gradients,
7403 internal::VectorDistributorLocalToGlobal<Number> writer;
7412 ((integrate_gradients ==
false &&
7413 this->data->nodal_at_cell_boundaries ==
true) ||
7414 (this->data->element_type ==
7415 internal::MatrixFreeFunctions::tensor_symmetric_hermite &&
7418 const unsigned int *indices =
7424 if (integrate_gradients ==
true &&
7425 this->data->element_type ==
7426 internal::MatrixFreeFunctions::tensor_symmetric_hermite)
7433 this->data->shape_data_on_face[0][fe_degree + 1];
7436 this->data->shape_data_on_face[0][fe_degree + 2];
7439 const unsigned int *index_array =
7440 &this->data->face_to_cell_index_hermite(this->
face_no, 0);
7441 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7443 const unsigned int ind1 = index_array[2 * i];
7444 const unsigned int ind2 = index_array[2 * i + 1];
7445 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7448 temp1[i + 2 * comp * dofs_per_face] +
7450 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
7453 temp1[i + dofs_per_face + 2 * comp * dofs_per_face];
7454 writer.process_dof_gather(
7459 [this->active_fe_index][this->first_selected_component],
7461 std::integral_constant<
7463 std::is_same<
typename VectorType::value_type,
7465 writer.process_dof_gather(
7470 [this->active_fe_index][this->first_selected_component],
7472 std::integral_constant<
7474 std::is_same<
typename VectorType::value_type,
7483 const unsigned int *index_array =
7484 &this->data->face_to_cell_index_nodal(this->
face_no, 0);
7485 for (
unsigned int i = 0; i < dofs_per_face; ++i)
7487 const unsigned int ind = index_array[i];
7488 for (
unsigned int comp = 0; comp < n_components_; ++comp)
7489 writer.process_dof_gather(
7493 this->dof_info->component_dof_indices_offset
7494 [this->active_fe_index][this->first_selected_component],
7495 temp1[i + 2 * comp * dofs_per_face],
7496 std::integral_constant<
7498 std::is_same<
typename VectorType::value_type,
7505 internal::FEFaceNormalEvaluationImpl<dim,
7509 template interpolate<false, false>(*this->
data,
7511 this->values_dofs[0],
7512 integrate_gradients,
7529 const bool gradients)
7532 const unsigned int * orientations =
7540 for (
unsigned int q = 0; q <
n_q_points; ++q)
7541 tmp_values[orientations[q]] = this->
values_quad[c][q];
7543 for (
unsigned int q = 0; q <
n_q_points; ++q)
7544 tmp_values[q] = this->
values_quad[c][orientations[q]];
7545 for (
unsigned int q = 0; q <
n_q_points; ++q)
7548 if (gradients ==
true)
7549 for (
unsigned int d = 0; d < dim; ++d)
7552 for (
unsigned int q = 0; q <
n_q_points; ++q)
7555 for (
unsigned int q = 0; q <
n_q_points; ++q)
7557 for (
unsigned int q = 0; q <
n_q_points; ++q)
7586 Assert(this->matrix_info->get_mapping_info()
7587 .face_data_by_cells[this->
quad_no]
7588 .quadrature_point_offsets.empty() ==
false,
7590 const unsigned int index =
7593 this->matrix_info->get_mapping_info()
7594 .face_data_by_cells[this->
quad_no]
7595 .quadrature_point_offsets.size());
7596 return this->matrix_info->get_mapping_info()
7597 .face_data_by_cells[this->
quad_no]
7598 .quadrature_points[this->matrix_info->get_mapping_info()
7599 .face_data_by_cells[this->
quad_no]
7600 .quadrature_point_offsets[index] +
7610 #endif // ifndef DOXYGEN 7613 DEAL_II_NAMESPACE_CLOSE
const unsigned int active_quad_index
const internal::MatrixFreeFunctions::TaskInfo & get_size_info() const
std::vector< unsigned int > plain_dof_indices
bool gradients_quad_submitted
AlignedVector< Tensor< 1, spacedim, VectorizedArray< Number > > > normals_times_jacobians[2]
static const unsigned int invalid_unsigned_int
unsigned int dofs_per_component_on_cell
AlignedVector< unsigned int > data_index_offsets
value_type integrate_value() const
#define AssertDimension(dim1, dim2)
Number local_element(const size_type local_index) const
void submit_divergence(const VectorizedArray< Number > div_in, const unsigned int q_point)
void read_write_operation(const VectorOperation &operation, VectorType *vectors[], const bool apply_constraints=true) const
bool values_quad_initialized
VectorizedArray< Number > JxW(const unsigned int q_index) const
void check_template_arguments(const unsigned int fe_no, const unsigned int first_selected_component)
FEEvaluation & operator=(const FEEvaluation &other)
AlignedVector< Tensor< 1, spacedim *(spacedim+1)/2, Tensor< 1, spacedim, VectorizedArray< Number > > > > jacobian_gradients[2]
void read_write_operation_contiguous(const VectorOperation &operation, VectorType *vectors[]) const
internal::MatrixFreeFunctions::GeometryType cell_type
static::ExceptionBase & ExcAccessToUninitializedField()
std::vector< unsigned int > component_to_base_index
bool mapping_initialized() const
internal::MatrixFreeFunctions::GeometryType get_cell_type() const
constexpr unsigned int pow(const unsigned int base, const unsigned int iexp)
std::vector< IndexStorageVariants > index_storage_variants[3]
const unsigned int dofs_per_cell
void evaluate(const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
AlignedVector< unsigned int > quadrature_point_offsets
void integrate(const bool integrate_values, const bool integrate_gradients)
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > & get_shape_info() const
void submit_normal_derivative(const value_type grad_in, const unsigned int q_point)
unsigned char face_orientation
#define AssertIndexRange(index, range)
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
FEEvaluationBase & operator=(const FEEvaluationBase &other)
const internal::MatrixFreeFunctions::MappingInfoStorage<(is_face?dim-1:dim), dim, Number > * mapping_data
const unsigned int active_fe_index
unsigned int get_mapping_data_index_offset() const
void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector)
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > * data
Point< dim, VectorizedArray< Number > > quadrature_point(const unsigned int q_point) const
Tensor< 1, dim, VectorizedArray< Number > > get_normal_vector(const unsigned int q_point) const
Transformed quadrature points.
static::ExceptionBase & ExcNotInitialized()
std::vector< unsigned int > cell_partition_data
unsigned int get_cell_data_number() const
void read_dof_values(const VectorType &src, const unsigned int first_index=0)
bool values_quad_submitted
value_type get_value(const unsigned int q_point) const
FEEvaluationAccess & operator=(const FEEvaluationAccess &other)
AlignedVector< VectorizedArray< Number > > * scratch_data_array
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
gradient_type get_gradient(const unsigned int q_point) const
std::vector< unsigned int > dof_indices
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
const unsigned int dofs_per_component
unsigned long long int global_dof_index
const VectorizedArray< Number > * begin_gradients() const
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
ArrayView< VectorizedArray< Number > > get_scratch_data() const
const internal::MatrixFreeFunctions::FaceToCellTopology< VectorizedArray< Number >::n_array_elements > & get_face_info(const unsigned int face_batch_number) const
void submit_value(const value_type val_in, const unsigned int q_point)
std::vector< QuadratureDescriptor > descriptor
void scatter(const unsigned int *offsets, Number *base_ptr) const
const std::vector< unsigned int > & get_internal_dof_numbering() const
std::vector< unsigned char > n_vectorization_lanes_filled[3]
unsigned int vectorization_length
const Tensor< 1, dim, VectorizedArray< Number > > * normal_vectors
void submit_curl(const Tensor< 1, dim==2?1:dim, VectorizedArray< Number >> curl_in, const unsigned int q_point)
const Number * quadrature_weights
unsigned int element_multiplicity(const unsigned int index) const
void read_dof_values_plain(const VectorType &src, const unsigned int first_index=0)
const unsigned int dofs_per_cell
internal::MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index
static::ExceptionBase & ExcMessage(std::string arg1)
const unsigned int n_q_points
void submit_symmetric_gradient(const SymmetricTensor< 2, dim, VectorizedArray< Number >> grad_in, const unsigned int q_point)
const Tensor< 2, dim, VectorizedArray< Number > > * jacobian
std::vector< unsigned int > dof_indices_interleaved
const unsigned int quad_no
VectorizedArray< Number > * scratch_data
#define Assert(cond, exc)
Point< dim, VectorizedArray< Number > > quadrature_point(const unsigned int q_point) const
const internal::MatrixFreeFunctions::DoFInfo * dof_info
unsigned int n_components() const
unsigned int subface_index
bool indices_initialized() const
std::vector< unsigned int > row_starts_plain_indices
std::pair< unsigned int, unsigned int > component_to_base_index(const unsigned int component) const
unsigned int n_q_points_face
const MatrixFree< dim, Number > * matrix_info
const VectorizedArray< Number > * begin_values() const
#define DeclException0(Exception0)
std::vector< unsigned int > boundary_partition_data
SymmetricTensor< 2, dim, VectorizedArray< Number > > get_symmetric_gradient(const unsigned int q_point) const
void release_scratch_data(const AlignedVector< VectorizedArray< Number >> *memory) const
std::vector< std::pair< unsigned int, unsigned int > > row_starts
void reinit(const unsigned int face_batch_number)
Tensor< 2, dim, VectorizedArray< Number > > inverse_jacobian(const unsigned int q_index) const
void fill_JxW_values(AlignedVector< VectorizedArray< Number >> &JxW_values) const
VectorizedArray< Number > * gradients_quad[n_components][dim]
std::shared_ptr< internal::MatrixFreeFunctions::MappingDataOnTheFly< dim, Number > > mapped_geometry
friend class FEEvaluationBase
void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients)
std::vector< std::pair< unsigned short, unsigned short > > constraint_indicator
unsigned char subface_index
VectorizedArray< Number > read_cell_data(const AlignedVector< VectorizedArray< Number >> &array) const
const VectorizedArray< Number > * J_value
bool hessians_quad_initialized
AlignedVector< Point< spacedim, VectorizedArray< Number > > > quadrature_points
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
bool partitioners_are_compatible(const Utilities::MPI::Partitioner &part) const
void reinit(const unsigned int cell_batch_index)
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0) const
void adjust_for_face_orientation(const bool integrate, const bool values, const bool gradients)
void integrate(const bool integrate_values, const bool integrate_gradients)
static constexpr unsigned int n_components
const Number * constraint_pool_end(const unsigned int pool_index) const
std::vector< unsigned int > face_partition_data
unsigned int n_base_elements(const unsigned int dof_handler_index) const
unsigned char exterior_face_no
void read_write_operation_global(const VectorOperation &operation, VectorType *vectors[]) const
FEFaceEvaluation(const MatrixFree< dim, Number > &matrix_free, const bool is_interior_face=true, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
void resize_fast(const size_type size)
unsigned int n_q_points_1d
void evaluate(const bool evaluate_values, const bool evaluate_gradients)
std::vector< unsigned int > dof_indices_contiguous[3]
AlignedVector< Tensor< 1, spacedim, VectorizedArray< Number > > > normal_vectors
const unsigned int n_q_points
std::vector< std::vector< unsigned int > > component_dof_indices_offset
const VectorizedArray< Number > * begin_dof_values() const
VectorizedArray< Number > * values_dofs[n_components]
VectorizedArray< Number > get_divergence(const unsigned int q_point) const
static constexpr unsigned int static_dofs_per_component
const unsigned int n_quadrature_points
void gather(const Number *base_ptr, const unsigned int *offsets)
const unsigned int dofs_per_component
static::ExceptionBase & ExcNotImplemented()
const Tensor< 1, dim, VectorizedArray< Number > > * normal_x_jacobian
value_type get_normal_derivative(const unsigned int q_point) const
std::vector< types::global_dof_index > local_dof_indices
gradient_type get_hessian_diagonal(const unsigned int q_point) const
bool dof_values_initialized
void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
VectorizedArray< Number > * values_quad[n_components]
void submit_dof_value(const value_type val_in, const unsigned int dof)
bool gradients_quad_initialized
std::vector< unsigned int > start_components
const Number * constraint_pool_begin(const unsigned int pool_index) const
void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector)
std::vector< unsigned int > lexicographic_numbering
FEEvaluation(const MatrixFree< dim, Number > &matrix_free, const unsigned int dof_no=0, const unsigned int quad_no=0, const unsigned int first_selected_component=0)
const VectorizedArray< Number > * begin_hessians() const
AlignedVector< VectorizedArray< Number > > * acquire_scratch_data() const
FEEvaluationAccess(const MatrixFree< dim, Number > &matrix_free, const unsigned int dof_no, const unsigned int first_selected_component, const unsigned int quad_no, const unsigned int fe_degree, const unsigned int n_q_points, const bool is_interior_face=true)
unsigned int face_orientation
void set_dof_values(VectorType &dst, const unsigned int first_index=0) const
static constexpr unsigned int static_n_q_points
value_type get_laplacian(const unsigned int q_point) const
AlignedVector< Tensor< 2, spacedim, VectorizedArray< Number > > > jacobians[2]
unsigned char interior_face_no
AlignedVector< VectorizedArray< Number > > JxW_values
value_type get_dof_value(const unsigned int dof) const
const unsigned int n_fe_components
void submit_gradient(const gradient_type grad_in, const unsigned int q_point)
const unsigned int first_selected_component
static::ExceptionBase & ExcInternalError()
Tensor< 1, n_components_, Tensor< 2, dim, VectorizedArray< Number > > > get_hessian(const unsigned int q_point) const
Tensor< 1,(dim==2?1:dim), VectorizedArray< Number > > get_curl(const unsigned int q_point) const