21#include <deal.II/matrix_free/dof_info.templates.h>
29 namespace MatrixFreeFunctions
57 for (
unsigned int i = 0; i < 3; ++i)
74 const unsigned int cell,
75 const bool apply_constraints)
const
78 const unsigned int fe_index =
86 const unsigned int n_vectorization_actual =
92 my_rows.reserve(n_vectorization * dofs_this_cell);
94 unsigned int total_size = 0;
95 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
97 const unsigned int ib =
98 (cell * n_vectorization + v) * n_fe_components;
99 const unsigned int ie =
100 (cell * n_vectorization + v + 1) * n_fe_components;
105 const bool has_constraints =
108 auto do_copy = [&](
const unsigned int *
begin,
109 const unsigned int *
end) {
110 const unsigned int shift = total_size;
112 my_rows.resize(total_size);
116 if (!has_constraints || apply_constraints)
118 const unsigned int *
begin =
120 const unsigned int *
end =
129 const unsigned int *
begin =
132 const unsigned int *
end =
begin + dofs_this_cell;
143 const bool use_vector_data_exchanger_full)
150 const std::size_t n_ghosts =
ghost_dofs.size();
157 std::vector<unsigned int> ghost_numbering(n_ghosts);
161 unsigned int n_unique_ghosts = 0;
165 std::vector<std::pair<types::global_dof_index, unsigned int>>
166 ghost_origin(n_ghosts);
167 for (std::size_t i = 0; i < n_ghosts; ++i)
170 ghost_origin[i].second = i;
172 std::sort(ghost_origin.begin(), ghost_origin.end());
175 ghost_numbering[ghost_origin[0].second] = 0;
176 for (std::size_t i = 1; i < n_ghosts; i++)
178 if (ghost_origin[i].
first > ghost_origin[i - 1].
first + 1)
180 ghost_indices.
add_range(last_contiguous_start,
181 ghost_origin[i - 1].
first + 1);
182 last_contiguous_start = ghost_origin[i].first;
184 if (ghost_origin[i].
first > ghost_origin[i - 1].
first)
186 ghost_numbering[ghost_origin[i].second] = n_unique_ghosts;
189 ghost_indices.
add_range(last_contiguous_start,
190 ghost_origin.back().first + 1);
197 for (std::size_t i = 0; i < n_ghosts; ++i)
198 Assert(ghost_numbering[i] ==
207 const unsigned int n_boundary_cells = boundary_cells.size();
208 for (
unsigned int i = 0; i < n_boundary_cells; ++i)
210 unsigned int *data_ptr =
213 const unsigned int *row_end =
216 for (; data_ptr != row_end; ++data_ptr)
217 *data_ptr = ((*data_ptr < n_owned) ?
219 n_owned + ghost_numbering[*data_ptr - n_owned]);
227 unsigned int *data_ptr =
230 const unsigned int fe_index =
236 const unsigned int *row_end =
238 for (; data_ptr != row_end; ++data_ptr)
240 ((*data_ptr < n_owned) ?
242 n_owned + ghost_numbering[*data_ptr - n_owned]);
248 std::vector<types::global_dof_index> empty;
258 if (use_vector_data_exchanger_full ==
false)
264 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
273 const std::vector<unsigned int> & renumbering,
274 const std::vector<unsigned int> & constraint_pool_row_index,
275 const std::vector<unsigned char> &irregular_cells)
277 (void)constraint_pool_row_index;
283 std::vector<unsigned int> new_active_fe_index;
285 unsigned int position_cell = 0;
286 for (
unsigned int cell = 0;
290 const unsigned int n_comp =
291 (irregular_cells[cell] > 0 ? irregular_cells[cell] :
296 unsigned int fe_index =
298 for (
unsigned int j = 1; j < n_comp; ++j)
303 new_active_fe_index.push_back(fe_index);
304 position_cell += n_comp;
314 std::vector<std::pair<unsigned int, unsigned int>> new_row_starts(
318 std::vector<unsigned int> new_dof_indices;
319 std::vector<std::pair<unsigned short, unsigned short>>
320 new_constraint_indicator;
321 std::vector<unsigned int> new_plain_indices, new_rowstart_plain;
322 unsigned int position_cell = 0;
342 const unsigned int n_vect =
343 (irregular_cells[i] > 0 ? irregular_cells[i] :
347 this->dofs_per_cell[0];
349 for (
unsigned int j = 0; j < n_vect; ++j)
351 const unsigned int cell_no =
353 for (
unsigned int comp = 0; comp <
n_components; ++comp)
357 .
first = new_dof_indices.size();
360 .
second = new_constraint_indicator.size();
362 new_dof_indices.insert(
363 new_dof_indices.end(),
367 index !=
row_starts[cell_no + comp + 1].second;
369 new_constraint_indicator.push_back(
377 new_plain_indices.size();
378 new_plain_indices.insert(
379 new_plain_indices.end(),
388 for (
unsigned int comp = 0; comp <
n_components; ++comp)
392 .
first = new_dof_indices.size();
395 .
second = new_constraint_indicator.size();
397 position_cell += n_vect;
404 .first = new_dof_indices.size();
407 .second = new_constraint_indicator.size();
410 new_constraint_indicator.size());
421 const unsigned int index_range =
435 const unsigned int row_length_ind =
441 const std::pair<unsigned short, unsigned short> *
448 for (; con_it != end_con; ++con_it)
452 constraint_pool_row_index.size() - 1);
460 if (irregular_cells[c] > 0)
474 const std::vector<unsigned char> &irregular_cells)
484 irregular_cells.size());
488 irregular_cells.size());
489 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
490 if (irregular_cells[i] > 0)
505 std::vector<unsigned int> index_kinds(
506 static_cast<unsigned int>(
510 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
512 const unsigned int ndofs =
514 const unsigned int n_comp =
518 bool has_constraints =
false;
519 for (
unsigned int j = 0; j < n_comp; ++j)
525 has_constraints =
true;
534 bool indices_are_contiguous =
true;
535 for (
unsigned int j = 0; j < n_comp; ++j)
539 this->dof_indices.data() +
545 for (
unsigned int i = 1; i < ndofs; ++i)
548 indices_are_contiguous =
false;
553 bool indices_are_interleaved_and_contiguous =
558 this->dof_indices.data() +
560 for (
unsigned int k = 0; k < ndofs; ++k)
561 for (
unsigned int j = 0; j < n_comp; ++j)
565 indices_are_interleaved_and_contiguous =
false;
570 if (indices_are_contiguous ||
571 indices_are_interleaved_and_contiguous)
573 for (
unsigned int j = 0; j < n_comp; ++j)
582 if (indices_are_interleaved_and_contiguous)
587 for (
unsigned int j = 0; j < n_comp; ++j)
591 else if (indices_are_contiguous)
595 for (
unsigned int j = 0; j < n_comp; ++j)
601 int indices_are_interleaved_and_mixed = 2;
606 for (
unsigned int j = 0; j < n_comp; ++j)
609 for (
unsigned int k = 0; k < ndofs; ++k)
610 for (
unsigned int j = 0; j < n_comp; ++j)
617 indices_are_interleaved_and_mixed = 0;
620 if (indices_are_interleaved_and_mixed == 2)
622 for (
unsigned int j = 0; j < n_comp; ++j)
626 for (
unsigned int j = 0; j < n_comp; ++j)
630 for (
unsigned int j = 0; j < n_comp; ++j)
633 indices_are_interleaved_and_mixed = 1;
636 if (indices_are_interleaved_and_mixed == 1 ||
648 this->dof_indices.data() +
661 for (
unsigned int k = 0; k < ndofs; ++k)
662 for (
unsigned int l = 0;
l < n_comp; ++
l)
663 for (
unsigned int j =
l + 1; j < n_comp; ++j)
674 index_kinds[
static_cast<unsigned int>(
684 auto fix_single_interleaved_indices =
686 if (index_kinds[
static_cast<unsigned int>(
689 index_kinds[
static_cast<unsigned int>(variant)] > 0)
690 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
694 interleaved_contiguous_mixed_strides &&
702 index_kinds[
static_cast<unsigned int>(
705 index_kinds[
static_cast<unsigned int>(variant)]++;
714 unsigned int n_interleaved =
715 index_kinds[
static_cast<unsigned int>(
717 index_kinds[
static_cast<unsigned int>(
719 index_kinds[
static_cast<unsigned int>(
724 if (n_interleaved > 0 && index_kinds[
static_cast<unsigned int>(
726 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
732 index_kinds[
static_cast<unsigned int>(
734 index_kinds[
static_cast<unsigned int>(
740 if (n_interleaved > 0 &&
742 index_kinds[
static_cast<unsigned int>(
745 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
749 index_kinds[
static_cast<unsigned int>(
758 index_kinds[
static_cast<unsigned int>(
763 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
774 const unsigned int ndofs =
779 unsigned int *interleaved_dof_indices =
783 this->dof_indices_interleaved.size());
793 for (
unsigned int k = 0; k < ndofs; ++k)
805 const unsigned int n_owned_cells,
806 const unsigned int n_lanes,
809 const bool fill_cell_centric,
811 const bool use_vector_data_exchanger_full)
817 std::vector<types::global_dof_index> ghost_indices;
820 for (
unsigned int cell = 0; cell < n_owned_cells; ++cell)
828 const unsigned int fe_index =
837 ghost_indices.push_back(
840 std::sort(ghost_indices.begin(), ghost_indices.end());
841 ghost_indices.erase(std::unique(ghost_indices.begin(),
842 ghost_indices.end()),
843 ghost_indices.end());
845 compressed_set.
add_indices(ghost_indices.begin(), ghost_indices.end());
847 const bool all_ghosts_equal =
848 Utilities::MPI::min<int>(
static_cast<int>(
853 std::shared_ptr<const Utilities::MPI::Partitioner> temp_0;
855 if (all_ghosts_equal)
859 temp_0 = std::make_shared<Utilities::MPI::Partitioner>(
865 if (use_vector_data_exchanger_full ==
false)
871 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
872 temp_0, communicator_sm);
876 std::vector<FaceToCellTopology<1>> all_faces(inner_faces);
877 all_faces.insert(all_faces.end(),
878 ghosted_faces.begin(),
879 ghosted_faces.end());
882 2 * shape_info(0, 0).n_dimensions);
884 for (
unsigned int f = 0; f < all_faces.size(); ++f)
886 cell_and_face_to_faces(all_faces[f].cells_interior[0],
887 all_faces[f].interior_face_no) = f;
888 Assert(all_faces[f].cells_exterior[0] !=
891 cell_and_face_to_faces(all_faces[f].cells_exterior[0],
892 all_faces[f].exterior_face_no) = f;
896 const auto loop_over_faces =
897 [&](
const std::function<
898 void(
const unsigned int,
const unsigned int,
const bool)> &fu) {
899 for (
const auto &face : inner_faces)
902 fu(face.cells_exterior[0], face.exterior_face_no,
false );
906 const auto loop_over_all_faces =
907 [&](
const std::function<
908 void(
const unsigned int,
const unsigned int,
const bool)> &fu) {
909 for (
unsigned int c = 0; c < cell_and_face_to_faces.size(0); ++c)
910 for (
unsigned int d = 0;
d < cell_and_face_to_faces.size(1); ++
d)
912 const unsigned int f = cell_and_face_to_faces(c,
d);
916 const unsigned int cell_m = all_faces[f].cells_interior[0];
917 const unsigned int cell_p = all_faces[f].cells_exterior[0];
919 const bool ext = c == cell_m;
924 const unsigned int p = ext ? cell_p : cell_m;
925 const unsigned int face_no = ext ?
926 all_faces[f].exterior_face_no :
927 all_faces[f].interior_face_no;
929 fu(p, face_no,
true);
933 const auto process_values =
935 std::shared_ptr<const Utilities::MPI::Partitioner>
936 &vector_partitioner_values,
937 const std::function<void(
938 const std::function<
void(
939 const unsigned int,
const unsigned int,
const bool)> &)> &
loop) {
940 bool all_nodal_and_tensorial =
true;
945 if (!si.nodal_at_cell_boundaries ||
948 all_nodal_and_tensorial =
false;
950 if (all_nodal_and_tensorial ==
false)
954 bool has_noncontiguous_cell =
false;
956 loop([&](
const unsigned int cell_no,
957 const unsigned int face_no,
959 const unsigned int index =
964 const unsigned int stride =
965 dof_indices_interleave_strides[dof_access_cell][cell_no];
967 for (unsigned int e = 0; e < n_base_elements; ++e)
968 for (unsigned int c = 0; c < n_components[e]; ++c)
970 const ShapeInfo<double> &shape =
971 shape_info(global_base_element_offset + e, 0);
972 for (unsigned int j = 0;
973 j < shape.dofs_per_component_on_face;
975 ghost_indices.push_back(part.local_to_global(
977 shape.face_to_cell_index_nodal(face_no, j) *
979 i += shape.dofs_per_component_on_cell * stride;
984 has_noncontiguous_cell =
true;
986 has_noncontiguous_cell =
987 Utilities::MPI::min<int>(
static_cast<int>(
988 has_noncontiguous_cell),
991 std::sort(ghost_indices.begin(), ghost_indices.end());
992 ghost_indices.erase(std::unique(ghost_indices.begin(),
993 ghost_indices.end()),
994 ghost_indices.end());
997 ghost_indices.end());
999 const bool all_ghosts_equal =
1000 Utilities::MPI::min<int>(
static_cast<int>(
1004 if (all_ghosts_equal || has_noncontiguous_cell)
1008 vector_partitioner_values =
1009 std::make_shared<Utilities::MPI::Partitioner>(
1012 vector_partitioner_values.get())
1019 const auto process_gradients =
1021 const std::shared_ptr<const Utilities::MPI::Partitioner>
1022 &vector_partitoner_values,
1023 std::shared_ptr<const Utilities::MPI::Partitioner>
1024 &vector_partitioner_gradients,
1025 const std::function<void(
1026 const std::function<
void(
1027 const unsigned int,
const unsigned int,
const bool)> &)> &
loop) {
1028 bool all_hermite =
true;
1029 for (
unsigned int c = 0; c < n_base_elements; ++c)
1030 if (shape_info(global_base_element_offset + c, 0).element_type !=
1032 all_hermite =
false;
1033 if (all_hermite ==
false ||
1034 vector_partitoner_values.get() == vector_partitioner.get())
1035 vector_partitioner_gradients = vector_partitioner;
1038 loop([&](
const unsigned int cell_no,
1039 const unsigned int face_no,
1041 const unsigned int index =
1042 dof_indices_contiguous[dof_access_cell][cell_no];
1044 index >= part.local_size()))
1046 const unsigned int stride =
1047 dof_indices_interleave_strides[dof_access_cell][cell_no];
1049 for (unsigned int e = 0; e < n_base_elements; ++e)
1050 for (unsigned int c = 0; c < n_components[e]; ++c)
1052 const ShapeInfo<double> &shape =
1053 shape_info(global_base_element_offset + e, 0);
1054 for (unsigned int j = 0;
1055 j < 2 * shape.dofs_per_component_on_face;
1057 ghost_indices.push_back(part.local_to_global(
1059 shape.face_to_cell_index_hermite(face_no, j) *
1061 i += shape.dofs_per_component_on_cell * stride;
1066 std::sort(ghost_indices.begin(), ghost_indices.end());
1067 ghost_indices.erase(std::unique(ghost_indices.begin(),
1068 ghost_indices.end()),
1069 ghost_indices.end());
1070 IndexSet compressed_set(part.size());
1071 compressed_set.add_indices(ghost_indices.begin(),
1072 ghost_indices.end());
1073 compressed_set.subtract_set(part.locally_owned_range());
1074 const bool all_ghosts_equal =
1075 Utilities::MPI::min<int>(
static_cast<int>(
1076 compressed_set.n_elements() ==
1077 part.ghost_indices().n_elements()),
1078 part.get_mpi_communicator()) != 0;
1079 if (all_ghosts_equal)
1080 vector_partitioner_gradients = vector_partitioner;
1083 vector_partitioner_gradients =
1084 std::make_shared<Utilities::MPI::Partitioner>(
1085 part.locally_owned_range(), part.get_mpi_communicator());
1087 vector_partitioner_gradients.get())
1088 ->set_ghost_indices(compressed_set, part.ghost_indices());
1093 std::shared_ptr<const Utilities::MPI::Partitioner> temp_1, temp_2, temp_3,
1097 process_values(temp_1, loop_over_faces);
1100 process_gradients(temp_1, temp_2, loop_over_faces);
1102 if (fill_cell_centric)
1104 ghost_indices.clear();
1106 process_values(temp_3, loop_over_all_faces);
1108 process_gradients(temp_3, temp_4, loop_over_all_faces);
1112 temp_3 = std::make_shared<Utilities::MPI::Partitioner>(
1113 part.locally_owned_range(), part.get_mpi_communicator());
1114 temp_4 = std::make_shared<Utilities::MPI::Partitioner>(
1115 part.locally_owned_range(), part.get_mpi_communicator());
1118 if (use_vector_data_exchanger_full ==
false)
1120 vector_exchanger_face_variants[1] = std::make_shared<
1121 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1123 vector_exchanger_face_variants[2] = std::make_shared<
1124 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1126 vector_exchanger_face_variants[3] = std::make_shared<
1127 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1129 vector_exchanger_face_variants[4] = std::make_shared<
1130 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1135 vector_exchanger_face_variants[1] =
1136 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1137 temp_1, communicator_sm);
1138 vector_exchanger_face_variants[2] =
1139 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1140 temp_2, communicator_sm);
1141 vector_exchanger_face_variants[3] =
1142 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1143 temp_3, communicator_sm);
1144 vector_exchanger_face_variants[4] =
1145 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1146 temp_4, communicator_sm);
1153 DoFInfo::compute_shared_memory_contiguous_indices(
1154 std::array<std::vector<std::pair<unsigned int, unsigned int>>, 3>
1155 &cell_indices_contiguous_sm)
1159 for (
unsigned int i = 0; i < 3; ++i)
1161 dof_indices_contiguous_sm[i].resize(
1162 cell_indices_contiguous_sm[i].size());
1164 for (
unsigned int j = 0; j < cell_indices_contiguous_sm[i].size();
1166 if (cell_indices_contiguous_sm[i][j].
first !=
1168 dof_indices_contiguous_sm[i][j] = {
1169 cell_indices_contiguous_sm[i][j].first,
1170 cell_indices_contiguous_sm[i][j].second * dofs_per_cell[0]};
1190 const unsigned int end,
1192 std::vector<std::mutex> & mutexes,
1193 std::vector<unsigned int> &row_lengths)
1195 std::vector<unsigned int> scratch;
1197 for (
unsigned int block =
begin; block <
end; ++block)
1203 dof_info.
row_starts[block * n_components].first,
1205 dof_info.
row_starts[(block + 1) * n_components].first);
1206 std::sort(scratch.begin(), scratch.end());
1207 std::vector<unsigned int>::const_iterator end_unique =
1208 std::unique(scratch.begin(), scratch.end());
1209 std::vector<unsigned int>::const_iterator it = scratch.begin();
1210 while (it != end_unique)
1214 const unsigned int next_bucket =
1216 std::lock_guard<std::mutex> lock(
1218 for (; it != end_unique && *it < next_bucket; ++it)
1229 const unsigned int end,
1231 const std::vector<unsigned int> &row_lengths,
1232 std::vector<std::mutex> & mutexes,
1235 std::vector<unsigned int> scratch;
1237 for (
unsigned int block =
begin; block <
end; ++block)
1243 dof_info.
row_starts[block * n_components].first,
1245 dof_info.
row_starts[(block + 1) * n_components].first);
1246 std::sort(scratch.begin(), scratch.end());
1247 std::vector<unsigned int>::const_iterator end_unique =
1248 std::unique(scratch.begin(), scratch.end());
1249 std::vector<unsigned int>::const_iterator it = scratch.begin();
1250 while (it != end_unique)
1252 const unsigned int next_bucket =
1254 std::lock_guard<std::mutex> lock(
1256 for (; it != end_unique && *it < next_bucket; ++it)
1257 if (row_lengths[*it] > 0)
1258 connectivity_dof.
add(*it, block);
1267 const unsigned int end,
1269 const std::vector<unsigned int> &renumbering,
1270 const ::SparsityPattern & connectivity_dof,
1273 ordered_vector row_entries;
1275 for (
unsigned int block =
begin; block <
end; ++block)
1277 row_entries.clear();
1281 dof_info.
row_starts[block * n_components].first,
1284 for (; it != end_cell; ++it)
1287 std::vector<types::global_dof_index>::iterator insert_pos =
1288 row_entries.begin();
1289 for (; sp != connectivity_dof.end(*it); ++sp)
1290 if (sp->column() != block)
1291 row_entries.insert(renumbering[sp->column()], insert_pos);
1294 row_entries.begin(),
1302 DoFInfo::make_connectivity_graph(
1304 const std::vector<unsigned int> &renumbering,
1307 unsigned int n_rows = (vector_partitioner->local_range().second -
1308 vector_partitioner->local_range().first) +
1309 vector_partitioner->ghost_indices().n_elements();
1316 std::vector<unsigned int> row_lengths(n_rows);
1322 [
this, &mutexes, &row_lengths](
const unsigned int begin,
1323 const unsigned int end) {
1324 internal::compute_row_lengths(
1325 begin, end, *this, mutexes, row_lengths);
1331 for (
unsigned int row = 0; row < n_rows; ++row)
1332 if (row_lengths[row] <= 1)
1333 row_lengths[row] = 0;
1344 [
this, &row_lengths, &mutexes, &connectivity_dof](
1345 const unsigned int begin,
const unsigned int end) {
1346 internal::fill_connectivity_dofs(
1347 begin, end, *this, row_lengths, mutexes, connectivity_dof);
1354 std::vector<unsigned int> reverse_numbering(task_info.
n_active_cells);
1364 [
this, &reverse_numbering, &connectivity_dof, &connectivity](
1365 const unsigned int begin,
const unsigned int end) {
1366 internal::fill_connectivity(begin,
1379 DoFInfo::compute_dof_renumbering(
1380 std::vector<types::global_dof_index> &renumbering)
1382 const unsigned int locally_owned_size =
1383 vector_partitioner->locally_owned_size();
1384 renumbering.resize(0);
1388 const unsigned int n_components = start_components.back();
1389 const unsigned int n_cell_batches =
1390 n_vectorization_lanes_filled[dof_access_cell].size();
1392 (row_starts.size() - 1) / vectorization_length / n_components,
1394 for (
unsigned int cell_no = 0; cell_no < n_cell_batches; ++cell_no)
1397 if (row_starts[cell_no * n_components * vectorization_length]
1399 row_starts[(cell_no + 1) * n_components * vectorization_length]
1402 const unsigned int ndofs =
1403 dofs_per_cell.size() == 1 ?
1405 (dofs_per_cell[cell_active_fe_index.size() > 0 ?
1406 cell_active_fe_index[cell_no] :
1408 const unsigned int *dof_ind =
1409 dof_indices.data() +
1410 row_starts[cell_no * n_components * vectorization_length].first;
1411 for (
unsigned int i = 0; i < ndofs; ++i)
1412 for (
unsigned int j = 0;
1413 j < n_vectorization_lanes_filled[dof_access_cell][cell_no];
1415 if (dof_ind[j * ndofs + i] < locally_owned_size)
1416 if (renumbering[dof_ind[j * ndofs + i]] ==
1418 renumbering[dof_ind[j * ndofs + i]] = counter++;
1425 dof_index = counter++;
1429 dof_index = vector_partitioner->local_to_global(dof_index);
1439 std::size_t memory =
sizeof(*this);
1441 (row_starts.capacity() *
sizeof(std::pair<unsigned int, unsigned int>));
1454 namespace MatrixFreeFunctions
1456 template struct ConstraintValues<double>;
1457 template struct ConstraintValues<float>;
1460 DoFInfo::read_dof_indices<double>(
1461 const std::vector<types::global_dof_index> &,
1462 const std::vector<unsigned int> &,
1463 const ::AffineConstraints<double> &,
1465 ConstraintValues<double> &,
1469 DoFInfo::read_dof_indices<float>(
1470 const std::vector<types::global_dof_index> &,
1471 const std::vector<unsigned int> &,
1472 const ::AffineConstraints<float> &,
1474 ConstraintValues<double> &,
1478 DoFInfo::compute_face_index_compression<1>(
1479 const std::vector<FaceToCellTopology<1>> &);
1481 DoFInfo::compute_face_index_compression<2>(
1482 const std::vector<FaceToCellTopology<2>> &);
1484 DoFInfo::compute_face_index_compression<4>(
1485 const std::vector<FaceToCellTopology<4>> &);
1487 DoFInfo::compute_face_index_compression<8>(
1488 const std::vector<FaceToCellTopology<8>> &);
1490 DoFInfo::compute_face_index_compression<16>(
1491 const std::vector<FaceToCellTopology<16>> &);
1494 DoFInfo::compute_vector_zero_access_pattern<1>(
1496 const std::vector<FaceToCellTopology<1>> &);
1498 DoFInfo::compute_vector_zero_access_pattern<2>(
1500 const std::vector<FaceToCellTopology<2>> &);
1502 DoFInfo::compute_vector_zero_access_pattern<4>(
1504 const std::vector<FaceToCellTopology<4>> &);
1506 DoFInfo::compute_vector_zero_access_pattern<8>(
1508 const std::vector<FaceToCellTopology<8>> &);
1510 DoFInfo::compute_vector_zero_access_pattern<16>(
1512 const std::vector<FaceToCellTopology<16>> &);
1515 DoFInfo::print_memory_consumption<std::ostream>(std::ostream &,
1518 DoFInfo::print_memory_consumption<ConditionalOStream>(
1523 DoFInfo::print<double>(
const std::vector<double> &,
1524 const std::vector<unsigned int> &,
1525 std::ostream &)
const;
1528 DoFInfo::print<float>(
const std::vector<float> &,
1529 const std::vector<unsigned int> &,
1530 std::ostream &)
const;
size_type index_within_set(const size_type global_index) const
size_type n_elements() const
void subtract_set(const IndexSet &other)
void add_range(const size_type begin, const size_type end)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
const IndexSet & locally_owned_range() const
unsigned int local_size() const
const IndexSet & ghost_indices() const
types::global_dof_index local_to_global(const unsigned int local_index) const
void set_ghost_indices(const IndexSet &ghost_indices, const IndexSet &larger_ghost_index_set=IndexSet())
virtual const MPI_Comm & get_mpi_communicator() const override
types::global_dof_index size() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNotInitialized()
void loop(ITERATOR begin, typename identity< ITERATOR >::type end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &assembler, const LoopControl &lctrl=LoopControl())
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_unique_and_sorted=false)
void add(const size_type i, const size_type j)
@ tensor_symmetric_hermite
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
std::vector< Integer > invert_permutation(const std::vector< Integer > &permutation)
void fill_connectivity_dofs(const unsigned int begin, const unsigned int end, const DoFInfo &dof_info, const std::vector< unsigned int > &row_lengths, std::vector< std::mutex > &mutexes, ::SparsityPattern &connectivity_dof)
void fill_connectivity(const unsigned int begin, const unsigned int end, const DoFInfo &dof_info, const std::vector< unsigned int > &renumbering, const ::SparsityPattern &connectivity_dof, DynamicSparsityPattern &connectivity)
void compute_row_lengths(const unsigned int begin, const unsigned int end, const DoFInfo &dof_info, std::vector< std::mutex > &mutexes, std::vector< unsigned int > &row_lengths)
static constexpr unsigned int bucket_size_threading
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
void copy(const T *begin, const T *end, U *dest)
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
void apply_to_subranges(const tbb::blocked_range< RangeType > &range, const Function &f)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
void reorder_cells(const TaskInfo &task_info, const std::vector< unsigned int > &renumbering, const std::vector< unsigned int > &constraint_pool_row_index, const std::vector< unsigned char > &irregular_cells)
std::vector< std::pair< unsigned short, unsigned short > > constraint_indicator
std::vector< std::pair< unsigned int, unsigned int > > row_starts
unsigned int n_base_elements
unsigned int global_base_element_offset
unsigned int max_fe_index
void compute_cell_index_compression(const std::vector< unsigned char > &irregular_cells)
std::vector< unsigned int > dofs_per_cell
unsigned int vectorization_length
std::shared_ptr< const internal::MatrixFreeFunctions::VectorDataExchange::Base > vector_exchanger
@ interleaved_contiguous_strided
@ interleaved_contiguous_mixed_strides
std::vector< std::vector< unsigned int > > fe_index_conversion
void compute_tight_partitioners(const Table< 2, ShapeInfo< double > > &shape_info, const unsigned int n_owned_cells, const unsigned int n_lanes, const std::vector< FaceToCellTopology< 1 > > &inner_faces, const std::vector< FaceToCellTopology< 1 > > &ghosted_faces, const bool fill_cell_centric, const MPI_Comm &communicator_sm, const bool use_vector_data_exchanger_full)
std::vector< unsigned int > dof_indices
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
std::array< std::vector< unsigned int >, 3 > dof_indices_interleave_strides
std::vector< unsigned int > row_starts_plain_indices
std::vector< unsigned int > dofs_per_face
std::vector< unsigned int > n_components
void assign_ghosts(const std::vector< unsigned int > &boundary_cells, const MPI_Comm &communicator_sm, const bool use_vector_data_exchanger_full)
std::vector< types::global_dof_index > ghost_dofs
std::array< std::vector< unsigned int >, 3 > dof_indices_contiguous
void get_dof_indices_on_cell_batch(std::vector< unsigned int > &locall_indices, const unsigned int cell, const bool with_constraints=true) const
std::vector< unsigned int > cell_active_fe_index
std::array< std::shared_ptr< const internal::MatrixFreeFunctions::VectorDataExchange::Base >, 5 > vector_exchanger_face_variants
std::vector< unsigned int > plain_dof_indices
std::array< std::vector< unsigned char >, 3 > n_vectorization_lanes_filled
std::vector< unsigned int > start_components
std::vector< unsigned int > dof_indices_interleaved
std::array< std::vector< IndexStorageVariants >, 3 > index_storage_variants
unsigned int n_active_cells
std::vector< unsigned int > cell_partition_data