41 template <
int dim,
typename AdditionalData>
44 AdditionalData & additional_data);
59 typename VectorizedArrayType,
71 const unsigned int dof_no = 0,
72 const unsigned int quad_no = 0,
73 const unsigned int first_selected_component = 0);
78 template <
typename CLASS,
84 typename VectorizedArrayType,
95 VectorizedArrayType> &)
const,
99 const unsigned
int first_selected_component = 0);
115 typename VectorizedArrayType,
128 const unsigned int dof_no = 0,
129 const unsigned int quad_no = 0,
130 const unsigned int first_selected_component = 0);
135 template <
typename CLASS,
141 typename VectorizedArrayType,
153 VectorizedArrayType> &)
const,
157 const unsigned
int first_selected_component = 0);
211 const auto &fe_collection =
212 matrix_free.get_dof_handler(additional_data.dof_index)
213 .get_fe_collection();
215 for (
unsigned int i = 0; i < fe_collection.size(); ++i)
216 if (fe_collection[i].n_dofs_per_cell() > 0)
231 template <
typename VectorTypeOut,
typename VectorTypeIn>
265 template <
typename VectorTypeOut,
typename VectorTypeIn>
281 const std::pair<unsigned int, unsigned int> &,
306 const unsigned int type =
346 template <
int dim,
typename AdditionalData>
349 AdditionalData & additional_data)
352 const unsigned int level = additional_data.mg_level;
357 additional_data.cell_vectorization_category.assign(
360 additional_data.cell_vectorization_category.assign(
tria.n_active_cells(),
366 auto bids =
tria.get_boundary_ids();
373 i++, offset = offset *
n_bids)
378 unsigned int c_num = 0;
381 const auto face = cell->face(i);
382 if (face->at_boundary() && !cell->has_periodic_neighbor(i))
384 factors[i] * (1 + std::distance(
bids.
begin(),
387 face->boundary_id())));
394 for (
auto cell =
tria.begin_active(); cell !=
tria.
end(); ++cell)
396 if (cell->is_locally_owned())
398 .cell_vectorization_category[cell->active_cell_index()] =
406 if (cell->is_locally_owned_on_level())
407 additional_data.cell_vectorization_category[cell->index()] =
413 additional_data.hold_all_faces_to_owned_cells =
true;
414 additional_data.cell_vectorization_categories_strict =
true;
415 additional_data.mapping_update_flags_faces_by_cells =
416 additional_data.mapping_update_flags_inner_faces |
417 additional_data.mapping_update_flags_boundary_faces;
422 template <
typename Number>
426 std::vector<unsigned int> row;
427 std::vector<unsigned int> col;
428 std::vector<Number> val;
439 typename VectorizedArrayType>
443 static const unsigned int n_lanes = VectorizedArrayType::size();
447 , dofs_per_component(0)
452 , dofs_per_component(0)
461 VectorizedArrayType> &
phi)
465 if (dofs_per_component !=
phi.dofs_per_component)
468 dofs_per_component =
phi.dofs_per_component;
474 reinit(
const unsigned int cell)
479 const auto & dof_info =
phi->get_dof_info();
480 const unsigned int n_fe_components = dof_info.start_components.back();
481 const auto & matrix_free =
phi->get_matrix_free();
487 const unsigned int first_selected_component =
488 n_fe_components == 1 ? 0 :
phi->get_first_selected_component();
491 matrix_free.n_active_entries_per_cell_batch(cell);
498 std::vector<std::tuple<unsigned int, unsigned int, Number>>
506 const unsigned int *dof_indices;
509 const unsigned int start =
510 (cell * n_lanes + v) * n_fe_components + first_selected_component;
512 dof_info.dof_indices.data() + dof_info.row_starts[start].first;
520 if (n_components == 1 || n_fe_components == 1)
526 const std::pair<unsigned short, unsigned short>
indicator =
538 matrix_free.constraint_pool_begin(
indicator.second);
540 matrix_free.constraint_pool_end(
indicator.second);
563 for (
unsigned int comp = 0;
comp < n_components; ++
comp)
572 const std::pair<unsigned short, unsigned short>
586 matrix_free.constraint_pool_begin(
indicator.second);
588 matrix_free.constraint_pool_end(
indicator.second);
607 if (
comp + 1 < n_components)
609 dof_info.row_starts[start +
comp + 2].second;
623 if (dof_info.hanging_node_constraint_masks.size() > 0 &&
624 dof_info.hanging_node_constraint_masks_comp.size() > 0 &&
625 dof_info.hanging_node_constraint_masks_comp
626 [
phi->get_active_fe_index()][first_selected_component])
629 dof_info.hanging_node_constraint_masks[cell * n_lanes + v];
632 if (mask != ::internal::MatrixFreeFunctions::
684 std::get<0>(*
other) == std::get<1>(
hn);
689 std::get<2>(
hn) * std::get<2>(*
other));
700 [](
const auto &a,
const auto &b) {
701 if (std::get<1>(a) < std::get<1>(b))
703 return (std::get<1>(a) == std::get<1>(b)) &&
704 (std::get<0>(a) < std::get<0>(b));
710 c_pool.row_lid_to_gid.clear();
717 c_pool.row_lid_to_gid.emplace_back(
721 if (
c_pool.row_lid_to_gid.back() != std::get<1>(
j))
723 c_pool.row_lid_to_gid.push_back(std::get<1>(
j));
727 c_pool.col.emplace_back(std::get<0>(
j));
728 c_pool.val.emplace_back(std::get<2>(
j));
734 c_pool.inverse_lookup_rows.clear();
735 c_pool.inverse_lookup_rows.resize(1 +
phi->dofs_per_cell);
736 for (
const unsigned int i :
c_pool.col)
739 std::partial_sum(
c_pool.inverse_lookup_rows.
begin(),
748 for (
unsigned int row = 0; row <
c_pool.row.
size() - 1; ++row)
749 for (
unsigned int col =
c_pool.row[row];
750 col <
c_pool.row[row + 1];
754 c_pool.inverse_lookup_origins
789 (n_fe_components == 1 ? n_components : 1),
795 const ::internal::MatrixFreeFunctions::compressed_constraint_kind
803 const unsigned int degree =
804 phi->get_shape_info().
data.front().fe_degree;
809 values_dofs.resize(dofs_per_component);
812 VectorizedArrayType::size()>
814 constraint_mask.fill(::internal::MatrixFreeFunctions::
816 constraint_mask[0] =
mask;
818 for (
unsigned int i = 0; i < dofs_per_component; ++i)
820 for (
unsigned int j = 0;
j < dofs_per_component; ++
j)
821 values_dofs[
j] = VectorizedArrayType();
822 values_dofs[i] = Number(1);
827 VectorizedArrayType>::apply(1,
829 phi->get_shape_info(),
834 const Number tolerance =
836 std::numeric_limits<Number>::epsilon() * 16);
837 for (
unsigned int j = 0;
j < dofs_per_component; ++
j)
838 if (
std::abs(values_dofs[
j][0]) > tolerance &&
840 std::abs(values_dofs[
j][0] - Number(1)) > tolerance))
848 for (
unsigned int c = 1; c < n_components; ++c)
864 for (
unsigned int j = 0;
j <
phi->dofs_per_cell; ++
j)
865 phi->begin_dof_values()[
j] = VectorizedArrayType();
866 phi->begin_dof_values()[i] = Number(1);
875 const unsigned int n_fe_components =
876 phi->get_dof_info().start_components.back();
877 const unsigned int comp =
878 n_fe_components == 1 ? i / dofs_per_component : 0;
879 const unsigned int i_comp =
880 n_fe_components == 1 ? (i % dofs_per_component) : i;
884 for (
unsigned int v = 0;
885 v <
phi->get_matrix_free().n_active_entries_per_cell_batch(
886 phi->get_current_cell_index());
895 const unsigned int j =
c_pool.inverse_lookup_origins[
jj].first;
900 phi->begin_dof_values()[
comp * dofs_per_component +
911 template <
typename VectorType>
913 distribute_local_to_global(
917 const unsigned int n_fe_components =
918 phi->get_dof_info().start_components.back();
920 for (
unsigned int v = 0;
921 v <
phi->get_matrix_free().n_active_entries_per_cell_batch(
922 phi->get_current_cell_index());
928 for (
unsigned int comp = 0;
929 comp < (n_fe_components == 1 ?
930 static_cast<unsigned int>(n_components) :
946 VectorizedArrayType> *
phi;
948 unsigned int dofs_per_component;
952 std::array<internal::LocalCSR<Number>, n_lanes>
c_pools;
961 std::vector<std::tuple<unsigned int, unsigned int, Number>>>
975 typename VectorizedArrayType,
987 const unsigned int dof_no,
988 const unsigned int quad_no,
989 const unsigned int first_selected_component)
993 std::array<typename ::internal::BlockVectorSelector<
999 for (
unsigned int d = 0;
d < n_components; ++
d)
1004 const auto &dof_info = matrix_free.get_dof_info(
dof_no);
1006 if (dof_info.start_components.back() == 1)
1007 for (
unsigned int comp = 0;
comp < n_components; ++
comp)
1010 ExcMessage(
"The finite element underlying this FEEvaluation "
1011 "object is scalar, but you requested " +
1012 std::to_string(n_components) +
1013 " components via the template argument in "
1014 "FEEvaluation. In that case, you must pass an "
1015 "std::vector<VectorType> or a BlockVector to " +
1016 "read_dof_values and distribute_local_to_global."));
1026 using Helper = internal::ComputeDiagonalHelper<dim,
1031 VectorizedArrayType>;
1038 const std::pair<unsigned int, unsigned int> &
range)
mutable {
1046 VectorizedArrayType>
1047 phi(matrix_free,
range,
dof_no, quad_no, first_selected_component);
1050 for (
unsigned int cell =
range.first; cell <
range.second; ++cell)
1054 for (
unsigned int i = 0; i <
phi.dofs_per_cell; ++i)
1056 helper.prepare_basis_vector(i);
1069 template <
typename CLASS,
1075 typename VectorizedArrayType,
1076 typename VectorType>
1086 VectorizedArrayType> &)
const,
1090 const unsigned
int first_selected_component)
1097 VectorizedArrayType,
1104 first_selected_component);
1113 template <
typename MatrixType,
1115 std::enable_if_t<std::is_same<
1116 typename std::remove_const<
typename std::remove_reference<
1117 typename MatrixType::value_type>::type>::type,
1118 typename std::remove_const<
typename std::remove_reference<
1119 Number>::type>::type>::value> * =
nullptr>
1134 template <
typename MatrixType,
1136 std::enable_if_t<!std::is_same<
1137 typename std::remove_const<
typename std::remove_reference<
1138 typename MatrixType::value_type>::type>::type,
1139 typename std::remove_const<
typename std::remove_reference<
1140 Number>::type>::type>::value> * =
nullptr>
1149 std::make_unique<AffineConstraints<typename MatrixType::value_type>>();
1161 typename VectorizedArrayType,
1162 typename MatrixType>
1167 MatrixType & matrix,
1174 const unsigned int dof_no,
1175 const unsigned int quad_no,
1176 const unsigned int first_selected_component)
1178 std::unique_ptr<AffineConstraints<typename MatrixType::value_type>>
1181 internal::create_new_affine_constraints_if_needed(matrix,
1186 [&](
const auto &,
auto &dst,
const auto &,
const auto range) {
1192 VectorizedArrayType>
1194 matrix_free,
range,
dof_no, quad_no, first_selected_component);
1196 const unsigned int dofs_per_cell =
integrator.dofs_per_cell;
1198 std::vector<types::global_dof_index> dof_indices(dofs_per_cell);
1199 std::vector<types::global_dof_index>
dof_indices_mf(dofs_per_cell);
1201 std::array<FullMatrix<typename MatrixType::value_type>,
1202 VectorizedArrayType::size()>
1205 std::fill_n(matrices.begin(),
1206 VectorizedArrayType::size(),
1210 const auto lexicographic_numbering =
1214 first_selected_component,
1217 .lexicographic_numbering;
1219 for (
auto cell =
range.first; cell <
range.second; ++cell)
1224 matrix_free.n_active_entries_per_cell_batch(cell);
1229 for (
unsigned int j = 0;
j < dofs_per_cell; ++
j)
1231 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1233 static_cast<Number
>(i ==
j);
1237 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1239 matrices[v](i,
j) =
integrator.begin_dof_values()[i][v];
1245 matrix_free.get_cell_iterator(cell, v,
dof_no);
1248 cell_v->get_mg_dof_indices(dof_indices);
1250 cell_v->get_dof_indices(dof_indices);
1252 for (
unsigned int j = 0;
j < dof_indices.size(); ++
j)
1255 constraints.distribute_local_to_global(matrices[v],
1267 template <
typename CLASS,
1273 typename VectorizedArrayType,
1274 typename MatrixType>
1279 MatrixType & matrix,
1285 VectorizedArrayType> &)
const,
1289 const unsigned
int first_selected_component)
1296 VectorizedArrayType,
1304 first_selected_component);