16 #include <deal.II/base/thread_management.h> 17 #include <deal.II/base/utilities.h> 18 #include <deal.II/base/quadrature_lib.h> 19 #include <deal.II/base/types.h> 20 #include <deal.II/base/template_constraints.h> 22 #include <deal.II/lac/sparsity_pattern.h> 23 #include <deal.II/lac/sparsity_tools.h> 24 #include <deal.II/lac/dynamic_sparsity_pattern.h> 25 #include <deal.II/lac/constraint_matrix.h> 27 #include <deal.II/dofs/dof_accessor.h> 28 #include <deal.II/dofs/dof_handler.h> 29 #include <deal.II/dofs/dof_tools.h> 30 #include <deal.II/dofs/dof_renumbering.h> 32 #include <deal.II/grid/tria_iterator.h> 33 #include <deal.II/grid/tria.h> 35 #include <deal.II/fe/fe.h> 36 #include <deal.II/hp/dof_handler.h> 37 #include <deal.II/hp/fe_collection.h> 38 #include <deal.II/hp/fe_values.h> 40 #include <deal.II/multigrid/mg_tools.h> 42 #include <deal.II/distributed/tria.h> 44 #include <boost/config.hpp> 45 #include <boost/graph/adjacency_list.hpp> 46 #include <boost/graph/cuthill_mckee_ordering.hpp> 47 #include <boost/graph/king_ordering.hpp> 48 #include <boost/graph/minimum_degree_ordering.hpp> 49 #include <boost/graph/properties.hpp> 50 #include <boost/graph/bandwidth.hpp> 51 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
52 #include <boost/random.hpp> 53 #include <boost/random/uniform_int_distribution.hpp> 54 DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
63 DEAL_II_NAMESPACE_OPEN
71 using namespace ::boost;
74 typedef adjacency_list<vecS, vecS, undirectedS,
75 property<vertex_color_t, default_color_type,
76 property<vertex_degree_t,int> > > Graph;
77 typedef graph_traits<Graph>::vertex_descriptor Vertex;
78 typedef graph_traits<Graph>::vertices_size_type
size_type;
80 typedef std::pair<size_type, size_type> Pair;
86 template <
typename DoFHandlerType>
88 (
const DoFHandlerType &dof_handler,
89 const bool use_constraints,
90 boosttypes::Graph &graph,
91 boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type &graph_degree)
100 constraints.
close ();
102 dof_handler.n_dofs());
106 for (
unsigned int row=0; row<dsp.n_rows(); ++row)
107 for (
unsigned int col=0; col < dsp.row_length(row); ++col)
108 add_edge (row, dsp.column_number (row, col), graph);
111 boosttypes::graph_traits<boosttypes::Graph>::vertex_iterator ui, ui_end;
113 graph_degree =
get(::boost::vertex_degree, graph);
114 for (::boost::tie(ui, ui_end) = vertices(graph); ui != ui_end; ++ui)
115 graph_degree[*ui] = degree(*ui, graph);
120 template <
typename DoFHandlerType>
123 const bool reversed_numbering,
124 const bool use_constraints)
126 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
127 DoFHandlerType::invalid_dof_index);
134 dof_handler.renumber_dofs (renumbering);
138 template <
typename DoFHandlerType>
141 const DoFHandlerType &dof_handler,
142 const bool reversed_numbering,
143 const bool use_constraints)
146 graph(dof_handler.n_dofs());
147 boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type
150 internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
152 boosttypes::property_map<boosttypes::Graph, boosttypes::vertex_index_t>::type
153 index_map =
get(::boost::vertex_index, graph);
156 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
158 if (reversed_numbering ==
false)
159 ::boost::cuthill_mckee_ordering(graph, inv_perm.rbegin(),
160 get(::boost::vertex_color, graph),
161 make_degree_map(graph));
163 ::boost::cuthill_mckee_ordering(graph, inv_perm.begin(),
164 get(::boost::vertex_color, graph),
165 make_degree_map(graph));
167 for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
168 new_dof_indices[index_map[inv_perm[c]]] = c;
170 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
171 DoFHandlerType::invalid_dof_index) == new_dof_indices.end(),
177 template <
typename DoFHandlerType>
180 const bool reversed_numbering,
181 const bool use_constraints)
183 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
184 DoFHandlerType::invalid_dof_index);
191 dof_handler.renumber_dofs (renumbering);
195 template <
typename DoFHandlerType>
198 const DoFHandlerType &dof_handler,
199 const bool reversed_numbering,
200 const bool use_constraints)
203 graph(dof_handler.n_dofs());
204 boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type
207 internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
209 boosttypes::property_map<boosttypes::Graph, boosttypes::vertex_index_t>::type
210 index_map =
get(::boost::vertex_index, graph);
213 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
215 if (reversed_numbering ==
false)
216 ::boost::king_ordering(graph, inv_perm.rbegin());
218 ::boost::king_ordering(graph, inv_perm.begin());
220 for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
221 new_dof_indices[index_map[inv_perm[c]]] = c;
223 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
224 DoFHandlerType::invalid_dof_index) == new_dof_indices.end(),
230 template <
typename DoFHandlerType>
233 const bool reversed_numbering,
234 const bool use_constraints)
236 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
237 DoFHandlerType::invalid_dof_index);
244 dof_handler.renumber_dofs (renumbering);
248 template <
typename DoFHandlerType>
251 const DoFHandlerType &dof_handler,
252 const bool reversed_numbering,
253 const bool use_constraints)
255 (void)use_constraints;
264 using namespace ::boost;
269 typedef adjacency_list<vecS, vecS, directedS> Graph;
271 int n = dof_handler.n_dofs();
275 std::vector<::types::global_dof_index> dofs_on_this_cell;
277 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
278 endc = dof_handler.end();
280 for (; cell!=endc; ++cell)
283 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
285 dofs_on_this_cell.resize (dofs_per_cell);
287 cell->get_active_or_mg_dof_indices (dofs_on_this_cell);
288 for (
unsigned int i=0; i<dofs_per_cell; ++i)
289 for (
unsigned int j=0; j<dofs_per_cell; ++j)
290 if (dofs_on_this_cell[i] > dofs_on_this_cell[j])
292 add_edge (dofs_on_this_cell[i], dofs_on_this_cell[j], G);
293 add_edge (dofs_on_this_cell[j], dofs_on_this_cell[i], G);
298 typedef std::vector<int>
Vector;
301 Vector inverse_perm(n, 0);
306 Vector supernode_sizes(n, 1);
309 ::boost::property_map<Graph, vertex_index_t>::type
310 id =
get(vertex_index, G);
316 minimum_degree_ordering
318 make_iterator_property_map(°ree[0],
id, degree[0]),
321 make_iterator_property_map(&supernode_sizes[0],
id, supernode_sizes[0]),
325 for (
int i=0; i<n; ++i)
331 != inverse_perm.
end(),
336 if (reversed_numbering ==
true)
337 std::copy (perm.
begin(), perm.
end(),
338 new_dof_indices.begin());
340 std::copy (inverse_perm.
begin(), inverse_perm.
end(),
341 new_dof_indices.begin());
348 template <
typename DoFHandlerType>
351 const bool reversed_numbering,
352 const bool use_constraints,
353 const std::vector<types::global_dof_index> &starting_indices)
355 std::vector<types::global_dof_index> renumbering(dof_handler.locally_owned_dofs().n_elements(),
356 DoFHandlerType::invalid_dof_index);
358 use_constraints, starting_indices);
363 dof_handler.renumber_dofs (renumbering);
368 template <
typename DoFHandlerType>
371 const DoFHandlerType &dof_handler,
372 const bool reversed_numbering,
373 const bool use_constraints,
374 const std::vector<types::global_dof_index> &starting_indices)
377 if (dof_handler.locally_owned_dofs().n_elements() == 0)
395 constraints.
reinit(relevant_dofs);
398 constraints.
close ();
400 const IndexSet locally_owned = dof_handler.locally_owned_dofs();
404 dof_handler.n_dofs(),
409 constraints.
clear ();
419 std::vector<types::global_dof_index> row_entries;
420 for (
unsigned int i=0; i<locally_owned.
n_elements(); ++i)
423 const unsigned int row_length = dsp.row_length(row);
425 for (
unsigned int j=0; j<row_length; ++j)
427 const unsigned int col = dsp.column_number(row, j);
428 if (col != row && locally_owned.
is_element(col))
431 sparsity.add_entries(i, row_entries.begin(), row_entries.end(),
436 std::vector<types::global_dof_index> local_starting_indices (starting_indices.size());
437 for (
unsigned int i=0; i<starting_indices.size(); ++i)
440 ExcMessage (
"You specified global degree of freedom " 442 " as a starting index, but this index is not among the " 443 "locally owned ones on this processor."));
444 local_starting_indices[i] = locally_owned.
index_within_set(starting_indices[i]);
450 local_starting_indices);
451 if (reversed_numbering)
455 for (std::size_t i=0; i<new_indices.size(); ++i)
463 if (reversed_numbering)
470 template <
typename DoFHandlerType>
472 const unsigned int level,
473 const bool reversed_numbering,
474 const std::vector<types::global_dof_index> &starting_indices)
481 dof_handler.n_dofs(level));
484 std::vector<types::global_dof_index> new_indices(dsp.n_rows());
488 if (reversed_numbering)
494 dof_handler.renumber_dofs (level, new_indices);
499 template <
int dim,
int spacedim>
502 const std::vector<unsigned int> &component_order_arg)
509 const typename DoFHandler<dim,spacedim>::level_cell_iterator
510 end = dof_handler.
end();
515 typename DoFHandler<dim,spacedim>::level_cell_iterator>
516 (renumbering, start, end, component_order_arg,
false);
531 (result <= dof_handler.
n_dofs())),
546 const std::vector<unsigned int> &component_order_arg)
549 std::vector<types::global_dof_index> renumbering (dof_handler.
n_dofs(),
554 const typename hp::DoFHandler<dim>::level_cell_iterator
555 end = dof_handler.
end();
560 typename hp::DoFHandler<dim>::level_cell_iterator>
561 (renumbering, start, end, component_order_arg,
false);
563 if (result == 0)
return;
573 template <
typename DoFHandlerType>
576 const unsigned int level,
577 const std::vector<unsigned int> &component_order_arg)
582 std::vector<types::global_dof_index> renumbering (dof_handler.n_dofs(level),
583 DoFHandlerType::invalid_dof_index);
585 typename DoFHandlerType::level_cell_iterator start =dof_handler.begin(level);
586 typename DoFHandlerType::level_cell_iterator end = dof_handler.end(level);
590 typename DoFHandlerType::level_cell_iterator,
typename DoFHandlerType::level_cell_iterator>
591 (renumbering, start, end, component_order_arg,
true);
593 if (result == 0)
return;
595 Assert (result == dof_handler.n_dofs(level),
598 if (renumbering.size()!=0)
599 dof_handler.renumber_dofs (level, renumbering);
604 template <
int dim,
int spacedim,
class ITERATOR,
class ENDITERATOR>
607 const ITERATOR &start,
608 const ENDITERATOR &end,
609 const std::vector<unsigned int> &component_order_arg,
610 bool is_level_operation)
613 fe_collection (start->get_dof_handler().get_fe ());
617 if (fe_collection.n_components() == 1)
619 new_indices.resize(0);
625 std::vector<unsigned int> component_order (component_order_arg);
630 if (component_order.size() == 0)
631 for (
unsigned int i=0; i<fe_collection.n_components(); ++i)
632 component_order.push_back (i);
634 Assert (component_order.size() == fe_collection.n_components(),
637 for (
unsigned int i=0; i<component_order.size(); ++i)
638 Assert(component_order[i] < fe_collection.n_components(),
639 ExcIndexRange(component_order[i], 0, fe_collection.n_components()));
643 std::vector<types::global_dof_index> local_dof_indices;
655 std::vector<std::vector<unsigned int> > component_list (fe_collection.size());
656 for (
unsigned int f=0; f<fe_collection.size(); ++f)
660 component_list[f].resize(dofs_per_cell);
661 for (
unsigned int i=0; i<dofs_per_cell; ++i)
667 const unsigned int comp
673 component_list[f][i] = component_order[comp];
688 std::vector<std::vector<types::global_dof_index> >
689 component_to_dof_map (fe_collection.n_components());
690 for (ITERATOR cell=start; cell!=end; ++cell)
692 if (is_level_operation)
695 if (!cell->is_locally_owned_on_level())
702 if (!cell->is_locally_owned())
708 const unsigned int fe_index = cell->active_fe_index();
709 const unsigned int dofs_per_cell = fe_collection[fe_index].dofs_per_cell;
710 local_dof_indices.resize (dofs_per_cell);
711 cell->get_active_or_mg_dof_indices (local_dof_indices);
712 for (
unsigned int i=0; i<dofs_per_cell; ++i)
713 if (start->get_dof_handler().locally_owned_dofs().is_element(local_dof_indices[i]))
714 component_to_dof_map[component_list[fe_index][i]].
715 push_back (local_dof_indices[i]);
741 for (
unsigned int component=0; component<fe_collection.n_components();
744 std::sort (component_to_dof_map[component].begin(),
745 component_to_dof_map[component].end());
746 component_to_dof_map[component]
747 .erase (std::unique (component_to_dof_map[component].begin(),
748 component_to_dof_map[component].end()),
749 component_to_dof_map[component].end());
754 const unsigned int n_buckets = fe_collection.n_components();
755 std::vector<types::global_dof_index> shifts(n_buckets);
759 (&start->get_dof_handler().get_triangulation())))
761 #ifdef DEAL_II_WITH_MPI 762 std::vector<types::global_dof_index> local_dof_count(n_buckets);
764 for (
unsigned int c=0; c<n_buckets; ++c)
765 local_dof_count[c] = component_to_dof_map[c].size();
769 std::vector<types::global_dof_index>
770 all_dof_counts(fe_collection.n_components() *
773 const int ierr = MPI_Allgather ( &local_dof_count[0],
774 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
776 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
777 tria->get_communicator());
780 for (
unsigned int i=0; i<n_buckets; ++i)
781 Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
787 unsigned int cumulated = 0;
788 for (
unsigned int c=0; c<n_buckets; ++c)
792 shifts[c] += all_dof_counts[c+n_buckets*i];
794 cumulated += all_dof_counts[c+n_buckets*i];
804 for (
unsigned int c=1; c<fe_collection.n_components(); ++c)
805 shifts[c] = shifts[c-1] + component_to_dof_map[c-1].size();
815 for (
unsigned int component=0; component<fe_collection.n_components(); ++component)
817 const typename std::vector<types::global_dof_index>::const_iterator
818 begin_of_component = component_to_dof_map[component].begin(),
819 end_of_component = component_to_dof_map[component].end();
821 next_free_index = shifts[component];
823 for (
typename std::vector<types::global_dof_index>::const_iterator
824 dof_index = begin_of_component;
825 dof_index != end_of_component; ++dof_index)
827 Assert (start->get_dof_handler().locally_owned_dofs()
828 .index_within_set(*dof_index)
832 new_indices[start->get_dof_handler().locally_owned_dofs()
833 .index_within_set(*dof_index)]
838 return next_free_index;
843 template <
int dim,
int spacedim>
852 const typename DoFHandler<dim,spacedim>::level_cell_iterator
853 end = dof_handler.
end();
856 compute_block_wise<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator,
857 typename DoFHandler<dim,spacedim>::level_cell_iterator>
858 (renumbering, start, end,
false);
873 (result <= dof_handler.
n_dofs())),
881 template <
int dim,
int spacedim>
885 std::vector<types::global_dof_index> renumbering (dof_handler.
n_dofs(),
890 const typename hp::DoFHandler<dim,spacedim>::level_cell_iterator
891 end = dof_handler.
end();
894 compute_block_wise<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator,
895 typename hp::DoFHandler<dim,spacedim>::level_cell_iterator>(renumbering,
909 template <
int dim,
int spacedim>
916 std::vector<types::global_dof_index> renumbering (dof_handler.
n_dofs(level),
919 typename DoFHandler<dim, spacedim>::level_cell_iterator
920 start =dof_handler.
begin(level);
921 typename DoFHandler<dim, spacedim>::level_cell_iterator
922 end = dof_handler.
end(level);
925 compute_block_wise<dim, spacedim, typename DoFHandler<dim, spacedim>::level_cell_iterator,
926 typename DoFHandler<dim, spacedim>::level_cell_iterator>(
927 renumbering, start, end,
true);
929 if (result == 0)
return;
934 if (renumbering.size()!=0)
940 template <
int dim,
int spacedim,
class ITERATOR,
class ENDITERATOR>
943 const ITERATOR &start,
944 const ENDITERATOR &end,
945 const bool is_level_operation)
948 fe_collection (start->get_dof_handler().get_fe ());
952 if (fe_collection.n_blocks() == 1)
954 new_indices.resize(0);
960 std::vector<types::global_dof_index> local_dof_indices;
965 std::vector<std::vector<types::global_dof_index> > block_list (fe_collection.size());
966 for (
unsigned int f=0; f<fe_collection.size(); ++f)
986 std::vector<std::vector<types::global_dof_index> >
987 block_to_dof_map (fe_collection.n_blocks());
988 for (ITERATOR cell=start; cell!=end; ++cell)
990 if (is_level_operation)
993 if (!cell->is_locally_owned_on_level())
1000 if (!cell->is_locally_owned())
1007 const unsigned int fe_index = cell->active_fe_index();
1008 const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
1009 local_dof_indices.resize (dofs_per_cell);
1010 cell->get_active_or_mg_dof_indices (local_dof_indices);
1011 for (
unsigned int i=0; i<dofs_per_cell; ++i)
1012 if (start->get_dof_handler().locally_owned_dofs().is_element(local_dof_indices[i]))
1013 block_to_dof_map[block_list[fe_index][i]].
1014 push_back (local_dof_indices[i]);
1029 for (
unsigned int block=0; block<fe_collection.n_blocks();
1032 std::sort (block_to_dof_map[block].begin(),
1033 block_to_dof_map[block].end());
1034 block_to_dof_map[block]
1035 .erase (std::unique (block_to_dof_map[block].begin(),
1036 block_to_dof_map[block].end()),
1037 block_to_dof_map[block].end());
1042 const unsigned int n_buckets = fe_collection.n_blocks();
1043 std::vector<types::global_dof_index> shifts(n_buckets);
1047 (&start->get_dof_handler().get_triangulation())))
1049 #ifdef DEAL_II_WITH_MPI 1050 std::vector<types::global_dof_index> local_dof_count(n_buckets);
1052 for (
unsigned int c=0; c<n_buckets; ++c)
1053 local_dof_count[c] = block_to_dof_map[c].size();
1057 std::vector<types::global_dof_index>
1058 all_dof_counts(fe_collection.n_components() *
1061 const int ierr = MPI_Allgather ( &local_dof_count[0],
1062 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
1064 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
1065 tria->get_communicator());
1068 for (
unsigned int i=0; i<n_buckets; ++i)
1069 Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
1076 for (
unsigned int c=0; c<n_buckets; ++c)
1078 shifts[c]=cumulated;
1080 shifts[c] += all_dof_counts[c+n_buckets*i];
1082 cumulated += all_dof_counts[c+n_buckets*i];
1092 for (
unsigned int c=1; c<fe_collection.n_blocks(); ++c)
1093 shifts[c] = shifts[c-1] + block_to_dof_map[c-1].size();
1103 for (
unsigned int block=0; block<fe_collection.n_blocks(); ++block)
1105 const typename std::vector<types::global_dof_index>::const_iterator
1106 begin_of_component = block_to_dof_map[block].begin(),
1107 end_of_component = block_to_dof_map[block].end();
1109 next_free_index = shifts[block];
1111 for (
typename std::vector<types::global_dof_index>::const_iterator
1112 dof_index = begin_of_component;
1113 dof_index != end_of_component; ++dof_index)
1115 Assert (start->get_dof_handler().locally_owned_dofs()
1116 .index_within_set(*dof_index)
1120 new_indices[start->get_dof_handler().locally_owned_dofs()
1121 .index_within_set(*dof_index)]
1122 = next_free_index++;
1126 return next_free_index;
1136 template <
int dim,
class iterator>
1138 compute_hierarchical_recursive (
1140 std::vector<types::global_dof_index> &new_indices,
1141 const iterator &cell,
1144 if (cell->has_children())
1147 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell; ++c)
1148 next_free = compute_hierarchical_recursive<dim> (
1156 if (cell->is_locally_owned())
1158 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1159 std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1160 cell->get_dof_indices (local_dof_indices);
1162 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1164 if (locally_owned.
is_element (local_dof_indices[i]))
1201 #ifdef DEAL_II_WITH_P4EST 1204 for (
unsigned int c = 0; c < tria->
n_cells (0); ++c)
1206 const unsigned int coarse_cell_index =
1210 this_cell (tria, 0, coarse_cell_index, &dof_handler);
1212 next_free = compute_hierarchical_recursive<dim> (next_free,
1225 for (cell = dof_handler.
begin (0); cell != dof_handler.
end (0); ++cell)
1226 next_free = compute_hierarchical_recursive<dim> (next_free,
1243 (next_free <= dof_handler.
n_dofs())),
1247 Assert (std::find (renumbering.begin(), renumbering.end(),
1249 == renumbering.end(),
1257 template <
typename DoFHandlerType>
1260 const std::vector<bool> &selected_dofs)
1262 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1263 DoFHandlerType::invalid_dof_index);
1266 dof_handler.renumber_dofs(renumbering);
1271 template <
typename DoFHandlerType>
1274 const std::vector<bool> &selected_dofs,
1275 const unsigned int level)
1280 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(level),
1281 DoFHandlerType::invalid_dof_index);
1284 dof_handler.renumber_dofs(level, renumbering);
1289 template <
typename DoFHandlerType>
1292 const DoFHandlerType &dof_handler,
1293 const std::vector<bool> &selected_dofs)
1296 Assert (selected_dofs.size() == n_dofs,
1301 Assert (new_indices.size() == n_dofs,
1305 selected_dofs.end(),
1311 if (selected_dofs[i] ==
false)
1313 new_indices[i] = next_unselected;
1318 new_indices[i] = next_selected;
1327 template <
typename DoFHandlerType>
1330 const DoFHandlerType &dof_handler,
1331 const std::vector<bool> &selected_dofs,
1332 const unsigned int level)
1337 const unsigned int n_dofs = dof_handler.n_dofs(level);
1338 Assert (selected_dofs.size() == n_dofs,
1343 Assert (new_indices.size() == n_dofs,
1346 const unsigned int n_selected_dofs = std::count (selected_dofs.begin(),
1347 selected_dofs.end(),
1350 unsigned int next_unselected = 0;
1351 unsigned int next_selected = n_selected_dofs;
1352 for (
unsigned int i=0; i<n_dofs; ++i)
1353 if (selected_dofs[i] ==
false)
1355 new_indices[i] = next_unselected;
1360 new_indices[i] = next_selected;
1369 template <
typename DoFHandlerType>
1372 const std::vector<typename DoFHandlerType::active_cell_iterator> &cells)
1374 std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1375 std::vector<types::global_dof_index> reverse(dof.n_dofs());
1378 dof.renumber_dofs(renumbering);
1382 template <
typename DoFHandlerType>
1385 (std::vector<types::global_dof_index> &new_indices,
1386 std::vector<types::global_dof_index> &reverse,
1387 const DoFHandlerType &dof,
1388 const typename std::vector<typename DoFHandlerType::active_cell_iterator> &cells)
1390 Assert(cells.size() == dof.get_triangulation().n_active_cells(),
1392 dof.get_triangulation().n_active_cells()));
1403 Assert(new_indices.size() == n_global_dofs,
1405 Assert(reverse.size() == n_global_dofs,
1411 std::vector<bool> already_sorted(n_global_dofs,
false);
1412 std::vector<types::global_dof_index> cell_dofs;
1414 unsigned int global_index = 0;
1416 typename std::vector<typename DoFHandlerType::active_cell_iterator>::const_iterator cell;
1418 for (cell = cells.begin(); cell != cells.end(); ++cell)
1424 unsigned int n_cell_dofs = (*cell)->get_fe().n_dofs_per_cell();
1425 cell_dofs.resize(n_cell_dofs);
1427 (*cell)->get_active_or_mg_dof_indices(cell_dofs);
1433 std::sort(cell_dofs.begin(), cell_dofs.end());
1435 for (
unsigned int i=0; i<n_cell_dofs; ++i)
1437 if (!already_sorted[cell_dofs[i]])
1439 already_sorted[cell_dofs[i]] =
true;
1440 reverse[global_index++] = cell_dofs[i];
1447 new_indices[reverse[i]] = i;
1452 template <
typename DoFHandlerType>
1454 (DoFHandlerType &dof,
1455 const unsigned int level,
1456 const typename std::vector<typename DoFHandlerType::level_cell_iterator> &cells)
1461 std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1462 std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1465 dof.renumber_dofs(level, renumbering);
1470 template <
typename DoFHandlerType>
1472 (std::vector<types::global_dof_index> &new_order,
1473 std::vector<types::global_dof_index> &reverse,
1474 const DoFHandlerType &dof,
1475 const unsigned int level,
1476 const typename std::vector<typename DoFHandlerType::level_cell_iterator> &cells)
1478 Assert(cells.size() == dof.get_triangulation().n_cells(level),
1480 dof.get_triangulation().n_cells(level)));
1481 Assert (new_order.size() == dof.n_dofs(level),
1483 Assert (reverse.size() == dof.n_dofs(level),
1486 unsigned int n_global_dofs = dof.n_dofs(level);
1487 unsigned int n_cell_dofs = dof.get_fe().n_dofs_per_cell();
1489 std::vector<bool> already_sorted(n_global_dofs,
false);
1490 std::vector<types::global_dof_index> cell_dofs(n_cell_dofs);
1492 unsigned int global_index = 0;
1494 typename std::vector<typename DoFHandlerType::level_cell_iterator>::const_iterator cell;
1496 for (cell = cells.begin(); cell != cells.end(); ++cell)
1500 (*cell)->get_active_or_mg_dof_indices(cell_dofs);
1501 std::sort(cell_dofs.begin(), cell_dofs.end());
1503 for (
unsigned int i=0; i<n_cell_dofs; ++i)
1505 if (!already_sorted[cell_dofs[i]])
1507 already_sorted[cell_dofs[i]] =
true;
1508 reverse[global_index++] = cell_dofs[i];
1515 new_order[reverse[i]] = i;
1524 template <
typename DoFHandlerType>
1527 (std::vector<types::global_dof_index> &new_indices,
1528 std::vector<types::global_dof_index> &reverse,
1529 const DoFHandlerType &dof,
1531 const bool dof_wise_renumbering)
1533 if (dof_wise_renumbering ==
false)
1535 std::vector<typename DoFHandlerType::active_cell_iterator> ordered_cells;
1536 ordered_cells.reserve(dof.get_triangulation().n_active_cells());
1538 DoFHandlerType::space_dimension> comparator(direction);
1540 typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
1541 typename DoFHandlerType::active_cell_iterator end = dof.end();
1545 ordered_cells.push_back(p);
1548 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1560 const unsigned int n_dofs = dof.n_dofs();
1561 std::vector<std::pair<Point<DoFHandlerType::space_dimension>,
unsigned int> > support_point_list
1565 Assert (fe_collection[0].has_support_points(),
1568 for (
unsigned int comp=0; comp<fe_collection.size(); ++comp)
1570 Assert (fe_collection[comp].has_support_points(),
1574 get_unit_support_points()));
1577 hp_fe_values (fe_collection, quadrature_collection,
1580 std::vector<bool> already_touched (n_dofs,
false);
1582 std::vector<types::global_dof_index> local_dof_indices;
1583 typename DoFHandlerType::active_cell_iterator begin = dof.begin_active();
1584 typename DoFHandlerType::active_cell_iterator end = dof.end();
1585 for ( ; begin != end; ++begin)
1587 const unsigned int dofs_per_cell = begin->get_fe().dofs_per_cell;
1588 local_dof_indices.resize (dofs_per_cell);
1589 hp_fe_values.
reinit (begin);
1592 begin->get_active_or_mg_dof_indices(local_dof_indices);
1593 const std::vector<Point<DoFHandlerType::space_dimension> > &points
1595 for (
unsigned int i=0; i<dofs_per_cell; ++i)
1596 if (!already_touched[local_dof_indices[i]])
1598 support_point_list[local_dof_indices[i]].first = points[i];
1599 support_point_list[local_dof_indices[i]].second =
1600 local_dof_indices[i];
1601 already_touched[local_dof_indices[i]] =
true;
1606 std::sort (support_point_list.begin(), support_point_list.end(),
1609 new_indices[support_point_list[i].second] = i;
1615 template <
typename DoFHandlerType>
1617 const unsigned int level,
1619 const bool dof_wise_renumbering)
1621 std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1622 std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1624 dof_wise_renumbering);
1626 dof.renumber_dofs(level, renumbering);
1631 template <
typename DoFHandlerType>
1634 (std::vector<types::global_dof_index> &new_indices,
1635 std::vector<types::global_dof_index> &reverse,
1636 const DoFHandlerType &dof,
1637 const unsigned int level,
1639 const bool dof_wise_renumbering)
1641 if (dof_wise_renumbering ==
false)
1643 std::vector<typename DoFHandlerType::level_cell_iterator> ordered_cells;
1644 ordered_cells.reserve (dof.get_triangulation().n_cells(level));
1646 DoFHandlerType::space_dimension> comparator(direction);
1648 typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
1649 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1653 ordered_cells.push_back(p);
1656 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1662 Assert (dof.get_fe().has_support_points(),
1664 const unsigned int n_dofs = dof.n_dofs(level);
1665 std::vector<std::pair<Point<DoFHandlerType::space_dimension>,
unsigned int> > support_point_list
1672 std::vector<bool> already_touched (dof.n_dofs(),
false);
1674 const unsigned int dofs_per_cell = dof.
get_fe().dofs_per_cell;
1675 std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1676 typename DoFHandlerType::level_cell_iterator begin = dof.begin(level);
1677 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1678 for ( ; begin != end; ++begin)
1681 DoFHandlerType::space_dimension>::cell_iterator &begin_tria = begin;
1682 begin->get_active_or_mg_dof_indices(local_dof_indices);
1683 fe_values.reinit (begin_tria);
1684 const std::vector<Point<DoFHandlerType::space_dimension> > &points
1685 = fe_values.get_quadrature_points ();
1686 for (
unsigned int i=0; i<dofs_per_cell; ++i)
1687 if (!already_touched[local_dof_indices[i]])
1689 support_point_list[local_dof_indices[i]].first = points[i];
1690 support_point_list[local_dof_indices[i]].second =
1691 local_dof_indices[i];
1692 already_touched[local_dof_indices[i]] =
true;
1697 std::sort (support_point_list.begin(), support_point_list.end(),
1700 new_indices[support_point_list[i].second] = i;
1726 ClockCells (
const Point<dim> ¢er,
bool counter) :
1734 template <
class DHCellIterator>
1735 bool operator () (
const DHCellIterator &c1,
1736 const DHCellIterator &c2)
const 1747 template <
class DHCellIterator,
int xdim>
1748 bool compare (
const DHCellIterator &c1,
1749 const DHCellIterator &c2,
1754 const double s1 = std::atan2(v1[0], v1[1]);
1755 const double s2 = std::atan2(v2[0], v2[1]);
1756 return ( counter ? (s1>s2) : (s2>s1));
1764 template <
class DHCellIterator>
1765 bool compare (
const DHCellIterator &,
1766 const DHCellIterator &,
1770 ExcMessage (
"This operation only makes sense for dim>=2."));
1779 template <
typename DoFHandlerType>
1782 DoFHandlerType &dof,
1786 std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1789 dof.renumber_dofs(renumbering);
1794 template <
typename DoFHandlerType>
1797 (std::vector<types::global_dof_index> &new_indices,
1798 const DoFHandlerType &dof,
1802 std::vector<typename DoFHandlerType::active_cell_iterator> ordered_cells;
1803 ordered_cells.reserve (dof.get_triangulation().n_active_cells());
1804 internal::ClockCells<DoFHandlerType::space_dimension> comparator(center, counter);
1806 typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
1807 typename DoFHandlerType::active_cell_iterator end = dof.end();
1811 ordered_cells.push_back(p);
1814 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1816 std::vector<types::global_dof_index> reverse(new_indices.size());
1822 template <
typename DoFHandlerType>
1824 const unsigned int level,
1828 std::vector<typename DoFHandlerType::level_cell_iterator> ordered_cells;
1829 ordered_cells.reserve(dof.get_triangulation().n_active_cells());
1830 internal::ClockCells<DoFHandlerType::space_dimension> comparator(center, counter);
1832 typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
1833 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1837 ordered_cells.push_back(p);
1840 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1847 template <
typename DoFHandlerType>
1851 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1852 DoFHandlerType::invalid_dof_index);
1855 dof_handler.renumber_dofs(renumbering);
1860 template <
typename DoFHandlerType>
1863 std::vector<types::global_dof_index> &new_indices,
1864 const DoFHandlerType &dof_handler)
1867 Assert(new_indices.size() == n_dofs,
1870 for (
unsigned int i=0; i<n_dofs; ++i)
1875 ::boost::mt19937 random_number_generator;
1876 for (
unsigned int i=1; i<n_dofs; ++i)
1879 const unsigned int j
1880 = ::boost::random::uniform_int_distribution<>(0, i)(random_number_generator);
1884 std::swap (new_indices[i], new_indices[j]);
1890 template <
typename DoFHandlerType>
1894 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1895 DoFHandlerType::invalid_dof_index);
1898 dof_handler.renumber_dofs(renumbering);
1903 template <
typename DoFHandlerType>
1906 const DoFHandlerType &dof_handler)
1909 Assert (new_dof_indices.size() == n_dofs,
1915 std::vector<types::subdomain_id> subdomain_association (n_dofs);
1917 subdomain_association);
1918 const unsigned int n_subdomains
1919 = *std::max_element (subdomain_association.begin(),
1920 subdomain_association.end()) + 1;
1929 std::fill (new_dof_indices.begin(), new_dof_indices.end(),
1934 if (subdomain_association[i] == subdomain)
1938 new_dof_indices[i] = next_free_index;
1944 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
1946 == new_dof_indices.end(),
1955 #include "dof_renumbering.inst" 1958 DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcFEHasNoSupportPoints()
types::global_dof_index size_type
#define AssertDimension(dim1, dim2)
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)
unsigned int n_cells() const
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)
void hierarchical(DoFHandler< dim > &dof_handler)
cell_iterator end() const
void component_wise(DoFHandler< dim, spacedim > &dof_handler, const std::vector< unsigned int > &target_component=std::vector< unsigned int >())
active_cell_iterator begin_active(const unsigned int level=0) const
const FiniteElement< dim, spacedim > & get_fe() const
ActiveSelector::active_cell_iterator active_cell_iterator
Transformed quadrature points.
static ::ExceptionBase & ExcNotInitialized()
bool is_primitive() const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const std::vector< types::global_dof_index > & get_p4est_tree_to_coarse_cell_permutation() const
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
ActiveSelector::active_cell_iterator active_cell_iterator
const ::FEValues< dim, spacedim > & get_present_fe_values() const
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 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)
void make_hanging_node_constraints(const DoFHandlerType &dof_handler, ConstraintMatrix &constraints)
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)
void Cuthill_McKee(DoFHandlerType &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false)
unsigned int global_dof_index
#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
static ::ExceptionBase & ExcRenumberingIncomplete()
void compute_random(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &dof_handler)
unsigned int subdomain_id
void downstream(DoFHandlerType &dof_handler, const Point< DoFHandlerType::space_dimension > &direction, const bool dof_wise_renumbering=false)
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)
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
#define AssertThrowMPI(error_code)
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern, const ConstraintMatrix &constraints=ConstraintMatrix(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
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 block_wise(DoFHandler< dim, spacedim > &dof_handler)
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
types::global_dof_index compute_component_wise(std::vector< types::global_dof_index > &new_dof_indices, const ITERATOR &start, const ENDITERATOR &end, const std::vector< unsigned int > &target_component, bool is_level_operation)
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()
const Triangulation< dim, spacedim > & get_triangulation() const
bool is_element(const size_type index) const
void reinit(const IndexSet &local_constraints=IndexSet())
void subdomain_wise(DoFHandlerType &dof_handler)
void clockwise_dg(DoFHandlerType &dof_handler, const Point< DoFHandlerType::space_dimension > ¢er, const bool counter=false)
const types::global_dof_index invalid_dof_index
const IndexSet & locally_owned_dofs() const
void compute_downstream(std::vector< types::global_dof_index > &new_dof_indices, std::vector< types::global_dof_index > &reverse, const DoFHandlerType &dof_handler, const Point< DoFHandlerType::space_dimension > &direction, const bool dof_wise_renumbering)
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)