47#define BOOST_BIND_GLOBAL_PLACEHOLDERS
48#include <boost/config.hpp>
49#include <boost/graph/adjacency_list.hpp>
50#include <boost/graph/bandwidth.hpp>
51#include <boost/graph/cuthill_mckee_ordering.hpp>
52#include <boost/graph/king_ordering.hpp>
53#include <boost/graph/minimum_degree_ordering.hpp>
54#include <boost/graph/properties.hpp>
55#include <boost/random.hpp>
56#include <boost/random/uniform_int_distribution.hpp>
58#undef BOOST_BIND_GLOBAL_PLACEHOLDERS
75 using namespace ::
boost;
77 using Graph = adjacency_list<vecS,
80 property<vertex_color_t,
82 property<vertex_degree_t, int>>>;
83 using Vertex = graph_traits<Graph>::vertex_descriptor;
84 using size_type = graph_traits<Graph>::vertices_size_type;
86 using Pair = std::pair<size_type, size_type>;
92 template <
int dim,
int spacedim>
95 const bool use_constraints,
98 boosttypes::vertex_degree_t>::type
113 for (
unsigned int row = 0; row < dsp.
n_rows(); ++row)
114 for (
unsigned int col = 0; col < dsp.
row_length(row); ++col)
118 boosttypes::graph_traits<boosttypes::Graph>::vertex_iterator ui, ui_end;
120 graph_degree = get(::boost::vertex_degree, graph);
121 for (::boost::tie(ui, ui_end) =
vertices(graph); ui != ui_end; ++ui)
122 graph_degree[*ui] = degree(*ui, graph);
127 template <
int dim,
int spacedim>
130 const bool reversed_numbering,
131 const bool use_constraints)
133 std::vector<types::global_dof_index> renumbering(
147 template <
int dim,
int spacedim>
151 const bool reversed_numbering,
152 const bool use_constraints)
156 boosttypes::vertex_degree_t>::type graph_degree;
161 boosttypes::vertex_index_t>::type index_map =
162 get(::boost::vertex_index, graph);
165 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
167 if (reversed_numbering ==
false)
168 ::boost::cuthill_mckee_ordering(graph,
170 get(::boost::vertex_color, graph),
171 make_degree_map(graph));
173 ::boost::cuthill_mckee_ordering(graph,
175 get(::boost::vertex_color, graph),
176 make_degree_map(graph));
179 new_dof_indices[index_map[inv_perm[c]]] = c;
181 Assert(std::find(new_dof_indices.begin(),
182 new_dof_indices.end(),
189 template <
int dim,
int spacedim>
192 const bool reversed_numbering,
193 const bool use_constraints)
195 std::vector<types::global_dof_index> renumbering(
209 template <
int dim,
int spacedim>
213 const bool reversed_numbering,
214 const bool use_constraints)
218 boosttypes::vertex_degree_t>::type graph_degree;
223 boosttypes::vertex_index_t>::type index_map =
224 get(::boost::vertex_index, graph);
227 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
229 if (reversed_numbering ==
false)
232 ::boost::king_ordering(graph, inv_perm.begin());
235 new_dof_indices[index_map[inv_perm[c]]] = c;
237 Assert(std::find(new_dof_indices.begin(),
238 new_dof_indices.end(),
245 template <
int dim,
int spacedim>
248 const bool reversed_numbering,
249 const bool use_constraints)
251 std::vector<types::global_dof_index> renumbering(
265 template <
int dim,
int spacedim>
268 std::vector<types::global_dof_index> &new_dof_indices,
270 const bool reversed_numbering,
271 const bool use_constraints)
273 (void)use_constraints;
282 using namespace ::
boost;
287 using Graph = adjacency_list<vecS, vecS, directedS>;
289 int n = dof_handler.
n_dofs();
293 std::vector<::types::global_dof_index> dofs_on_this_cell;
297 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
299 dofs_on_this_cell.resize(dofs_per_cell);
301 cell->get_active_or_mg_dof_indices(dofs_on_this_cell);
302 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
303 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
304 if (dofs_on_this_cell[i] > dofs_on_this_cell[j])
306 add_edge(dofs_on_this_cell[i], dofs_on_this_cell[j], G);
307 add_edge(dofs_on_this_cell[j], dofs_on_this_cell[i], G);
312 using Vector = std::vector<int>;
315 Vector inverse_perm(n, 0);
320 Vector supernode_sizes(n, 1);
323 ::boost::property_map<Graph, vertex_index_t>::type
id =
324 get(vertex_index, G);
330 minimum_degree_ordering(
332 make_iterator_property_map(degree.
begin(),
id, degree[0]),
335 make_iterator_property_map(supernode_sizes.
begin(),
342 for (
int i = 0; i < n; ++i)
352 if (reversed_numbering ==
true)
353 std::copy(perm.
begin(), perm.
end(), new_dof_indices.begin());
355 std::copy(inverse_perm.
begin(),
357 new_dof_indices.begin());
364 template <
int dim,
int spacedim>
367 const bool reversed_numbering,
368 const bool use_constraints,
369 const std::vector<types::global_dof_index> &starting_indices)
371 std::vector<types::global_dof_index> renumbering(
388 template <
int dim,
int spacedim>
391 std::vector<types::global_dof_index> &new_indices,
393 const bool reversed_numbering,
394 const bool use_constraints,
395 const std::vector<types::global_dof_index> &starting_indices,
396 const unsigned int level)
398 const bool reorder_level_dofs =
413 if (reorder_level_dofs ==
true)
417 const IndexSet locally_relevant_dofs =
418 (reorder_level_dofs ==
false ?
421 const IndexSet &locally_owned_dofs =
431 constraints.
reinit(locally_owned_dofs, locally_relevant_dofs);
442 locally_owned_dofs.
size());
443 if (reorder_level_dofs ==
false)
455 if (reversed_numbering)
468 const IndexSet locally_active_dofs =
469 (reorder_level_dofs ==
false ?
473 bool needs_locally_active =
false;
474 for (
const auto starting_index : starting_indices)
476 if ((needs_locally_active ==
478 (locally_owned_dofs.
is_element(starting_index) ==
false))
481 locally_active_dofs.
is_element(starting_index),
483 "You specified global degree of freedom " +
484 std::to_string(starting_index) +
485 " as a starting index, but this index is not among the "
486 "locally active ones on this processor, as required "
487 "for this function."));
488 needs_locally_active =
true;
493 (needs_locally_active ? locally_active_dofs : locally_owned_dofs);
504 index_set_to_use.
size(),
506 if (reorder_level_dofs ==
false)
517 std::vector<types::global_dof_index> row_entries;
518 for (
unsigned int i = 0; i < index_set_to_use.
n_elements(); ++i)
522 const unsigned int row_length = dsp.
row_length(row);
524 for (
unsigned int j = 0; j < row_length; ++j)
527 if (col != row && index_set_to_use.
is_element(col))
537 std::vector<types::global_dof_index> local_starting_indices(
538 starting_indices.size());
539 for (
unsigned int i = 0; i < starting_indices.size(); ++i)
540 local_starting_indices[i] =
545 std::vector<types::global_dof_index> my_new_indices(
549 local_starting_indices);
550 if (reversed_numbering)
559 if (needs_locally_active ==
true)
562 IndexSet active_but_not_owned_dofs = locally_active_dofs;
563 active_but_not_owned_dofs.
subtract_set(locally_owned_dofs);
565 std::set<types::global_dof_index> erase_these_indices;
566 for (
const auto p : active_but_not_owned_dofs)
571 erase_these_indices.insert(my_new_indices[index]);
574 Assert(erase_these_indices.size() ==
577 Assert(
static_cast<unsigned int>(
578 std::count(my_new_indices.begin(),
579 my_new_indices.end(),
585 std::vector<types::global_dof_index> translate_indices(
586 my_new_indices.size());
588 std::set<types::global_dof_index>::const_iterator
589 next_erased_index = erase_these_indices.begin();
591 for (
unsigned int i = 0; i < translate_indices.size(); ++i)
592 if ((next_erased_index != erase_these_indices.end()) &&
593 (*next_erased_index == i))
600 translate_indices[i] = next_new_index;
610 new_indices.reserve(locally_owned_dofs.
n_elements());
611 for (
const auto &p : my_new_indices)
616 new_indices.push_back(translate_indices[p]);
622 new_indices = std::move(my_new_indices);
635 template <
int dim,
int spacedim>
638 const unsigned int level,
639 const bool reversed_numbering,
640 const std::vector<types::global_dof_index> &starting_indices)
645 std::vector<types::global_dof_index> new_indices(
664 template <
int dim,
int spacedim>
667 const std::vector<unsigned int> &component_order_arg)
669 std::vector<types::global_dof_index> renumbering(
673 compute_component_wise<dim, spacedim>(renumbering,
695 (result <= dof_handler.
n_dofs())),
703 template <
int dim,
int spacedim>
706 const unsigned int level,
707 const std::vector<unsigned int> &component_order_arg)
712 std::vector<types::global_dof_index> renumbering(
722 compute_component_wise<dim, spacedim>(
723 renumbering, start, end, component_order_arg,
true);
736 template <
int dim,
int spacedim,
typename CellIterator>
739 const CellIterator &start,
741 const std::vector<unsigned int> &component_order_arg,
742 const bool is_level_operation)
745 start->get_dof_handler().get_fe_collection();
751 new_indices.resize(0);
758 const IndexSet &locally_owned_dofs =
760 start->get_dof_handler().locally_owned_mg_dofs(start->level()) :
761 start->get_dof_handler().locally_owned_dofs();
765 std::vector<unsigned int> component_order(component_order_arg);
770 if (component_order.empty())
771 for (
unsigned int i = 0; i < fe_collection.
n_components(); ++i)
772 component_order.push_back(i);
778 for (
const unsigned int component : component_order)
786 std::vector<types::global_dof_index> local_dof_indices;
798 std::vector<std::vector<unsigned int>> component_list(fe_collection.
size());
799 for (
unsigned int f = 0; f < fe_collection.
size(); ++f)
803 component_list[f].resize(dofs_per_cell);
804 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
806 component_list[f][i] =
810 const unsigned int comp =
816 component_list[f][i] = component_order[comp];
831 std::vector<std::vector<types::global_dof_index>> component_to_dof_map(
833 for (CellIterator cell = start; cell != end; ++cell)
835 if (is_level_operation)
838 if (!cell->is_locally_owned_on_level())
845 if (!cell->is_locally_owned())
849 if (is_level_operation)
851 cell->level() == start->level(),
853 "Multigrid renumbering in compute_component_wise() needs to be applied to a single level!"));
859 const unsigned int dofs_per_cell =
860 fe_collection[fe_index].n_dofs_per_cell();
861 local_dof_indices.resize(dofs_per_cell);
862 cell->get_active_or_mg_dof_indices(local_dof_indices);
864 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
865 if (locally_owned_dofs.
is_element(local_dof_indices[i]))
866 component_to_dof_map[component_list[fe_index][i]].
push_back(
867 local_dof_indices[i]);
893 for (
unsigned int component = 0; component < fe_collection.
n_components();
896 std::sort(component_to_dof_map[component].begin(),
897 component_to_dof_map[component].end());
898 component_to_dof_map[component].erase(
899 std::unique(component_to_dof_map[component].begin(),
900 component_to_dof_map[component].end()),
901 component_to_dof_map[component].end());
906 const unsigned int n_buckets = fe_collection.
n_components();
907 std::vector<types::global_dof_index> shifts(n_buckets);
911 &start->get_dof_handler().get_triangulation())))
913#ifdef DEAL_II_WITH_MPI
914 std::vector<types::global_dof_index> local_dof_count(n_buckets);
916 for (
unsigned int c = 0; c < n_buckets; ++c)
917 local_dof_count[c] = component_to_dof_map[c].size();
919 std::vector<types::global_dof_index> prefix_dof_count(n_buckets);
920 const int ierr = MPI_Exscan(local_dof_count.data(),
921 prefix_dof_count.data(),
928 std::vector<types::global_dof_index> global_dof_count(n_buckets);
935 for (
unsigned int c = 0; c < n_buckets; ++c)
937 shifts[c] = prefix_dof_count[c] + cumulated;
938 cumulated += global_dof_count[c];
948 for (
unsigned int c = 1; c < fe_collection.
n_components(); ++c)
949 shifts[c] = shifts[c - 1] + component_to_dof_map[c - 1].size();
958 for (
unsigned int component = 0; component < fe_collection.
n_components();
961 next_free_index = shifts[component];
964 component_to_dof_map[component])
976 return next_free_index;
981 template <
int dim,
int spacedim>
985 std::vector<types::global_dof_index> renumbering(
1006 (result <= dof_handler.
n_dofs())),
1014 template <
int dim,
int spacedim>
1021 std::vector<types::global_dof_index> renumbering(
1050 template <
int dim,
int spacedim,
class IteratorType,
class EndIteratorType>
1053 const IteratorType &start,
1054 const EndIteratorType &end,
1055 const bool is_level_operation)
1058 start->get_dof_handler().get_fe_collection();
1064 new_indices.resize(0);
1071 const IndexSet &locally_owned_dofs =
1072 is_level_operation ?
1073 start->get_dof_handler().locally_owned_mg_dofs(start->level()) :
1074 start->get_dof_handler().locally_owned_dofs();
1078 std::vector<types::global_dof_index> local_dof_indices;
1083 std::vector<std::vector<types::global_dof_index>> block_list(
1084 fe_collection.
size());
1085 for (
unsigned int f = 0; f < fe_collection.
size(); ++f)
1104 std::vector<std::vector<types::global_dof_index>> block_to_dof_map(
1106 for (IteratorType cell = start; cell != end; ++cell)
1108 if (is_level_operation)
1111 if (!cell->is_locally_owned_on_level())
1118 if (!cell->is_locally_owned())
1122 if (is_level_operation)
1124 cell->level() == start->level(),
1126 "Multigrid renumbering in compute_block_wise() needs to be applied to a single level!"));
1132 const unsigned int dofs_per_cell =
1133 fe_collection[fe_index].n_dofs_per_cell();
1134 local_dof_indices.resize(dofs_per_cell);
1135 cell->get_active_or_mg_dof_indices(local_dof_indices);
1137 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1138 if (locally_owned_dofs.
is_element(local_dof_indices[i]))
1139 block_to_dof_map[block_list[fe_index][i]].
push_back(
1140 local_dof_indices[i]);
1155 for (
unsigned int block = 0; block < fe_collection.
n_blocks(); ++block)
1157 std::sort(block_to_dof_map[block].begin(),
1158 block_to_dof_map[block].end());
1159 block_to_dof_map[block].erase(
1160 std::unique(block_to_dof_map[block].begin(),
1161 block_to_dof_map[block].end()),
1162 block_to_dof_map[block].end());
1167 const unsigned int n_buckets = fe_collection.
n_blocks();
1168 std::vector<types::global_dof_index> shifts(n_buckets);
1172 &start->get_dof_handler().get_triangulation())))
1174#ifdef DEAL_II_WITH_MPI
1175 std::vector<types::global_dof_index> local_dof_count(n_buckets);
1177 for (
unsigned int c = 0; c < n_buckets; ++c)
1178 local_dof_count[c] = block_to_dof_map[c].size();
1180 std::vector<types::global_dof_index> prefix_dof_count(n_buckets);
1181 const int ierr = MPI_Exscan(local_dof_count.data(),
1182 prefix_dof_count.data(),
1189 std::vector<types::global_dof_index> global_dof_count(n_buckets);
1196 for (
unsigned int c = 0; c < n_buckets; ++c)
1198 shifts[c] = prefix_dof_count[c] + cumulated;
1199 cumulated += global_dof_count[c];
1209 for (
unsigned int c = 1; c < fe_collection.
n_blocks(); ++c)
1210 shifts[c] = shifts[c - 1] + block_to_dof_map[c - 1].size();
1219 for (
unsigned int block = 0; block < fe_collection.
n_blocks(); ++block)
1221 const typename std::vector<types::global_dof_index>::const_iterator
1222 begin_of_component = block_to_dof_map[block].begin(),
1223 end_of_component = block_to_dof_map[block].end();
1225 next_free_index = shifts[block];
1227 for (
typename std::vector<types::global_dof_index>::const_iterator
1228 dof_index = begin_of_component;
1229 dof_index != end_of_component;
1240 return next_free_index;
1252 template <
int dim,
typename CellIteratorType>
1254 compute_hierarchical_recursive(
1257 const CellIteratorType &cell,
1258 const IndexSet &locally_owned_dof_indices,
1259 std::vector<types::global_dof_index> &new_indices)
1262 next_free_dof_offset;
1264 if (cell->has_children())
1267 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1269 current_next_free_dof_offset =
1270 compute_hierarchical_recursive<dim>(current_next_free_dof_offset,
1273 locally_owned_dof_indices,
1293 if (cell->is_locally_owned())
1296 const unsigned int dofs_per_cell =
1297 cell->get_fe().n_dofs_per_cell();
1298 std::vector<types::global_dof_index> local_dof_indices(
1300 cell->get_dof_indices(local_dof_indices);
1319 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1320 if (locally_owned_dof_indices.
is_element(local_dof_indices[i]))
1324 const unsigned int idx =
1326 local_dof_indices[i]);
1330 my_starting_index + current_next_free_dof_offset;
1331 ++current_next_free_dof_offset;
1337 return current_next_free_dof_offset;
1343 template <
int dim,
int spacedim>
1347 std::vector<types::global_dof_index> renumbering(
1370#ifdef DEAL_II_WITH_MPI
1373 const int ierr = MPI_Exscan(&locally_owned_size,
1387#ifdef DEAL_II_WITH_P4EST
1392 for (
unsigned int c = 0; c < tria->
n_cells(0); ++c)
1394 const unsigned int coarse_cell_index =
1395 tria->get_p4est_tree_to_coarse_cell_permutation()[c];
1398 this_cell(tria, 0, coarse_cell_index, &dof_handler);
1400 next_free_dof_offset =
1401 compute_hierarchical_recursive<dim>(next_free_dof_offset,
1416 dof_handler.
begin(0);
1417 cell != dof_handler.
end(0);
1419 next_free_dof_offset =
1420 compute_hierarchical_recursive<dim>(next_free_dof_offset,
1433 (next_free_dof_offset <= dof_handler.
n_dofs())),
1437 Assert(std::find(renumbering.begin(),
1447 template <
int dim,
int spacedim>
1450 const std::vector<bool> &selected_dofs)
1452 std::vector<types::global_dof_index> renumbering(
1461 template <
int dim,
int spacedim>
1464 const std::vector<bool> &selected_dofs,
1465 const unsigned int level)
1470 std::vector<types::global_dof_index> renumbering(
1482 template <
int dim,
int spacedim>
1485 std::vector<types::global_dof_index> &new_indices,
1487 const std::vector<bool> &selected_dofs)
1490 Assert(selected_dofs.size() == n_dofs,
1495 Assert(new_indices.size() == n_dofs,
1499 std::count(selected_dofs.begin(), selected_dofs.end(),
false);
1504 if (selected_dofs[i] ==
false)
1506 new_indices[i] = next_unselected;
1511 new_indices[i] = next_selected;
1520 template <
int dim,
int spacedim>
1523 std::vector<types::global_dof_index> &new_indices,
1525 const std::vector<bool> &selected_dofs,
1526 const unsigned int level)
1531 const unsigned int n_dofs = dof_handler.
n_dofs(
level);
1532 Assert(selected_dofs.size() == n_dofs,
1537 Assert(new_indices.size() == n_dofs,
1540 const unsigned int n_selected_dofs =
1541 std::count(selected_dofs.begin(), selected_dofs.end(),
false);
1543 unsigned int next_unselected = 0;
1544 unsigned int next_selected = n_selected_dofs;
1545 for (
unsigned int i = 0; i < n_dofs; ++i)
1546 if (selected_dofs[i] ==
false)
1548 new_indices[i] = next_unselected;
1553 new_indices[i] = next_selected;
1562 template <
int dim,
int spacedim>
1569 std::vector<types::global_dof_index> renumbering(
1578 template <
int dim,
int spacedim>
1581 std::vector<types::global_dof_index> &new_indices,
1582 std::vector<types::global_dof_index> &reverse,
1584 const typename std::vector<
1609 std::vector<bool> already_sorted(n_owned_dofs,
false);
1610 std::vector<types::global_dof_index> cell_dofs;
1614 unsigned int index = 0;
1616 for (
const auto &cell : cells)
1620 const unsigned int n_cell_dofs = cell->get_fe().n_dofs_per_cell();
1621 cell_dofs.resize(n_cell_dofs);
1623 cell->get_active_or_mg_dof_indices(cell_dofs);
1627 std::sort(cell_dofs.begin(), cell_dofs.end());
1629 for (
const auto dof : cell_dofs)
1631 const auto local_dof = owned_dofs.index_within_set(dof);
1633 !already_sorted[local_dof])
1635 already_sorted[local_dof] =
true;
1636 reverse[index++] = local_dof;
1640 Assert(index == n_owned_dofs,
1642 "Traversing over the given set of cells did not cover all "
1643 "degrees of freedom in the DoFHandler. Does the set of cells "
1644 "not include all active cells?"));
1647 new_indices[reverse[i]] = owned_dofs.nth_index_in_set(i);
1652 template <
int dim,
int spacedim>
1655 const unsigned int level,
1656 const typename std::vector<
1662 std::vector<types::global_dof_index> renumbering(dof.
n_dofs(
level));
1663 std::vector<types::global_dof_index> reverse(dof.
n_dofs(
level));
1671 template <
int dim,
int spacedim>
1674 std::vector<types::global_dof_index> &new_order,
1675 std::vector<types::global_dof_index> &reverse,
1677 const unsigned int level,
1678 const typename std::vector<
1692 std::vector<bool> already_sorted(n_global_dofs,
false);
1693 std::vector<types::global_dof_index> cell_dofs(n_cell_dofs);
1695 unsigned int global_index = 0;
1697 for (
const auto &cell : cells)
1701 cell->get_active_or_mg_dof_indices(cell_dofs);
1702 std::sort(cell_dofs.begin(), cell_dofs.end());
1704 for (
unsigned int i = 0; i < n_cell_dofs; ++i)
1706 if (!already_sorted[cell_dofs[i]])
1708 already_sorted[cell_dofs[i]] =
true;
1709 reverse[global_index++] = cell_dofs[i];
1713 Assert(global_index == n_global_dofs,
1715 "Traversing over the given set of cells did not cover all "
1716 "degrees of freedom in the DoFHandler. Does the set of cells "
1717 "not include all cells of the specified level?"));
1720 new_order[reverse[i]] = i;
1725 template <
int dim,
int spacedim>
1729 const bool dof_wise_renumbering)
1731 std::vector<types::global_dof_index> renumbering(dof.
n_dofs());
1732 std::vector<types::global_dof_index> reverse(dof.
n_dofs());
1734 renumbering, reverse, dof, direction, dof_wise_renumbering);
1741 template <
int dim,
int spacedim>
1744 std::vector<types::global_dof_index> &reverse,
1747 const bool dof_wise_renumbering)
1753 if (dof_wise_renumbering ==
false)
1755 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>
1761 comparator(direction);
1764 ordered_cells.push_back(cell);
1766 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
1778 const unsigned int n_dofs = dof.
n_dofs();
1779 std::vector<std::pair<Point<spacedim>,
unsigned int>>
1780 support_point_list(n_dofs);
1783 Assert(fe_collection[0].has_support_points(),
1786 for (
unsigned int comp = 0; comp < fe_collection.
size(); ++comp)
1788 Assert(fe_collection[comp].has_support_points(),
1794 quadrature_collection,
1797 std::vector<bool> already_touched(n_dofs,
false);
1799 std::vector<types::global_dof_index> local_dof_indices;
1803 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
1804 local_dof_indices.resize(dofs_per_cell);
1805 hp_fe_values.
reinit(cell);
1808 cell->get_active_or_mg_dof_indices(local_dof_indices);
1809 const std::vector<Point<spacedim>> &points =
1811 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1812 if (!already_touched[local_dof_indices[i]])
1814 support_point_list[local_dof_indices[i]].first = points[i];
1815 support_point_list[local_dof_indices[i]].second =
1816 local_dof_indices[i];
1817 already_touched[local_dof_indices[i]] =
true;
1822 std::sort(support_point_list.begin(),
1823 support_point_list.end(),
1826 new_indices[support_point_list[i].
second] = i;
1832 template <
int dim,
int spacedim>
1835 const unsigned int level,
1837 const bool dof_wise_renumbering)
1839 std::vector<types::global_dof_index> renumbering(dof.
n_dofs(
level));
1840 std::vector<types::global_dof_index> reverse(dof.
n_dofs(
level));
1842 renumbering, reverse, dof,
level, direction, dof_wise_renumbering);
1849 template <
int dim,
int spacedim>
1852 std::vector<types::global_dof_index> &reverse,
1854 const unsigned int level,
1856 const bool dof_wise_renumbering)
1858 if (dof_wise_renumbering ==
false)
1860 std::vector<typename DoFHandler<dim, spacedim>::level_cell_iterator>
1866 comparator(direction);
1875 ordered_cells.push_back(p);
1878 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
1887 std::vector<std::pair<Point<spacedim>,
unsigned int>>
1888 support_point_list(n_dofs);
1895 std::vector<bool> already_touched(dof.
n_dofs(),
false);
1898 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1903 for (; begin != end; ++begin)
1906 &begin_tria = begin;
1907 begin->get_active_or_mg_dof_indices(local_dof_indices);
1908 fe_values.
reinit(begin_tria);
1909 const std::vector<Point<spacedim>> &points =
1911 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1912 if (!already_touched[local_dof_indices[i]])
1914 support_point_list[local_dof_indices[i]].first = points[i];
1915 support_point_list[local_dof_indices[i]].second =
1916 local_dof_indices[i];
1917 already_touched[local_dof_indices[i]] =
true;
1922 std::sort(support_point_list.begin(),
1923 support_point_list.end(),
1926 new_indices[support_point_list[i].
second] = i;
1960 template <
class DHCellIterator>
1962 operator()(
const DHCellIterator &c1,
const DHCellIterator &c2)
const
1966 return compare(c1, c2, std::integral_constant<int, dim>());
1973 template <
class DHCellIterator,
int xdim>
1976 const DHCellIterator &c2,
1977 std::integral_constant<int, xdim>)
const
1981 const double s1 = std::atan2(
v1[0],
v1[1]);
1982 const double s2 = std::atan2(v2[0], v2[1]);
1983 return (
counter ? (s1 > s2) : (s2 > s1));
1991 template <
class DHCellIterator>
1994 const DHCellIterator &,
1995 std::integral_constant<int, 1>)
const
1998 ExcMessage(
"This operation only makes sense for dim>=2."));
2006 template <
int dim,
int spacedim>
2012 std::vector<types::global_dof_index> renumbering(dof.
n_dofs());
2020 template <
int dim,
int spacedim>
2027 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>
2033 ordered_cells.push_back(cell);
2035 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
2037 std::vector<types::global_dof_index> reverse(new_indices.size());
2043 template <
int dim,
int spacedim>
2046 const unsigned int level,
2050 std::vector<typename DoFHandler<dim, spacedim>::level_cell_iterator>
2062 ordered_cells.push_back(p);
2065 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
2072 template <
int dim,
int spacedim>
2076 std::vector<types::global_dof_index> renumbering(
2085 template <
int dim,
int spacedim>
2092 std::vector<types::global_dof_index> renumbering(
2103 template <
int dim,
int spacedim>
2109 Assert(new_indices.size() == n_dofs,
2112 std::iota(new_indices.begin(),
2120 ::boost::mt19937 random_number_generator;
2121 for (
unsigned int i = 1; i < n_dofs; ++i)
2124 const unsigned int j =
2125 ::boost::random::uniform_int_distribution<>(0, i)(
2126 random_number_generator);
2130 std::swap(new_indices[i], new_indices[j]);
2136 template <
int dim,
int spacedim>
2140 const unsigned int level)
2143 Assert(new_indices.size() == n_dofs,
2146 std::iota(new_indices.begin(),
2154 ::boost::mt19937 random_number_generator;
2155 for (
unsigned int i = 1; i < n_dofs; ++i)
2158 const unsigned int j =
2159 ::boost::random::uniform_int_distribution<>(0, i)(
2160 random_number_generator);
2164 std::swap(new_indices[i], new_indices[j]);
2170 template <
int dim,
int spacedim>
2178 "Parallel triangulations are already enumerated according to their MPI process id."));
2180 std::vector<types::global_dof_index> renumbering(
2189 template <
int dim,
int spacedim>
2195 Assert(new_dof_indices.size() == n_dofs,
2201 std::vector<types::subdomain_id> subdomain_association(n_dofs);
2203 const unsigned int n_subdomains =
2204 *std::max_element(subdomain_association.begin(),
2205 subdomain_association.end()) +
2215 std::fill(new_dof_indices.begin(),
2216 new_dof_indices.end(),
2222 if (subdomain_association[i] == subdomain)
2226 new_dof_indices[i] = next_free_index;
2232 Assert(std::find(new_dof_indices.begin(),
2233 new_dof_indices.end(),
2240 template <
int dim,
int spacedim>
2244 std::vector<types::global_dof_index> renumbering(
2257 template <
int dim,
int spacedim>
2260 std::vector<types::global_dof_index> &new_dof_indices,
2264 Assert(new_dof_indices.size() == n_dofs,
2276 std::vector<types::global_dof_index> component_renumbering(
2278 compute_component_wise<dim, spacedim>(component_renumbering,
2281 std::vector<unsigned int>(),
2286 const std::vector<types::global_dof_index> dofs_per_component =
2288 for (
const auto &dpc : dofs_per_component)
2292 const unsigned int n_components =
2296 dof_handler.
n_dofs() / n_components;
2302 if (component_renumbering.empty())
2304 new_dof_indices.resize(0);
2307 std::fill(new_dof_indices.begin(),
2308 new_dof_indices.end(),
2316 std::vector<types::global_dof_index> component_dofs(
2317 local_dofs_per_component);
2318 for (
unsigned int component = 0; component < n_components; ++component)
2320 for (std::size_t i = 0; i < local_dofs_per_component; ++i)
2322 component_renumbering[n_components * i + component];
2323 component_renumbered_dofs.
add_indices(component_dofs.begin(),
2324 component_dofs.end());
2326 component_renumbered_dofs.
compress();
2330 component_renumbered_dofs2.
add_indices(component_renumbering.begin(),
2331 component_renumbering.end());
2332 Assert(component_renumbered_dofs2 == component_renumbered_dofs,
2339 AssertThrow(fe.dofs_per_cell == 0 || fe.has_support_points(),
2341 for (
unsigned int i = 0; i < fe.n_base_elements(); ++i)
2343 fe.base_element(0).get_unit_support_points() ==
2344 fe.base_element(i).get_unit_support_points(),
2346 "All base elements should have the same support points."));
2349 std::vector<types::global_dof_index> component_to_nodal(
2353 std::vector<types::global_dof_index> cell_dofs;
2354 std::vector<types::global_dof_index> component_renumbered_cell_dofs;
2358 auto next_dof_it = locally_owned_dofs.
begin();
2360 if (cell->is_locally_owned())
2365 cell->get_dof_indices(cell_dofs);
2372 if (locally_owned_dofs.
is_element(cell_dofs[i]))
2374 const auto local_index =
2376 component_renumbered_cell_dofs[i] =
2377 component_renumbering[local_index];
2381 component_renumbered_cell_dofs[i] =
2390 component_renumbered_cell_dofs[i]))
2392 for (
unsigned int component = 0;
2399 const auto local_index =
2401 component_renumbered_cell_dofs[i] +
2402 dofs_per_component * component);
2404 if (component_to_nodal[local_index] ==
2407 component_to_nodal[local_index] = *next_dof_it;
2418 const auto local_index =
2420 new_dof_indices[i] = component_to_nodal[local_index];
2429 typename VectorizedArrayType>
2435 const std::vector<types::global_dof_index> new_global_numbers =
2445 template <
int dim,
int spacedim,
typename Number,
typename AdditionalDataType>
2449 const AdditionalDataType &matrix_free_data)
2451 const std::vector<types::global_dof_index> new_global_numbers =
2458 dof_handler.
renumber_dofs(matrix_free_data.mg_level, new_global_numbers);
2463 template <
int dim,
int spacedim,
typename Number,
typename AdditionalDataType>
2464 std::vector<types::global_dof_index>
2468 const AdditionalDataType &matrix_free_data)
2470 AdditionalDataType my_mf_data = matrix_free_data;
2471 my_mf_data.initialize_mapping =
false;
2472 my_mf_data.tasks_parallel_scheme = AdditionalDataType::none;
2474 typename AdditionalDataType::MatrixFreeType separate_matrix_free;
2493 std::vector<std::vector<unsigned int>>
2494 group_dofs_by_rank_access(
2495 const ::Utilities::MPI::Partitioner &partitioner)
2499 std::vector<unsigned int> touch_count(partitioner.locally_owned_size());
2500 for (
const auto &p : partitioner.import_indices())
2501 for (unsigned
int i = p.
first; i < p.second; ++i)
2505 std::vector<std::vector<unsigned int>> result(1);
2506 for (
unsigned int i = 0; i < touch_count.size(); ++i)
2507 if (touch_count[i] == 0)
2508 result.back().push_back(i);
2513 std::map<unsigned int, std::vector<unsigned int>>
2514 multiple_ranks_access_dof;
2515 const std::vector<std::pair<unsigned int, unsigned int>> &import_targets =
2516 partitioner.import_targets();
2517 auto it = partitioner.import_indices().begin();
2518 for (
const std::pair<unsigned int, unsigned int> &proc : import_targets)
2520 result.emplace_back();
2521 unsigned int count_dofs = 0;
2522 while (count_dofs < proc.second)
2524 for (
unsigned int i = it->first; i < it->second;
2527 if (touch_count[i] == 1)
2528 result.back().push_back(i);
2530 multiple_ranks_access_dof[i].push_back(proc.first);
2540 std::map<std::vector<unsigned int>,
2541 std::vector<unsigned int>,
2542 std::function<
bool(
const std::vector<unsigned int> &,
2543 const std::vector<unsigned int> &)>>
2544 dofs_by_rank{[](
const std::vector<unsigned int> &a,
2545 const std::vector<unsigned int> &
b) {
2546 if (a.size() <
b.size())
2548 if (a.size() ==
b.size())
2550 for (
unsigned int i = 0; i < a.size(); ++i)
2553 else if (a[i] > b[i])
2558 for (
const auto &entry : multiple_ranks_access_dof)
2559 dofs_by_rank[entry.
second].push_back(entry.
first);
2561 for (
const auto &procs : dofs_by_rank)
2562 result.push_back(procs.
second);
2573 template <
int dim,
typename Number,
typename VectorizedArrayType>
2574 std::pair<std::vector<unsigned int>, std::vector<unsigned char>>
2575 compute_mf_numbering(
2577 const unsigned int component)
2581 const unsigned int n_comp =
2584 matrix_free.
get_dof_handler(component).get_fe().n_base_elements() == 1,
2592 const unsigned int fe_degree =
2594 const unsigned int nn = fe_degree - 1;
2603 std::array<std::pair<unsigned int, unsigned int>,
2608 dofs_on_objects[0] = std::make_pair(0U, 1U);
2609 dofs_on_objects[1] = std::make_pair(2 * n_comp, nn);
2610 dofs_on_objects[2] = std::make_pair(n_comp, 1U);
2614 dofs_on_objects[0] = std::make_pair(0U, 1U);
2615 dofs_on_objects[1] = std::make_pair(n_comp * (4 + 2 * nn), nn);
2616 dofs_on_objects[2] = std::make_pair(n_comp, 1U);
2617 dofs_on_objects[3] = std::make_pair(n_comp * 4, nn);
2618 dofs_on_objects[4] = std::make_pair(n_comp * (4 + 4 * nn), nn * nn);
2619 dofs_on_objects[5] = std::make_pair(n_comp * (4 + 1 * nn), nn);
2620 dofs_on_objects[6] = std::make_pair(2 * n_comp, 1U);
2621 dofs_on_objects[7] = std::make_pair(n_comp * (4 + 3 * nn), nn);
2622 dofs_on_objects[8] = std::make_pair(3 * n_comp, 1U);
2626 dofs_on_objects[0] = std::make_pair(0U, 1U);
2627 dofs_on_objects[1] = std::make_pair(n_comp * (8 + 2 * nn), nn);
2628 dofs_on_objects[2] = std::make_pair(n_comp, 1U);
2629 dofs_on_objects[3] = std::make_pair(n_comp * 8, nn);
2630 dofs_on_objects[4] =
2631 std::make_pair(n_comp * (8 + 12 * nn + 4 * nn * nn), nn * nn);
2632 dofs_on_objects[5] = std::make_pair(n_comp * (8 + 1 * nn), nn);
2633 dofs_on_objects[6] = std::make_pair(n_comp * 2, 1U);
2634 dofs_on_objects[7] = std::make_pair(n_comp * (8 + 3 * nn), nn);
2635 dofs_on_objects[8] = std::make_pair(n_comp * 3, 1U);
2636 dofs_on_objects[9] = std::make_pair(n_comp * (8 + 8 * nn), nn);
2637 dofs_on_objects[10] =
2638 std::make_pair(n_comp * (8 + 12 * nn + 2 * nn * nn), nn * nn);
2639 dofs_on_objects[11] = std::make_pair(n_comp * (8 + 9 * nn), nn);
2640 dofs_on_objects[12] = std::make_pair(n_comp * (8 + 12 * nn), nn * nn);
2641 dofs_on_objects[13] =
2642 std::make_pair(n_comp * (8 + 12 * nn + 6 * nn * nn), nn * nn * nn);
2643 dofs_on_objects[14] =
2644 std::make_pair(n_comp * (8 + 12 * nn + 1 * nn * nn), nn * nn);
2645 dofs_on_objects[15] = std::make_pair(n_comp * (8 + 10 * nn), nn);
2646 dofs_on_objects[16] =
2647 std::make_pair(n_comp * (8 + 12 * nn + 3 * nn * nn), nn * nn);
2648 dofs_on_objects[17] = std::make_pair(n_comp * (8 + 11 * nn), nn);
2649 dofs_on_objects[18] = std::make_pair(n_comp * 4, 1U);
2650 dofs_on_objects[19] = std::make_pair(n_comp * (8 + 6 * nn), nn);
2651 dofs_on_objects[20] = std::make_pair(n_comp * 5, 1U);
2652 dofs_on_objects[21] = std::make_pair(n_comp * (8 + 4 * nn), nn);
2653 dofs_on_objects[22] =
2654 std::make_pair(n_comp * (8 + 12 * nn + 5 * nn * nn), nn * nn);
2655 dofs_on_objects[23] = std::make_pair(n_comp * (8 + 5 * nn), nn);
2656 dofs_on_objects[24] = std::make_pair(n_comp * 6, 1U);
2657 dofs_on_objects[25] = std::make_pair(n_comp * (8 + 7 * nn), nn);
2658 dofs_on_objects[26] = std::make_pair(n_comp * 7, 1U);
2663 std::vector<unsigned int> &result,
2664 unsigned int &counter_dof_numbers) {
2666 owned_dofs.index_within_set(dof_index);
2671 result[local_dof_index] = counter_dof_numbers++;
2675 unsigned int counter_dof_numbers = 0;
2676 std::vector<unsigned int> dofs_extracted;
2677 std::vector<types::global_dof_index> dof_indices(
2694 const unsigned int n_owned_dofs = owned_dofs.n_elements();
2695 std::vector<unsigned int> dof_numbers_mf_order(
2697 std::vector<unsigned int> last_touch_by_cell_batch_range(
2699 std::vector<unsigned char> touch_count(n_owned_dofs);
2701 const auto operation_on_cell_range =
2704 const unsigned int &,
2705 const std::pair<unsigned int, unsigned int> &cell_range) {
2706 for (
unsigned int cell = cell_range.first; cell < cell_range.second;
2710 for (
unsigned int v = 0;
2717 ->get_dof_indices(dof_indices);
2720 ->get_mg_dof_indices(dof_indices);
2722 for (
unsigned int a = 0; a < dofs_on_objects.size(); ++a)
2724 const auto &r = dofs_on_objects[a];
2725 if (a == 10 || a == 16)
2728 for (
unsigned int i1 = 0; i1 < nn; ++i1)
2729 for (
unsigned int i0 = 0; i0 < nn; ++i0)
2730 for (
unsigned int c = 0; c < n_comp; ++c)
2731 renumber_func(dof_indices[r.first + r.second * c +
2734 dof_numbers_mf_order,
2735 counter_dof_numbers);
2737 for (
unsigned int i = 0; i < r.second; ++i)
2738 for (
unsigned int c = 0; c < n_comp; ++c)
2740 dof_indices[r.first + r.second * c + i],
2742 dof_numbers_mf_order,
2743 counter_dof_numbers);
2752 dofs_extracted, cell);
2753 for (
const unsigned int dof_index : dofs_extracted)
2754 if (dof_index < n_owned_dofs &&
2755 last_touch_by_cell_batch_range[dof_index] !=
2758 ++touch_count[dof_index];
2759 last_touch_by_cell_batch_range[dof_index] =
2769 "version of MatrixFree::cell_loop"));
2771 matrix_free.template cell_loop<unsigned int, unsigned int>(
2772 operation_on_cell_range, counter_dof_numbers, counter_dof_numbers);
2776 return std::make_pair(dof_numbers_mf_order, touch_count);
2786 typename VectorizedArrayType>
2787 std::vector<types::global_dof_index>
2793 ExcMessage(
"You need to set up indices in MatrixFree "
2794 "to be able to compute a renumbering!"));
2797 unsigned int component = 0;
2798 for (; component < matrix_free.
n_components(); ++component)
2803 ExcMessage(
"Could not locate the given DoFHandler in MatrixFree"));
2815 const std::vector<std::vector<unsigned int>> dofs_by_rank_access =
2816 group_dofs_by_rank_access(
2819 const auto &[local_numbering, touch_count] =
2820 compute_mf_numbering(matrix_free, component);
2830 enum class Category :
unsigned char
2837 std::vector<Category> categories(locally_owned_size);
2838 for (
unsigned int i = 0; i < locally_owned_size; ++i)
2839 switch (touch_count[i])
2842 categories[local_numbering[i]] = Category::constrained;
2845 categories[local_numbering[i]] = Category::single;
2848 categories[local_numbering[i]] = Category::multiple;
2851 for (
unsigned int chunk = 1; chunk < dofs_by_rank_access.size(); ++chunk)
2852 for (
const auto i : dofs_by_rank_access[chunk])
2853 categories[local_numbering[i]] = Category::mpi_dof;
2857 std::array<unsigned int, 4> n_entries_per_category{};
2858 for (
const Category i : categories)
2861 ++n_entries_per_category[
static_cast<int>(i)];
2863 std::array<unsigned int, 4> counters{};
2864 for (
unsigned int i = 1; i < 4; ++i)
2865 counters[i] = counters[i - 1] + n_entries_per_category[i - 1];
2866 std::vector<unsigned int> numbering_categories;
2867 numbering_categories.reserve(locally_owned_size);
2868 for (
const Category category : categories)
2870 numbering_categories.push_back(counters[
static_cast<int>(category)]);
2871 ++counters[
static_cast<int>(category)];
2875 std::vector<::types::global_dof_index> new_global_numbers(
2876 locally_owned_size);
2877 for (
unsigned int i = 0; i < locally_owned_size; ++i)
2878 new_global_numbers[i] =
2881 return new_global_numbers;
2889#include "dof_renumbering.inst"
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_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 n_active_entries_per_cell_batch(const unsigned int cell_batch_index) 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
DoFHandler< dim >::cell_iterator get_cell_iterator(const unsigned int cell_batch_index, const unsigned int lane_index, const unsigned int dof_handler_index=0) const
bool indices_initialized() const
unsigned int n_components() const
virtual MPI_Comm get_communicator() 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
#define DEAL_II_NAMESPACE_CLOSE
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 & 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.
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
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 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)
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)
T sum(const T &t, const MPI_Comm mpi_communicator)
T max(const T &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)
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
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
void get_dof_indices_on_cell_batch(std::vector< unsigned int > &local_indices, const unsigned int cell_batch, const bool with_constraints=true) const
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
TasksParallelScheme scheme
#define DEAL_II_DOF_INDEX_MPI_TYPE