17 #ifndef dealii_matrix_free_fe_evaluation_h
18 #define dealii_matrix_free_fe_evaluation_h
53 int n_q_points_1d = fe_degree + 1,
54 int n_components_ = 1,
101 "Type of Number and of VectorizedArrayType do not match.");
184 template <
typename VectorType>
216 template <
typename VectorType>
219 const unsigned int first_index = 0);
251 template <
typename VectorType>
255 const unsigned int first_index = 0,
256 const std::bitset<VectorizedArrayType::size()> &mask =
257 std::bitset<VectorizedArrayType::size()>().flip())
const;
291 template <
typename VectorType>
294 const unsigned int first_index = 0,
295 const std::bitset<VectorizedArrayType::size()> &mask =
296 std::bitset<VectorizedArrayType::size()>().flip())
const;
348 get_value(
const unsigned int q_point)
const;
426 const unsigned int q_point);
496 Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
497 get_curl(
const unsigned int q_point)
const;
516 const unsigned int q_point);
537 const unsigned int q_point);
553 const unsigned int q_point);
581 JxW(
const unsigned int q_index)
const;
628 template <
typename T>
629 std::array<
T, VectorizedArrayType::size()>
637 std::array<
unsigned int, VectorizedArrayType::size()>
654 const VectorizedArrayType *
665 VectorizedArrayType *
678 const VectorizedArrayType *
691 VectorizedArrayType *
705 const VectorizedArrayType *
719 VectorizedArrayType *
734 const VectorizedArrayType *
749 VectorizedArrayType *
757 const std::vector<unsigned int> &
782 const unsigned int dof_no,
785 const unsigned int fe_degree,
786 const unsigned int n_q_points,
823 template <
int n_components_other>
833 VectorizedArrayType> *other);
858 template <
typename VectorType,
typename VectorOperation>
862 const std::bitset<VectorizedArrayType::size()> &mask,
863 const bool apply_constraints =
true)
const;
872 template <
typename VectorType,
typename VectorOperation>
877 const std::bitset<VectorizedArrayType::size()> &mask)
const;
886 template <
typename VectorType,
typename VectorOperation>
1005 (is_face ? dim - 1 : dim),
1140 std::shared_ptr<internal::MatrixFreeFunctions::
1141 MappingDataOnTheFly<dim, Number, VectorizedArrayType>>
1165 template <
int,
int,
typename,
bool,
typename>
1167 template <
int,
int,
int,
int,
typename,
typename>
1191 VectorizedArrayType>
1195 "Type of Number and of VectorizedArrayType do not match.");
1217 const unsigned int dof_no,
1220 const unsigned int fe_degree,
1221 const unsigned int n_q_points,
1228 template <
int n_components_other>
1238 VectorizedArrayType> *other);
1264 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
1270 "Type of Number and of VectorizedArrayType do not match.");
1293 get_value(
const unsigned int q_point)
const;
1304 const unsigned int q_point);
1325 const unsigned int q_point);
1357 const unsigned int dof_no,
1360 const unsigned int fe_degree,
1361 const unsigned int n_q_points,
1368 template <
int n_components_other>
1378 VectorizedArrayType> *other);
1405 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
1411 "Type of Number and of VectorizedArrayType do not match.");
1447 Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
1448 get_curl(
const unsigned int q_point)
const;
1476 const unsigned int q_point);
1488 const unsigned int q_point);
1501 const unsigned int q_point);
1509 const unsigned int q_point);
1521 const unsigned int dof_no,
1524 const unsigned int dofs_per_cell,
1525 const unsigned int n_q_points,
1532 template <
int n_components_other>
1542 VectorizedArrayType> *other);
1568 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
1574 "Type of Number and of VectorizedArrayType do not match.");
1597 get_value(
const unsigned int q_point)
const;
1633 const unsigned int q_point);
1639 const unsigned int q_point);
1671 const unsigned int dof_no,
1674 const unsigned int fe_degree,
1675 const unsigned int n_q_points,
1682 template <
int n_components_other>
1692 VectorizedArrayType> *other);
2258 typename VectorizedArrayType>
2263 VectorizedArrayType>
2267 "Type of Number and of VectorizedArrayType do not match.");
2371 const unsigned int dof_no = 0,
2372 const unsigned int quad_no = 0,
2373 const unsigned int first_selected_component = 0);
2405 const unsigned int first_selected_component = 0);
2415 const unsigned int first_selected_component = 0);
2427 template <
int n_components_other>
2433 VectorizedArrayType> &other,
2434 const unsigned int first_selected_component = 0);
2462 reinit(
const unsigned int cell_batch_index);
2476 template <
typename DoFHandlerType,
bool level_dof_access>
2504 evaluate(
const bool evaluate_values,
2505 const bool evaluate_gradients,
2506 const bool evaluate_hessians =
false);
2521 evaluate(
const VectorizedArrayType *values_array,
2522 const bool evaluate_values,
2523 const bool evaluate_gradients,
2524 const bool evaluate_hessians =
false);
2539 template <
typename VectorType>
2542 const bool evaluate_values,
2543 const bool evaluate_gradients,
2544 const bool evaluate_hessians =
false);
2557 integrate(
const bool integrate_values,
const bool integrate_gradients);
2572 const bool integrate_gradients,
2573 VectorizedArrayType *values_array);
2588 template <
typename VectorType>
2591 const bool integrate_gradients,
2633 const unsigned int first_selected_component);
2677 int n_q_points_1d = fe_degree + 1,
2678 int n_components_ = 1,
2679 typename Number =
double,
2685 VectorizedArrayType>
2689 "Type of Number and of VectorizedArrayType do not match.");
2806 const unsigned int dof_no = 0,
2807 const unsigned int quad_no = 0,
2821 reinit(
const unsigned int face_batch_number);
2831 reinit(
const unsigned int cell_batch_number,
const unsigned int face_number);
2844 evaluate(
const bool evaluate_values,
const bool evaluate_gradients);
2859 evaluate(
const VectorizedArrayType *values_array,
2860 const bool evaluate_values,
2861 const bool evaluate_gradients);
2874 template <
typename VectorType>
2877 const bool evaluate_values,
2878 const bool evaluate_gradients);
2890 integrate(
const bool integrate_values,
const bool integrate_gradients);
2902 const bool integrate_gradients,
2903 VectorizedArrayType *values_array);
2916 template <
typename VectorType>
2919 const bool integrate_gradients,
2959 namespace MatrixFreeFunctions
2963 template <
int dim,
int degree>
2972 template <
int degree>
2975 static constexpr
unsigned int value = degree + 1;
2993 typename VectorizedArrayType>
2998 VectorizedArrayType>::
3000 const unsigned int dof_no,
3001 const unsigned int first_selected_component,
3002 const unsigned int quad_no_in,
3003 const unsigned int fe_degree,
3004 const unsigned int n_q_points,
3005 const bool is_interior_face)
3006 : scratch_data_array(data_in.acquire_scratch_data())
3007 , quad_no(quad_no_in)
3008 , n_fe_components(data_in.get_dof_info(dof_no).start_components.back())
3010 data_in.get_dof_info(dof_no).fe_index_from_degree(
3011 first_selected_component,
3015 (is_face ? data_in.get_mapping_info()
3016 .face_data[quad_no_in]
3017 .quad_index_from_n_q_points(n_q_points) :
3018 data_in.get_mapping_info()
3019 .cell_data[quad_no_in]
3020 .quad_index_from_n_q_points(n_q_points)) :
3025 .get_shape_info(dof_no,
3031 .get_shape_info(dof_no,
3036 , matrix_info(&data_in)
3037 , dof_info(&data_in.get_dof_info(dof_no))
3040 MappingInfoCellsOrFaces<dim, Number, is_face, VectorizedArrayType>::get(
3041 data_in.get_mapping_info(),
3043 , data(&data_in.get_shape_info(
3046 dof_info->component_to_base_index[first_selected_component],
3051 , normal_vectors(nullptr)
3052 , normal_x_jacobian(nullptr)
3053 , quadrature_weights(
3054 mapping_data->descriptor[active_quad_index].quadrature_weights.
begin())
3056 , is_interior_face(is_interior_face)
3060 internal::MatrixFreeFunctions::DoFInfo::dof_access_face_interior :
3061 internal::MatrixFreeFunctions::DoFInfo::dof_access_face_exterior) :
3062 internal::MatrixFreeFunctions::DoFInfo::dof_access_cell)
3064 , dof_values_initialized(false)
3065 , values_quad_initialized(false)
3066 , gradients_quad_initialized(false)
3067 , hessians_quad_initialized(false)
3068 , values_quad_submitted(false)
3069 , gradients_quad_submitted(false)
3070 , first_selected_component(first_selected_component)
3072 set_data_pointers();
3075 VectorizedArrayType::size());
3077 n_quadrature_points);
3079 mapping_data->descriptor[active_quad_index].n_q_points);
3081 dof_info->start_components.back() == 1 ||
3082 static_cast<int>(n_components_) <=
3084 dof_info->start_components
3085 [dof_info->component_to_base_index[first_selected_component] + 1]) -
3086 first_selected_component,
3088 "You tried to construct a vector-valued evaluator with " +
3090 " components. However, "
3091 "the current base element has only " +
3093 dof_info->start_components
3094 [dof_info->component_to_base_index[first_selected_component] + 1] -
3095 first_selected_component) +
3096 " components left when starting from local element index " +
3098 first_selected_component -
3099 dof_info->start_components
3100 [dof_info->component_to_base_index[first_selected_component]]) +
3101 " (global index " +
std::to_string(first_selected_component) +
")"));
3113 typename VectorizedArrayType>
3114 template <
int n_components_other>
3119 VectorizedArrayType>::
3124 const unsigned int first_selected_component,
3129 VectorizedArrayType> *other)
3130 : scratch_data_array(new
AlignedVector<VectorizedArrayType>())
3132 , n_fe_components(n_components_)
3135 , n_quadrature_points(
3137 , matrix_info(nullptr)
3139 , mapping_data(nullptr)
3142 data(new
internal::MatrixFreeFunctions::ShapeInfo<VectorizedArrayType>(
3145 fe.component_to_base_index(first_selected_component).
first))
3148 , normal_vectors(nullptr)
3149 , normal_x_jacobian(nullptr)
3150 , quadrature_weights(nullptr)
3153 , is_interior_face(true)
3154 , dof_access_index(
internal::MatrixFreeFunctions::DoFInfo::dof_access_cell)
3155 , dof_values_initialized(false)
3156 , values_quad_initialized(false)
3157 , gradients_quad_initialized(false)
3158 , hessians_quad_initialized(false)
3159 , values_quad_submitted(false)
3160 , gradients_quad_submitted(false)
3164 first_selected_component(first_selected_component)
3166 set_data_pointers();
3168 Assert(other ==
nullptr || other->mapped_geometry.get() !=
nullptr,
3170 if (other !=
nullptr &&
3171 other->mapped_geometry->get_quadrature() == quadrature)
3172 mapped_geometry = other->mapped_geometry;
3175 std::make_shared<internal::MatrixFreeFunctions::
3176 MappingDataOnTheFly<dim, Number, VectorizedArrayType>>(
3177 mapping, quadrature, update_flags);
3180 mapping_data = &mapped_geometry->get_data_storage();
3181 jacobian = mapped_geometry->get_data_storage().jacobians[0].begin();
3182 J_value = mapped_geometry->get_data_storage().JxW_values.begin();
3184 const unsigned int base_element_number =
3188 first_selected_component >=
3190 ExcMessage(
"The underlying element must at least contain as many "
3191 "components as requested by this class"));
3192 (void)base_element_number;
3201 typename VectorizedArrayType>
3206 VectorizedArrayType>::
3211 VectorizedArrayType> &other)
3212 : scratch_data_array(other.matrix_info == nullptr ?
3214 other.matrix_info->acquire_scratch_data())
3215 , quad_no(other.quad_no)
3216 , n_fe_components(other.n_fe_components)
3217 , active_fe_index(other.active_fe_index)
3218 , active_quad_index(other.active_quad_index)
3219 , n_quadrature_points(other.n_quadrature_points)
3220 , matrix_info(other.matrix_info)
3221 , dof_info(other.dof_info)
3222 , mapping_data(other.mapping_data)
3223 , data(other.matrix_info == nullptr ?
3224 new
internal::MatrixFreeFunctions::ShapeInfo<VectorizedArrayType>(
3229 , normal_vectors(nullptr)
3230 , normal_x_jacobian(nullptr)
3231 , quadrature_weights(
3232 other.matrix_info == nullptr ?
3234 mapping_data->descriptor[active_quad_index].quadrature_weights.
begin())
3237 , is_interior_face(other.is_interior_face)
3238 , dof_access_index(other.dof_access_index)
3239 , dof_values_initialized(false)
3240 , values_quad_initialized(false)
3241 , gradients_quad_initialized(false)
3242 , hessians_quad_initialized(false)
3243 , values_quad_submitted(false)
3244 , gradients_quad_submitted(false)
3245 , first_selected_component(other.first_selected_component)
3247 set_data_pointers();
3250 if (other.mapped_geometry.get() !=
nullptr)
3252 mapped_geometry = std::make_shared<
3253 internal::MatrixFreeFunctions::
3254 MappingDataOnTheFly<dim, Number, VectorizedArrayType>>(
3255 other.mapped_geometry->get_fe_values().get_mapping(),
3256 other.mapped_geometry->get_quadrature(),
3257 other.mapped_geometry->get_fe_values().get_update_flags());
3258 mapping_data = &mapped_geometry->get_data_storage();
3261 jacobian = mapped_geometry->get_data_storage().jacobians[0].begin();
3262 J_value = mapped_geometry->get_data_storage().JxW_values.begin();
3272 typename VectorizedArrayType>
3277 VectorizedArrayType> &
3283 VectorizedArrayType> &other)
3289 AssertDimension(first_selected_component, other.first_selected_component);
3292 if (matrix_info ==
nullptr)
3295 delete scratch_data_array;
3299 matrix_info->release_scratch_data(scratch_data_array);
3302 matrix_info = other.matrix_info;
3303 dof_info = other.dof_info;
3304 mapping_data = other.mapping_data;
3305 if (other.matrix_info ==
nullptr)
3314 scratch_data_array = matrix_info->acquire_scratch_data();
3316 set_data_pointers();
3318 quadrature_weights =
3319 (mapping_data !=
nullptr ?
3320 mapping_data->descriptor[active_quad_index].quadrature_weights.begin() :
3324 is_interior_face = other.is_interior_face;
3325 dof_access_index = other.dof_access_index;
3328 if (other.mapped_geometry.get() !=
nullptr)
3330 mapped_geometry = std::make_shared<
3331 internal::MatrixFreeFunctions::
3332 MappingDataOnTheFly<dim, Number, VectorizedArrayType>>(
3333 other.mapped_geometry->get_fe_values().get_mapping(),
3334 other.mapped_geometry->get_quadrature(),
3335 other.mapped_geometry->get_fe_values().get_update_flags());
3337 mapping_data = &mapped_geometry->get_data_storage();
3338 jacobian = mapped_geometry->get_data_storage().jacobians[0].begin();
3339 J_value = mapped_geometry->get_data_storage().JxW_values.begin();
3351 typename VectorizedArrayType>
3356 VectorizedArrayType>::~FEEvaluationBase()
3358 if (matrix_info !=
nullptr)
3362 matrix_info->release_scratch_data(scratch_data_array);
3369 delete scratch_data_array;
3373 scratch_data_array =
nullptr;
3382 typename VectorizedArrayType>
3389 const unsigned int tensor_dofs_per_component =
3390 Utilities::fixed_power<dim>(this->data->data.front().fe_degree + 1);
3391 const unsigned int dofs_per_component =
3392 this->data->dofs_per_component_on_cell;
3393 const unsigned int n_quadrature_points =
3394 is_face ? this->data->n_q_points_face : this->data->n_q_points;
3396 const unsigned int shift =
3397 std::max(tensor_dofs_per_component + 1, dofs_per_component) *
3399 2 * n_quadrature_points;
3400 const unsigned int allocated_size =
3401 shift + n_components_ * dofs_per_component +
3402 (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3403 scratch_data_array->resize_fast(allocated_size);
3406 for (
unsigned int c = 0; c < n_components_; ++c)
3408 this->values_dofs[c] =
3409 scratch_data_array->begin() + c * dofs_per_component;
3410 this->values_quad[c] = scratch_data_array->begin() +
3412 c * n_quadrature_points;
3413 for (
unsigned int d = 0;
d < dim; ++
d)
3414 this->gradients_quad[c][
d] =
3415 scratch_data_array->begin() +
3416 n_components * (dofs_per_component + n_quadrature_points) +
3417 (c * dim +
d) * n_quadrature_points;
3418 for (
unsigned int d = 0;
d < (dim * dim + dim) / 2; ++
d)
3419 this->hessians_quad[c][
d] =
3420 scratch_data_array->begin() +
3422 ((dim + 1) * n_quadrature_points + dofs_per_component) +
3423 (c * (dim * dim + dim) +
d) * n_quadrature_points;
3426 scratch_data_array->begin() + n_components_ * dofs_per_component +
3427 (n_components_ * (dim * dim + 2 * dim + 1) * n_quadrature_points);
3436 typename VectorizedArrayType>
3441 if (matrix_info ==
nullptr)
3446 return this->mapping_data->data_index_offsets[cell];
3456 typename VectorizedArrayType>
3471 typename VectorizedArrayType>
3486 typename VectorizedArrayType>
3495 VectorizedArrayType J = J_value[0];
3496 for (
unsigned int q = 0; q < this->n_quadrature_points; ++q)
3497 JxW_values[q] = J * this->quadrature_weights[q];
3500 for (
unsigned int q = 0; q < n_quadrature_points; ++q)
3501 JxW_values[q] = J_value[q];
3510 typename VectorizedArrayType>
3518 return normal_vectors[0];
3520 return normal_vectors[q_index];
3529 typename VectorizedArrayType>
3532 const unsigned int q_index)
const
3539 return J_value[0] * this->quadrature_weights[q_index];
3542 return J_value[q_index];
3551 typename VectorizedArrayType>
3561 return jacobian[q_index];
3568 typename VectorizedArrayType>
3569 std::array<
unsigned int, VectorizedArrayType::size()>
3573 const unsigned int n_lanes = VectorizedArrayType::size();
3574 std::array<unsigned int, n_lanes> cells;
3577 for (
unsigned int i = 0; i < n_lanes; ++i)
3580 if ((is_face ==
false) ||
3582 this->dof_access_index ==
3584 this->is_interior_face))
3587 for (
unsigned int i = 0; i < n_lanes; ++i)
3588 cells[i] = cell * n_lanes + i;
3591 this->dof_access_index ==
3593 this->is_interior_face ==
false)
3599 for (
unsigned int i = 0; i < n_lanes; i++)
3602 const unsigned int cell_this = this->cell * n_lanes + i;
3604 unsigned int face_index =
3605 this->matrix_info->get_cell_and_face_to_plain_faces()(this->cell,
3613 auto cell_m = this->matrix_info->get_face_info(face_index / n_lanes)
3614 .cells_interior[face_index % n_lanes];
3615 auto cell_p = this->matrix_info->get_face_info(face_index / n_lanes)
3616 .cells_exterior[face_index % n_lanes];
3619 if (cell_m == cell_this)
3621 else if (cell_p == cell_this)
3628 const unsigned int *cells_ =
3630 &this->matrix_info->get_face_info(cell).cells_interior[0] :
3631 &this->matrix_info->get_face_info(cell).cells_exterior[0];
3632 for (
unsigned int i = 0; i < VectorizedArrayType::size(); ++i)
3634 cells[i] = cells_[i];
3646 typename VectorizedArrayType>
3647 inline VectorizedArrayType
3653 matrix_info->get_task_info().cell_partition_data.back());
3656 const auto cells = this->get_cell_ids();
3659 VectorizedArrayType out = make_vectorized_array<Number>(Number(1.));
3660 for (
unsigned int i = 0; i < VectorizedArrayType::size(); ++i)
3662 out[i] = array[cells[i] / VectorizedArrayType::size()]
3663 [cells[i] % VectorizedArrayType::size()];
3673 typename VectorizedArrayType>
3674 template <
typename T>
3675 inline std::array<
T, VectorizedArrayType::size()>
3682 matrix_info->get_task_info().cell_partition_data.back());
3685 const auto cells = this->get_cell_ids();
3688 std::array<
T, VectorizedArrayType::size()> out;
3689 for (
unsigned int i = 0; i < VectorizedArrayType::size(); ++i)
3691 out[i] = array[cells[i] / VectorizedArrayType::size()]
3692 [cells[i] % VectorizedArrayType::size()];
3703 template <
typename VectorType,
bool>
3704 struct BlockVectorSelector
3707 template <
typename VectorType>
3710 using BaseVectorType =
typename VectorType::BlockType;
3712 static BaseVectorType *
3713 get_vector_component(
VectorType &vec,
const unsigned int component)
3716 return &vec.block(component);
3720 template <
typename VectorType>
3721 struct BlockVectorSelector<
VectorType, false>
3725 static BaseVectorType *
3726 get_vector_component(
VectorType &vec,
const unsigned int component)
3745 template <
typename VectorType>
3746 struct BlockVectorSelector<std::vector<VectorType>, false>
3750 static BaseVectorType *
3751 get_vector_component(std::vector<VectorType> &vec,
3752 const unsigned int component)
3755 return &vec[component];
3759 template <
typename VectorType>
3760 struct BlockVectorSelector<std::vector<VectorType *>, false>
3764 static BaseVectorType *
3765 get_vector_component(std::vector<VectorType *> &vec,
3766 const unsigned int component)
3769 return vec[component];
3780 typename VectorizedArrayType>
3781 template <
typename VectorType,
typename VectorOperation>
3786 const std::bitset<VectorizedArrayType::size()> &mask,
3787 const bool apply_constraints)
const
3792 if (matrix_info ==
nullptr)
3794 read_write_operation_global(operation, src);
3800 if (n_fe_components == 1)
3801 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3803 Assert(src[comp] !=
nullptr,
3804 ExcMessage(
"The finite element underlying this FEEvaluation "
3805 "object is scalar, but you requested " +
3807 " components via the template argument in "
3808 "FEEvaluation. In that case, you must pass an "
3809 "std::vector<VectorType> or a BlockVector to " +
3810 "read_dof_values and distribute_local_to_global."));
3821 dof_info->index_storage_variants[dof_access_index].size());
3822 if (dof_info->index_storage_variants
3823 [is_face ? dof_access_index :
3828 read_write_operation_contiguous(operation, src, mask);
3834 constexpr
unsigned int n_lanes = VectorizedArrayType::size();
3835 Assert(mask.count() == n_lanes,
3837 "non-contiguous DoF storage"));
3839 std::integral_constant<
bool,
3843 const unsigned int dofs_per_component =
3844 this->data->dofs_per_component_on_cell;
3845 if (dof_info->index_storage_variants
3846 [is_face ? dof_access_index :
3851 const unsigned int *dof_indices =
3852 dof_info->dof_indices_interleaved.data() +
3853 dof_info->row_starts[cell * n_fe_components * n_lanes].first +
3854 dof_info->component_dof_indices_offset[active_fe_index]
3855 [first_selected_component] *
3858 for (
unsigned int i = 0; i < dofs_per_component;
3859 ++i, dof_indices += n_lanes)
3860 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3861 operation.process_dof_gather(dof_indices,
3864 values_dofs[comp][i],
3867 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3868 for (
unsigned int i = 0; i < dofs_per_component;
3869 ++i, dof_indices += n_lanes)
3870 operation.process_dof_gather(
3871 dof_indices, *src[0], 0, values_dofs[comp][i], vector_selector);
3875 const unsigned int * dof_indices[n_lanes];
3876 VectorizedArrayType **values_dofs =
3877 const_cast<VectorizedArrayType **
>(&this->values_dofs[0]);
3881 unsigned int cells_copied[n_lanes];
3882 const unsigned int *cells;
3883 unsigned int n_vectorization_actual =
3884 dof_info->n_vectorization_lanes_filled[dof_access_index][cell];
3885 bool has_constraints =
false;
3888 if (dof_access_index ==
3890 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3891 cells_copied[v] = cell * VectorizedArrayType::size() + v;
3892 cells = dof_access_index ==
3896 &this->matrix_info->get_face_info(cell).cells_interior[0] :
3897 &this->matrix_info->get_face_info(cell).cells_exterior[0]);
3898 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3900 Assert(cells[v] < dof_info->row_starts.size() - 1,
3902 const std::pair<unsigned int, unsigned int> *my_index_start =
3903 &dof_info->row_starts[cells[v] * n_fe_components +
3904 first_selected_component];
3910 has_constraints =
true;
3913 dof_info->dof_indices.data() + my_index_start[0].first;
3915 for (
unsigned int v = n_vectorization_actual; v < n_lanes; ++v)
3916 dof_indices[v] =
nullptr;
3921 dof_info->row_starts.size());
3922 const unsigned int n_components_read =
3924 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3926 const std::pair<unsigned int, unsigned int> *my_index_start =
3927 &dof_info->row_starts[(cell * n_lanes + v) * n_fe_components +
3928 first_selected_component];
3929 if (my_index_start[n_components_read].
second !=
3930 my_index_start[0].
second)
3931 has_constraints =
true;
3933 my_index_start[0].
first ||
3934 my_index_start[0].first < dof_info->dof_indices.size(),
3936 my_index_start[0].
first,
3937 dof_info->dof_indices.size()));
3939 dof_info->dof_indices.data() + my_index_start[0].first;
3941 for (
unsigned int v = n_vectorization_actual; v < n_lanes; ++v)
3942 dof_indices[v] =
nullptr;
3947 if (!has_constraints)
3949 if (n_vectorization_actual < n_lanes)
3950 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3951 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3952 operation.process_empty(values_dofs[comp][i]);
3955 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3956 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3957 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3958 operation.process_dof(dof_indices[v][i],
3960 values_dofs[comp][i][v]);
3964 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3965 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3966 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3967 operation.process_dof(
3968 dof_indices[v][comp * dofs_per_component + i],
3970 values_dofs[comp][i][v]);
3980 if (n_vectorization_actual < n_lanes)
3981 for (
unsigned int comp = 0; comp <
n_components; ++comp)
3982 for (
unsigned int i = 0; i < dofs_per_component; ++i)
3983 operation.process_empty(values_dofs[comp][i]);
3984 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
3986 const unsigned int cell_index = is_face ? cells[v] : cell * n_lanes + v;
3987 const unsigned int cell_dof_index =
3988 cell_index * n_fe_components + first_selected_component;
3989 const unsigned int n_components_read =
3991 unsigned int index_indicators =
3992 dof_info->row_starts[cell_dof_index].second;
3993 unsigned int next_index_indicators =
3994 dof_info->row_starts[cell_dof_index + 1].second;
3998 if (apply_constraints ==
false &&
3999 dof_info->row_starts[cell_dof_index].second !=
4000 dof_info->row_starts[cell_dof_index + n_components_read].second)
4002 Assert(dof_info->row_starts_plain_indices[cell_index] !=
4006 dof_info->plain_dof_indices.data() +
4007 dof_info->component_dof_indices_offset[active_fe_index]
4008 [first_selected_component] +
4009 dof_info->row_starts_plain_indices[cell_index];
4010 next_index_indicators = index_indicators;
4015 unsigned int ind_local = 0;
4016 for (; index_indicators != next_index_indicators; ++index_indicators)
4018 const std::pair<unsigned short, unsigned short> indicator =
4019 dof_info->constraint_indicator[index_indicators];
4021 for (
unsigned int j = 0; j < indicator.first; ++j)
4022 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4023 operation.process_dof(dof_indices[v][j],
4025 values_dofs[comp][ind_local + j][v]);
4027 ind_local += indicator.first;
4028 dof_indices[v] += indicator.first;
4033 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4034 operation.pre_constraints(values_dofs[comp][ind_local][v],
4037 const Number *data_val =
4038 matrix_info->constraint_pool_begin(indicator.second);
4039 const Number *end_pool =
4040 matrix_info->constraint_pool_end(indicator.second);
4041 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4042 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4043 operation.process_constraint(*dof_indices[v],
4048 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4049 operation.post_constraints(
value[comp],
4050 values_dofs[comp][ind_local][v]);
4056 for (; ind_local < dofs_per_component; ++dof_indices[v], ++ind_local)
4057 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4058 operation.process_dof(*dof_indices[v],
4060 values_dofs[comp][ind_local][v]);
4069 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4071 unsigned int ind_local = 0;
4074 for (; index_indicators != next_index_indicators;
4077 const std::pair<unsigned short, unsigned short> indicator =
4078 dof_info->constraint_indicator[index_indicators];
4081 for (
unsigned int j = 0; j < indicator.first; ++j)
4082 operation.process_dof(dof_indices[v][j],
4084 values_dofs[comp][ind_local + j][v]);
4085 ind_local += indicator.first;
4086 dof_indices[v] += indicator.first;
4091 operation.pre_constraints(values_dofs[comp][ind_local][v],
4094 const Number *data_val =
4095 matrix_info->constraint_pool_begin(indicator.second);
4096 const Number *end_pool =
4097 matrix_info->constraint_pool_end(indicator.second);
4099 for (; data_val != end_pool; ++data_val, ++dof_indices[v])
4100 operation.process_constraint(*dof_indices[v],
4105 operation.post_constraints(
value,
4106 values_dofs[comp][ind_local][v]);
4113 for (; ind_local < dofs_per_component;
4114 ++dof_indices[v], ++ind_local)
4117 operation.process_dof(*dof_indices[v],
4119 values_dofs[comp][ind_local][v]);
4122 if (apply_constraints ==
true && comp + 1 <
n_components)
4123 next_index_indicators =
4124 dof_info->row_starts[cell_dof_index + comp + 2].second;
4136 typename VectorizedArrayType>
4137 template <
typename VectorType,
typename VectorOperation>
4145 unsigned int index =
4146 first_selected_component * data->dofs_per_component_on_cell;
4147 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4149 for (
unsigned int i = 0; i < data->dofs_per_component_on_cell;
4152 operation.process_empty(values_dofs[comp][i]);
4153 operation.process_dof_global(
4154 local_dof_indices[data->lexicographic_numbering[index]],
4156 values_dofs[comp][i][0]);
4167 typename VectorizedArrayType>
4168 template <
typename VectorType,
typename VectorOperation>
4174 const std::bitset<VectorizedArrayType::size()> &mask)
const
4183 std::integral_constant<
bool,
4187 is_face ? dof_access_index :
4189 const unsigned int n_lanes = mask.count();
4191 const std::vector<unsigned int> &dof_indices_cont =
4192 dof_info->dof_indices_contiguous[ind];
4196 if (dof_info->index_storage_variants[ind][cell] ==
4198 interleaved_contiguous &&
4199 n_lanes == VectorizedArrayType::size())
4201 const unsigned int dof_index =
4202 dof_indices_cont[cell * VectorizedArrayType::size()] +
4203 dof_info->component_dof_indices_offset[active_fe_index]
4204 [first_selected_component] *
4205 VectorizedArrayType::size();
4207 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4208 operation.process_dofs_vectorized(data->dofs_per_component_on_cell,
4214 operation.process_dofs_vectorized(data->dofs_per_component_on_cell *
4225 const unsigned int n_filled_lanes =
4226 dof_info->n_vectorization_lanes_filled[ind][this->cell];
4228 unsigned int dof_indices[VectorizedArrayType::size()];
4229 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4231 dof_indices_cont[cell * VectorizedArrayType::size() + v] +
4232 dof_info->component_dof_indices_offset[active_fe_index]
4233 [first_selected_component] *
4234 dof_info->dof_indices_interleave_strides
4235 [ind][cell * VectorizedArrayType::size() + v];
4237 for (
unsigned int v = n_filled_lanes; v < VectorizedArrayType::size(); ++v)
4242 if (n_filled_lanes == VectorizedArrayType::size() &&
4243 n_lanes == VectorizedArrayType::size())
4245 if (dof_info->index_storage_variants[ind][cell] ==
4250 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4251 operation.process_dofs_vectorized_transpose(
4252 data->dofs_per_component_on_cell,
4258 operation.process_dofs_vectorized_transpose(
4265 else if (dof_info->index_storage_variants[ind][cell] ==
4267 interleaved_contiguous_strided)
4270 for (
unsigned int i = 0; i < data->dofs_per_component_on_cell; ++i)
4272 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4273 operation.process_dof_gather(dof_indices,
4275 i * VectorizedArrayType::size(),
4276 values_dofs[comp][i],
4280 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4281 for (
unsigned int i = 0; i < data->dofs_per_component_on_cell;
4284 operation.process_dof_gather(
4287 (comp * data->dofs_per_component_on_cell + i) *
4288 VectorizedArrayType::size(),
4289 values_dofs[comp][i],
4295 Assert(dof_info->index_storage_variants[ind][cell] ==
4297 IndexStorageVariants::interleaved_contiguous_mixed_strides,
4299 const unsigned int *offsets =
4300 &dof_info->dof_indices_interleave_strides
4301 [ind][VectorizedArrayType::size() * cell];
4303 for (
unsigned int i = 0; i < data->dofs_per_component_on_cell; ++i)
4305 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4306 operation.process_dof_gather(dof_indices,
4309 values_dofs[comp][i],
4312 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
4313 dof_indices[v] += offsets[v];
4316 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4317 for (
unsigned int i = 0; i < data->dofs_per_component_on_cell;
4320 operation.process_dof_gather(dof_indices,
4323 values_dofs[comp][i],
4326 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
4327 dof_indices[v] += offsets[v];
4332 for (
unsigned int comp = 0; comp <
n_components; ++comp)
4334 for (
unsigned int i = 0; i < data->dofs_per_component_on_cell; ++i)
4335 operation.process_empty(values_dofs[comp][i]);
4336 if (dof_info->index_storage_variants[ind][cell] ==
4342 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4343 if (mask[v] ==
true)
4344 for (
unsigned int i = 0;
4345 i < data->dofs_per_component_on_cell;
4347 operation.process_dof(dof_indices[v] + i,
4349 values_dofs[comp][i][v]);
4353 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4354 if (mask[v] ==
true)
4355 for (
unsigned int i = 0;
4356 i < data->dofs_per_component_on_cell;
4358 operation.process_dof(
4359 dof_indices[v] + i +
4360 comp * data->dofs_per_component_on_cell,
4362 values_dofs[comp][i][v]);
4367 const unsigned int *offsets =
4368 &dof_info->dof_indices_interleave_strides
4369 [ind][VectorizedArrayType::size() * cell];
4370 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4373 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4375 if (mask[v] ==
true)
4376 for (
unsigned int i = 0;
4377 i < data->dofs_per_component_on_cell;
4379 operation.process_dof(dof_indices[v] + i * offsets[v],
4381 values_dofs[comp][i][v]);
4385 for (
unsigned int v = 0; v < n_filled_lanes; ++v)
4386 if (mask[v] ==
true)
4387 for (
unsigned int i = 0;
4388 i < data->dofs_per_component_on_cell;
4390 operation.process_dof(
4392 (i + comp * data->dofs_per_component_on_cell) *
4395 values_dofs[comp][i][v]);
4407 typename VectorizedArrayType>
4408 template <
typename VectorType>
4415 typename internal::BlockVectorSelector<
4422 get_vector_component(
const_cast<VectorType &
>(src),
d + first_index);
4425 read_write_operation(reader,
4427 std::bitset<VectorizedArrayType::size()>().flip(),
4431 dof_values_initialized =
true;
4441 typename VectorizedArrayType>
4442 template <
typename VectorType>
4449 typename internal::BlockVectorSelector<
4456 get_vector_component(
const_cast<VectorType &
>(src),
d + first_index);
4459 read_write_operation(reader,
4461 std::bitset<VectorizedArrayType::size()>().flip(),
4465 dof_values_initialized =
true;
4475 typename VectorizedArrayType>
4476 template <
typename VectorType>
4481 const unsigned int first_index,
4482 const std::bitset<VectorizedArrayType::size()> &mask)
const
4485 Assert(dof_values_initialized ==
true,
4491 typename internal::BlockVectorSelector<
4495 dst_data[
d] = internal::BlockVectorSelector<
4502 read_write_operation(distributor, dst_data, mask);
4511 typename VectorizedArrayType>
4512 template <
typename VectorType>
4516 const unsigned int first_index,
4517 const std::bitset<VectorizedArrayType::size()> &mask)
const
4520 Assert(dof_values_initialized ==
true,
4526 typename internal::BlockVectorSelector<
4530 dst_data[
d] = internal::BlockVectorSelector<
4536 read_write_operation(setter, dst_data, mask);
4547 typename VectorizedArrayType>
4548 inline const std::vector<unsigned int> &
4552 return data->lexicographic_numbering;
4561 typename VectorizedArrayType>
4567 const_cast<VectorizedArrayType *
>(scratch_data),
4568 scratch_data_array->end() - scratch_data);
4577 typename VectorizedArrayType>
4578 inline const VectorizedArrayType *
4582 return &values_dofs[0][0];
4591 typename VectorizedArrayType>
4592 inline VectorizedArrayType *
4597 dof_values_initialized =
true;
4599 return &values_dofs[0][0];
4608 typename VectorizedArrayType>
4609 inline const VectorizedArrayType *
4616 return &values_quad[0][0];
4625 typename VectorizedArrayType>
4626 inline VectorizedArrayType *
4631 values_quad_initialized =
true;
4632 values_quad_submitted =
true;
4634 return &values_quad[0][0];
4643 typename VectorizedArrayType>
4644 inline const VectorizedArrayType *
4649 Assert(gradients_quad_initialized || gradients_quad_submitted,
4652 return &gradients_quad[0][0][0];
4661 typename VectorizedArrayType>
4662 inline VectorizedArrayType *
4667 gradients_quad_submitted =
true;
4668 gradients_quad_initialized =
true;
4670 return &gradients_quad[0][0][0];
4679 typename VectorizedArrayType>
4680 inline const VectorizedArrayType *
4687 return &hessians_quad[0][0][0];
4696 typename VectorizedArrayType>
4697 inline VectorizedArrayType *
4702 hessians_quad_initialized =
true;
4704 return &hessians_quad[0][0][0];
4713 typename VectorizedArrayType>
4720 for (
unsigned int comp = 0; comp <
n_components; comp++)
4721 return_value[comp] = this->values_dofs[comp][dof];
4722 return return_value;
4731 typename VectorizedArrayType>
4734 get_value(
const unsigned int q_point)
const
4737 Assert(this->values_quad_initialized ==
true,
4742 for (
unsigned int comp = 0; comp <
n_components; comp++)
4743 return_value[comp] = this->values_quad[comp][q_point];
4744 return return_value;
4753 typename VectorizedArrayType>
4760 Assert(this->gradients_quad_initialized ==
true,
4772 for (
unsigned int comp = 0; comp <
n_components; comp++)
4773 for (
unsigned int d = 0;
d < dim; ++
d)
4775 (this->gradients_quad[comp][
d][q_point] * jacobian[0][
d][
d]);
4784 for (
unsigned int comp = 0; comp <
n_components; comp++)
4785 for (
unsigned int d = 0;
d < dim; ++
d)
4788 jac[
d][0] * this->gradients_quad[comp][0][q_point];
4789 for (
unsigned int e = 1;
e < dim; ++
e)
4790 grad_out[comp][
d] +=
4791 jac[
d][
e] * this->gradients_quad[comp][
e][q_point];
4803 typename VectorizedArrayType>
4810 Assert(this->gradients_quad_initialized ==
true,
4818 for (
unsigned int comp = 0; comp <
n_components; comp++)
4819 grad_out[comp] = this->gradients_quad[comp][dim - 1][q_point] *
4820 (this->normal_x_jacobian[0][dim - 1]);
4823 const unsigned int index =
4825 for (
unsigned int comp = 0; comp <
n_components; comp++)
4827 grad_out[comp] = this->gradients_quad[comp][0][q_point] *
4828 this->normal_x_jacobian[index][0];
4829 for (
unsigned int d = 1;
d < dim; ++
d)
4830 grad_out[comp] += this->gradients_quad[comp][
d][q_point] *
4831 this->normal_x_jacobian[index][
d];
4843 template <
typename VectorizedArrayType>
4846 const VectorizedArrayType *
const hessians_quad[1],
4847 const unsigned int q_point,
4848 VectorizedArrayType (&tmp)[1][1])
4850 tmp[0][0] = jac[0][0] * hessians_quad[0][q_point];
4853 template <
typename VectorizedArrayType>
4856 const VectorizedArrayType *
const hessians_quad[3],
4857 const unsigned int q_point,
4858 VectorizedArrayType (&tmp)[2][2])
4860 for (
unsigned int d = 0;
d < 2; ++
d)
4862 tmp[0][
d] = (jac[
d][0] * hessians_quad[0][q_point] +
4863 jac[
d][1] * hessians_quad[2][q_point]);
4864 tmp[1][
d] = (jac[
d][0] * hessians_quad[2][q_point] +
4865 jac[
d][1] * hessians_quad[1][q_point]);
4869 template <
typename VectorizedArrayType>
4872 const VectorizedArrayType *
const hessians_quad[6],
4873 const unsigned int q_point,
4874 VectorizedArrayType (&tmp)[3][3])
4876 for (
unsigned int d = 0;
d < 3; ++
d)
4878 tmp[0][
d] = (jac[
d][0] * hessians_quad[0][q_point] +
4879 jac[
d][1] * hessians_quad[3][q_point] +
4880 jac[
d][2] * hessians_quad[4][q_point]);
4881 tmp[1][
d] = (jac[
d][0] * hessians_quad[3][q_point] +
4882 jac[
d][1] * hessians_quad[1][q_point] +
4883 jac[
d][2] * hessians_quad[5][q_point]);
4884 tmp[2][
d] = (jac[
d][0] * hessians_quad[4][q_point] +
4885 jac[
d][1] * hessians_quad[5][q_point] +
4886 jac[
d][2] * hessians_quad[2][q_point]);
4897 typename VectorizedArrayType>
4904 Assert(this->hessians_quad_initialized ==
true,
4920 for (
unsigned int comp = 0; comp <
n_components; comp++)
4921 for (
unsigned int d = 0;
d < dim; ++
d)
4923 hessian_out[comp][
d][
d] =
4924 (this->hessians_quad[comp][
d][q_point] * jac[
d][
d] * jac[
d][
d]);
4930 hessian_out[comp][0][1] =
4931 (this->hessians_quad[comp][2][q_point] * jac[0][0] *
4935 hessian_out[comp][0][1] =
4936 (this->hessians_quad[comp][3][q_point] * jac[0][0] *
4938 hessian_out[comp][0][2] =
4939 (this->hessians_quad[comp][4][q_point] * jac[0][0] *
4941 hessian_out[comp][1][2] =
4942 (this->hessians_quad[comp][5][q_point] * jac[1][1] *
4948 for (
unsigned int e =
d + 1;
e < dim; ++
e)
4949 hessian_out[comp][
e][
d] = hessian_out[comp][
d][
e];
4955 for (
unsigned int comp = 0; comp <
n_components; comp++)
4959 VectorizedArrayType tmp[dim][dim];
4960 internal::hessian_unit_times_jac(jac,
4961 this->hessians_quad[comp],
4966 for (
unsigned int d = 0;
d < dim; ++
d)
4967 for (
unsigned int e =
d;
e < dim; ++
e)
4969 hessian_out[comp][
d][
e] = jac[
d][0] * tmp[0][
e];
4970 for (
unsigned int f = 1; f < dim; ++f)
4971 hessian_out[comp][
d][
e] += jac[
d][f] * tmp[f][
e];
4978 for (
unsigned int d = 0;
d < dim; ++
d)
4979 for (
unsigned int e =
d + 1;
e < dim; ++
e)
4980 hessian_out[comp][
e][
d] = hessian_out[comp][
d][
e];
4988 mapping_data->jacobian_gradients
4989 [1 - this->is_interior_face]
4990 [this->mapping_data->data_index_offsets[this->cell] + q_point];
4991 for (
unsigned int comp = 0; comp <
n_components; comp++)
4995 VectorizedArrayType tmp[dim][dim];
4996 internal::hessian_unit_times_jac(jac,
4997 this->hessians_quad[comp],
5002 for (
unsigned int d = 0;
d < dim; ++
d)
5003 for (
unsigned int e =
d;
e < dim; ++
e)
5005 hessian_out[comp][
d][
e] = jac[
d][0] * tmp[0][
e];
5006 for (
unsigned int f = 1; f < dim; ++f)
5007 hessian_out[comp][
d][
e] += jac[
d][f] * tmp[f][
e];
5011 for (
unsigned int d = 0;
d < dim; ++
d)
5012 for (
unsigned int e = 0;
e < dim; ++
e)
5013 hessian_out[comp][
d][
d] +=
5014 (jac_grad[
d][
e] * this->gradients_quad[comp][
e][q_point]);
5017 for (
unsigned int d = 0, count = dim;
d < dim; ++
d)
5018 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++count)
5019 for (
unsigned int f = 0; f < dim; ++f)
5020 hessian_out[comp][
d][
e] +=
5021 (jac_grad[count][f] * this->gradients_quad[comp][f][q_point]);
5024 for (
unsigned int d = 0;
d < dim; ++
d)
5025 for (
unsigned int e =
d + 1;
e < dim; ++
e)
5026 hessian_out[comp][
e][
d] = hessian_out[comp][
d][
e];
5039 typename VectorizedArrayType>
5046 Assert(this->hessians_quad_initialized ==
true,
5062 for (
unsigned int comp = 0; comp <
n_components; comp++)
5063 for (
unsigned int d = 0;
d < dim; ++
d)
5064 hessian_out[comp][
d] =
5065 (this->hessians_quad[comp][
d][q_point] * jac[
d][
d] * jac[
d][
d]);
5070 for (
unsigned int comp = 0; comp <
n_components; comp++)
5074 VectorizedArrayType tmp[dim][dim];
5075 internal::hessian_unit_times_jac(jac,
5076 this->hessians_quad[comp],
5082 for (
unsigned int d = 0;
d < dim; ++
d)
5084 hessian_out[comp][
d] = jac[
d][0] * tmp[0][
d];
5085 for (
unsigned int f = 1; f < dim; ++f)
5086 hessian_out[comp][
d] += jac[
d][f] * tmp[f][
d];
5095 mapping_data->jacobian_gradients
5096 [0][this->mapping_data->data_index_offsets[this->cell] + q_point];
5097 for (
unsigned int comp = 0; comp <
n_components; comp++)
5101 VectorizedArrayType tmp[dim][dim];
5102 internal::hessian_unit_times_jac(jac,
5103 this->hessians_quad[comp],
5109 for (
unsigned int d = 0;
d < dim; ++
d)
5111 hessian_out[comp][
d] = jac[
d][0] * tmp[0][
d];
5112 for (
unsigned int f = 1; f < dim; ++f)
5113 hessian_out[comp][
d] += jac[
d][f] * tmp[f][
d];
5116 for (
unsigned int d = 0;
d < dim; ++
d)
5117 for (
unsigned int e = 0;
e < dim; ++
e)
5118 hessian_out[comp][
d] +=
5119 (jac_grad[
d][
e] * this->gradients_quad[comp][
e][q_point]);
5131 typename VectorizedArrayType>
5138 Assert(this->hessians_quad_initialized ==
true,
5145 hess_diag = get_hessian_diagonal(q_point);
5146 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5148 laplacian_out[comp] = hess_diag[comp][0];
5149 for (
unsigned int d = 1;
d < dim; ++
d)
5150 laplacian_out[comp] += hess_diag[comp][
d];
5152 return laplacian_out;
5161 typename VectorizedArrayType>
5165 const unsigned int dof)
5168 this->dof_values_initialized =
true;
5171 for (
unsigned int comp = 0; comp <
n_components; comp++)
5172 this->values_dofs[comp][dof] = val_in[comp];
5181 typename VectorizedArrayType>
5185 const unsigned int q_point)
5191 this->values_quad_submitted =
true;
5196 const VectorizedArrayType JxW = J_value[0] * quadrature_weights[q_point];
5197 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5198 this->values_quad[comp][q_point] = val_in[comp] * JxW;
5202 const VectorizedArrayType JxW = J_value[q_point];
5203 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5204 this->values_quad[comp][q_point] = val_in[comp] * JxW;
5214 typename VectorizedArrayType>
5219 const unsigned int q_point)
5226 this->gradients_quad_submitted =
true;
5231 const VectorizedArrayType JxW = J_value[0] * quadrature_weights[q_point];
5232 for (
unsigned int comp = 0; comp <
n_components; comp++)
5233 for (
unsigned int d = 0;
d < dim; ++
d)
5234 this->gradients_quad[comp][
d][q_point] =
5235 (grad_in[comp][
d] * jacobian[0][
d][
d] * JxW);
5243 const VectorizedArrayType JxW =
5246 J_value[0] * quadrature_weights[q_point];
5247 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5248 for (
unsigned int d = 0;
d < dim; ++
d)
5250 VectorizedArrayType new_val = jac[0][
d] * grad_in[comp][0];
5251 for (
unsigned int e = 1;
e < dim; ++
e)
5252 new_val += (jac[
e][
d] * grad_in[comp][
e]);
5253 this->gradients_quad[comp][
d][q_point] = new_val * JxW;
5264 typename VectorizedArrayType>
5269 const unsigned int q_point)
5274 this->gradients_quad_submitted =
true;
5278 for (
unsigned int comp = 0; comp <
n_components; comp++)
5280 for (
unsigned int d = 0;
d < dim - 1; ++
d)
5281 this->gradients_quad[comp][
d][q_point] = VectorizedArrayType();
5282 this->gradients_quad[comp][dim - 1][q_point] =
5284 (this->normal_x_jacobian[0][dim - 1] * this->J_value[0] *
5285 this->quadrature_weights[q_point]);
5289 const unsigned int index =
5291 for (
unsigned int comp = 0; comp <
n_components; comp++)
5293 VectorizedArrayType factor = grad_in[comp] * this->J_value[index];
5295 factor = factor * this->quadrature_weights[q_point];
5296 for (
unsigned int d = 0;
d < dim; ++
d)
5297 this->gradients_quad[comp][
d][q_point] =
5298 factor * this->normal_x_jacobian[index][
d];
5309 typename VectorizedArrayType>
5316 Assert(this->values_quad_submitted ==
true,
5320 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5321 return_value[comp] = this->values_quad[comp][0];
5322 const unsigned int n_q_points = this->n_quadrature_points;
5323 for (
unsigned int q = 1; q < n_q_points; ++q)
5324 for (
unsigned int comp = 0; comp <
n_components; ++comp)
5325 return_value[comp] += this->values_quad[comp][q];
5326 return (return_value);
5338 typename VectorizedArrayType>
5343 VectorizedArrayType>::
5346 const unsigned int dof_no,
5347 const unsigned int first_selected_component,
5348 const unsigned int quad_no_in,
5349 const unsigned int fe_degree,
5350 const unsigned int n_q_points,
5351 const bool is_interior_face)
5352 :
FEEvaluationBase<dim, n_components_, Number, is_face, VectorizedArrayType>(
5355 first_selected_component,
5368 typename VectorizedArrayType>
5369 template <
int n_components_other>
5374 VectorizedArrayType>::
5379 const unsigned int first_selected_component,
5384 VectorizedArrayType> *other)
5385 :
FEEvaluationBase<dim, n_components_, Number, is_face, VectorizedArrayType>(
5390 first_selected_component,
5400 typename VectorizedArrayType>
5405 VectorizedArrayType>::
5410 VectorizedArrayType> &other)
5411 :
FEEvaluationBase<dim, n_components_, Number, is_face, VectorizedArrayType>(
5421 typename VectorizedArrayType>
5426 VectorizedArrayType> &
5432 VectorizedArrayType> &other)
5438 VectorizedArrayType>::operator=(other);
5447 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5451 const unsigned int dof_no,
5452 const unsigned int first_selected_component,
5453 const unsigned int quad_no_in,
5454 const unsigned int fe_degree,
5455 const unsigned int n_q_points,
5456 const bool is_interior_face)
5460 first_selected_component,
5469 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5470 template <
int n_components_other>
5476 const unsigned int first_selected_component,
5481 VectorizedArrayType> *other)
5487 first_selected_component,
5493 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5503 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5515 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5518 const unsigned int dof)
const
5521 return this->values_dofs[0][dof];
5526 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5529 const unsigned int q_point)
const
5532 Assert(this->values_quad_initialized ==
true,
5536 return this->values_quad[0][q_point];
5541 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5546 return BaseClass::get_normal_derivative(q_point)[0];
5551 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5554 const unsigned int q_point)
const
5560 Assert(this->gradients_quad_initialized ==
true,
5571 for (
unsigned int d = 0;
d < dim; ++
d)
5573 (this->gradients_quad[0][
d][q_point] * this->jacobian[0][
d][
d]);
5582 for (
unsigned int d = 0;
d < dim; ++
d)
5584 grad_out[
d] = jac[
d][0] * this->gradients_quad[0][0][q_point];
5585 for (
unsigned int e = 1;
e < dim; ++
e)
5586 grad_out[
d] += jac[
d][
e] * this->gradients_quad[0][
e][q_point];
5594 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5597 const unsigned int q_point)
const
5599 return BaseClass::get_hessian(q_point)[0];
5604 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5609 return BaseClass::get_hessian_diagonal(q_point)[0];
5614 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5615 inline VectorizedArrayType
5617 const unsigned int q_point)
const
5619 return BaseClass::get_laplacian(q_point)[0];
5624 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5630 this->dof_values_initialized =
true;
5633 this->values_dofs[0][dof] = val_in;
5638 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5641 const VectorizedArrayType val_in,
5642 const unsigned int q_index)
5648 this->values_quad_submitted =
true;
5653 const VectorizedArrayType JxW =
5654 this->J_value[0] * this->quadrature_weights[q_index];
5655 this->values_quad[0][q_index] = val_in * JxW;
5659 this->values_quad[0][q_index] = val_in * this->J_value[q_index];
5665 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5669 const unsigned int q_point)
5671 submit_value(val_in[0], q_point);
5676 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5680 const unsigned int q_point)
5684 BaseClass::submit_normal_derivative(grad, q_point);
5689 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5693 const unsigned int q_index)
5700 this->gradients_quad_submitted =
true;
5705 const VectorizedArrayType JxW =
5706 this->J_value[0] * this->quadrature_weights[q_index];
5707 for (
unsigned int d = 0;
d < dim; ++
d)
5708 this->gradients_quad[0][
d][q_index] =
5709 (grad_in[
d] * this->jacobian[0][
d][
d] * JxW);
5716 this->jacobian[q_index] :
5718 const VectorizedArrayType JxW =
5720 this->J_value[q_index] :
5721 this->J_value[0] * this->quadrature_weights[q_index];
5722 for (
unsigned int d = 0;
d < dim; ++
d)
5724 VectorizedArrayType new_val = jac[0][
d] * grad_in[0];
5725 for (
unsigned int e = 1;
e < dim; ++
e)
5726 new_val += jac[
e][
d] * grad_in[
e];
5727 this->gradients_quad[0][
d][q_index] = new_val * JxW;
5734 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5735 inline VectorizedArrayType
5739 return BaseClass::integrate_value()[0];
5747 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5751 const unsigned int dof_no,
5752 const unsigned int first_selected_component,
5753 const unsigned int quad_no_in,
5754 const unsigned int fe_degree,
5755 const unsigned int n_q_points,
5756 const bool is_interior_face)
5760 first_selected_component,
5769 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5770 template <
int n_components_other>
5776 const unsigned int first_selected_component,
5781 VectorizedArrayType> *other)
5787 first_selected_component,
5793 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5803 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5816 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5821 return BaseClass::get_gradient(q_point);
5826 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5832 Assert(this->gradients_quad_initialized ==
true,
5838 VectorizedArrayType divergence;
5844 (this->gradients_quad[0][0][q_point] * this->jacobian[0][0][0]);
5845 for (
unsigned int d = 1;
d < dim; ++
d)
5847 (this->gradients_quad[
d][
d][q_point] * this->jacobian[0][
d][
d]);
5854 this->jacobian[q_point] :
5856 divergence = (jac[0][0] * this->gradients_quad[0][0][q_point]);
5857 for (
unsigned int e = 1;
e < dim; ++
e)
5858 divergence += (jac[0][
e] * this->gradients_quad[0][
e][q_point]);
5859 for (
unsigned int d = 1;
d < dim; ++
d)
5860 for (
unsigned int e = 0;
e < dim; ++
e)
5861 divergence += (jac[
d][
e] * this->gradients_quad[
d][
e][q_point]);
5868 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5875 VectorizedArrayType symmetrized[(dim * dim + dim) / 2];
5876 VectorizedArrayType half = make_vectorized_array<Number>(0.5);
5877 for (
unsigned int d = 0;
d < dim; ++
d)
5878 symmetrized[
d] = grad[
d][
d];
5884 symmetrized[2] = grad[0][1] + grad[1][0];
5885 symmetrized[2] *= half;
5888 symmetrized[3] = grad[0][1] + grad[1][0];
5889 symmetrized[3] *= half;
5890 symmetrized[4] = grad[0][2] + grad[2][0];
5891 symmetrized[4] *= half;
5892 symmetrized[5] = grad[1][2] + grad[2][1];
5893 symmetrized[5] *= half;
5903 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5905 Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType>
5907 const unsigned int q_point)
const
5911 Tensor<1, (dim == 2 ? 1 : dim), VectorizedArrayType> curl;
5917 "Computing the curl in 1d is not a useful operation"));
5920 curl[0] = grad[1][0] - grad[0][1];
5923 curl[0] = grad[2][1] - grad[1][2];
5924 curl[1] = grad[0][2] - grad[2][0];
5925 curl[2] = grad[1][0] - grad[0][1];
5935 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5940 return BaseClass::get_hessian_diagonal(q_point);
5945 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5948 const unsigned int q_point)
const
5951 Assert(this->hessians_quad_initialized ==
true,
5955 return BaseClass::get_hessian(q_point);
5960 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5964 const unsigned int q_point)
5966 BaseClass::submit_gradient(grad_in, q_point);
5971 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5976 const unsigned int q_point)
5978 BaseClass::submit_gradient(grad_in, q_point);
5983 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
5987 const unsigned int q_point)
5994 this->gradients_quad_submitted =
true;
5999 const VectorizedArrayType fac =
6000 this->J_value[0] * this->quadrature_weights[q_point] * div_in;
6001 for (
unsigned int d = 0;
d < dim; ++
d)
6003 this->gradients_quad[
d][
d][q_point] = (fac * this->jacobian[0][
d][
d]);
6004 for (
unsigned int e =
d + 1;
e < dim; ++
e)
6006 this->gradients_quad[
d][
e][q_point] = VectorizedArrayType();
6007 this->gradients_quad[
e][
d][q_point] = VectorizedArrayType();
6015 this->jacobian[q_point] :
6017 const VectorizedArrayType fac =
6019 this->J_value[q_point] :
6020 this->J_value[0] * this->quadrature_weights[q_point]) *
6022 for (
unsigned int d = 0;
d < dim; ++
d)
6024 for (
unsigned int e = 0;
e < dim; ++
e)
6025 this->gradients_quad[
d][
e][q_point] = jac[
d][
e] * fac;
6032 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
6037 const unsigned int q_point)
6047 this->gradients_quad_submitted =
true;
6052 const VectorizedArrayType JxW =
6053 this->J_value[0] * this->quadrature_weights[q_point];
6054 for (
unsigned int d = 0;
d < dim; ++
d)
6055 this->gradients_quad[
d][
d][q_point] =
6057 for (
unsigned int e = 0, counter = dim;
e < dim; ++
e)
6058 for (
unsigned int d =
e + 1;
d < dim; ++
d, ++counter)
6060 const VectorizedArrayType
value =
6062 this->gradients_quad[
e][
d][q_point] =
6063 (
value * this->jacobian[0][
d][
d]);
6064 this->gradients_quad[
d][
e][q_point] =
6065 (
value * this->jacobian[0][
e][
e]);
6071 const VectorizedArrayType JxW =
6073 this->J_value[q_point] :
6074 this->J_value[0] * this->quadrature_weights[q_point];
6077 this->jacobian[q_point] :
6079 VectorizedArrayType weighted[dim][dim];
6080 for (
unsigned int i = 0; i < dim; ++i)
6082 for (
unsigned int i = 0, counter = dim; i < dim; ++i)
6083 for (
unsigned int j = i + 1; j < dim; ++j, ++counter)
6085 const VectorizedArrayType
value =
6087 weighted[i][j] =
value;
6088 weighted[j][i] =
value;
6090 for (
unsigned int comp = 0; comp < dim; ++comp)
6091 for (
unsigned int d = 0;
d < dim; ++
d)
6093 VectorizedArrayType new_val = jac[0][
d] * weighted[comp][0];
6094 for (
unsigned int e = 1;
e < dim; ++
e)
6095 new_val += jac[
e][
d] * weighted[comp][
e];
6096 this->gradients_quad[comp][
d][q_point] = new_val;
6103 template <
int dim,
typename Number,
bool is_face,
typename VectorizedArrayType>
6107 const unsigned int q_point)
6115 "Testing by the curl in 1d is not a useful operation"));
6118 grad[1][0] = curl[0];
6119 grad[0][1] = -curl[0];
6122 grad[2][1] = curl[0];
6123 grad[1][2] = -curl[0];
6124 grad[0][2] = curl[1];
6125 grad[2][0] = -curl[1];
6126 grad[1][0] = curl[2];
6127 grad[0][1] = -curl[2];
6132 submit_gradient(grad, q_point);
6139 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6142 const unsigned int dof_no,
6143 const unsigned int first_selected_component,
6144 const unsigned int quad_no_in,
6145 const unsigned int fe_degree,
6146 const unsigned int n_q_points,
6147 const bool is_interior_face)
6151 first_selected_component,
6160 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6161 template <
int n_components_other>
6167 const unsigned int first_selected_component,
6172 VectorizedArrayType> *other)
6178 first_selected_component,
6184 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6193 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6205 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6208 const unsigned int dof)
const
6211 return this->values_dofs[0][dof];
6216 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6219 const unsigned int q_point)
const
6222 Assert(this->values_quad_initialized ==
true,
6226 return this->values_quad[0][q_point];
6231 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6234 const unsigned int q_point)
const
6240 Assert(this->gradients_quad_initialized ==
true,
6247 this->jacobian[q_point] :
6251 grad_out[0] = jac[0][0] * this->gradients_quad[0][0][q_point];
6258 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6263 return BaseClass::get_normal_derivative(q_point)[0];
6268 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6271 const unsigned int q_point)
const
6273 return BaseClass::get_hessian(q_point)[0];
6278 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6283 return BaseClass::get_hessian_diagonal(q_point)[0];
6288 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6291 const unsigned int q_point)
const
6293 return BaseClass::get_laplacian(q_point)[0];
6298 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6304 this->dof_values_initialized =
true;
6307 this->values_dofs[0][dof] = val_in;
6312 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6315 const VectorizedArrayType val_in,
6316 const unsigned int q_point)
6321 this->values_quad_submitted =
true;
6326 const VectorizedArrayType JxW = this->J_value[q_point];
6327 this->values_quad[0][q_point] = val_in * JxW;
6331 const VectorizedArrayType JxW =
6332 this->J_value[0] * this->quadrature_weights[q_point];
6333 this->values_quad[0][q_point] = val_in * JxW;
6339 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6343 const unsigned int q_point)
6345 submit_value(val_in[0], q_point);
6350 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6354 const unsigned int q_point)
6356 submit_gradient(grad_in[0], q_point);
6361 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6364 const VectorizedArrayType grad_in,
6365 const unsigned int q_point)
6370 this->gradients_quad_submitted =
true;
6375 this->jacobian[q_point] :
6377 const VectorizedArrayType JxW =
6379 this->J_value[q_point] :
6380 this->J_value[0] * this->quadrature_weights[q_point];
6382 this->gradients_quad[0][0][q_point] = jac[0][0] * grad_in * JxW;
6387 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6391 const unsigned int q_point)
6395 BaseClass::submit_normal_derivative(grad, q_point);
6400 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6404 const unsigned int q_point)
6406 BaseClass::submit_normal_derivative(grad_in, q_point);
6411 template <
typename Number,
bool is_face,
typename VectorizedArrayType>
6412 inline VectorizedArrayType
6416 return BaseClass::integrate_value()[0];
6429 typename VectorizedArrayType>
6435 VectorizedArrayType>::
6437 const unsigned int fe_no,
6438 const unsigned int quad_no,
6439 const unsigned int first_selected_component)
6440 : BaseClass(data_in,
6442 first_selected_component,
6446 , dofs_per_component(this->data->dofs_per_component_on_cell)
6447 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6448 , n_q_points(this->data->n_q_points)
6450 check_template_arguments(fe_no, 0);
6460 typename VectorizedArrayType>
6466 VectorizedArrayType>::
6471 const unsigned int first_selected_component)
6472 : BaseClass(mapping,
6476 first_selected_component,
6480 , dofs_per_component(this->data->dofs_per_component_on_cell)
6481 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6482 , n_q_points(this->data->n_q_points)
6494 typename VectorizedArrayType>
6500 VectorizedArrayType>::
6504 const unsigned int first_selected_component)
6509 first_selected_component,
6513 , dofs_per_component(this->data->dofs_per_component_on_cell)
6514 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6515 , n_q_points(this->data->n_q_points)
6527 typename VectorizedArrayType>
6528 template <
int n_components_other>
6534 VectorizedArrayType>::
6540 VectorizedArrayType> &other,
6541 const unsigned int first_selected_component)
6542 : BaseClass(other.mapped_geometry->get_fe_values().get_mapping(),
6544 other.mapped_geometry->get_quadrature(),
6545 other.mapped_geometry->get_fe_values().get_update_flags(),
6546 first_selected_component,
6548 , dofs_per_component(this->data->dofs_per_component_on_cell)
6549 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6550 , n_q_points(this->data->n_q_points)
6562 typename VectorizedArrayType>
6571 , dofs_per_component(this->data->dofs_per_component_on_cell)
6572 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
6573 , n_q_points(this->data->n_q_points)
6585 typename VectorizedArrayType>
6591 VectorizedArrayType> &
6597 VectorizedArrayType>::operator=(
const FEEvaluation &other)
6599 BaseClass::operator=(other);
6611 typename VectorizedArrayType>
6618 VectorizedArrayType>::
6619 check_template_arguments(
const unsigned int dof_no,
6620 const unsigned int first_selected_component)
6623 (void)first_selected_component;
6629 static_cast<unsigned int>(fe_degree) !=
6630 this->data->data.front().fe_degree) ||
6631 n_q_points != this->n_quadrature_points)
6633 std::string message =
6634 "-------------------------------------------------------\n";
6635 message +=
"Illegal arguments in constructor/wrong template arguments!\n";
6636 message +=
" Called --> FEEvaluation<dim,";
6640 message +=
",Number>(data";
6656 if (
static_cast<unsigned int>(fe_degree) ==
6657 this->data->data.front().fe_degree)
6659 proposed_dof_comp = dof_no;
6660 proposed_fe_comp = first_selected_component;
6663 for (
unsigned int no = 0; no < this->matrix_info->n_components();
6665 for (
unsigned int nf = 0;
6666 nf < this->matrix_info->n_base_elements(no);
6668 if (this->matrix_info
6669 ->get_shape_info(no, 0, nf, this->active_fe_index, 0)
6671 .fe_degree ==
static_cast<unsigned int>(fe_degree))
6673 proposed_dof_comp = no;
6674 proposed_fe_comp = nf;
6678 this->mapping_data->descriptor[this->active_quad_index]
6680 proposed_quad_comp = this->quad_no;
6682 for (
unsigned int no = 0;
6683 no < this->matrix_info->get_mapping_info().cell_data.size();
6685 if (this->matrix_info->get_mapping_info()
6687 .descriptor[this->active_quad_index]
6688 .n_q_points == n_q_points)
6690 proposed_quad_comp = no;
6697 if (proposed_dof_comp != first_selected_component)
6698 message +=
"Wrong vector component selection:\n";
6700 message +=
"Wrong quadrature formula selection:\n";
6701 message +=
" Did you mean FEEvaluation<dim,";
6705 message +=
",Number>(data";
6714 std::string correct_pos;
6715 if (proposed_dof_comp != dof_no)
6716 correct_pos =
" ^ ";
6719 if (proposed_quad_comp != this->quad_no)
6720 correct_pos +=
" ^ ";
6723 if (proposed_fe_comp != first_selected_component)
6724 correct_pos +=
" ^\n";
6726 correct_pos +=
" \n";
6732 const unsigned int proposed_n_q_points_1d =
static_cast<unsigned int>(
6733 std::pow(1.001 * this->n_quadrature_points, 1. / dim));
6734 message +=
"Wrong template arguments:\n";
6735 message +=
" Did you mean FEEvaluation<dim,";
6740 message +=
",Number>(data";
6748 std::string correct_pos;
6749 if (this->data->data.front().fe_degree !=
6750 static_cast<unsigned int>(fe_degree))
6754 if (proposed_n_q_points_1d != n_q_points_1d)
6755 correct_pos +=
" ^\n";
6757 correct_pos +=
" \n";
6758 message +=
" " + correct_pos;
6760 Assert(
static_cast<unsigned int>(fe_degree) ==
6761 this->data->data.front().fe_degree &&
6762 n_q_points == this->n_quadrature_points,
6768 this->mapping_data->descriptor[this->active_quad_index].n_q_points);
6779 typename VectorizedArrayType>
6786 VectorizedArrayType>
::reinit(
const unsigned int cell_index)
6788 Assert(this->mapped_geometry ==
nullptr,
6789 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
6790 " Integer indexing is not possible"));
6791 if (this->mapped_geometry !=
nullptr)
6796 this->cell = cell_index;
6798 this->matrix_info->get_mapping_info().get_cell_type(cell_index);
6800 const unsigned int offsets =
6801 this->mapping_data->data_index_offsets[cell_index];
6802 this->jacobian = &this->mapping_data->jacobians[0][offsets];
6803 this->J_value = &this->mapping_data->JxW_values[offsets];
6806 this->dof_values_initialized =
false;
6807 this->values_quad_initialized =
false;
6808 this->gradients_quad_initialized =
false;
6809 this->hessians_quad_initialized =
false;
6820 typename VectorizedArrayType>
6821 template <
typename DoFHandlerType,
bool level_dof_access>
6828 VectorizedArrayType>
::
6832 Assert(this->matrix_info ==
nullptr,
6833 ExcMessage(
"Cannot use initialization from cell iterator if "
6834 "initialized from MatrixFree object. Use variant for "
6835 "on the fly computation with arguments as for FEValues "
6838 this->mapped_geometry->reinit(
6840 this->local_dof_indices.resize(cell->get_fe().dofs_per_cell);
6841 if (level_dof_access)
6842 cell->get_mg_dof_indices(this->local_dof_indices);
6844 cell->get_dof_indices(this->local_dof_indices);
6854 typename VectorizedArrayType>
6861 VectorizedArrayType>
::
6864 Assert(this->matrix_info == 0,
6865 ExcMessage(
"Cannot use initialization from cell iterator if "
6866 "initialized from MatrixFree object. Use variant for "
6867 "on the fly computation with arguments as for FEValues "
6870 this->mapped_geometry->reinit(cell);
6880 typename VectorizedArrayType>
6887 VectorizedArrayType>::quadrature_point(
const unsigned int q)
const
6889 if (this->matrix_info ==
nullptr)
6891 Assert((this->mapped_geometry->get_fe_values().get_update_flags() |
6897 Assert(this->mapping_data->quadrature_point_offsets.empty() ==
false,
6904 &this->mapping_data->quadrature_points
6905 [this->mapping_data->quadrature_point_offsets[this->cell]];
6917 for (
unsigned int d = 0;
d < dim; ++
d)
6919 static_cast<Number
>(
6920 this->mapping_data->descriptor[this->active_quad_index]
6921 .quadrature.point(q)[
d]);
6923 for (
unsigned int d = 0;
d < dim; ++
d)
6924 for (
unsigned int e = 0;
e < dim; ++
e)
6925 point[
d] += jac[
d][
e] *
static_cast<Number
>(
6927 ->descriptor[this->active_quad_index]
6928 .quadrature.point(q)[
e]);
6942 typename VectorizedArrayType>
6949 VectorizedArrayType>::evaluate(
const bool evaluate_values,
6950 const bool evaluate_gradients,
6951 const bool evaluate_hessians)
6954 Assert(this->dof_values_initialized ==
true,
6957 evaluate(this->values_dofs[0],
6970 typename VectorizedArrayType>
6977 VectorizedArrayType>::evaluate(
const VectorizedArrayType
6979 const bool evaluate_values,
6980 const bool evaluate_gradients,
6981 const bool evaluate_hessians)
6988 VectorizedArrayType>::evaluate(*this->data,
6989 const_cast<VectorizedArrayType *
>(
6991 this->values_quad[0],
6992 this->gradients_quad[0][0],
6993 this->hessians_quad[0][0],
7000 if (evaluate_values ==
true)
7001 this->values_quad_initialized =
true;
7002 if (evaluate_gradients ==
true)
7003 this->gradients_quad_initialized =
true;
7004 if (evaluate_hessians ==
true)
7005 this->hessians_quad_initialized =
true;
7016 typename VectorizedArrayType>
7017 template <
typename VectorType>
7025 VectorizedArrayType>::gather_evaluate(
const VectorType &input_vector,
7026 const bool evaluate_values,
7027 const bool evaluate_gradients,
7028 const bool evaluate_hessians)
7035 this->dof_info->index_storage_variants
7038 IndexStorageVariants::interleaved_contiguous &&
7039 reinterpret_cast<std::size_t
>(
7040 input_vector.begin() +
7041 this->dof_info->dof_indices_contiguous
7043 [this->cell * VectorizedArrayType::size()]) %
7044 sizeof(VectorizedArrayType) ==
7047 const VectorizedArrayType *vec_values =
7048 reinterpret_cast<const VectorizedArrayType *
>(
7049 input_vector.begin() +
7050 this->dof_info->dof_indices_contiguous
7052 [this->cell * VectorizedArrayType::size()] +
7054 ->component_dof_indices_offset[this->active_fe_index]
7055 [this->first_selected_component] *
7056 VectorizedArrayType::size());
7058 evaluate(vec_values,
7065 this->read_dof_values(input_vector);
7066 evaluate(this->begin_dof_values(),
7080 typename VectorizedArrayType>
7087 VectorizedArrayType>::integrate(
const bool integrate_values,
7088 const bool integrate_gradients)
7090 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7093 this->dof_values_initialized =
true;
7104 typename VectorizedArrayType>
7111 VectorizedArrayType>::integrate(
const bool integrate_values,
7112 const bool integrate_gradients,
7113 VectorizedArrayType *values_array)
7116 if (integrate_values ==
true)
7117 Assert(this->values_quad_submitted ==
true,
7119 if (integrate_gradients ==
true)
7120 Assert(this->gradients_quad_submitted ==
true,
7123 Assert(this->matrix_info !=
nullptr ||
7124 this->mapped_geometry->is_initialized(),
7131 VectorizedArrayType>::integrate(*this->data,
7133 this->values_quad[0],
7134 this->gradients_quad[0][0],
7137 integrate_gradients,
7141 this->dof_values_initialized =
true;
7152 typename VectorizedArrayType>
7153 template <
typename VectorType>
7161 VectorizedArrayType>::integrate_scatter(
const bool integrate_values,
7162 const bool integrate_gradients,
7171 this->dof_info->index_storage_variants
7174 IndexStorageVariants::interleaved_contiguous &&
7175 reinterpret_cast<std::size_t
>(
7176 destination.begin() +
7177 this->dof_info->dof_indices_contiguous
7179 [this->cell * VectorizedArrayType::size()]) %
7180 sizeof(VectorizedArrayType) ==
7183 VectorizedArrayType *vec_values =
reinterpret_cast<VectorizedArrayType *
>(
7184 destination.begin() +
7185 this->dof_info->dof_indices_contiguous
7187 [this->cell * VectorizedArrayType::size()] +
7189 ->component_dof_indices_offset[this->active_fe_index]
7190 [this->first_selected_component] *
7191 VectorizedArrayType::size());
7196 VectorizedArrayType>::integrate(*this->data,
7198 this->values_quad[0],
7200 ->gradients_quad[0][0],
7203 integrate_gradients,
7208 integrate(integrate_values,
7209 integrate_gradients,
7210 this->begin_dof_values());
7211 this->distribute_local_to_global(destination);
7226 typename VectorizedArrayType>
7232 VectorizedArrayType>::
7235 const bool is_interior_face,
7236 const unsigned int dof_no,
7237 const unsigned int quad_no,
7238 const unsigned int first_selected_component)
7239 : BaseClass(matrix_free,
7241 first_selected_component,
7246 , dofs_per_component(this->data->dofs_per_component_on_cell)
7247 , dofs_per_cell(this->data->dofs_per_component_on_cell * n_components_)
7248 , n_q_points(this->data->n_q_points_face)
7258 typename VectorizedArrayType>
7265 VectorizedArrayType>
::reinit(
const unsigned int face_index)
7267 Assert(this->mapped_geometry ==
nullptr,
7268 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
7269 " Integer indexing is not possible"));
7270 if (this->mapped_geometry !=
nullptr)
7273 this->cell = face_index;
7274 this->dof_access_index =
7275 this->is_interior_face ?
7280 VectorizedArrayType::size()> &faces =
7281 this->matrix_info->get_face_info(face_index);
7283 this->matrix_info->get_task_info().face_partition_data.back() &&
7285 this->matrix_info->get_task_info().boundary_partition_data.back())
7286 Assert(this->is_interior_face,
7287 ExcMessage(
"Boundary faces do not have a neighbor"));
7292 if (this->is_interior_face ==
true)
7298 this->face_orientation = 0;
7305 this->face_orientation = 0;
7308 this->cell_type = this->matrix_info->get_mapping_info().face_type[face_index];
7309 const unsigned int offsets =
7310 this->mapping_data->data_index_offsets[face_index];
7311 this->J_value = &this->mapping_data->JxW_values[offsets];
7312 this->normal_vectors = &this->mapping_data->normal_vectors[offsets];
7314 &this->mapping_data->jacobians[!this->is_interior_face][offsets];
7315 this->normal_x_jacobian =
7317 ->normals_times_jacobians[!this->is_interior_face][offsets];
7320 this->dof_values_initialized =
false;
7321 this->values_quad_initialized =
false;
7322 this->gradients_quad_initialized =
false;
7323 this->hessians_quad_initialized =
false;
7334 typename VectorizedArrayType>
7341 VectorizedArrayType>
::reinit(
const unsigned int cell_index,
7342 const unsigned int face_number)
7346 this->matrix_info->get_mapping_info().face_data_by_cells.size(),
7348 "You must set MatrixFree::AdditionalData::mapping_update_flags_faces_by_cells to use the present reinit method."));
7351 this->matrix_info->get_mapping_info().cell_type.size());
7352 Assert(this->mapped_geometry ==
nullptr,
7353 ExcMessage(
"FEEvaluation was initialized without a matrix-free object."
7354 " Integer indexing is not possible"));
7355 if (this->mapped_geometry !=
nullptr)
7359 this->cell_type = this->matrix_info->get_mapping_info().cell_type[cell_index];
7360 this->cell = cell_index;
7361 this->face_orientation = 0;
7363 this->face_no = face_number;
7364 this->dof_access_index =
7367 const unsigned int offsets =
7368 this->matrix_info->get_mapping_info()
7369 .face_data_by_cells[this->quad_no]
7373 this->matrix_info->get_mapping_info()
7374 .face_data_by_cells[this->quad_no]
7375 .JxW_values.size());
7376 this->J_value = &this->matrix_info->get_mapping_info()
7377 .face_data_by_cells[this->quad_no]
7378 .JxW_values[offsets];
7379 this->normal_vectors = &this->matrix_info->get_mapping_info()
7380 .face_data_by_cells[this->quad_no]
7381 .normal_vectors[offsets];
7382 this->jacobian = &this->matrix_info->get_mapping_info()
7383 .face_data_by_cells[this->quad_no]
7384 .jacobians[!this->is_interior_face][offsets];
7385 this->normal_x_jacobian =
7386 &this->matrix_info->get_mapping_info()
7387 .face_data_by_cells[this->quad_no]
7388 .normals_times_jacobians[!this->is_interior_face][offsets];
7391 this->dof_values_initialized =
false;
7392 this->values_quad_initialized =
false;
7393 this->gradients_quad_initialized =
false;
7394 this->hessians_quad_initialized =
false;
7405 typename VectorizedArrayType>
7412 VectorizedArrayType>::evaluate(
const bool evaluate_values,
7413 const bool evaluate_gradients)
7419 evaluate(this->values_dofs[0], evaluate_values, evaluate_gradients);
7429 typename VectorizedArrayType>
7436 VectorizedArrayType>::evaluate(
const VectorizedArrayType
7438 const bool evaluate_values,
7439 const bool evaluate_gradients)
7441 if (!(evaluate_values + evaluate_gradients))
7450 VectorizedArrayType>::evaluate(*this->data,
7452 this->begin_values(),
7453 this->begin_gradients(),
7458 this->subface_index,
7459 this->face_orientation,
7461 ->descriptor[this->active_fe_index]
7462 .face_orientations);
7465 if (evaluate_values ==
true)
7466 this->values_quad_initialized =
true;
7467 if (evaluate_gradients ==
true)
7468 this->gradients_quad_initialized =
true;
7479 typename VectorizedArrayType>
7486 VectorizedArrayType>::integrate(
const bool integrate_values,
7487 const bool integrate_gradients)
7489 integrate(integrate_values, integrate_gradients, this->values_dofs[0]);
7492 this->dof_values_initialized =
true;
7503 typename VectorizedArrayType>
7510 VectorizedArrayType>::integrate(
const bool integrate_values,
7511 const bool integrate_gradients,
7515 if (!(integrate_values + integrate_gradients))
7524 VectorizedArrayType>::integrate(*this->data,
7526 this->begin_values(),
7527 this->begin_gradients(),
7530 integrate_gradients,
7532 this->subface_index,
7533 this->face_orientation,
7535 ->descriptor[this->active_fe_index]
7536 .face_orientations);
7546 typename VectorizedArrayType>
7547 template <
typename VectorType>
7555 VectorizedArrayType>::gather_evaluate(
const VectorType &input_vector,
7556 const bool evaluate_values,
7557 const bool evaluate_gradients)
7560 (std::is_same<decltype(std::declval<VectorType>().
begin()),
7562 std::is_same<decltype(std::declval<VectorType>().
begin()),
7564 "This function requires a vector type with begin() function "
7565 "evaluating to a pointer to basic number (float,double). "
7566 "Use read_dof_values() followed by evaluate() instead.");
7573 VectorizedArrayType>::
7574 gather_evaluate(input_vector.begin(),
7577 this->begin_values(),
7578 this->begin_gradients(),
7582 this->active_fe_index,
7583 this->first_selected_component,
7586 this->subface_index,
7587 this->dof_access_index,
7588 this->face_orientation,
7589 this->mapping_data->descriptor[this->active_fe_index]
7590 .face_orientations))
7592 this->read_dof_values(input_vector);
7593 this->evaluate(evaluate_values, evaluate_gradients);
7597 if (evaluate_values ==
true)
7598 this->values_quad_initialized =
true;
7599 if (evaluate_gradients ==
true)
7600 this->gradients_quad_initialized =
true;
7611 typename VectorizedArrayType>
7612 template <
typename VectorType>
7620 VectorizedArrayType>::integrate_scatter(
const bool integrate_values,
7621 const bool integrate_gradients,
7625 (std::is_same<decltype(std::declval<VectorType>().
begin()),
7627 std::is_same<decltype(std::declval<VectorType>().
begin()),
7629 "This function requires a vector type with begin() function "
7630 "evaluating to a pointer to basic number (float,double). "
7631 "Use integrate() followed by distribute_local_to_global() "
7639 VectorizedArrayType>::
7640 integrate_scatter(destination.begin(),
7643 this->begin_dof_values(),
7644 this->begin_values(),
7645 this->begin_gradients(),
7648 integrate_gradients,
7649 this->active_fe_index,
7650 this->first_selected_component,
7653 this->subface_index,
7654 this->dof_access_index,
7655 this->face_orientation,
7656 this->mapping_data->descriptor[this->active_fe_index]
7657 .face_orientations))
7663 this->distribute_local_to_global(destination);
7674 typename VectorizedArrayType>
7681 VectorizedArrayType>::quadrature_point(
const unsigned int q)
7685 if (this->dof_access_index < 2)
7687 Assert(this->mapping_data->quadrature_point_offsets.empty() ==
false,
7690 this->mapping_data->quadrature_point_offsets.size());
7691 return this->mapping_data->quadrature_points
7692 [this->mapping_data->quadrature_point_offsets[this->cell] + q];
7696 Assert(this->matrix_info->get_mapping_info()
7697 .face_data_by_cells[this->quad_no]
7698 .quadrature_point_offsets.empty() ==
false,
7700 const unsigned int index =
7703 this->matrix_info->get_mapping_info()
7704 .face_data_by_cells[this->quad_no]
7705 .quadrature_point_offsets.size());
7706 return this->matrix_info->get_mapping_info()
7707 .face_data_by_cells[this->quad_no]
7708 .quadrature_points[this->matrix_info->get_mapping_info()
7709 .face_data_by_cells[this->quad_no]
7710 .quadrature_point_offsets[index] +
7720 #endif // ifndef DOXYGEN