45#define BOOST_BIND_GLOBAL_PLACEHOLDERS
46#include <boost/config.hpp>
47#include <boost/graph/adjacency_list.hpp>
48#include <boost/graph/bandwidth.hpp>
49#include <boost/graph/cuthill_mckee_ordering.hpp>
50#include <boost/graph/king_ordering.hpp>
51#include <boost/graph/minimum_degree_ordering.hpp>
52#include <boost/graph/properties.hpp>
53#include <boost/random.hpp>
54#include <boost/random/uniform_int_distribution.hpp>
56#undef BOOST_BIND_GLOBAL_PLACEHOLDERS
73 using namespace ::
boost;
75 using Graph = adjacency_list<vecS,
78 property<vertex_color_t,
80 property<vertex_degree_t, int>>>;
81 using Vertex = graph_traits<Graph>::vertex_descriptor;
82 using size_type = graph_traits<Graph>::vertices_size_type;
84 using Pair = std::pair<size_type, size_type>;
90 template <
int dim,
int spacedim>
93 const bool use_constraints,
96 boosttypes::vertex_degree_t>::type
117 boosttypes::graph_traits<boosttypes::Graph>::vertex_iterator ui, ui_end;
119 graph_degree = get(::boost::vertex_degree, graph);
120 for (::boost::tie(ui, ui_end) = vertices(graph); ui != ui_end; ++ui)
121 graph_degree[*ui] = degree(*ui, graph);
126 template <
int dim,
int spacedim>
129 const bool reversed_numbering,
130 const bool use_constraints)
132 std::vector<types::global_dof_index> renumbering(
146 template <
int dim,
int spacedim>
150 const bool reversed_numbering,
151 const bool use_constraints)
155 boosttypes::vertex_degree_t>::type graph_degree;
160 boosttypes::vertex_index_t>::type index_map =
161 get(::boost::vertex_index, graph);
164 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
166 if (reversed_numbering ==
false)
167 ::boost::cuthill_mckee_ordering(graph,
169 get(::boost::vertex_color, graph),
170 make_degree_map(graph));
172 ::boost::cuthill_mckee_ordering(graph,
174 get(::boost::vertex_color, graph),
175 make_degree_map(graph));
178 new_dof_indices[index_map[inv_perm[c]]] = c;
180 Assert(std::find(new_dof_indices.begin(),
181 new_dof_indices.end(),
188 template <
int dim,
int spacedim>
191 const bool reversed_numbering,
192 const bool use_constraints)
194 std::vector<types::global_dof_index> renumbering(
208 template <
int dim,
int spacedim>
212 const bool reversed_numbering,
213 const bool use_constraints)
217 boosttypes::vertex_degree_t>::type graph_degree;
222 boosttypes::vertex_index_t>::type index_map =
223 get(::boost::vertex_index, graph);
226 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
228 if (reversed_numbering ==
false)
231 ::boost::king_ordering(graph, inv_perm.begin());
234 new_dof_indices[index_map[inv_perm[c]]] = c;
236 Assert(std::find(new_dof_indices.begin(),
237 new_dof_indices.end(),
244 template <
int dim,
int spacedim>
247 const bool reversed_numbering,
248 const bool use_constraints)
250 std::vector<types::global_dof_index> renumbering(
264 template <
int dim,
int spacedim>
267 std::vector<types::global_dof_index> &new_dof_indices,
269 const bool reversed_numbering,
270 const bool use_constraints)
272 (void)use_constraints;
281 using namespace ::
boost;
286 using Graph = adjacency_list<vecS, vecS, directedS>;
292 std::vector<::types::global_dof_index> dofs_on_this_cell;
296 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
298 dofs_on_this_cell.resize(dofs_per_cell);
300 cell->get_active_or_mg_dof_indices(dofs_on_this_cell);
301 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
302 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
303 if (dofs_on_this_cell[i] > dofs_on_this_cell[j])
305 add_edge(dofs_on_this_cell[i], dofs_on_this_cell[j], G);
306 add_edge(dofs_on_this_cell[j], dofs_on_this_cell[i], G);
314 using Vector = std::vector<types::signed_global_dof_index>;
317 Vector inverse_perm(n_dofs, 0);
322 Vector supernode_sizes(n_dofs, 1);
325 ::boost::property_map<Graph, vertex_index_t>::type
id =
326 get(vertex_index, G);
332 minimum_degree_ordering(
334 make_iterator_property_map(degree.
begin(),
id, degree[0]),
337 make_iterator_property_map(supernode_sizes.
begin(),
351 Assert(inverse_perm[perm[i]] ==
356 if (reversed_numbering ==
true)
357 std::copy(perm.
begin(), perm.
end(), new_dof_indices.begin());
359 std::copy(inverse_perm.
begin(),
361 new_dof_indices.begin());
368 template <
int dim,
int spacedim>
371 const bool reversed_numbering,
372 const bool use_constraints,
373 const std::vector<types::global_dof_index> &starting_indices)
375 std::vector<types::global_dof_index> renumbering(
392 template <
int dim,
int spacedim>
395 std::vector<types::global_dof_index> &new_indices,
397 const bool reversed_numbering,
398 const bool use_constraints,
399 const std::vector<types::global_dof_index> &starting_indices,
400 const unsigned int level)
402 const bool reorder_level_dofs =
417 if (reorder_level_dofs ==
true)
421 const IndexSet locally_relevant_dofs =
422 (reorder_level_dofs ==
false ?
425 const IndexSet &locally_owned_dofs =
435 constraints.
reinit(locally_owned_dofs, locally_relevant_dofs);
446 locally_owned_dofs.
size());
447 if (reorder_level_dofs ==
false)
459 if (reversed_numbering)
472 const IndexSet locally_active_dofs =
473 (reorder_level_dofs ==
false ?
477 bool needs_locally_active =
false;
478 for (
const auto starting_index : starting_indices)
480 if ((needs_locally_active ==
482 (locally_owned_dofs.
is_element(starting_index) ==
false))
485 locally_active_dofs.
is_element(starting_index),
487 "You specified global degree of freedom " +
488 std::to_string(starting_index) +
489 " as a starting index, but this index is not among the "
490 "locally active ones on this processor, as required "
491 "for this function."));
492 needs_locally_active =
true;
497 (needs_locally_active ? locally_active_dofs : locally_owned_dofs);
508 index_set_to_use.
size(),
510 if (reorder_level_dofs ==
false)
521 std::vector<types::global_dof_index> row_entries;
522 for (
unsigned int i = 0; i < index_set_to_use.
n_elements(); ++i)
526 const unsigned int row_length = dsp.
row_length(row);
528 for (
unsigned int j = 0; j < row_length; ++j)
531 if (col != row && index_set_to_use.
is_element(col))
541 std::vector<types::global_dof_index> local_starting_indices(
542 starting_indices.size());
543 for (
unsigned int i = 0; i < starting_indices.size(); ++i)
544 local_starting_indices[i] =
549 std::vector<types::global_dof_index> my_new_indices(
553 local_starting_indices);
554 if (reversed_numbering)
563 if (needs_locally_active ==
true)
566 IndexSet active_but_not_owned_dofs = locally_active_dofs;
567 active_but_not_owned_dofs.
subtract_set(locally_owned_dofs);
569 std::set<types::global_dof_index> erase_these_indices;
570 for (
const auto p : active_but_not_owned_dofs)
575 erase_these_indices.insert(my_new_indices[index]);
578 Assert(erase_these_indices.size() ==
581 Assert(
static_cast<unsigned int>(
582 std::count(my_new_indices.begin(),
583 my_new_indices.end(),
589 std::vector<types::global_dof_index> translate_indices(
590 my_new_indices.size());
592 std::set<types::global_dof_index>::const_iterator
593 next_erased_index = erase_these_indices.begin();
595 for (
unsigned int i = 0; i < translate_indices.size(); ++i)
596 if ((next_erased_index != erase_these_indices.end()) &&
597 (*next_erased_index == i))
604 translate_indices[i] = next_new_index;
614 new_indices.reserve(locally_owned_dofs.
n_elements());
615 for (
const auto &p : my_new_indices)
620 new_indices.push_back(translate_indices[p]);
626 new_indices = std::move(my_new_indices);
639 template <
int dim,
int spacedim>
642 const unsigned int level,
643 const bool reversed_numbering,
644 const std::vector<types::global_dof_index> &starting_indices)
649 std::vector<types::global_dof_index> new_indices(
668 template <
int dim,
int spacedim>
671 const std::vector<unsigned int> &component_order_arg)
673 std::vector<types::global_dof_index> renumbering(
677 compute_component_wise<dim, spacedim>(renumbering,
699 (result <= dof_handler.
n_dofs())),
707 template <
int dim,
int spacedim>
710 const unsigned int level,
711 const std::vector<unsigned int> &component_order_arg)
716 std::vector<types::global_dof_index> renumbering(
726 compute_component_wise<dim, spacedim>(
727 renumbering, start,
end, component_order_arg,
true);
760 template <
int dim,
int spacedim>
761 std::vector<unsigned int>
762 generate_component_order(
763 const std::vector<FEValuesExtractors::AnyExtractor> &order,
764 const unsigned int fe_n_components)
768 std::vector<unsigned int> component_order(fe_n_components,
773 unsigned int block_index = 0;
774 for (
const auto &extractor : order)
779 if (std::holds_alternative<FEValuesExtractors::Scalar>(extractor))
781 start_component_index =
782 std::get<FEValuesExtractors::Scalar>(extractor).component;
785 else if (std::holds_alternative<FEValuesExtractors::Vector>(
788 start_component_index =
789 std::get<FEValuesExtractors::Vector>(extractor)
790 .first_vector_component;
792 n_independent_components;
797 start_component_index =
798 std::get<FEValuesExtractors::Tensor<2>>(extractor)
799 .first_tensor_component;
801 value_type::n_independent_components;
803 else if (std::holds_alternative<
806 start_component_index =
807 std::get<FEValuesExtractors::SymmetricTensor<2>>(extractor)
808 .first_tensor_component;
810 value_type::n_independent_components;
817 "An unsupported ExtractorVariant was passed in the component_wise extractor_order argument."));
822 for (
unsigned int i = start_component_index;
823 i < start_component_index + n_components;
832 "A component which has already been assigned a block "
833 "index is trying to be overwritten. This indicates that the "
834 "component_wise function is being called with an invalid set "
835 "of extractors in the extractor_order argument "
836 "that overlap in component indices."));
838 component_order[i] = block_index;
843 return component_order;
847 template <
int dim,
int spacedim>
850 const std::vector<FEValuesExtractors::AnyExtractor> &order)
855 std::vector<unsigned int> component_order =
856 generate_component_order<dim, spacedim>(
867 std::none_of(component_order.begin(),
868 component_order.end(),
869 [](
unsigned int value) {
870 return value == numbers::invalid_unsigned_int;
873 "All entries in component_order must contain valid indices, no "
874 "numbers::invalid_unsigned_int must be present after processing all given "
875 "extractors. This error typically occurs when the component_wise function "
876 "is passed fewer extractors than needed or when the set of extractors "
877 "provided in the extractor_order argument doesn't cover all required components."));
884 template <
int dim,
int spacedim>
887 const unsigned int level,
888 const std::vector<FEValuesExtractors::AnyExtractor> &order)
893 std::vector<unsigned int> component_order =
894 generate_component_order<dim, spacedim>(
905 std::none_of(component_order.begin(),
906 component_order.end(),
907 [](
unsigned int value) {
908 return value == numbers::invalid_unsigned_int;
911 "All entries in component_order must contain valid indices, no "
912 "numbers::invalid_unsigned_int must be present after processing all given "
913 "extractors. This error typically occurs when the component_wise function "
914 "is passed fewer extractors than needed or when the set of extractors "
915 "provided in the extractor_order argument doesn't cover all required components. "));
923 template <
int dim,
int spacedim,
typename CellIterator>
926 const CellIterator &start,
928 const std::vector<unsigned int> &component_order_arg,
929 const bool is_level_operation)
932 start->get_dof_handler().get_fe_collection();
938 new_indices.resize(0);
945 const IndexSet &locally_owned_dofs =
947 start->get_dof_handler().locally_owned_mg_dofs(start->level()) :
948 start->get_dof_handler().locally_owned_dofs();
952 std::vector<unsigned int> component_order(component_order_arg);
957 if (component_order.empty())
958 for (
unsigned int i = 0; i < fe_collection.
n_components(); ++i)
959 component_order.push_back(i);
965 for (
const unsigned int component : component_order)
973 std::vector<types::global_dof_index> local_dof_indices;
985 std::vector<std::vector<unsigned int>> component_list(fe_collection.
size());
986 for (
unsigned int f = 0; f < fe_collection.
size(); ++f)
990 component_list[f].resize(dofs_per_cell);
991 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
993 component_list[f][i] =
997 const unsigned int comp =
1003 component_list[f][i] = component_order[comp];
1018 std::vector<std::vector<types::global_dof_index>> component_to_dof_map(
1020 for (CellIterator cell = start; cell !=
end; ++cell)
1022 if (is_level_operation)
1025 if (!cell->is_locally_owned_on_level())
1032 if (!cell->is_locally_owned())
1036 if (is_level_operation)
1038 cell->level() == start->level(),
1040 "Multigrid renumbering in compute_component_wise() needs to be applied to a single level!"));
1046 const unsigned int dofs_per_cell =
1047 fe_collection[fe_index].n_dofs_per_cell();
1048 local_dof_indices.resize(dofs_per_cell);
1049 cell->get_active_or_mg_dof_indices(local_dof_indices);
1051 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1052 if (locally_owned_dofs.
is_element(local_dof_indices[i]))
1053 component_to_dof_map[component_list[fe_index][i]].
push_back(
1054 local_dof_indices[i]);
1080 for (
unsigned int component = 0; component < fe_collection.
n_components();
1083 std::sort(component_to_dof_map[component].
begin(),
1084 component_to_dof_map[component].
end());
1085 component_to_dof_map[component].erase(
1086 std::unique(component_to_dof_map[component].
begin(),
1087 component_to_dof_map[component].
end()),
1088 component_to_dof_map[component].
end());
1093 const unsigned int n_buckets = fe_collection.
n_components();
1094 std::vector<types::global_dof_index> shifts(n_buckets);
1098 &start->get_dof_handler().get_triangulation())))
1100#ifdef DEAL_II_WITH_MPI
1101 std::vector<types::global_dof_index> local_dof_count(n_buckets);
1103 for (
unsigned int c = 0; c < n_buckets; ++c)
1104 local_dof_count[c] = component_to_dof_map[c].
size();
1106 std::vector<types::global_dof_index> prefix_dof_count(n_buckets);
1107 const int ierr = MPI_Exscan(
1108 local_dof_count.data(),
1109 prefix_dof_count.data(),
1111 Utilities::MPI::mpi_type_id_for_type<types::global_dof_index>,
1113 tria->get_mpi_communicator());
1116 std::vector<types::global_dof_index> global_dof_count(n_buckets);
1118 tria->get_mpi_communicator(),
1123 for (
unsigned int c = 0; c < n_buckets; ++c)
1125 shifts[c] = prefix_dof_count[c] + cumulated;
1126 cumulated += global_dof_count[c];
1136 for (
unsigned int c = 1; c < fe_collection.
n_components(); ++c)
1137 shifts[c] = shifts[c - 1] + component_to_dof_map[c - 1].
size();
1146 for (
unsigned int component = 0; component < fe_collection.
n_components();
1149 next_free_index = shifts[component];
1152 component_to_dof_map[component])
1164 return next_free_index;
1169 template <
int dim,
int spacedim>
1173 std::vector<types::global_dof_index> renumbering(
1194 (result <= dof_handler.
n_dofs())),
1202 template <
int dim,
int spacedim>
1209 std::vector<types::global_dof_index> renumbering(
1242 template <
int dim,
int spacedim,
class IteratorType,
class EndIteratorType>
1245 const IteratorType &start,
1246 const EndIteratorType &
end,
1247 const bool is_level_operation)
1250 start->get_dof_handler().get_fe_collection();
1256 new_indices.resize(0);
1263 const IndexSet &locally_owned_dofs =
1264 is_level_operation ?
1265 start->get_dof_handler().locally_owned_mg_dofs(start->level()) :
1266 start->get_dof_handler().locally_owned_dofs();
1270 std::vector<types::global_dof_index> local_dof_indices;
1275 std::vector<std::vector<types::global_dof_index>> block_list(
1276 fe_collection.
size());
1277 for (
unsigned int f = 0; f < fe_collection.
size(); ++f)
1296 std::vector<std::vector<types::global_dof_index>> block_to_dof_map(
1298 for (IteratorType cell = start; cell !=
end; ++cell)
1300 if (is_level_operation)
1303 if (!cell->is_locally_owned_on_level())
1310 if (!cell->is_locally_owned())
1314 if (is_level_operation)
1316 cell->level() == start->level(),
1318 "Multigrid renumbering in compute_block_wise() needs to be applied to a single level!"));
1324 const unsigned int dofs_per_cell =
1325 fe_collection[fe_index].n_dofs_per_cell();
1326 local_dof_indices.resize(dofs_per_cell);
1327 cell->get_active_or_mg_dof_indices(local_dof_indices);
1329 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1330 if (locally_owned_dofs.
is_element(local_dof_indices[i]))
1331 block_to_dof_map[block_list[fe_index][i]].
push_back(
1332 local_dof_indices[i]);
1347 for (
unsigned int block = 0; block < fe_collection.
n_blocks(); ++block)
1349 std::sort(block_to_dof_map[block].
begin(),
1350 block_to_dof_map[block].
end());
1351 block_to_dof_map[block].erase(
1352 std::unique(block_to_dof_map[block].
begin(),
1353 block_to_dof_map[block].
end()),
1354 block_to_dof_map[block].
end());
1359 const unsigned int n_buckets = fe_collection.
n_blocks();
1360 std::vector<types::global_dof_index> shifts(n_buckets);
1364 &start->get_dof_handler().get_triangulation())))
1366#ifdef DEAL_II_WITH_MPI
1367 std::vector<types::global_dof_index> local_dof_count(n_buckets);
1369 for (
unsigned int c = 0; c < n_buckets; ++c)
1370 local_dof_count[c] = block_to_dof_map[c].
size();
1372 std::vector<types::global_dof_index> prefix_dof_count(n_buckets);
1373 const int ierr = MPI_Exscan(
1374 local_dof_count.data(),
1375 prefix_dof_count.data(),
1377 Utilities::MPI::mpi_type_id_for_type<types::global_dof_index>,
1379 tria->get_mpi_communicator());
1382 std::vector<types::global_dof_index> global_dof_count(n_buckets);
1384 tria->get_mpi_communicator(),
1389 for (
unsigned int c = 0; c < n_buckets; ++c)
1391 shifts[c] = prefix_dof_count[c] + cumulated;
1392 cumulated += global_dof_count[c];
1402 for (
unsigned int c = 1; c < fe_collection.
n_blocks(); ++c)
1403 shifts[c] = shifts[c - 1] + block_to_dof_map[c - 1].
size();
1412 for (
unsigned int block = 0; block < fe_collection.
n_blocks(); ++block)
1414 const typename std::vector<types::global_dof_index>::const_iterator
1415 begin_of_component = block_to_dof_map[block].begin(),
1416 end_of_component = block_to_dof_map[block].end();
1418 next_free_index = shifts[block];
1420 for (
typename std::vector<types::global_dof_index>::const_iterator
1421 dof_index = begin_of_component;
1422 dof_index != end_of_component;
1433 return next_free_index;
1445 template <
int dim,
typename CellIteratorType>
1447 compute_hierarchical_recursive(
1450 const CellIteratorType &cell,
1451 const IndexSet &locally_owned_dof_indices,
1452 std::vector<types::global_dof_index> &new_indices)
1455 next_free_dof_offset;
1457 if (cell->has_children())
1460 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1462 current_next_free_dof_offset =
1463 compute_hierarchical_recursive<dim>(current_next_free_dof_offset,
1466 locally_owned_dof_indices,
1486 if (cell->is_locally_owned())
1489 const unsigned int dofs_per_cell =
1490 cell->get_fe().n_dofs_per_cell();
1491 std::vector<types::global_dof_index> local_dof_indices(
1493 cell->get_dof_indices(local_dof_indices);
1512 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1513 if (locally_owned_dof_indices.
is_element(local_dof_indices[i]))
1517 const unsigned int idx =
1519 local_dof_indices[i]);
1523 my_starting_index + current_next_free_dof_offset;
1524 ++current_next_free_dof_offset;
1530 return current_next_free_dof_offset;
1536 template <
int dim,
int spacedim>
1540 std::vector<types::global_dof_index> renumbering(
1563#ifdef DEAL_II_WITH_MPI
1566 const int ierr = MPI_Exscan(
1570 Utilities::MPI::mpi_type_id_for_type<types::global_dof_index>,
1572 tria->get_mpi_communicator());
1581#ifdef DEAL_II_WITH_P4EST
1586 for (
unsigned int c = 0; c < tria->n_cells(0); ++c)
1588 const unsigned int coarse_cell_index =
1589 tria->get_p4est_tree_to_coarse_cell_permutation()[c];
1592 this_cell(tria, 0, coarse_cell_index, &dof_handler);
1594 next_free_dof_offset =
1595 compute_hierarchical_recursive<dim>(next_free_dof_offset,
1610 dof_handler.
begin(0);
1611 cell != dof_handler.
end(0);
1613 next_free_dof_offset =
1614 compute_hierarchical_recursive<dim>(next_free_dof_offset,
1627 (next_free_dof_offset <= dof_handler.
n_dofs())),
1631 Assert(std::find(renumbering.begin(),
1641 template <
int dim,
int spacedim>
1644 const std::vector<bool> &selected_dofs)
1646 std::vector<types::global_dof_index> renumbering(
1655 template <
int dim,
int spacedim>
1658 const std::vector<bool> &selected_dofs,
1659 const unsigned int level)
1664 std::vector<types::global_dof_index> renumbering(
1676 template <
int dim,
int spacedim>
1679 std::vector<types::global_dof_index> &new_indices,
1681 const std::vector<bool> &selected_dofs)
1684 Assert(selected_dofs.size() == n_dofs,
1689 Assert(new_indices.size() == n_dofs,
1693 std::count(selected_dofs.begin(), selected_dofs.end(),
false);
1698 if (selected_dofs[i] ==
false)
1700 new_indices[i] = next_unselected;
1705 new_indices[i] = next_selected;
1714 template <
int dim,
int spacedim>
1717 std::vector<types::global_dof_index> &new_indices,
1719 const std::vector<bool> &selected_dofs,
1720 const unsigned int level)
1726 Assert(selected_dofs.size() == n_dofs,
1731 Assert(new_indices.size() == n_dofs,
1735 std::count(selected_dofs.begin(), selected_dofs.end(),
false);
1740 if (selected_dofs[i] ==
false)
1742 new_indices[i] = next_unselected;
1747 new_indices[i] = next_selected;
1756 template <
int dim,
int spacedim>
1763 std::vector<types::global_dof_index> renumbering(
1772 template <
int dim,
int spacedim>
1775 std::vector<types::global_dof_index> &new_indices,
1776 std::vector<types::global_dof_index> &reverse,
1778 const typename std::vector<
1803 std::vector<bool> already_sorted(n_owned_dofs,
false);
1804 std::vector<types::global_dof_index> cell_dofs;
1810 for (
const auto &cell : cells)
1814 const unsigned int n_cell_dofs = cell->get_fe().n_dofs_per_cell();
1815 cell_dofs.resize(n_cell_dofs);
1817 cell->get_active_or_mg_dof_indices(cell_dofs);
1821 std::sort(cell_dofs.begin(), cell_dofs.end());
1823 for (
const auto dof : cell_dofs)
1825 const auto local_dof = owned_dofs.index_within_set(dof);
1827 !already_sorted[local_dof])
1829 already_sorted[local_dof] =
true;
1830 reverse[index++] = local_dof;
1834 Assert(index == n_owned_dofs,
1836 "Traversing over the given set of cells did not cover all "
1837 "degrees of freedom in the DoFHandler. Does the set of cells "
1838 "not include all active cells?"));
1841 new_indices[reverse[i]] = owned_dofs.nth_index_in_set(i);
1846 template <
int dim,
int spacedim>
1849 const unsigned int level,
1850 const typename std::vector<
1856 std::vector<types::global_dof_index> renumbering(dof.
n_dofs(
level));
1857 std::vector<types::global_dof_index> reverse(dof.
n_dofs(
level));
1865 template <
int dim,
int spacedim>
1868 std::vector<types::global_dof_index> &new_order,
1869 std::vector<types::global_dof_index> &reverse,
1871 const unsigned int level,
1872 const typename std::vector<
1886 std::vector<bool> already_sorted(n_global_dofs,
false);
1887 std::vector<types::global_dof_index> cell_dofs(n_cell_dofs);
1891 for (
const auto &cell : cells)
1895 cell->get_active_or_mg_dof_indices(cell_dofs);
1896 std::sort(cell_dofs.begin(), cell_dofs.end());
1898 for (
unsigned int i = 0; i < n_cell_dofs; ++i)
1900 if (!already_sorted[cell_dofs[i]])
1902 already_sorted[cell_dofs[i]] =
true;
1903 reverse[global_index++] = cell_dofs[i];
1907 Assert(global_index == n_global_dofs,
1909 "Traversing over the given set of cells did not cover all "
1910 "degrees of freedom in the DoFHandler. Does the set of cells "
1911 "not include all cells of the specified level?"));
1914 new_order[reverse[i]] = i;
1919 template <
int dim,
int spacedim>
1923 const bool dof_wise_renumbering)
1925 std::vector<types::global_dof_index> renumbering(dof.
n_dofs());
1926 std::vector<types::global_dof_index> reverse(dof.
n_dofs());
1928 renumbering, reverse, dof, direction, dof_wise_renumbering);
1935 template <
int dim,
int spacedim>
1938 std::vector<types::global_dof_index> &reverse,
1941 const bool dof_wise_renumbering)
1947 if (dof_wise_renumbering ==
false)
1949 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>
1955 comparator(direction);
1958 ordered_cells.push_back(cell);
1960 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
1972 const unsigned int n_dofs = dof.
n_dofs();
1973 std::vector<std::pair<Point<spacedim>,
unsigned int>>
1974 support_point_list(n_dofs);
1977 Assert(fe_collection[0].has_support_points(),
1980 for (
unsigned int comp = 0; comp < fe_collection.
size(); ++comp)
1982 Assert(fe_collection[comp].has_support_points(),
1988 quadrature_collection,
1991 std::vector<bool> already_touched(n_dofs,
false);
1993 std::vector<types::global_dof_index> local_dof_indices;
1997 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
1998 local_dof_indices.resize(dofs_per_cell);
1999 hp_fe_values.
reinit(cell);
2002 cell->get_active_or_mg_dof_indices(local_dof_indices);
2003 const std::vector<Point<spacedim>> &points =
2005 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2006 if (!already_touched[local_dof_indices[i]])
2008 support_point_list[local_dof_indices[i]].first = points[i];
2009 support_point_list[local_dof_indices[i]].second =
2010 local_dof_indices[i];
2011 already_touched[local_dof_indices[i]] =
true;
2016 std::sort(support_point_list.begin(),
2017 support_point_list.end(),
2020 new_indices[support_point_list[i].
second] = i;
2026 template <
int dim,
int spacedim>
2029 const unsigned int level,
2031 const bool dof_wise_renumbering)
2033 std::vector<types::global_dof_index> renumbering(dof.
n_dofs(
level));
2034 std::vector<types::global_dof_index> reverse(dof.
n_dofs(
level));
2036 renumbering, reverse, dof,
level, direction, dof_wise_renumbering);
2043 template <
int dim,
int spacedim>
2046 std::vector<types::global_dof_index> &reverse,
2048 const unsigned int level,
2050 const bool dof_wise_renumbering)
2052 if (dof_wise_renumbering ==
false)
2054 std::vector<typename DoFHandler<dim, spacedim>::level_cell_iterator>
2060 comparator(direction);
2069 ordered_cells.push_back(p);
2072 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
2081 std::vector<std::pair<Point<spacedim>,
unsigned int>>
2082 support_point_list(n_dofs);
2089 std::vector<bool> already_touched(dof.
n_dofs(),
false);
2092 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
2100 &begin_tria =
begin;
2101 begin->get_active_or_mg_dof_indices(local_dof_indices);
2102 fe_values.
reinit(begin_tria);
2103 const std::vector<Point<spacedim>> &points =
2105 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2106 if (!already_touched[local_dof_indices[i]])
2108 support_point_list[local_dof_indices[i]].first = points[i];
2109 support_point_list[local_dof_indices[i]].second =
2110 local_dof_indices[i];
2111 already_touched[local_dof_indices[i]] =
true;
2116 std::sort(support_point_list.begin(),
2117 support_point_list.end(),
2120 new_indices[support_point_list[i].
second] = i;
2154 template <
class DHCellIterator>
2156 operator()(
const DHCellIterator &c1,
const DHCellIterator &c2)
const
2160 return compare(c1, c2, std::integral_constant<int, dim>());
2167 template <
class DHCellIterator,
int xdim>
2170 const DHCellIterator &c2,
2171 std::integral_constant<int, xdim>)
const
2175 const double s1 = std::atan2(
v1[0],
v1[1]);
2176 const double s2 = std::atan2(v2[0], v2[1]);
2177 return (
counter ? (s1 > s2) : (s2 > s1));
2185 template <
class DHCellIterator>
2188 const DHCellIterator &,
2189 std::integral_constant<int, 1>)
const
2192 ExcMessage(
"This operation only makes sense for dim>=2."));
2200 template <
int dim,
int spacedim>
2206 std::vector<types::global_dof_index> renumbering(dof.
n_dofs());
2214 template <
int dim,
int spacedim>
2221 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>
2227 ordered_cells.push_back(cell);
2229 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
2231 std::vector<types::global_dof_index> reverse(new_indices.size());
2237 template <
int dim,
int spacedim>
2240 const unsigned int level,
2244 std::vector<typename DoFHandler<dim, spacedim>::level_cell_iterator>
2256 ordered_cells.push_back(p);
2259 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
2266 template <
int dim,
int spacedim>
2270 std::vector<types::global_dof_index> renumbering(
2279 template <
int dim,
int spacedim>
2286 std::vector<types::global_dof_index> renumbering(
2297 template <
int dim,
int spacedim>
2303 Assert(new_indices.size() == n_dofs,
2306 std::iota(new_indices.begin(),
2314 ::boost::mt19937 random_number_generator;
2315 for (
unsigned int i = 1; i < n_dofs; ++i)
2318 const unsigned int j =
2319 ::boost::random::uniform_int_distribution<>(0, i)(
2320 random_number_generator);
2324 std::swap(new_indices[i], new_indices[j]);
2330 template <
int dim,
int spacedim>
2334 const unsigned int level)
2337 Assert(new_indices.size() == n_dofs,
2340 std::iota(new_indices.begin(),
2348 ::boost::mt19937 random_number_generator;
2349 for (
unsigned int i = 1; i < n_dofs; ++i)
2352 const unsigned int j =
2353 ::boost::random::uniform_int_distribution<>(0, i)(
2354 random_number_generator);
2358 std::swap(new_indices[i], new_indices[j]);
2364 template <
int dim,
int spacedim>
2372 "Parallel triangulations are already enumerated according to their MPI process id."));
2374 std::vector<types::global_dof_index> renumbering(
2383 template <
int dim,
int spacedim>
2389 Assert(new_dof_indices.size() == n_dofs,
2395 std::vector<types::subdomain_id> subdomain_association(n_dofs);
2397 const unsigned int n_subdomains =
2398 *std::max_element(subdomain_association.begin(),
2399 subdomain_association.end()) +
2409 std::fill(new_dof_indices.begin(),
2410 new_dof_indices.end(),
2416 if (subdomain_association[i] == subdomain)
2420 new_dof_indices[i] = next_free_index;
2426 Assert(std::find(new_dof_indices.begin(),
2427 new_dof_indices.end(),
2434 template <
int dim,
int spacedim>
2438 std::vector<types::global_dof_index> renumbering(
2453 template <
int dim,
int spacedim>
2456 std::vector<types::global_dof_index> &new_dof_indices,
2460 Assert(new_dof_indices.size() == n_dofs,
2472 std::vector<types::global_dof_index> component_renumbering(
2474 compute_component_wise<dim, spacedim>(component_renumbering,
2477 std::vector<unsigned int>(),
2483 const std::vector<types::global_dof_index> dofs_per_component =
2485 for (
const auto &dpc : dofs_per_component)
2489 const unsigned int n_components =
2493 dof_handler.
n_dofs() / n_components;
2499 if (component_renumbering.empty())
2501 new_dof_indices.resize(0);
2504 std::fill(new_dof_indices.begin(),
2505 new_dof_indices.end(),
2513 std::vector<types::global_dof_index> component_dofs(
2514 local_dofs_per_component);
2515 for (
unsigned int component = 0; component < n_components; ++component)
2517 for (std::size_t i = 0; i < local_dofs_per_component; ++i)
2519 component_renumbering[n_components * i + component];
2520 component_renumbered_dofs.
add_indices(component_dofs.begin(),
2521 component_dofs.end());
2523 component_renumbered_dofs.
compress();
2528 component_renumbered_dofs2.
add_indices(component_renumbering.begin(),
2529 component_renumbering.end());
2530 Assert(component_renumbered_dofs2 == component_renumbered_dofs,
2537 AssertThrow(fe.dofs_per_cell == 0 || fe.has_support_points(),
2539 for (
unsigned int i = 0; i < fe.n_base_elements(); ++i)
2541 fe.base_element(0).get_unit_support_points() ==
2542 fe.base_element(i).get_unit_support_points(),
2544 "All base elements should have the same support points."));
2547 std::vector<types::global_dof_index> component_to_nodal(
2551 std::vector<types::global_dof_index> cell_dofs;
2552 std::vector<types::global_dof_index> component_renumbered_cell_dofs;
2556 auto next_dof_it = locally_owned_dofs.
begin();
2558 if (cell->is_locally_owned())
2563 cell->get_dof_indices(cell_dofs);
2570 if (locally_owned_dofs.
is_element(cell_dofs[i]))
2572 const auto local_index =
2574 component_renumbered_cell_dofs[i] =
2575 component_renumbering[local_index];
2579 component_renumbered_cell_dofs[i] =
2588 component_renumbered_cell_dofs[i]))
2590 for (
unsigned int component = 0;
2597 const auto local_index =
2599 component_renumbered_cell_dofs[i] +
2600 dofs_per_component * component);
2602 if (component_to_nodal[local_index] ==
2605 component_to_nodal[local_index] = *next_dof_it;
2616 const auto local_index =
2618 new_dof_indices[i] = component_to_nodal[local_index];
2628 std::vector<types::global_dof_index> renumbering;
2638 const double tolerance)
2643 "Lexicographic renumbering is not implemented for distributed "
2644 "triangulations."));
2646 std::map<types::global_dof_index, Point<dim>> dof_location_map =
2648 std::vector<std::pair<types::global_dof_index, Point<dim>>>
2649 dof_location_vector;
2651 dof_location_vector.reserve(dof_location_map.size());
2652 for (
const auto &s : dof_location_map)
2653 dof_location_vector.push_back(s);
2656 dof_location_vector.begin(),
2657 dof_location_vector.end(),
2660 for (int i = dim - 1; i >= 0; --i)
2662 const double diff = p1.second(i) - p2.second(i);
2664 if (diff < -tolerance)
2667 if (diff > tolerance)
2675 return p1.first < p2.first;
2678 new_dof_indices.resize(dof_location_vector.size(),
2683 new_dof_indices[dof_location_vector[dof].
first] = dof;
2691 typename VectorizedArrayType>
2697 const std::vector<types::global_dof_index> new_global_numbers =
2707 template <
int dim,
int spacedim,
typename Number,
typename AdditionalDataType>
2711 const AdditionalDataType &matrix_free_data)
2713 const std::vector<types::global_dof_index> new_global_numbers =
2720 dof_handler.
renumber_dofs(matrix_free_data.mg_level, new_global_numbers);
2725 template <
int dim,
int spacedim,
typename Number,
typename AdditionalDataType>
2726 std::vector<types::global_dof_index>
2730 const AdditionalDataType &matrix_free_data)
2732 AdditionalDataType my_mf_data = matrix_free_data;
2733 my_mf_data.initialize_mapping =
false;
2734 my_mf_data.tasks_parallel_scheme = AdditionalDataType::none;
2736 typename AdditionalDataType::MatrixFreeType separate_matrix_free;
2755 std::vector<std::vector<unsigned int>>
2756 group_dofs_by_rank_access(
2757 const ::Utilities::MPI::Partitioner &partitioner)
2761 std::vector<unsigned int> touch_count(partitioner.locally_owned_size());
2762 for (
const auto &p : partitioner.import_indices())
2767 std::vector<std::vector<unsigned int>> result(1);
2768 for (
unsigned int i = 0; i < touch_count.size(); ++i)
2769 if (touch_count[i] == 0)
2770 result.back().push_back(i);
2775 std::map<unsigned int, std::vector<unsigned int>>
2776 multiple_ranks_access_dof;
2777 const std::vector<std::pair<unsigned int, unsigned int>> &import_targets =
2778 partitioner.import_targets();
2779 auto it = partitioner.import_indices().begin();
2780 for (
const std::pair<unsigned int, unsigned int> &proc : import_targets)
2782 result.emplace_back();
2783 unsigned int count_dofs = 0;
2784 while (count_dofs < proc.second)
2786 for (
unsigned int i = it->first; i < it->second;
2789 if (touch_count[i] == 1)
2790 result.back().push_back(i);
2792 multiple_ranks_access_dof[i].push_back(proc.first);
2802 std::map<std::vector<unsigned int>,
2803 std::vector<unsigned int>,
2804 std::function<
bool(
const std::vector<unsigned int> &,
2805 const std::vector<unsigned int> &)>>
2806 dofs_by_rank{[](
const std::vector<unsigned int> &a,
2807 const std::vector<unsigned int> &
b) {
2808 if (a.size() <
b.size())
2810 if (a.size() ==
b.size())
2812 for (
unsigned int i = 0; i < a.size(); ++i)
2815 else if (a[i] > b[i])
2820 for (
const auto &entry : multiple_ranks_access_dof)
2823 for (
const auto &procs : dofs_by_rank)
2835 template <
int dim,
typename Number,
typename VectorizedArrayType>
2836 std::pair<std::vector<unsigned int>, std::vector<unsigned char>>
2837 compute_mf_numbering(
2839 const unsigned int component)
2843 const unsigned int n_comp =
2846 matrix_free.
get_dof_handler(component).get_fe().n_base_elements() == 1,
2851 const unsigned int fe_degree =
2853 const unsigned int nn = fe_degree - 1;
2862 std::array<std::pair<unsigned int, unsigned int>,
2867 dofs_on_objects[0] = std::make_pair(0U, 1U);
2868 dofs_on_objects[1] = std::make_pair(2 * n_comp, nn);
2869 dofs_on_objects[2] = std::make_pair(n_comp, 1U);
2873 dofs_on_objects[0] = std::make_pair(0U, 1U);
2874 dofs_on_objects[1] = std::make_pair(n_comp * (4 + 2 * nn), nn);
2875 dofs_on_objects[2] = std::make_pair(n_comp, 1U);
2876 dofs_on_objects[3] = std::make_pair(n_comp * 4, nn);
2877 dofs_on_objects[4] = std::make_pair(n_comp * (4 + 4 * nn), nn * nn);
2878 dofs_on_objects[5] = std::make_pair(n_comp * (4 + 1 * nn), nn);
2879 dofs_on_objects[6] = std::make_pair(2 * n_comp, 1U);
2880 dofs_on_objects[7] = std::make_pair(n_comp * (4 + 3 * nn), nn);
2881 dofs_on_objects[8] = std::make_pair(3 * n_comp, 1U);
2885 dofs_on_objects[0] = std::make_pair(0U, 1U);
2886 dofs_on_objects[1] = std::make_pair(n_comp * (8 + 2 * nn), nn);
2887 dofs_on_objects[2] = std::make_pair(n_comp, 1U);
2888 dofs_on_objects[3] = std::make_pair(n_comp * 8, nn);
2889 dofs_on_objects[4] =
2890 std::make_pair(n_comp * (8 + 12 * nn + 4 * nn * nn), nn * nn);
2891 dofs_on_objects[5] = std::make_pair(n_comp * (8 + 1 * nn), nn);
2892 dofs_on_objects[6] = std::make_pair(n_comp * 2, 1U);
2893 dofs_on_objects[7] = std::make_pair(n_comp * (8 + 3 * nn), nn);
2894 dofs_on_objects[8] = std::make_pair(n_comp * 3, 1U);
2895 dofs_on_objects[9] = std::make_pair(n_comp * (8 + 8 * nn), nn);
2896 dofs_on_objects[10] =
2897 std::make_pair(n_comp * (8 + 12 * nn + 2 * nn * nn), nn * nn);
2898 dofs_on_objects[11] = std::make_pair(n_comp * (8 + 9 * nn), nn);
2899 dofs_on_objects[12] = std::make_pair(n_comp * (8 + 12 * nn), nn * nn);
2900 dofs_on_objects[13] =
2901 std::make_pair(n_comp * (8 + 12 * nn + 6 * nn * nn), nn * nn * nn);
2902 dofs_on_objects[14] =
2903 std::make_pair(n_comp * (8 + 12 * nn + 1 * nn * nn), nn * nn);
2904 dofs_on_objects[15] = std::make_pair(n_comp * (8 + 10 * nn), nn);
2905 dofs_on_objects[16] =
2906 std::make_pair(n_comp * (8 + 12 * nn + 3 * nn * nn), nn * nn);
2907 dofs_on_objects[17] = std::make_pair(n_comp * (8 + 11 * nn), nn);
2908 dofs_on_objects[18] = std::make_pair(n_comp * 4, 1U);
2909 dofs_on_objects[19] = std::make_pair(n_comp * (8 + 6 * nn), nn);
2910 dofs_on_objects[20] = std::make_pair(n_comp * 5, 1U);
2911 dofs_on_objects[21] = std::make_pair(n_comp * (8 + 4 * nn), nn);
2912 dofs_on_objects[22] =
2913 std::make_pair(n_comp * (8 + 12 * nn + 5 * nn * nn), nn * nn);
2914 dofs_on_objects[23] = std::make_pair(n_comp * (8 + 5 * nn), nn);
2915 dofs_on_objects[24] = std::make_pair(n_comp * 6, 1U);
2916 dofs_on_objects[25] = std::make_pair(n_comp * (8 + 7 * nn), nn);
2917 dofs_on_objects[26] = std::make_pair(n_comp * 7, 1U);
2922 std::vector<unsigned int> &result,
2923 unsigned int &counter_dof_numbers) {
2925 owned_dofs.index_within_set(dof_index);
2930 result[local_dof_index] = counter_dof_numbers++;
2934 unsigned int counter_dof_numbers = 0;
2935 std::vector<unsigned int> dofs_extracted;
2936 std::vector<types::global_dof_index> dof_indices(
2953 const unsigned int n_owned_dofs = owned_dofs.n_elements();
2954 std::vector<unsigned int> dof_numbers_mf_order(
2956 std::vector<unsigned int> last_touch_by_cell_batch_range(
2958 std::vector<unsigned char> touch_count(n_owned_dofs);
2960 const auto operation_on_cell_range =
2963 const unsigned int &,
2964 const std::pair<unsigned int, unsigned int> &cell_range) {
2965 for (
unsigned int cell = cell_range.first; cell < cell_range.second;
2969 for (
unsigned int v = 0;
2970 v <
data.n_active_entries_per_cell_batch(cell);
2975 data.get_cell_iterator(cell, v, component)
2976 ->get_dof_indices(dof_indices);
2978 data.get_cell_iterator(cell, v, component)
2979 ->get_mg_dof_indices(dof_indices);
2982 for (
unsigned int a = 0; a < dofs_on_objects.size(); ++a)
2984 const auto &r = dofs_on_objects[a];
2985 if (a == 10 || a == 16)
2988 for (
unsigned int i1 = 0; i1 < nn; ++i1)
2989 for (
unsigned int i0 = 0; i0 < nn; ++i0)
2990 for (
unsigned int c = 0; c < n_comp; ++c)
2992 dof_indices[r.first + r.second * c + i1 +
2995 dof_numbers_mf_order,
2996 counter_dof_numbers);
2998 for (
unsigned int i = 0; i < r.second; ++i)
2999 for (
unsigned int c = 0; c < n_comp; ++c)
3001 dof_indices[r.first + r.second * c + i],
3003 dof_numbers_mf_order,
3004 counter_dof_numbers);
3010 dof_numbers_mf_order,
3011 counter_dof_numbers);
3018 data.get_dof_info(component).get_dof_indices_on_cell_batch(
3019 dofs_extracted, cell);
3020 for (
const unsigned int dof_index : dofs_extracted)
3021 if (dof_index < n_owned_dofs &&
3022 last_touch_by_cell_batch_range[dof_index] !=
3025 ++touch_count[dof_index];
3026 last_touch_by_cell_batch_range[dof_index] =
3036 "version of MatrixFree::cell_loop"));
3038 matrix_free.template cell_loop<unsigned int, unsigned int>(
3039 operation_on_cell_range, counter_dof_numbers, counter_dof_numbers);
3043 return std::make_pair(dof_numbers_mf_order, touch_count);
3053 typename VectorizedArrayType>
3054 std::vector<types::global_dof_index>
3060 ExcMessage(
"You need to set up indices in MatrixFree "
3061 "to be able to compute a renumbering!"));
3064 unsigned int component = 0;
3065 for (; component < matrix_free.
n_components(); ++component)
3070 ExcMessage(
"Could not locate the given DoFHandler in MatrixFree"));
3082 const std::vector<std::vector<unsigned int>> dofs_by_rank_access =
3083 group_dofs_by_rank_access(
3086 const auto &[local_numbering, touch_count] =
3087 compute_mf_numbering(matrix_free, component);
3097 enum class Category :
unsigned char
3106 switch (touch_count[i])
3109 categories[local_numbering[i]] = Category::constrained;
3112 categories[local_numbering[i]] = Category::single;
3115 categories[local_numbering[i]] = Category::multiple;
3118 for (
unsigned int chunk = 1; chunk < dofs_by_rank_access.size(); ++chunk)
3119 for (
const auto i : dofs_by_rank_access[chunk])
3120 categories[local_numbering[i]] = Category::mpi_dof;
3124 std::array<unsigned int, 4> n_entries_per_category{};
3125 for (
const Category i : categories)
3128 ++n_entries_per_category[
static_cast<int>(i)];
3130 std::array<unsigned int, 4> counters{};
3131 for (
unsigned int i = 1; i < 4; ++i)
3132 counters[i] = counters[i - 1] + n_entries_per_category[i - 1];
3133 std::vector<unsigned int> numbering_categories;
3135 for (
const Category category : categories)
3137 numbering_categories.push_back(counters[
static_cast<int>(category)]);
3138 ++counters[
static_cast<int>(category)];
3142 std::vector<::types::global_dof_index> new_global_numbers(
3145 new_global_numbers[i] =
3148 return new_global_numbers;
3156#include "dofs/dof_renumbering.inst"
* * for(const auto &cell :triangulation.active_cell_iterators())
***mech_lbc_system increment_interpolation_handlers push_back(scale_z_handler)
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
cell_iterator end() const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
const Triangulation< dim, spacedim > & get_triangulation() const
const IndexSet & locally_owned_dofs() const
active_cell_iterator begin_active(const unsigned int level=0) const
types::global_dof_index n_dofs() const
typename LevelSelector::cell_iterator level_cell_iterator
cell_iterator begin(const unsigned int level=0) const
MPI_Comm get_mpi_communicator() const
types::global_dof_index n_locally_owned_dofs() const
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_unique_and_sorted=false)
size_type row_length(const size_type row) const
size_type column_number(const size_type row, const size_type index) const
const std::vector< Point< spacedim > > & get_quadrature_points() const
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
unsigned int n_dofs_per_cell() const
unsigned int n_components() const
const unsigned int dofs_per_cell
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
const ComponentMask & get_nonzero_components(const unsigned int i) const
bool has_support_points() const
const std::vector< Point< dim > > & get_unit_support_points() const
bool is_primitive() const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
size_type index_within_set(const size_type global_index) const
size_type n_elements() const
bool is_element(const size_type index) const
ElementIterator begin() const
void subtract_set(const IndexSet &other)
size_type nth_index_in_set(const size_type local_index) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
unsigned int get_mg_level() const
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info(const unsigned int dof_handler_index_component=0) const
const DoFHandler< dim > & get_dof_handler(const unsigned int dof_handler_index=0) const
bool indices_initialized() const
unsigned int n_components() const
unsigned int n_active_cells() const
unsigned int n_cells() const
unsigned int size() const
void push_back(const FiniteElement< dim, spacedim > &new_fe)
unsigned int n_blocks() const
unsigned int n_components() const
const FEValuesType & get_present_fe_values() const
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, lda > > &cell, const unsigned int q_index=numbers::invalid_unsigned_int, const unsigned int mapping_index=numbers::invalid_unsigned_int, const unsigned int fe_index=numbers::invalid_unsigned_int)
void push_back(const Quadrature< dim_in > &new_quadrature)
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcDoFHandlerNotInitialized()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::cell_iterator cell_iterator
typename ActiveSelector::active_cell_iterator active_cell_iterator
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
@ update_quadrature_points
Transformed quadrature points.
std::vector< index_type > data
types::global_dof_index locally_owned_size
graph_traits< Graph >::vertices_size_type size_type
graph_traits< Graph >::vertex_descriptor Vertex
adjacency_list< vecS, vecS, undirectedS, property< vertex_color_t, default_color_type, property< vertex_degree_t, int > > > Graph
std::pair< size_type, size_type > Pair
void create_graph(const DoFHandler< dim, spacedim > &dof_handler, const bool use_constraints, boosttypes::Graph &graph, boosttypes::property_map< boosttypes::Graph, boosttypes::vertex_degree_t >::type &graph_degree)
void compute_Cuthill_McKee(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &, const bool reversed_numbering=false, const bool use_constraints=false)
void Cuthill_McKee(DoFHandler< dim, spacedim > &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false)
void king_ordering(DoFHandler< dim, spacedim > &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false)
void compute_king_ordering(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &, const bool reversed_numbering=false, const bool use_constraints=false)
void compute_minimum_degree(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &, const bool reversed_numbering=false, const bool use_constraints=false)
void minimum_degree(DoFHandler< dim, spacedim > &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false)
void compute_support_point_wise(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &dof_handler)
void compute_subdomain_wise(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &dof_handler)
void matrix_free_data_locality(DoFHandler< dim, spacedim > &dof_handler, const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free)
void subdomain_wise(DoFHandler< dim, spacedim > &dof_handler)
types::global_dof_index compute_block_wise(std::vector< types::global_dof_index > &new_dof_indices, const IteratorType &start, const EndIteratorType &end, const bool is_level_operation)
void hierarchical(DoFHandler< dim, spacedim > &dof_handler)
void compute_random(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &dof_handler)
void component_wise(DoFHandler< dim, spacedim > &dof_handler, const std::vector< unsigned int > &target_component=std::vector< unsigned int >())
void downstream(DoFHandler< dim, spacedim > &dof_handler, const Tensor< 1, spacedim > &direction, const bool dof_wise_renumbering=false)
void compute_Cuthill_McKee(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &, const bool reversed_numbering=false, const bool use_constraints=false, const std::vector< types::global_dof_index > &starting_indices=std::vector< types::global_dof_index >(), const unsigned int level=numbers::invalid_unsigned_int)
void block_wise(DoFHandler< dim, spacedim > &dof_handler)
void Cuthill_McKee(DoFHandler< dim, spacedim > &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false, const std::vector< types::global_dof_index > &starting_indices=std::vector< types::global_dof_index >())
void compute_sort_selected_dofs_back(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &dof_handler, const std::vector< bool > &selected_dofs)
void sort_selected_dofs_back(DoFHandler< dim, spacedim > &dof_handler, const std::vector< bool > &selected_dofs)
void support_point_wise(DoFHandler< dim, spacedim > &dof_handler)
void compute_cell_wise(std::vector< types::global_dof_index > &renumbering, std::vector< types::global_dof_index > &inverse_renumbering, const DoFHandler< dim, spacedim > &dof_handler, const std::vector< typename DoFHandler< dim, spacedim >::active_cell_iterator > &cell_order)
std::vector< types::global_dof_index > compute_matrix_free_data_locality(const DoFHandler< dim, spacedim > &dof_handler, const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free)
void clockwise_dg(DoFHandler< dim, spacedim > &dof_handler, const Point< spacedim > ¢er, const bool counter=false)
void lexicographic(DoFHandler< dim > &dof_handler, const double tolerance=1e-12)
void random(DoFHandler< dim, spacedim > &dof_handler)
void compute_downstream(std::vector< types::global_dof_index > &new_dof_indices, std::vector< types::global_dof_index > &reverse, const DoFHandler< dim, spacedim > &dof_handler, const Tensor< 1, spacedim > &direction, const bool dof_wise_renumbering)
void cell_wise(DoFHandler< dim, spacedim > &dof_handler, const std::vector< typename DoFHandler< dim, spacedim >::active_cell_iterator > &cell_order)
void compute_lexicographic(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim > &handler, const double tolerance=1e-12)
types::global_dof_index compute_component_wise(std::vector< types::global_dof_index > &new_dof_indices, const CellIterator &start, const std_cxx20::type_identity_t< CellIterator > &end, const std::vector< unsigned int > &target_component, const bool is_level_operation)
void compute_clockwise_dg(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandler< dim, spacedim > &dof_handler, const Point< spacedim > ¢er, const bool counter)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
* * if(update_pressure &update_flags) * compute_pressure(constitutive_request
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
T sum(const T &t, const MPI_Comm mpi_communicator)
bool logical_and(const bool t, const MPI_Comm mpi_communicator)
constexpr T pow(const T base, const int iexp)
std::vector< Integer > reverse_permutation(const std::vector< Integer > &permutation)
constexpr types::global_dof_index invalid_dof_index
constexpr unsigned int invalid_unsigned_int
typename type_identity< T >::type type_identity_t
unsigned short int fe_index
bool compare(const DHCellIterator &c1, const DHCellIterator &c2, std::integral_constant< int, xdim >) const
bool compare(const DHCellIterator &, const DHCellIterator &, std::integral_constant< int, 1 >) const
ClockCells(const Point< dim > ¢er, bool counter)
const Point< dim > & center
bool operator()(const DHCellIterator &c1, const DHCellIterator &c2) const
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
TasksParallelScheme scheme