21#include <deal.II/matrix_free/dof_info.templates.h>
29 namespace MatrixFreeFunctions
33 static_assert(std::is_same<compressed_constraint_kind, std::uint8_t>::value,
34 "Unexpected type for compressed hanging node indicators!");
64 for (
unsigned int i = 0; i < 3; ++i)
81 const unsigned int cell,
82 const bool apply_constraints)
const
85 const unsigned int fe_index =
93 const unsigned int n_vectorization_actual =
99 my_rows.reserve(n_vectorization * dofs_this_cell);
101 unsigned int total_size = 0;
102 for (
unsigned int v = 0; v < n_vectorization_actual; ++v)
104 const unsigned int ib =
105 (cell * n_vectorization + v) * n_fe_components;
106 const unsigned int ie =
107 (cell * n_vectorization + v + 1) * n_fe_components;
112 const bool has_constraints =
120 auto do_copy = [&](
const unsigned int *begin,
121 const unsigned int *end) {
122 const unsigned int shift = total_size;
123 total_size += (end - begin);
124 my_rows.resize(total_size);
125 std::copy(begin, end, my_rows.begin() + shift);
128 if (!has_constraints || apply_constraints)
130 const unsigned int *begin =
132 const unsigned int *end =
141 const unsigned int *begin =
144 const unsigned int *end = begin + dofs_this_cell;
155 const bool use_vector_data_exchanger_full)
162 const std::size_t n_ghosts =
ghost_dofs.size();
169 std::vector<unsigned int> ghost_numbering(n_ghosts);
173 unsigned int n_unique_ghosts = 0;
177 std::vector<std::pair<types::global_dof_index, unsigned int>>
178 ghost_origin(n_ghosts);
179 for (std::size_t i = 0; i < n_ghosts; ++i)
182 ghost_origin[i].second = i;
184 std::sort(ghost_origin.begin(), ghost_origin.end());
187 ghost_numbering[ghost_origin[0].second] = 0;
188 for (std::size_t i = 1; i < n_ghosts; ++i)
190 if (ghost_origin[i].
first > ghost_origin[i - 1].
first + 1)
192 ghost_indices.
add_range(last_contiguous_start,
193 ghost_origin[i - 1].
first + 1);
194 last_contiguous_start = ghost_origin[i].first;
196 if (ghost_origin[i].
first > ghost_origin[i - 1].
first)
198 ghost_numbering[ghost_origin[i].second] = n_unique_ghosts;
201 ghost_indices.
add_range(last_contiguous_start,
202 ghost_origin.back().first + 1);
209 for (std::size_t i = 0; i < n_ghosts; ++i)
210 Assert(ghost_numbering[i] ==
219 const unsigned int n_boundary_cells = boundary_cells.size();
220 for (
unsigned int i = 0; i < n_boundary_cells; ++i)
222 unsigned int *data_ptr =
225 const unsigned int *row_end =
228 for (; data_ptr != row_end; ++data_ptr)
229 *data_ptr = ((*data_ptr < n_owned) ?
231 n_owned + ghost_numbering[*data_ptr - n_owned]);
236 bool has_hanging_nodes =
false;
238 const unsigned int fe_index =
249 for (
unsigned int comp = 0; comp <
n_components; ++comp)
253 if (has_hanging_nodes ||
258 unsigned int *data_ptr =
261 const unsigned int *row_end =
263 for (; data_ptr != row_end; ++data_ptr)
265 ((*data_ptr < n_owned) ?
267 n_owned + ghost_numbering[*data_ptr - n_owned]);
273 std::vector<types::global_dof_index> empty;
283 if (use_vector_data_exchanger_full ==
false)
289 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
298 const std::vector<unsigned int> & renumbering,
299 const std::vector<unsigned int> & constraint_pool_row_index,
300 const std::vector<unsigned char> &irregular_cells)
302 (void)constraint_pool_row_index;
308 std::vector<unsigned int> new_active_fe_index;
310 unsigned int position_cell = 0;
311 for (
unsigned int cell = 0;
315 const unsigned int n_comp =
316 (irregular_cells[cell] > 0 ? irregular_cells[cell] :
321 unsigned int fe_index =
323 for (
unsigned int j = 1; j < n_comp; ++j)
328 new_active_fe_index.push_back(fe_index);
329 position_cell += n_comp;
339 std::vector<std::pair<unsigned int, unsigned int>> new_row_starts(
343 std::vector<unsigned int> new_dof_indices;
344 std::vector<std::pair<unsigned short, unsigned short>>
345 new_constraint_indicator;
346 std::vector<unsigned int> new_plain_indices, new_rowstart_plain;
347 unsigned int position_cell = 0;
351 std::vector<compressed_constraint_kind> new_hanging_node_constraint_masks;
352 new_hanging_node_constraint_masks.reserve(
372 const unsigned int n_vect =
373 (irregular_cells[i] > 0 ? irregular_cells[i] :
377 this->dofs_per_cell[0];
379 for (
unsigned int j = 0; j < n_vect; ++j)
381 const unsigned int cell_no =
384 bool has_hanging_nodes =
false;
392 new_hanging_node_constraint_masks.push_back(
mask);
395 for (
unsigned int comp = 0; comp <
n_components; ++comp)
400 for (
unsigned int comp = 0; comp <
n_components; ++comp)
404 .
first = new_dof_indices.size();
407 .
second = new_constraint_indicator.size();
409 new_dof_indices.insert(
410 new_dof_indices.end(),
416 new_constraint_indicator.push_back(
425 new_plain_indices.size();
426 new_plain_indices.insert(
427 new_plain_indices.end(),
436 for (
unsigned int comp = 0; comp <
n_components; ++comp)
440 .
first = new_dof_indices.size();
443 .
second = new_constraint_indicator.size();
448 new_hanging_node_constraint_masks.push_back(
451 position_cell += n_vect;
458 .first = new_dof_indices.size();
461 .second = new_constraint_indicator.size();
464 new_constraint_indicator.size());
476 const unsigned int index_range =
490 const unsigned int row_length_ind =
496 const std::pair<unsigned short, unsigned short> *
503 for (; con_it != end_con; ++con_it)
507 constraint_pool_row_index.size() - 1);
512 unsigned int n_active_cells = 0;
515 if (irregular_cells[c] > 0)
516 n_active_cells += irregular_cells[c];
529 const std::vector<unsigned char> &irregular_cells)
539 irregular_cells.size());
543 irregular_cells.size());
544 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
545 if (irregular_cells[i] > 0)
560 std::vector<unsigned int> index_kinds(
561 static_cast<unsigned int>(
565 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
567 const unsigned int ndofs =
569 const unsigned int n_comp =
573 bool has_constraints =
false;
574 for (
unsigned int j = 0; j < n_comp; ++j)
580 has_constraints =
true;
589 bool indices_are_contiguous =
true;
590 for (
unsigned int j = 0; j < n_comp; ++j)
594 this->dof_indices.data() +
600 for (
unsigned int i = 1; i < ndofs; ++i)
603 indices_are_contiguous =
false;
608 bool indices_are_interleaved_and_contiguous =
613 this->dof_indices.data() +
615 for (
unsigned int k = 0; k < ndofs; ++k)
616 for (
unsigned int j = 0; j < n_comp; ++j)
620 indices_are_interleaved_and_contiguous =
false;
625 if (indices_are_contiguous ||
626 indices_are_interleaved_and_contiguous)
628 for (
unsigned int j = 0; j < n_comp; ++j)
639 if (indices_are_interleaved_and_contiguous)
644 for (
unsigned int j = 0; j < n_comp; ++j)
648 else if (indices_are_contiguous)
652 for (
unsigned int j = 0; j < n_comp; ++j)
658 int indices_are_interleaved_and_mixed = 2;
663 for (
unsigned int j = 0; j < n_comp; ++j)
666 for (
unsigned int k = 0; k < ndofs; ++k)
667 for (
unsigned int j = 0; j < n_comp; ++j)
674 indices_are_interleaved_and_mixed = 0;
677 if (indices_are_interleaved_and_mixed == 2)
679 for (
unsigned int j = 0; j < n_comp; ++j)
683 for (
unsigned int j = 0; j < n_comp; ++j)
687 for (
unsigned int j = 0; j < n_comp; ++j)
690 indices_are_interleaved_and_mixed = 1;
693 if (indices_are_interleaved_and_mixed == 1 ||
705 this->dof_indices.data() +
718 for (
unsigned int k = 0; k < ndofs; ++k)
719 for (
unsigned int l = 0; l < n_comp; ++l)
720 for (
unsigned int j = l + 1; j < n_comp; ++j)
731 index_kinds[
static_cast<unsigned int>(
741 auto fix_single_interleaved_indices =
743 if (index_kinds[
static_cast<unsigned int>(
746 index_kinds[
static_cast<unsigned int>(variant)] > 0)
747 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
759 index_kinds[
static_cast<unsigned int>(
762 index_kinds[
static_cast<unsigned int>(variant)]++;
771 unsigned int n_interleaved =
772 index_kinds[
static_cast<unsigned int>(
774 index_kinds[
static_cast<unsigned int>(
776 index_kinds[
static_cast<unsigned int>(
781 if (n_interleaved > 0 && index_kinds[
static_cast<unsigned int>(
783 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
789 index_kinds[
static_cast<unsigned int>(
791 index_kinds[
static_cast<unsigned int>(
797 if (n_interleaved > 0 &&
799 index_kinds[
static_cast<unsigned int>(
802 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
806 index_kinds[
static_cast<unsigned int>(
815 index_kinds[
static_cast<unsigned int>(
820 for (
unsigned int i = 0; i < irregular_cells.size(); ++i)
831 const unsigned int ndofs =
836 unsigned int *interleaved_dof_indices =
840 this->dof_indices_interleaved.size());
850 for (
unsigned int k = 0; k < ndofs; ++k)
862 const unsigned int n_owned_cells,
863 const unsigned int n_lanes,
866 const bool fill_cell_centric,
868 const bool use_vector_data_exchanger_full)
874 std::vector<types::global_dof_index> ghost_indices;
877 for (
unsigned int cell = 0; cell < n_owned_cells; ++cell)
885 const unsigned int fe_index =
894 ghost_indices.push_back(
897 std::sort(ghost_indices.begin(), ghost_indices.end());
898 ghost_indices.erase(std::unique(ghost_indices.begin(),
899 ghost_indices.end()),
900 ghost_indices.end());
902 compressed_set.
add_indices(ghost_indices.begin(), ghost_indices.end());
904 const bool all_ghosts_equal =
905 Utilities::MPI::min<int>(
static_cast<int>(
910 std::shared_ptr<const Utilities::MPI::Partitioner> temp_0;
912 if (all_ghosts_equal)
916 temp_0 = std::make_shared<Utilities::MPI::Partitioner>(
922 if (use_vector_data_exchanger_full ==
false)
928 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
929 temp_0, communicator_sm);
933 std::vector<FaceToCellTopology<1>> all_faces(inner_faces);
934 all_faces.insert(all_faces.end(),
935 ghosted_faces.begin(),
936 ghosted_faces.end());
939 2 * shape_info(0, 0).n_dimensions);
941 for (
unsigned int f = 0; f < all_faces.size(); ++f)
943 cell_and_face_to_faces(all_faces[f].cells_interior[0],
944 all_faces[f].interior_face_no) = f;
945 Assert(all_faces[f].cells_exterior[0] !=
948 cell_and_face_to_faces(all_faces[f].cells_exterior[0],
949 all_faces[f].exterior_face_no) = f;
953 const auto loop_over_faces =
954 [&](
const std::function<
955 void(
const unsigned int,
const unsigned int,
const bool)> &fu) {
956 for (
const auto &face : inner_faces)
959 fu(face.cells_exterior[0], face.exterior_face_no,
false );
963 const auto loop_over_all_faces =
964 [&](
const std::function<
965 void(
const unsigned int,
const unsigned int,
const bool)> &fu) {
966 for (
unsigned int c = 0; c < cell_and_face_to_faces.size(0); ++c)
967 for (
unsigned int d = 0; d < cell_and_face_to_faces.size(1); ++d)
969 const unsigned int f = cell_and_face_to_faces(c, d);
973 const unsigned int cell_m = all_faces[f].cells_interior[0];
974 const unsigned int cell_p = all_faces[f].cells_exterior[0];
976 const bool ext = c == cell_m;
981 const unsigned int p = ext ? cell_p : cell_m;
982 const unsigned int face_no = ext ?
983 all_faces[f].exterior_face_no :
984 all_faces[f].interior_face_no;
986 fu(p, face_no,
true);
990 const auto process_values =
992 std::shared_ptr<const Utilities::MPI::Partitioner>
993 &vector_partitioner_values,
994 const std::function<void(
995 const std::function<
void(
996 const unsigned int,
const unsigned int,
const bool)> &)> &loop) {
997 bool all_nodal_and_tensorial =
true;
1002 if (!si.nodal_at_cell_boundaries ||
1005 all_nodal_and_tensorial =
false;
1007 if (all_nodal_and_tensorial ==
false)
1011 bool has_noncontiguous_cell =
false;
1013 loop([&](
const unsigned int cell_no,
1014 const unsigned int face_no,
1016 const unsigned int index =
1021 const unsigned int stride =
1022 dof_indices_interleave_strides[dof_access_cell][cell_no];
1024 for (unsigned int e = 0; e < n_base_elements; ++e)
1025 for (unsigned int c = 0; c < n_components[e]; ++c)
1027 const ShapeInfo<double> &shape =
1028 shape_info(global_base_element_offset + e, 0);
1029 for (unsigned int j = 0;
1030 j < shape.dofs_per_component_on_face;
1032 ghost_indices.push_back(part.local_to_global(
1034 shape.face_to_cell_index_nodal(face_no, j) *
1036 i += shape.dofs_per_component_on_cell * stride;
1041 has_noncontiguous_cell =
true;
1043 has_noncontiguous_cell =
1044 Utilities::MPI::min<int>(
static_cast<int>(
1045 has_noncontiguous_cell),
1048 std::sort(ghost_indices.begin(), ghost_indices.end());
1049 ghost_indices.erase(std::unique(ghost_indices.begin(),
1050 ghost_indices.end()),
1051 ghost_indices.end());
1054 ghost_indices.end());
1056 const bool all_ghosts_equal =
1057 Utilities::MPI::min<int>(
static_cast<int>(
1061 if (all_ghosts_equal || has_noncontiguous_cell)
1065 vector_partitioner_values =
1066 std::make_shared<Utilities::MPI::Partitioner>(
1069 vector_partitioner_values.get())
1076 const auto process_gradients =
1078 const std::shared_ptr<const Utilities::MPI::Partitioner>
1079 &vector_partitoner_values,
1080 std::shared_ptr<const Utilities::MPI::Partitioner>
1081 &vector_partitioner_gradients,
1082 const std::function<void(
1083 const std::function<
void(
1084 const unsigned int,
const unsigned int,
const bool)> &)> &loop) {
1085 bool all_hermite =
true;
1086 for (
unsigned int c = 0; c < n_base_elements; ++c)
1087 if (shape_info(global_base_element_offset + c, 0).element_type !=
1089 all_hermite =
false;
1090 if (all_hermite ==
false ||
1091 vector_partitoner_values.get() == vector_partitioner.get())
1092 vector_partitioner_gradients = vector_partitioner;
1095 loop([&](
const unsigned int cell_no,
1096 const unsigned int face_no,
1098 const unsigned int index =
1099 dof_indices_contiguous[dof_access_cell][cell_no];
1101 index >= part.local_size()))
1103 const unsigned int stride =
1104 dof_indices_interleave_strides[dof_access_cell][cell_no];
1106 for (unsigned int e = 0; e < n_base_elements; ++e)
1107 for (unsigned int c = 0; c < n_components[e]; ++c)
1109 const ShapeInfo<double> &shape =
1110 shape_info(global_base_element_offset + e, 0);
1111 for (unsigned int j = 0;
1112 j < 2 * shape.dofs_per_component_on_face;
1114 ghost_indices.push_back(part.local_to_global(
1116 shape.face_to_cell_index_hermite(face_no, j) *
1118 i += shape.dofs_per_component_on_cell * stride;
1123 std::sort(ghost_indices.begin(), ghost_indices.end());
1124 ghost_indices.erase(std::unique(ghost_indices.begin(),
1125 ghost_indices.end()),
1126 ghost_indices.end());
1127 IndexSet compressed_set(part.size());
1128 compressed_set.add_indices(ghost_indices.begin(),
1129 ghost_indices.end());
1130 compressed_set.subtract_set(part.locally_owned_range());
1131 const bool all_ghosts_equal =
1132 Utilities::MPI::min<int>(
static_cast<int>(
1133 compressed_set.n_elements() ==
1134 part.ghost_indices().n_elements()),
1135 part.get_mpi_communicator()) != 0;
1136 if (all_ghosts_equal)
1137 vector_partitioner_gradients = vector_partitioner;
1140 vector_partitioner_gradients =
1141 std::make_shared<Utilities::MPI::Partitioner>(
1142 part.locally_owned_range(), part.get_mpi_communicator());
1144 vector_partitioner_gradients.get())
1145 ->set_ghost_indices(compressed_set, part.ghost_indices());
1150 std::shared_ptr<const Utilities::MPI::Partitioner> temp_1, temp_2, temp_3,
1154 process_values(temp_1, loop_over_faces);
1157 process_gradients(temp_1, temp_2, loop_over_faces);
1159 if (fill_cell_centric)
1161 ghost_indices.clear();
1163 process_values(temp_3, loop_over_all_faces);
1165 process_gradients(temp_3, temp_4, loop_over_all_faces);
1169 temp_3 = std::make_shared<Utilities::MPI::Partitioner>(
1170 part.locally_owned_range(), part.get_mpi_communicator());
1171 temp_4 = std::make_shared<Utilities::MPI::Partitioner>(
1172 part.locally_owned_range(), part.get_mpi_communicator());
1175 if (use_vector_data_exchanger_full ==
false)
1177 vector_exchanger_face_variants[1] = std::make_shared<
1178 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1180 vector_exchanger_face_variants[2] = std::make_shared<
1181 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1183 vector_exchanger_face_variants[3] = std::make_shared<
1184 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1186 vector_exchanger_face_variants[4] = std::make_shared<
1187 MatrixFreeFunctions::VectorDataExchange::PartitionerWrapper>(
1192 vector_exchanger_face_variants[1] =
1193 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1194 temp_1, communicator_sm);
1195 vector_exchanger_face_variants[2] =
1196 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1197 temp_2, communicator_sm);
1198 vector_exchanger_face_variants[3] =
1199 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1200 temp_3, communicator_sm);
1201 vector_exchanger_face_variants[4] =
1202 std::make_shared<MatrixFreeFunctions::VectorDataExchange::Full>(
1203 temp_4, communicator_sm);
1210 DoFInfo::compute_shared_memory_contiguous_indices(
1211 std::array<std::vector<std::pair<unsigned int, unsigned int>>, 3>
1212 &cell_indices_contiguous_sm)
1216 for (
unsigned int i = 0; i < 3; ++i)
1218 dof_indices_contiguous_sm[i].resize(
1219 cell_indices_contiguous_sm[i].size());
1221 for (
unsigned int j = 0; j < cell_indices_contiguous_sm[i].size();
1223 if (cell_indices_contiguous_sm[i][j].
first !=
1225 dof_indices_contiguous_sm[i][j] = {
1226 cell_indices_contiguous_sm[i][j].first,
1227 cell_indices_contiguous_sm[i][j].second * dofs_per_cell[0]};
1247 const unsigned int end,
1249 std::vector<std::mutex> & mutexes,
1250 std::vector<unsigned int> &row_lengths)
1252 std::vector<unsigned int> scratch;
1254 for (
unsigned int block = begin; block < end; ++block)
1260 dof_info.
row_starts[block * n_components].first,
1262 dof_info.
row_starts[(block + 1) * n_components].first);
1263 std::sort(scratch.begin(), scratch.end());
1264 std::vector<unsigned int>::const_iterator end_unique =
1265 std::unique(scratch.begin(), scratch.end());
1266 std::vector<unsigned int>::const_iterator it = scratch.begin();
1267 while (it != end_unique)
1271 const unsigned int next_bucket =
1273 std::lock_guard<std::mutex> lock(
1275 for (; it != end_unique && *it < next_bucket; ++it)
1286 const unsigned int end,
1288 const std::vector<unsigned int> &row_lengths,
1289 std::vector<std::mutex> & mutexes,
1292 std::vector<unsigned int> scratch;
1294 for (
unsigned int block = begin; block < end; ++block)
1300 dof_info.
row_starts[block * n_components].first,
1302 dof_info.
row_starts[(block + 1) * n_components].first);
1303 std::sort(scratch.begin(), scratch.end());
1304 std::vector<unsigned int>::const_iterator end_unique =
1305 std::unique(scratch.begin(), scratch.end());
1306 std::vector<unsigned int>::const_iterator it = scratch.begin();
1307 while (it != end_unique)
1309 const unsigned int next_bucket =
1311 std::lock_guard<std::mutex> lock(
1313 for (; it != end_unique && *it < next_bucket; ++it)
1314 if (row_lengths[*it] > 0)
1315 connectivity_dof.
add(*it, block);
1324 const unsigned int end,
1326 const std::vector<unsigned int> &renumbering,
1327 const ::SparsityPattern & connectivity_dof,
1330 ordered_vector row_entries;
1332 for (
unsigned int block = begin; block < end; ++block)
1334 row_entries.clear();
1338 dof_info.
row_starts[block * n_components].first,
1341 for (; it != end_cell; ++it)
1344 std::vector<types::global_dof_index>::iterator insert_pos =
1345 row_entries.begin();
1346 for (; sp != connectivity_dof.end(*it); ++sp)
1347 if (sp->column() != block)
1348 row_entries.insert(renumbering[sp->column()], insert_pos);
1351 row_entries.begin(),
1359 DoFInfo::make_connectivity_graph(
1361 const std::vector<unsigned int> &renumbering,
1364 unsigned int n_rows = (vector_partitioner->local_range().second -
1365 vector_partitioner->local_range().first) +
1366 vector_partitioner->ghost_indices().n_elements();
1373 std::vector<unsigned int> row_lengths(n_rows);
1374 std::vector<std::mutex> mutexes(n_rows / internal::bucket_size_threading +
1379 [
this, &mutexes, &row_lengths](
const unsigned int begin,
1380 const unsigned int end) {
1381 internal::compute_row_lengths(
1382 begin, end, *this, mutexes, row_lengths);
1388 for (
unsigned int row = 0; row < n_rows; ++row)
1389 if (row_lengths[row] <= 1)
1390 row_lengths[row] = 0;
1401 [
this, &row_lengths, &mutexes, &connectivity_dof](
1402 const unsigned int begin,
const unsigned int end) {
1403 internal::fill_connectivity_dofs(
1404 begin, end, *this, row_lengths, mutexes, connectivity_dof);
1411 std::vector<unsigned int> reverse_numbering(task_info.
n_active_cells);
1421 [
this, &reverse_numbering, &connectivity_dof, &connectivity](
1422 const unsigned int begin,
const unsigned int end) {
1423 internal::fill_connectivity(begin,
1436 DoFInfo::compute_dof_renumbering(
1437 std::vector<types::global_dof_index> &renumbering)
1439 const unsigned int locally_owned_size =
1440 vector_partitioner->locally_owned_size();
1441 renumbering.resize(0);
1445 const unsigned int n_components = start_components.back();
1446 const unsigned int n_cell_batches =
1447 n_vectorization_lanes_filled[dof_access_cell].size();
1449 (row_starts.size() - 1) / vectorization_length / n_components,
1451 for (
unsigned int cell_no = 0; cell_no < n_cell_batches; ++cell_no)
1454 if (row_starts[cell_no * n_components * vectorization_length]
1456 row_starts[(cell_no + 1) * n_components * vectorization_length]
1459 const unsigned int ndofs =
1460 dofs_per_cell.size() == 1 ?
1462 (dofs_per_cell[cell_active_fe_index.size() > 0 ?
1463 cell_active_fe_index[cell_no] :
1465 const unsigned int *dof_ind =
1466 dof_indices.data() +
1467 row_starts[cell_no * n_components * vectorization_length].first;
1468 for (
unsigned int i = 0; i < ndofs; ++i)
1469 for (
unsigned int j = 0;
1470 j < n_vectorization_lanes_filled[dof_access_cell][cell_no];
1472 if (dof_ind[j * ndofs + i] < locally_owned_size)
1473 if (renumbering[dof_ind[j * ndofs + i]] ==
1475 renumbering[dof_ind[j * ndofs + i]] = counter++;
1482 dof_index = counter++;
1486 dof_index = vector_partitioner->local_to_global(dof_index);
1494 DoFInfo::memory_consumption()
const
1496 std::size_t memory =
sizeof(*this);
1498 (row_starts.capacity() *
sizeof(std::pair<unsigned int, unsigned int>));
1513 namespace MatrixFreeFunctions
1515 template struct ConstraintValues<double>;
1517 template unsigned short
1519 const std::vector<std::pair<types::global_dof_index, float>> &);
1520 template unsigned short
1522 const std::vector<std::pair<types::global_dof_index, double>> &);
1526 DoFInfo::read_dof_indices<double>(
1527 const std::vector<types::global_dof_index> &,
1528 const std::vector<types::global_dof_index> &,
1530 const ::AffineConstraints<double> &,
1532 ConstraintValues<double> &,
1536 DoFInfo::read_dof_indices<float>(
1537 const std::vector<types::global_dof_index> &,
1538 const std::vector<types::global_dof_index> &,
1540 const ::AffineConstraints<float> &,
1542 ConstraintValues<double> &,
1546 DoFInfo::process_hanging_node_constraints<1>(
1547 const HangingNodes<1> &,
1548 const std::vector<std::vector<unsigned int>> &,
1551 std::vector<types::global_dof_index> &);
1553 DoFInfo::process_hanging_node_constraints<2>(
1554 const HangingNodes<2> &,
1555 const std::vector<std::vector<unsigned int>> &,
1558 std::vector<types::global_dof_index> &);
1560 DoFInfo::process_hanging_node_constraints<3>(
1561 const HangingNodes<3> &,
1562 const std::vector<std::vector<unsigned int>> &,
1565 std::vector<types::global_dof_index> &);
1568 DoFInfo::compute_face_index_compression<1>(
1569 const std::vector<FaceToCellTopology<1>> &);
1571 DoFInfo::compute_face_index_compression<2>(
1572 const std::vector<FaceToCellTopology<2>> &);
1574 DoFInfo::compute_face_index_compression<4>(
1575 const std::vector<FaceToCellTopology<4>> &);
1577 DoFInfo::compute_face_index_compression<8>(
1578 const std::vector<FaceToCellTopology<8>> &);
1580 DoFInfo::compute_face_index_compression<16>(
1581 const std::vector<FaceToCellTopology<16>> &);
1584 DoFInfo::compute_vector_zero_access_pattern<1>(
1586 const std::vector<FaceToCellTopology<1>> &);
1588 DoFInfo::compute_vector_zero_access_pattern<2>(
1590 const std::vector<FaceToCellTopology<2>> &);
1592 DoFInfo::compute_vector_zero_access_pattern<4>(
1594 const std::vector<FaceToCellTopology<4>> &);
1596 DoFInfo::compute_vector_zero_access_pattern<8>(
1598 const std::vector<FaceToCellTopology<8>> &);
1600 DoFInfo::compute_vector_zero_access_pattern<16>(
1602 const std::vector<FaceToCellTopology<16>> &);
1605 DoFInfo::print_memory_consumption<std::ostream>(std::ostream &,
1608 DoFInfo::print_memory_consumption<ConditionalOStream>(
1613 DoFInfo::print<double>(
const std::vector<double> &,
1614 const std::vector<unsigned int> &,
1615 std::ostream &)
const;
1618 DoFInfo::print<float>(
const std::vector<float> &,
1619 const std::vector<unsigned int> &,
1620 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)
void add(const size_type i, const size_type j)
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 add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_unique_and_sorted=false)
@ tensor_symmetric_hermite
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
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
constexpr compressed_constraint_kind unconstrained_compressed_constraint_kind
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
void apply_to_subranges(const RangeType &begin, const typename identity< RangeType >::type &end, const Function &f, const unsigned int grainsize)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
unsigned short insert_entries(const std::vector< std::pair< types::global_dof_index, number2 > > &entries)
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
std::vector< std::vector< bool > > hanging_node_constraint_masks_comp
unsigned int global_base_element_offset
unsigned int max_fe_index
void get_dof_indices_on_cell_batch(std::vector< unsigned int > &local_indices, const unsigned int cell_batch, const bool with_constraints=true) const
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::vector< compressed_constraint_kind > hanging_node_constraint_masks
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
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