16 #include <deal.II/base/quadrature_lib.h> 17 #include <deal.II/base/template_constraints.h> 18 #include <deal.II/base/thread_management.h> 19 #include <deal.II/base/types.h> 20 #include <deal.II/base/utilities.h> 22 #include <deal.II/distributed/tria.h> 24 #include <deal.II/dofs/dof_accessor.h> 25 #include <deal.II/dofs/dof_handler.h> 26 #include <deal.II/dofs/dof_renumbering.h> 27 #include <deal.II/dofs/dof_tools.h> 29 #include <deal.II/fe/fe.h> 31 #include <deal.II/grid/tria.h> 32 #include <deal.II/grid/tria_iterator.h> 34 #include <deal.II/hp/dof_handler.h> 35 #include <deal.II/hp/fe_collection.h> 36 #include <deal.II/hp/fe_values.h> 38 #include <deal.II/lac/affine_constraints.h> 39 #include <deal.II/lac/dynamic_sparsity_pattern.h> 40 #include <deal.II/lac/sparsity_pattern.h> 41 #include <deal.II/lac/sparsity_tools.h> 43 #include <deal.II/multigrid/mg_tools.h> 45 #include <boost/config.hpp> 46 #include <boost/graph/adjacency_list.hpp> 47 #include <boost/graph/bandwidth.hpp> 48 #include <boost/graph/cuthill_mckee_ordering.hpp> 49 #include <boost/graph/king_ordering.hpp> 50 #include <boost/graph/minimum_degree_ordering.hpp> 51 #include <boost/graph/properties.hpp> 52 #include <boost/random.hpp> 53 #include <boost/random/uniform_int_distribution.hpp> 62 DEAL_II_NAMESPACE_OPEN
70 using namespace ::
boost;
73 using Graph = adjacency_list<vecS,
76 property<vertex_color_t,
78 property<vertex_degree_t, int>>>;
79 using Vertex = graph_traits<Graph>::vertex_descriptor;
80 using size_type = graph_traits<Graph>::vertices_size_type;
82 using Pair = std::pair<size_type, size_type>;
88 template <
typename DoFHandlerType>
90 create_graph(
const DoFHandlerType &dof_handler,
91 const bool use_constraints,
92 boosttypes::Graph & graph,
93 boosttypes::property_map<boosttypes::Graph,
94 boosttypes::vertex_degree_t>::type
105 dof_handler.n_dofs());
109 for (
unsigned int row = 0; row < dsp.n_rows(); ++row)
110 for (
unsigned int col = 0; col < dsp.row_length(row); ++col)
111 add_edge(row, dsp.column_number(row, col), graph);
114 boosttypes::graph_traits<boosttypes::Graph>::vertex_iterator ui, ui_end;
116 graph_degree =
get(::boost::vertex_degree, graph);
117 for (::boost::tie(ui, ui_end) = vertices(graph); ui != ui_end; ++ui)
118 graph_degree[*ui] = degree(*ui, graph);
123 template <
typename DoFHandlerType>
126 const bool reversed_numbering,
127 const bool use_constraints)
129 std::vector<types::global_dof_index> renumbering(
139 dof_handler.renumber_dofs(renumbering);
143 template <
typename DoFHandlerType>
146 const DoFHandlerType & dof_handler,
147 const bool reversed_numbering,
148 const bool use_constraints)
150 boosttypes::Graph graph(dof_handler.n_dofs());
151 boosttypes::property_map<boosttypes::Graph,
152 boosttypes::vertex_degree_t>::type graph_degree;
154 internal::create_graph(dof_handler, use_constraints, graph, graph_degree);
156 boosttypes::property_map<boosttypes::Graph,
157 boosttypes::vertex_index_t>::type index_map =
158 get(::boost::vertex_index, graph);
161 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
163 if (reversed_numbering ==
false)
164 ::boost::cuthill_mckee_ordering(graph,
166 get(::boost::vertex_color, graph),
167 make_degree_map(graph));
169 ::boost::cuthill_mckee_ordering(graph,
171 get(::boost::vertex_color, graph),
172 make_degree_map(graph));
174 for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
175 new_dof_indices[index_map[inv_perm[c]]] = c;
177 Assert(std::find(new_dof_indices.begin(),
178 new_dof_indices.end(),
185 template <
typename DoFHandlerType>
188 const bool reversed_numbering,
189 const bool use_constraints)
191 std::vector<types::global_dof_index> renumbering(
201 dof_handler.renumber_dofs(renumbering);
205 template <
typename DoFHandlerType>
208 const DoFHandlerType & dof_handler,
209 const bool reversed_numbering,
210 const bool use_constraints)
212 boosttypes::Graph graph(dof_handler.n_dofs());
213 boosttypes::property_map<boosttypes::Graph,
214 boosttypes::vertex_degree_t>::type graph_degree;
216 internal::create_graph(dof_handler, use_constraints, graph, graph_degree);
218 boosttypes::property_map<boosttypes::Graph,
219 boosttypes::vertex_index_t>::type index_map =
220 get(::boost::vertex_index, graph);
223 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
225 if (reversed_numbering ==
false)
226 ::boost::king_ordering(graph, inv_perm.rbegin());
228 ::boost::king_ordering(graph, inv_perm.begin());
230 for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
231 new_dof_indices[index_map[inv_perm[c]]] = c;
233 Assert(std::find(new_dof_indices.begin(),
234 new_dof_indices.end(),
241 template <
typename DoFHandlerType>
244 const bool reversed_numbering,
245 const bool use_constraints)
247 std::vector<types::global_dof_index> renumbering(
257 dof_handler.renumber_dofs(renumbering);
261 template <
typename DoFHandlerType>
264 std::vector<types::global_dof_index> &new_dof_indices,
265 const DoFHandlerType & dof_handler,
266 const bool reversed_numbering,
267 const bool use_constraints)
269 (void)use_constraints;
278 using namespace ::
boost;
283 using Graph = adjacency_list<vecS, vecS, directedS>;
285 int n = dof_handler.n_dofs();
289 std::vector<::types::global_dof_index> dofs_on_this_cell;
291 typename DoFHandlerType::active_cell_iterator cell = dof_handler
293 endc = dof_handler.end();
295 for (; cell != endc; ++cell)
297 const unsigned int dofs_per_cell = cell->get_fe().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)
344 Assert(std::find(perm.begin(), perm.end(), i) != perm.end(),
346 Assert(std::find(inverse_perm.begin(), inverse_perm.end(), 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 <
typename DoFHandlerType>
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(
372 dof_handler.locally_owned_dofs().n_elements(),
383 dof_handler.renumber_dofs(renumbering);
388 template <
typename DoFHandlerType>
391 std::vector<types::global_dof_index> & new_indices,
392 const DoFHandlerType & dof_handler,
393 const bool reversed_numbering,
394 const bool use_constraints,
395 const std::vector<types::global_dof_index> &starting_indices)
399 if (dof_handler.locally_owned_dofs().n_elements() == 0)
415 constraints.
reinit(locally_relevant_dofs);
420 const IndexSet &locally_owned_dofs = dof_handler.locally_owned_dofs();
433 if (reversed_numbering)
449 bool needs_locally_active =
false;
450 for (
const auto starting_index : starting_indices)
452 if ((needs_locally_active ==
454 (locally_owned_dofs.
is_element(starting_index) ==
false))
457 locally_active_dofs.
is_element(starting_index),
459 "You specified global degree of freedom " +
461 " as a starting index, but this index is not among the " 462 "locally active ones on this processor, as required " 463 "for this function."));
464 needs_locally_active =
true;
469 (needs_locally_active ? locally_active_dofs : locally_owned_dofs);
475 dof_handler.n_dofs(),
481 std::vector<types::global_dof_index> row_entries;
482 for (
unsigned int i = 0; i < index_set_to_use.
n_elements(); ++i)
486 const unsigned int row_length = dsp.row_length(row);
488 for (
unsigned int j = 0; j < row_length; ++j)
490 const unsigned int col = dsp.column_number(row, j);
491 if (col != row && index_set_to_use.
is_element(col))
494 local_sparsity.add_entries(i,
501 std::vector<types::global_dof_index> local_starting_indices(
502 starting_indices.size());
503 for (
unsigned int i = 0; i < starting_indices.size(); ++i)
504 local_starting_indices[i] =
509 std::vector<types::global_dof_index> my_new_indices(
513 local_starting_indices);
514 if (reversed_numbering)
523 if (needs_locally_active ==
true)
526 IndexSet active_but_not_owned_dofs = locally_active_dofs;
527 active_but_not_owned_dofs.
subtract_set(locally_owned_dofs);
529 std::set<types::global_dof_index> erase_these_indices;
530 for (
const auto p : active_but_not_owned_dofs)
535 erase_these_indices.insert(my_new_indices[index]);
538 Assert(erase_these_indices.size() ==
539 active_but_not_owned_dofs.n_elements(),
541 Assert(static_cast<unsigned int>(
542 std::count(my_new_indices.begin(),
543 my_new_indices.end(),
545 active_but_not_owned_dofs.n_elements(),
549 std::vector<types::global_dof_index> translate_indices(
550 my_new_indices.size());
552 std::set<types::global_dof_index>::const_iterator
553 next_erased_index = erase_these_indices.begin();
555 for (
unsigned int i = 0; i < translate_indices.size(); ++i)
556 if ((next_erased_index != erase_these_indices.end()) &&
557 (*next_erased_index == i))
564 translate_indices[i] = next_new_index;
574 new_indices.reserve(locally_owned_dofs.
n_elements());
575 for (
const auto &p : my_new_indices)
580 new_indices.push_back(translate_indices[p]);
586 new_indices = std::move(my_new_indices);
599 template <
typename DoFHandlerType>
602 const unsigned int level,
603 const bool reversed_numbering,
604 const std::vector<types::global_dof_index> &starting_indices)
611 dof_handler.n_dofs(level));
614 std::vector<types::global_dof_index> new_indices(dsp.n_rows());
617 if (reversed_numbering)
623 dof_handler.renumber_dofs(level, new_indices);
628 template <
typename DoFHandlerType>
631 const std::vector<unsigned int> &component_order_arg)
633 std::vector<types::global_dof_index> renumbering(
636 typename DoFHandlerType::active_cell_iterator start =
637 dof_handler.begin_active();
638 const typename DoFHandlerType::level_cell_iterator end = dof_handler.end();
642 DoFHandlerType::space_dimension>(
643 renumbering, start, end, component_order_arg,
false);
654 Assert((result == dof_handler.n_locally_owned_dofs()) ||
655 ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs()) &&
656 (result <= dof_handler.n_dofs())),
659 dof_handler.renumber_dofs(renumbering);
664 template <
typename DoFHandlerType>
667 const unsigned int level,
668 const std::vector<unsigned int> &component_order_arg)
673 std::vector<types::global_dof_index> renumbering(
674 dof_handler.locally_owned_mg_dofs(level).n_elements(),
677 typename DoFHandlerType::level_cell_iterator start =
678 dof_handler.begin(level);
679 typename DoFHandlerType::level_cell_iterator end = dof_handler.end(level);
683 DoFHandlerType::space_dimension>(
684 renumbering, start, end, component_order_arg,
true);
691 if (renumbering.size() != 0)
692 dof_handler.renumber_dofs(level, renumbering);
697 template <
int dim,
int spacedim,
typename CellIterator>
700 const CellIterator & start,
701 const typename identity<CellIterator>::type &end,
702 const std::vector<unsigned int> &component_order_arg,
703 const bool is_level_operation)
706 start->get_dof_handler().get_fe_collection());
710 if (fe_collection.n_components() == 1)
712 new_indices.resize(0);
719 const IndexSet &locally_owned_dofs =
721 start->get_dof_handler().locally_owned_mg_dofs(start->level()) :
722 start->get_dof_handler().locally_owned_dofs();
726 std::vector<unsigned int> component_order(component_order_arg);
731 if (component_order.size() == 0)
732 for (
unsigned int i = 0; i < fe_collection.n_components(); ++i)
733 component_order.push_back(i);
735 Assert(component_order.size() == fe_collection.n_components(),
737 fe_collection.n_components()));
739 for (
const unsigned int component : component_order)
747 std::vector<types::global_dof_index> local_dof_indices;
759 std::vector<std::vector<unsigned int>> component_list(fe_collection.size());
760 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
764 component_list[f].resize(dofs_per_cell);
765 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
767 component_list[f][i] =
771 const unsigned int comp =
777 component_list[f][i] = component_order[comp];
792 std::vector<std::vector<types::global_dof_index>> component_to_dof_map(
793 fe_collection.n_components());
794 for (CellIterator cell = start; cell != end; ++cell)
796 if (is_level_operation)
799 if (!cell->is_locally_owned_on_level())
806 if (!cell->is_locally_owned())
810 if (is_level_operation)
812 cell->level() == start->level(),
814 "Multigrid renumbering in compute_component_wise() needs to be applied to a single level!"));
819 const unsigned int fe_index = cell->active_fe_index();
820 const unsigned int dofs_per_cell =
821 fe_collection[fe_index].dofs_per_cell;
822 local_dof_indices.resize(dofs_per_cell);
823 cell->get_active_or_mg_dof_indices(local_dof_indices);
825 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
826 if (locally_owned_dofs.
is_element(local_dof_indices[i]))
827 component_to_dof_map[component_list[fe_index][i]].push_back(
828 local_dof_indices[i]);
854 for (
unsigned int component = 0; component < fe_collection.n_components();
857 std::sort(component_to_dof_map[component].begin(),
858 component_to_dof_map[component].end());
859 component_to_dof_map[component].erase(
860 std::unique(component_to_dof_map[component].begin(),
861 component_to_dof_map[component].end()),
862 component_to_dof_map[component].end());
867 const unsigned int n_buckets = fe_collection.n_components();
868 std::vector<types::global_dof_index> shifts(n_buckets);
872 &start->get_dof_handler().get_triangulation())))
874 #ifdef DEAL_II_WITH_MPI 875 std::vector<types::global_dof_index> local_dof_count(n_buckets);
877 for (
unsigned int c = 0; c < n_buckets; ++c)
878 local_dof_count[c] = component_to_dof_map[c].size();
882 std::vector<types::global_dof_index> all_dof_counts(
883 fe_collection.n_components() *
886 const int ierr = MPI_Allgather(local_dof_count.data(),
888 DEAL_II_DOF_INDEX_MPI_TYPE,
889 all_dof_counts.data(),
891 DEAL_II_DOF_INDEX_MPI_TYPE,
892 tria->get_communicator());
895 for (
unsigned int i = 0; i < n_buckets; ++i)
897 all_dof_counts[n_buckets * tria->locally_owned_subdomain() + i] ==
902 unsigned int cumulated = 0;
903 for (
unsigned int c = 0; c < n_buckets; ++c)
905 shifts[c] = cumulated;
908 shifts[c] += all_dof_counts[c + n_buckets * i];
909 for (
unsigned int i = 0;
912 cumulated += all_dof_counts[c + n_buckets * i];
922 for (
unsigned int c = 1; c < fe_collection.n_components(); ++c)
923 shifts[c] = shifts[c - 1] + component_to_dof_map[c - 1].size();
932 for (
unsigned int component = 0; component < fe_collection.n_components();
935 const typename std::vector<types::global_dof_index>::const_iterator
936 begin_of_component = component_to_dof_map[component].begin(),
937 end_of_component = component_to_dof_map[component].end();
939 next_free_index = shifts[component];
941 for (
typename std::vector<types::global_dof_index>::const_iterator
942 dof_index = begin_of_component;
943 dof_index != end_of_component;
954 return next_free_index;
959 template <
int dim,
int spacedim>
963 std::vector<types::global_dof_index> renumbering(
968 const typename DoFHandler<dim, spacedim>::level_cell_iterator end =
975 typename DoFHandler<dim, spacedim>::level_cell_iterator>(renumbering,
991 (result <= dof_handler.
n_dofs())),
999 template <
int dim,
int spacedim>
1003 std::vector<types::global_dof_index> renumbering(
1008 const typename hp::DoFHandler<dim, spacedim>::level_cell_iterator end =
1015 typename hp::DoFHandler<dim, spacedim>::level_cell_iterator>(renumbering,
1030 template <
int dim,
int spacedim>
1037 std::vector<types::global_dof_index> renumbering(
1041 typename DoFHandler<dim, spacedim>::level_cell_iterator start =
1042 dof_handler.
begin(level);
1043 typename DoFHandler<dim, spacedim>::level_cell_iterator end =
1044 dof_handler.
end(level);
1049 typename DoFHandler<dim, spacedim>::level_cell_iterator,
1050 typename DoFHandler<dim, spacedim>::level_cell_iterator>(renumbering,
1060 if (renumbering.size() != 0)
1066 template <
int dim,
int spacedim,
class ITERATOR,
class ENDITERATOR>
1069 const ITERATOR & start,
1070 const ENDITERATOR & end,
1071 const bool is_level_operation)
1074 start->get_dof_handler().get_fe_collection());
1078 if (fe_collection.n_blocks() == 1)
1080 new_indices.resize(0);
1087 const IndexSet &locally_owned_dofs =
1088 is_level_operation ?
1089 start->get_dof_handler().locally_owned_mg_dofs(start->level()) :
1090 start->get_dof_handler().locally_owned_dofs();
1094 std::vector<types::global_dof_index> local_dof_indices;
1099 std::vector<std::vector<types::global_dof_index>> block_list(
1100 fe_collection.size());
1101 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
1120 std::vector<std::vector<types::global_dof_index>> block_to_dof_map(
1121 fe_collection.n_blocks());
1122 for (ITERATOR cell = start; cell != end; ++cell)
1124 if (is_level_operation)
1127 if (!cell->is_locally_owned_on_level())
1134 if (!cell->is_locally_owned())
1138 if (is_level_operation)
1140 cell->level() == start->level(),
1142 "Multigrid renumbering in compute_block_wise() needs to be applied to a single level!"));
1147 const unsigned int fe_index = cell->active_fe_index();
1148 const unsigned int dofs_per_cell =
1149 fe_collection[fe_index].dofs_per_cell;
1150 local_dof_indices.resize(dofs_per_cell);
1151 cell->get_active_or_mg_dof_indices(local_dof_indices);
1153 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1154 if (locally_owned_dofs.
is_element(local_dof_indices[i]))
1155 block_to_dof_map[block_list[fe_index][i]].push_back(
1156 local_dof_indices[i]);
1171 for (
unsigned int block = 0; block < fe_collection.n_blocks(); ++block)
1173 std::sort(block_to_dof_map[block].begin(),
1174 block_to_dof_map[block].end());
1175 block_to_dof_map[block].erase(
1176 std::unique(block_to_dof_map[block].begin(),
1177 block_to_dof_map[block].end()),
1178 block_to_dof_map[block].end());
1183 const unsigned int n_buckets = fe_collection.n_blocks();
1184 std::vector<types::global_dof_index> shifts(n_buckets);
1188 &start->get_dof_handler().get_triangulation())))
1190 #ifdef DEAL_II_WITH_MPI 1191 std::vector<types::global_dof_index> local_dof_count(n_buckets);
1193 for (
unsigned int c = 0; c < n_buckets; ++c)
1194 local_dof_count[c] = block_to_dof_map[c].size();
1198 std::vector<types::global_dof_index> all_dof_counts(
1199 fe_collection.n_components() *
1202 const int ierr = MPI_Allgather(local_dof_count.data(),
1204 DEAL_II_DOF_INDEX_MPI_TYPE,
1205 all_dof_counts.data(),
1207 DEAL_II_DOF_INDEX_MPI_TYPE,
1208 tria->get_communicator());
1211 for (
unsigned int i = 0; i < n_buckets; ++i)
1213 all_dof_counts[n_buckets * tria->locally_owned_subdomain() + i] ==
1219 for (
unsigned int c = 0; c < n_buckets; ++c)
1221 shifts[c] = cumulated;
1224 shifts[c] += all_dof_counts[c + n_buckets * i];
1225 for (
unsigned int i = 0;
1228 cumulated += all_dof_counts[c + n_buckets * i];
1238 for (
unsigned int c = 1; c < fe_collection.n_blocks(); ++c)
1239 shifts[c] = shifts[c - 1] + block_to_dof_map[c - 1].size();
1248 for (
unsigned int block = 0; block < fe_collection.n_blocks(); ++block)
1250 const typename std::vector<types::global_dof_index>::const_iterator
1251 begin_of_component = block_to_dof_map[block].begin(),
1252 end_of_component = block_to_dof_map[block].end();
1254 next_free_index = shifts[block];
1256 for (
typename std::vector<types::global_dof_index>::const_iterator
1257 dof_index = begin_of_component;
1258 dof_index != end_of_component;
1269 return next_free_index;
1281 template <
int dim,
class CellIteratorType>
1283 compute_hierarchical_recursive(
1286 const CellIteratorType & cell,
1287 const IndexSet & locally_owned_dof_indices,
1288 std::vector<types::global_dof_index> &new_indices)
1291 next_free_dof_offset;
1293 if (cell->has_children())
1296 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1298 current_next_free_dof_offset =
1299 compute_hierarchical_recursive<dim>(current_next_free_dof_offset,
1302 locally_owned_dof_indices,
1322 if (cell->is_locally_owned())
1325 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1326 std::vector<types::global_dof_index> local_dof_indices(
1328 cell->get_dof_indices(local_dof_indices);
1347 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1348 if (locally_owned_dof_indices.
is_element(local_dof_indices[i]))
1352 const unsigned int idx =
1354 local_dof_indices[i]);
1358 my_starting_index + current_next_free_dof_offset;
1359 ++current_next_free_dof_offset;
1365 return current_next_free_dof_offset;
1371 template <
typename DoFHandlerType>
1375 const int dim = DoFHandlerType::dimension;
1376 const int spacedim = DoFHandlerType::space_dimension;
1378 std::vector<types::global_dof_index> renumbering(
1382 const IndexSet locally_owned = dof_handler.locally_owned_dofs();
1399 &dof_handler.get_triangulation()))
1401 const std::vector<types::global_dof_index>
1402 &n_locally_owned_dofs_per_processor =
1403 dof_handler.n_locally_owned_dofs_per_processor();
1405 std::accumulate(n_locally_owned_dofs_per_processor.begin(),
1406 n_locally_owned_dofs_per_processor.begin() +
1407 tria->locally_owned_subdomain(),
1413 *
>(&dof_handler.get_triangulation()))
1415 #ifdef DEAL_II_WITH_P4EST 1420 for (
unsigned int c = 0; c < tria->n_cells(0); ++c)
1422 const unsigned int coarse_cell_index =
1423 tria->get_p4est_tree_to_coarse_cell_permutation()[c];
1425 const typename DoFHandlerType::level_cell_iterator this_cell(
1426 tria, 0, coarse_cell_index, &dof_handler);
1428 next_free_dof_offset =
1429 compute_hierarchical_recursive<dim>(next_free_dof_offset,
1443 for (
typename DoFHandlerType::cell_iterator cell = dof_handler.begin(0);
1444 cell != dof_handler.end(0);
1446 next_free_dof_offset =
1447 compute_hierarchical_recursive<dim>(next_free_dof_offset,
1458 Assert((next_free_dof_offset == dof_handler.n_locally_owned_dofs()) ||
1459 ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs()) &&
1460 (next_free_dof_offset <= dof_handler.n_dofs())),
1464 Assert(std::find(renumbering.begin(),
1469 dof_handler.renumber_dofs(renumbering);
1474 template <
typename DoFHandlerType>
1477 const std::vector<bool> &selected_dofs)
1479 std::vector<types::global_dof_index> renumbering(
1483 dof_handler.renumber_dofs(renumbering);
1488 template <
typename DoFHandlerType>
1491 const std::vector<bool> &selected_dofs,
1492 const unsigned int level)
1497 std::vector<types::global_dof_index> renumbering(
1504 dof_handler.renumber_dofs(level, renumbering);
1509 template <
typename DoFHandlerType>
1512 std::vector<types::global_dof_index> &new_indices,
1513 const DoFHandlerType & dof_handler,
1514 const std::vector<bool> & selected_dofs)
1517 Assert(selected_dofs.size() == n_dofs,
1522 Assert(new_indices.size() == n_dofs,
1526 std::count(selected_dofs.begin(), selected_dofs.end(),
false);
1531 if (selected_dofs[i] ==
false)
1533 new_indices[i] = next_unselected;
1538 new_indices[i] = next_selected;
1547 template <
typename DoFHandlerType>
1550 std::vector<types::global_dof_index> &new_indices,
1551 const DoFHandlerType & dof_handler,
1552 const std::vector<bool> & selected_dofs,
1553 const unsigned int level)
1558 const unsigned int n_dofs = dof_handler.n_dofs(level);
1559 Assert(selected_dofs.size() == n_dofs,
1564 Assert(new_indices.size() == n_dofs,
1567 const unsigned int n_selected_dofs =
1568 std::count(selected_dofs.begin(), selected_dofs.end(),
false);
1570 unsigned int next_unselected = 0;
1571 unsigned int next_selected = n_selected_dofs;
1572 for (
unsigned int i = 0; i < n_dofs; ++i)
1573 if (selected_dofs[i] ==
false)
1575 new_indices[i] = next_unselected;
1580 new_indices[i] = next_selected;
1589 template <
typename DoFHandlerType>
1592 DoFHandlerType & dof,
1593 const std::vector<typename DoFHandlerType::active_cell_iterator> &cells)
1595 std::vector<types::global_dof_index> renumbering(
1596 dof.n_locally_owned_dofs());
1597 std::vector<types::global_dof_index> reverse(dof.n_locally_owned_dofs());
1600 dof.renumber_dofs(renumbering);
1604 template <
typename DoFHandlerType>
1607 std::vector<types::global_dof_index> &new_indices,
1608 std::vector<types::global_dof_index> &reverse,
1609 const DoFHandlerType & dof,
1610 const typename std::vector<typename DoFHandlerType::active_cell_iterator>
1614 DoFHandlerType::space_dimension> *p =
1617 DoFHandlerType::space_dimension
> *>(
1618 &dof.get_triangulation()))
1624 AssertDimension(cells.size(), dof.get_triangulation().n_active_cells());
1627 const auto n_owned_dofs = dof.n_locally_owned_dofs();
1638 std::vector<bool> already_sorted(n_owned_dofs,
false);
1639 std::vector<types::global_dof_index> cell_dofs;
1641 const auto &owned_dofs = dof.locally_owned_dofs();
1643 unsigned int index = 0;
1645 for (
const auto &cell : cells)
1649 const unsigned int n_cell_dofs = cell->get_fe().n_dofs_per_cell();
1650 cell_dofs.resize(n_cell_dofs);
1652 cell->get_active_or_mg_dof_indices(cell_dofs);
1656 std::sort(cell_dofs.begin(), cell_dofs.end());
1658 for (
const auto dof : cell_dofs)
1660 const auto local_dof = owned_dofs.index_within_set(dof);
1662 !already_sorted[local_dof])
1664 already_sorted[local_dof] =
true;
1665 reverse[index++] = local_dof;
1669 Assert(index == n_owned_dofs,
1671 "Traversing over the given set of cells did not cover all " 1672 "degrees of freedom in the DoFHandler. Does the set of cells " 1673 "not include all active cells?"));
1676 new_indices[reverse[i]] = owned_dofs.nth_index_in_set(i);
1681 template <
typename DoFHandlerType>
1684 DoFHandlerType & dof,
1685 const unsigned int level,
1686 const typename std::vector<typename DoFHandlerType::level_cell_iterator>
1692 std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1693 std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1696 dof.renumber_dofs(level, renumbering);
1701 template <
typename DoFHandlerType>
1704 std::vector<types::global_dof_index> &new_order,
1705 std::vector<types::global_dof_index> &reverse,
1706 const DoFHandlerType & dof,
1707 const unsigned int level,
1708 const typename std::vector<typename DoFHandlerType::level_cell_iterator>
1711 Assert(cells.size() == dof.get_triangulation().n_cells(level),
1713 dof.get_triangulation().n_cells(level)));
1714 Assert(new_order.size() == dof.n_dofs(level),
1716 Assert(reverse.size() == dof.n_dofs(level),
1719 unsigned int n_global_dofs = dof.n_dofs(level);
1720 unsigned int n_cell_dofs = dof.get_fe().n_dofs_per_cell();
1722 std::vector<bool> already_sorted(n_global_dofs,
false);
1723 std::vector<types::global_dof_index> cell_dofs(n_cell_dofs);
1727 for (
const auto &cell : cells)
1731 cell->get_active_or_mg_dof_indices(cell_dofs);
1732 std::sort(cell_dofs.begin(), cell_dofs.end());
1734 for (
unsigned int i = 0; i < n_cell_dofs; ++i)
1736 if (!already_sorted[cell_dofs[i]])
1738 already_sorted[cell_dofs[i]] =
true;
1743 Assert(global_index == n_global_dofs,
1745 "Traversing over the given set of cells did not cover all " 1746 "degrees of freedom in the DoFHandler. Does the set of cells " 1747 "not include all cells of the specified level?"));
1750 new_order[reverse[i]] = i;
1755 template <
typename DoFHandlerType>
1759 const bool dof_wise_renumbering)
1761 std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1762 std::vector<types::global_dof_index> reverse(dof.n_dofs());
1764 renumbering, reverse, dof, direction, dof_wise_renumbering);
1766 dof.renumber_dofs(renumbering);
1771 template <
typename DoFHandlerType>
1774 std::vector<types::global_dof_index> & new_indices,
1775 std::vector<types::global_dof_index> & reverse,
1776 const DoFHandlerType & dof,
1778 const bool dof_wise_renumbering)
1782 DoFHandlerType::space_dimension
> *>(
1783 &dof.get_triangulation()) ==
nullptr),
1786 if (dof_wise_renumbering ==
false)
1788 std::vector<typename DoFHandlerType::active_cell_iterator>
1790 ordered_cells.reserve(dof.get_triangulation().n_active_cells());
1792 DoFHandlerType::space_dimension>
1793 comparator(direction);
1795 typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
1796 typename DoFHandlerType::active_cell_iterator end = dof.end();
1800 ordered_cells.push_back(p);
1803 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
1815 const unsigned int n_dofs = dof.n_dofs();
1817 std::pair<Point<DoFHandlerType::space_dimension>,
unsigned int>>
1818 support_point_list(n_dofs);
1821 dof.get_fe_collection();
1822 Assert(fe_collection[0].has_support_points(),
1824 DoFHandlerType::dimension>::ExcFEHasNoSupportPoints());
1826 for (
unsigned int comp = 0; comp < fe_collection.
size(); ++comp)
1828 Assert(fe_collection[comp].has_support_points(),
1830 DoFHandlerType::dimension>::ExcFEHasNoSupportPoints());
1833 fe_collection[comp].get_unit_support_points()));
1836 hp_fe_values(fe_collection,
1837 quadrature_collection,
1840 std::vector<bool> already_touched(n_dofs,
false);
1842 std::vector<types::global_dof_index> local_dof_indices;
1843 typename DoFHandlerType::active_cell_iterator begin =
1845 typename DoFHandlerType::active_cell_iterator end = dof.end();
1846 for (; begin != end; ++begin)
1848 const unsigned int dofs_per_cell = begin->get_fe().dofs_per_cell;
1849 local_dof_indices.resize(dofs_per_cell);
1850 hp_fe_values.
reinit(begin);
1852 hp_fe_values.get_present_fe_values();
1853 begin->get_active_or_mg_dof_indices(local_dof_indices);
1854 const std::vector<Point<DoFHandlerType::space_dimension>> &points =
1856 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1857 if (!already_touched[local_dof_indices[i]])
1859 support_point_list[local_dof_indices[i]].first = points[i];
1860 support_point_list[local_dof_indices[i]].second =
1861 local_dof_indices[i];
1862 already_touched[local_dof_indices[i]] =
true;
1868 std::sort(support_point_list.begin(),
1869 support_point_list.end(),
1872 new_indices[support_point_list[i].second] = i;
1878 template <
typename DoFHandlerType>
1881 const unsigned int level,
1883 const bool dof_wise_renumbering)
1885 std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1886 std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1888 renumbering, reverse, dof, level, direction, dof_wise_renumbering);
1890 dof.renumber_dofs(level, renumbering);
1895 template <
typename DoFHandlerType>
1898 std::vector<types::global_dof_index> & new_indices,
1899 std::vector<types::global_dof_index> & reverse,
1900 const DoFHandlerType & dof,
1901 const unsigned int level,
1903 const bool dof_wise_renumbering)
1905 if (dof_wise_renumbering ==
false)
1907 std::vector<typename DoFHandlerType::level_cell_iterator> ordered_cells;
1908 ordered_cells.reserve(dof.get_triangulation().n_cells(level));
1910 DoFHandlerType::space_dimension>
1911 comparator(direction);
1913 typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
1914 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1918 ordered_cells.push_back(p);
1921 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
1927 Assert(dof.get_fe().has_support_points(),
1929 DoFHandlerType::dimension>::ExcFEHasNoSupportPoints());
1930 const unsigned int n_dofs = dof.n_dofs(level);
1932 std::pair<Point<DoFHandlerType::space_dimension>,
unsigned int>>
1933 support_point_list(n_dofs);
1936 dof.get_fe().get_unit_support_points());
1940 std::vector<bool> already_touched(dof.n_dofs(),
false);
1942 const unsigned int dofs_per_cell = dof.
get_fe().dofs_per_cell;
1943 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1944 typename DoFHandlerType::level_cell_iterator begin = dof.begin(level);
1945 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1946 for (; begin != end; ++begin)
1949 DoFHandlerType::dimension,
1950 DoFHandlerType::space_dimension>::cell_iterator &begin_tria =
1952 begin->get_active_or_mg_dof_indices(local_dof_indices);
1953 fe_values.reinit(begin_tria);
1954 const std::vector<Point<DoFHandlerType::space_dimension>> &points =
1955 fe_values.get_quadrature_points();
1956 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1957 if (!already_touched[local_dof_indices[i]])
1959 support_point_list[local_dof_indices[i]].first = points[i];
1960 support_point_list[local_dof_indices[i]].second =
1961 local_dof_indices[i];
1962 already_touched[local_dof_indices[i]] =
true;
1968 std::sort(support_point_list.begin(),
1969 support_point_list.end(),
1972 new_indices[support_point_list[i].second] = i;
1998 ClockCells(
const Point<dim> ¢er,
bool counter)
2006 template <
class DHCellIterator>
2008 operator()(
const DHCellIterator &c1,
const DHCellIterator &c2)
const 2012 return compare(c1, c2, std::integral_constant<int, dim>());
2019 template <
class DHCellIterator,
int xdim>
2021 compare(
const DHCellIterator &c1,
2022 const DHCellIterator &c2,
2023 std::integral_constant<int, xdim>)
const 2027 const double s1 = std::atan2(v1[0], v1[1]);
2028 const double s2 = std::atan2(v2[0], v2[1]);
2029 return (counter ? (s1 > s2) : (s2 > s1));
2037 template <
class DHCellIterator>
2039 compare(
const DHCellIterator &,
2040 const DHCellIterator &,
2041 std::integral_constant<int, 1>)
const 2044 ExcMessage(
"This operation only makes sense for dim>=2."));
2052 template <
typename DoFHandlerType>
2058 std::vector<types::global_dof_index> renumbering(dof.n_dofs());
2061 dof.renumber_dofs(renumbering);
2066 template <
typename DoFHandlerType>
2069 const DoFHandlerType & dof,
2073 std::vector<typename DoFHandlerType::active_cell_iterator> ordered_cells;
2074 ordered_cells.reserve(dof.get_triangulation().n_active_cells());
2075 internal::ClockCells<DoFHandlerType::space_dimension> comparator(center,
2078 typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
2079 typename DoFHandlerType::active_cell_iterator end = dof.end();
2083 ordered_cells.push_back(p);
2086 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
2088 std::vector<types::global_dof_index> reverse(new_indices.size());
2094 template <
typename DoFHandlerType>
2097 const unsigned int level,
2101 std::vector<typename DoFHandlerType::level_cell_iterator> ordered_cells;
2102 ordered_cells.reserve(dof.get_triangulation().n_active_cells());
2103 internal::ClockCells<DoFHandlerType::space_dimension> comparator(center,
2106 typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
2107 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
2111 ordered_cells.push_back(p);
2114 std::sort(ordered_cells.begin(), ordered_cells.end(), comparator);
2121 template <
typename DoFHandlerType>
2125 std::vector<types::global_dof_index> renumbering(
2129 dof_handler.renumber_dofs(renumbering);
2134 template <
typename DoFHandlerType>
2136 random(DoFHandlerType &dof_handler,
const unsigned int level)
2141 std::vector<types::global_dof_index> renumbering(
2142 dof_handler.locally_owned_mg_dofs(level).n_elements(),
2147 dof_handler.renumber_dofs(level, renumbering);
2152 template <
typename DoFHandlerType>
2155 const DoFHandlerType & dof_handler)
2158 Assert(new_indices.size() == n_dofs,
2161 for (
unsigned int i = 0; i < n_dofs; ++i)
2166 ::boost::mt19937 random_number_generator;
2167 for (
unsigned int i = 1; i < n_dofs; ++i)
2170 const unsigned int j =
2171 ::boost::random::uniform_int_distribution<>(0, i)(
2172 random_number_generator);
2176 std::swap(new_indices[i], new_indices[j]);
2182 template <
typename DoFHandlerType>
2185 const DoFHandlerType & dof_handler,
2186 const unsigned int level)
2189 Assert(new_indices.size() == n_dofs,
2192 for (
unsigned int i = 0; i < n_dofs; ++i)
2197 ::boost::mt19937 random_number_generator;
2198 for (
unsigned int i = 1; i < n_dofs; ++i)
2201 const unsigned int j =
2202 ::boost::random::uniform_int_distribution<>(0, i)(
2203 random_number_generator);
2207 std::swap(new_indices[i], new_indices[j]);
2213 template <
typename DoFHandlerType>
2220 DoFHandlerType::space_dimension
> *>(
2221 &dof_handler.get_triangulation())),
2223 "Parallel triangulations are already enumerated according to their MPI process id."));
2225 std::vector<types::global_dof_index> renumbering(
2229 dof_handler.renumber_dofs(renumbering);
2234 template <
typename DoFHandlerType>
2237 const DoFHandlerType & dof_handler)
2240 Assert(new_dof_indices.size() == n_dofs,
2246 std::vector<types::subdomain_id> subdomain_association(n_dofs);
2248 const unsigned int n_subdomains =
2249 *std::max_element(subdomain_association.begin(),
2250 subdomain_association.end()) +
2260 std::fill(new_dof_indices.begin(),
2261 new_dof_indices.end(),
2267 if (subdomain_association[i] == subdomain)
2271 new_dof_indices[i] = next_free_index;
2277 Assert(std::find(new_dof_indices.begin(),
2278 new_dof_indices.end(),
2288 #include "dof_renumbering.inst" 2291 DEAL_II_NAMESPACE_CLOSE
void compute_downstream(std::vector< types::global_dof_index > &new_dof_indices, std::vector< types::global_dof_index > &reverse, const DoFHandlerType &dof_handler, const Tensor< 1, DoFHandlerType::space_dimension > &direction, const bool dof_wise_renumbering)
#define AssertDimension(dim1, dim2)
void downstream(DoFHandlerType &dof_handler, const Tensor< 1, DoFHandlerType::space_dimension > &direction, const bool dof_wise_renumbering=false)
cell_iterator begin(const unsigned int level=0) const
void minimum_degree(DoFHandlerType &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false)
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
void compute_cell_wise(std::vector< types::global_dof_index > &renumbering, std::vector< types::global_dof_index > &inverse_renumbering, const DoFHandlerType &dof_handler, const std::vector< typename DoFHandlerType::active_cell_iterator > &cell_order)
size_type nth_index_in_set(const unsigned int local_index) const
void compute_king_ordering(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &, const bool reversed_numbering=false, const bool use_constraints=false)
void sort_selected_dofs_back(DoFHandlerType &dof_handler, const std::vector< bool > &selected_dofs)
cell_iterator end() const
#define AssertIndexRange(index, range)
active_cell_iterator begin_active(const unsigned int level=0) const
const FiniteElement< dim, spacedim > & get_fe() const
void component_wise(DoFHandlerType &dof_handler, const std::vector< unsigned int > &target_component=std::vector< unsigned int >())
unsigned int size() const
Transformed quadrature points.
types::global_dof_index compute_component_wise(std::vector< types::global_dof_index > &new_dof_indices, const CellIterator &start, const typename identity< CellIterator >::type &end, const std::vector< unsigned int > &target_component, const bool is_level_operation)
bool is_primitive() const
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
void make_hanging_node_constraints(const DoFHandlerType &dof_handler, AffineConstraints< number > &constraints)
LinearAlgebra::distributed::Vector< Number > Vector
static ::ExceptionBase & ExcDoFHandlerNotInitialized()
typename ActiveSelector::active_cell_iterator active_cell_iterator
active_cell_iterator begin_active(const unsigned int level=0) const
const std::vector< Point< spacedim > > & get_quadrature_points() const
unsigned int n_locally_owned_dofs() const
void random(DoFHandlerType &dof_handler)
static ::ExceptionBase & ExcMessage(std::string arg1)
void compute_minimum_degree(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &, const bool reversed_numbering=false, const bool use_constraints=false)
unsigned int subdomain_id
void Cuthill_McKee(DoFHandlerType &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false)
void subtract_set(const IndexSet &other)
#define Assert(cond, exc)
void compute_subdomain_wise(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &dof_handler)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
size_type index_within_set(const size_type global_index) const
const ComponentMask & get_nonzero_components(const unsigned int i) const
types::global_dof_index n_dofs() const
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType, 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)
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
void compute_random(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &dof_handler)
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
void compute_sort_selected_dofs_back(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &dof_handler, const std::vector< bool > &selected_dofs)
const unsigned int dofs_per_cell
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
void swap(Vector< Number > &u, Vector< Number > &v)
void reinit(const IndexSet &local_constraints=IndexSet())
unsigned int global_dof_index
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
#define AssertThrowMPI(error_code)
void compute_clockwise_dg(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &dof_handler, const Point< DoFHandlerType::space_dimension > ¢er, const bool counter)
void king_ordering(DoFHandlerType &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false)
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
void hierarchical(DoFHandlerType &dof_handler)
void block_wise(DoFHandler< dim, spacedim > &dof_handler)
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
void compute_Cuthill_McKee(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &, const bool reversed_numbering=false, const bool use_constraints=false)
types::global_dof_index n_dofs() const
std::vector< unsigned int > reverse_permutation(const std::vector< unsigned int > &permutation)
static ::ExceptionBase & ExcNotImplemented()
TrilinosWrappers::types::int_type global_index(const Epetra_BlockMap &map, const ::types::global_dof_index i)
bool is_element(const size_type index) const
void subdomain_wise(DoFHandlerType &dof_handler)
typename ActiveSelector::active_cell_iterator active_cell_iterator
void clockwise_dg(DoFHandlerType &dof_handler, const Point< DoFHandlerType::space_dimension > ¢er, const bool counter=false)
const types::global_dof_index invalid_dof_index
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
types::global_dof_index compute_block_wise(std::vector< types::global_dof_index > &new_dof_indices, const ITERATOR &start, const ENDITERATOR &end, bool is_level_operation)
size_type n_elements() const
void push_back(const Quadrature< dim > &new_quadrature)
cell_iterator end() const
static ::ExceptionBase & ExcInternalError()
void cell_wise(DoFHandlerType &dof_handler, const std::vector< typename DoFHandlerType::active_cell_iterator > &cell_order)