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 #include <boost/random.hpp> 52 #include <boost/random/uniform_int_distribution.hpp> 61 DEAL_II_NAMESPACE_OPEN
69 using namespace ::boost;
72 typedef adjacency_list<vecS, vecS, undirectedS,
73 property<vertex_color_t, default_color_type,
74 property<vertex_degree_t,int> > > Graph;
75 typedef graph_traits<Graph>::vertex_descriptor Vertex;
76 typedef graph_traits<Graph>::vertices_size_type
size_type;
78 typedef std::pair<size_type, size_type> Pair;
84 template <
typename DoFHandlerType>
86 (
const DoFHandlerType &dof_handler,
87 const bool use_constraints,
88 boosttypes::Graph &graph,
89 boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type &graph_degree)
100 dof_handler.n_dofs());
104 for (
unsigned int row=0; row<dsp.n_rows(); ++row)
105 for (
unsigned int col=0; col < dsp.row_length(row); ++col)
106 add_edge (row, dsp.column_number (row, col), graph);
109 boosttypes::graph_traits<boosttypes::Graph>::vertex_iterator ui, ui_end;
111 graph_degree =
get(::boost::vertex_degree, graph);
112 for (::boost::tie(ui, ui_end) = vertices(graph); ui != ui_end; ++ui)
113 graph_degree[*ui] = degree(*ui, graph);
118 template <
typename DoFHandlerType>
121 const bool reversed_numbering,
122 const bool use_constraints)
124 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
132 dof_handler.renumber_dofs (renumbering);
136 template <
typename DoFHandlerType>
139 const DoFHandlerType &dof_handler,
140 const bool reversed_numbering,
141 const bool use_constraints)
144 graph(dof_handler.n_dofs());
145 boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type
148 internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
150 boosttypes::property_map<boosttypes::Graph, boosttypes::vertex_index_t>::type
151 index_map =
get(::boost::vertex_index, graph);
154 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
156 if (reversed_numbering ==
false)
157 ::boost::cuthill_mckee_ordering(graph, inv_perm.rbegin(),
158 get(::boost::vertex_color, graph),
159 make_degree_map(graph));
161 ::boost::cuthill_mckee_ordering(graph, inv_perm.begin(),
162 get(::boost::vertex_color, graph),
163 make_degree_map(graph));
165 for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
166 new_dof_indices[index_map[inv_perm[c]]] = c;
168 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
175 template <
typename DoFHandlerType>
178 const bool reversed_numbering,
179 const bool use_constraints)
181 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
189 dof_handler.renumber_dofs (renumbering);
193 template <
typename DoFHandlerType>
196 const DoFHandlerType &dof_handler,
197 const bool reversed_numbering,
198 const bool use_constraints)
201 graph(dof_handler.n_dofs());
202 boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type
205 internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
207 boosttypes::property_map<boosttypes::Graph, boosttypes::vertex_index_t>::type
208 index_map =
get(::boost::vertex_index, graph);
211 std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
213 if (reversed_numbering ==
false)
214 ::boost::king_ordering(graph, inv_perm.rbegin());
216 ::boost::king_ordering(graph, inv_perm.begin());
218 for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
219 new_dof_indices[index_map[inv_perm[c]]] = c;
221 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
228 template <
typename DoFHandlerType>
231 const bool reversed_numbering,
232 const bool use_constraints)
234 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
242 dof_handler.renumber_dofs (renumbering);
246 template <
typename DoFHandlerType>
249 const DoFHandlerType &dof_handler,
250 const bool reversed_numbering,
251 const bool use_constraints)
253 (void)use_constraints;
262 using namespace ::boost;
267 typedef adjacency_list<vecS, vecS, directedS> Graph;
269 int n = dof_handler.n_dofs();
273 std::vector<::types::global_dof_index> dofs_on_this_cell;
275 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
276 endc = dof_handler.end();
278 for (; cell!=endc; ++cell)
281 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
283 dofs_on_this_cell.resize (dofs_per_cell);
285 cell->get_active_or_mg_dof_indices (dofs_on_this_cell);
286 for (
unsigned int i=0; i<dofs_per_cell; ++i)
287 for (
unsigned int j=0; j<dofs_per_cell; ++j)
288 if (dofs_on_this_cell[i] > dofs_on_this_cell[j])
290 add_edge (dofs_on_this_cell[i], dofs_on_this_cell[j], G);
291 add_edge (dofs_on_this_cell[j], dofs_on_this_cell[i], G);
296 typedef std::vector<int> Vector;
299 Vector inverse_perm(n, 0);
304 Vector supernode_sizes(n, 1);
307 ::boost::property_map<Graph, vertex_index_t>::type
308 id =
get(vertex_index, G);
314 minimum_degree_ordering
316 make_iterator_property_map(degree.begin(), id, degree[0]),
319 make_iterator_property_map(supernode_sizes.begin(), id, supernode_sizes[0]),
323 for (
int i=0; i<n; ++i)
325 Assert (std::find (perm.begin(), perm.end(), i)
328 Assert (std::find (inverse_perm.begin(), inverse_perm.end(), i)
329 != inverse_perm.end(),
334 if (reversed_numbering ==
true)
335 std::copy (perm.begin(), perm.end(),
336 new_dof_indices.begin());
338 std::copy (inverse_perm.begin(), inverse_perm.end(),
339 new_dof_indices.begin());
346 template <
typename DoFHandlerType>
349 const bool reversed_numbering,
350 const bool use_constraints,
351 const std::vector<types::global_dof_index> &starting_indices)
353 std::vector<types::global_dof_index> renumbering(dof_handler.locally_owned_dofs().n_elements(),
356 use_constraints, starting_indices);
361 dof_handler.renumber_dofs (renumbering);
366 template <
typename DoFHandlerType>
369 const DoFHandlerType &dof_handler,
370 const bool reversed_numbering,
371 const bool use_constraints,
372 const std::vector<types::global_dof_index> &starting_indices)
375 if (dof_handler.locally_owned_dofs().n_elements() == 0)
391 constraints.
reinit(locally_relevant_dofs);
394 constraints.
close ();
396 const IndexSet &locally_owned_dofs = dof_handler.locally_owned_dofs();
404 dof_handler.n_dofs());
409 if (reversed_numbering)
425 bool needs_locally_active =
false;
426 for (
unsigned int i=0; i<starting_indices.size(); ++i)
428 if ((needs_locally_active ==
true)
430 (locally_owned_dofs.
is_element (starting_indices[i]) ==
false))
433 ExcMessage (
"You specified global degree of freedom " 435 " as a starting index, but this index is not among the " 436 "locally active ones on this processor, as required " 437 "for this function."));
438 needs_locally_active =
true;
442 const IndexSet index_set_to_use = (needs_locally_active ?
443 locally_active_dofs :
450 dof_handler.n_dofs(),
456 std::vector<types::global_dof_index> row_entries;
457 for (
unsigned int i=0; i<index_set_to_use.
n_elements(); ++i)
460 const unsigned int row_length = dsp.row_length(row);
462 for (
unsigned int j=0; j<row_length; ++j)
464 const unsigned int col = dsp.column_number(row, j);
465 if (col != row && index_set_to_use.
is_element(col))
468 local_sparsity.add_entries(i, row_entries.begin(), row_entries.end(),
473 std::vector<types::global_dof_index> local_starting_indices (starting_indices.size());
474 for (
unsigned int i=0; i<starting_indices.size(); ++i)
475 local_starting_indices[i] = index_set_to_use.
index_within_set(starting_indices[i]);
479 std::vector<types::global_dof_index> my_new_indices (index_set_to_use.
n_elements());
481 local_starting_indices);
482 if (reversed_numbering)
491 if (needs_locally_active ==
true)
494 IndexSet active_but_not_owned_dofs = locally_active_dofs;
495 active_but_not_owned_dofs.
subtract_set(locally_owned_dofs);
497 std::set<types::global_dof_index> erase_these_indices;
498 for (
const auto &p : active_but_not_owned_dofs)
502 erase_these_indices.insert (my_new_indices[index]);
505 Assert (erase_these_indices.size() == active_but_not_owned_dofs.n_elements(),
507 Assert (static_cast<unsigned int>(std::count (my_new_indices.begin(),
508 my_new_indices.end(),
510 == active_but_not_owned_dofs.n_elements(),
514 std::vector<types::global_dof_index> translate_indices (my_new_indices.size());
516 std::set<types::global_dof_index>::const_iterator
517 next_erased_index = erase_these_indices.begin();
519 for (
unsigned int i=0; i<translate_indices.size(); ++i)
520 if ((next_erased_index != erase_these_indices.end())
522 (*next_erased_index == i))
529 translate_indices[i] = next_new_index;
539 new_indices.reserve(locally_owned_dofs.
n_elements());
540 for (
const auto &p : my_new_indices)
545 new_indices.push_back (translate_indices[p]);
551 new_indices = std::move (my_new_indices);
557 for (std::size_t i=0; i<new_indices.size(); ++i)
564 template <
typename DoFHandlerType>
566 const unsigned int level,
567 const bool reversed_numbering,
568 const std::vector<types::global_dof_index> &starting_indices)
575 dof_handler.n_dofs(level));
578 std::vector<types::global_dof_index> new_indices(dsp.n_rows());
582 if (reversed_numbering)
588 dof_handler.renumber_dofs (level, new_indices);
593 template <
typename DoFHandlerType>
596 const std::vector<unsigned int> &component_order_arg)
598 std::vector<types::global_dof_index> renumbering (dof_handler.n_locally_owned_dofs(),
601 typename DoFHandlerType::active_cell_iterator
602 start = dof_handler.begin_active();
603 const typename DoFHandlerType::level_cell_iterator
604 end = dof_handler.end();
607 compute_component_wise<DoFHandlerType::dimension,DoFHandlerType::space_dimension>
608 (renumbering, start, end, component_order_arg,
false);
619 Assert ((result == dof_handler.n_locally_owned_dofs())
621 ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
623 (result <= dof_handler.n_dofs())),
626 dof_handler.renumber_dofs (renumbering);
631 template <
typename DoFHandlerType>
634 const unsigned int level,
635 const std::vector<unsigned int> &component_order_arg)
640 std::vector<types::global_dof_index> renumbering (dof_handler.n_dofs(level),
643 typename DoFHandlerType::level_cell_iterator start =dof_handler.begin(level);
644 typename DoFHandlerType::level_cell_iterator end = dof_handler.end(level);
647 compute_component_wise<DoFHandlerType::dimension, DoFHandlerType::space_dimension>
648 (renumbering, start, end, component_order_arg,
true);
650 if (result == 0)
return;
652 Assert (result == dof_handler.n_dofs(level),
655 if (renumbering.size()!=0)
656 dof_handler.renumber_dofs (level, renumbering);
661 template <
int dim,
int spacedim,
typename CellIterator>
664 const CellIterator &start,
665 const typename identity<CellIterator>::type &end,
666 const std::vector<unsigned int> &component_order_arg,
667 const bool is_level_operation)
670 fe_collection (start->get_dof_handler().get_fe_collection ());
674 if (fe_collection.n_components() == 1)
676 new_indices.resize(0);
682 std::vector<unsigned int> component_order (component_order_arg);
687 if (component_order.size() == 0)
688 for (
unsigned int i=0; i<fe_collection.n_components(); ++i)
689 component_order.push_back (i);
691 Assert (component_order.size() == fe_collection.n_components(),
694 for (
unsigned int i=0; i<component_order.size(); ++i)
695 Assert(component_order[i] < fe_collection.n_components(),
696 ExcIndexRange(component_order[i], 0, fe_collection.n_components()));
700 std::vector<types::global_dof_index> local_dof_indices;
712 std::vector<std::vector<unsigned int> > component_list (fe_collection.size());
713 for (
unsigned int f=0; f<fe_collection.size(); ++f)
717 component_list[f].resize(dofs_per_cell);
718 for (
unsigned int i=0; i<dofs_per_cell; ++i)
724 const unsigned int comp
730 component_list[f][i] = component_order[comp];
745 std::vector<std::vector<types::global_dof_index> >
746 component_to_dof_map (fe_collection.n_components());
747 for (CellIterator cell=start; cell!=end; ++cell)
749 if (is_level_operation)
752 if (!cell->is_locally_owned_on_level())
759 if (!cell->is_locally_owned())
765 const unsigned int fe_index = cell->active_fe_index();
766 const unsigned int dofs_per_cell = fe_collection[fe_index].dofs_per_cell;
767 local_dof_indices.resize (dofs_per_cell);
768 cell->get_active_or_mg_dof_indices (local_dof_indices);
769 for (
unsigned int i=0; i<dofs_per_cell; ++i)
770 if (start->get_dof_handler().locally_owned_dofs().is_element(local_dof_indices[i]))
771 component_to_dof_map[component_list[fe_index][i]].
772 push_back (local_dof_indices[i]);
798 for (
unsigned int component=0; component<fe_collection.n_components();
801 std::sort (component_to_dof_map[component].begin(),
802 component_to_dof_map[component].end());
803 component_to_dof_map[component]
804 .erase (std::unique (component_to_dof_map[component].begin(),
805 component_to_dof_map[component].end()),
806 component_to_dof_map[component].end());
811 const unsigned int n_buckets = fe_collection.n_components();
812 std::vector<types::global_dof_index> shifts(n_buckets);
816 (&start->get_dof_handler().get_triangulation())))
818 #ifdef DEAL_II_WITH_MPI 819 std::vector<types::global_dof_index> local_dof_count(n_buckets);
821 for (
unsigned int c=0; c<n_buckets; ++c)
822 local_dof_count[c] = component_to_dof_map[c].size();
826 std::vector<types::global_dof_index>
827 all_dof_counts(fe_collection.n_components() *
830 const int ierr = MPI_Allgather ( local_dof_count.data(),
831 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
832 all_dof_counts.data(),
833 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
834 tria->get_communicator());
837 for (
unsigned int i=0; i<n_buckets; ++i)
838 Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
844 unsigned int cumulated = 0;
845 for (
unsigned int c=0; c<n_buckets; ++c)
849 shifts[c] += all_dof_counts[c+n_buckets*i];
851 cumulated += all_dof_counts[c+n_buckets*i];
861 for (
unsigned int c=1; c<fe_collection.n_components(); ++c)
862 shifts[c] = shifts[c-1] + component_to_dof_map[c-1].size();
872 for (
unsigned int component=0; component<fe_collection.n_components(); ++component)
874 const typename std::vector<types::global_dof_index>::const_iterator
875 begin_of_component = component_to_dof_map[component].begin(),
876 end_of_component = component_to_dof_map[component].end();
878 next_free_index = shifts[component];
880 for (
typename std::vector<types::global_dof_index>::const_iterator
881 dof_index = begin_of_component;
882 dof_index != end_of_component; ++dof_index)
884 Assert (start->get_dof_handler().locally_owned_dofs()
885 .index_within_set(*dof_index)
889 new_indices[start->get_dof_handler().locally_owned_dofs()
890 .index_within_set(*dof_index)]
895 return next_free_index;
900 template <
int dim,
int spacedim>
909 const typename DoFHandler<dim,spacedim>::level_cell_iterator
910 end = dof_handler.
end();
913 compute_block_wise<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator,
914 typename DoFHandler<dim,spacedim>::level_cell_iterator>
915 (renumbering, start, end,
false);
930 (result <= dof_handler.
n_dofs())),
938 template <
int dim,
int spacedim>
942 std::vector<types::global_dof_index> renumbering (dof_handler.
n_dofs(),
947 const typename hp::DoFHandler<dim,spacedim>::level_cell_iterator
948 end = dof_handler.
end();
951 compute_block_wise<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator,
952 typename hp::DoFHandler<dim,spacedim>::level_cell_iterator>(renumbering,
966 template <
int dim,
int spacedim>
969 const unsigned int level)
974 std::vector<types::global_dof_index> renumbering (dof_handler.
n_dofs(level),
977 typename DoFHandler<dim, spacedim>::level_cell_iterator
978 start =dof_handler.
begin(level);
979 typename DoFHandler<dim, spacedim>::level_cell_iterator
980 end = dof_handler.
end(level);
983 compute_block_wise<dim, spacedim, typename DoFHandler<dim, spacedim>::level_cell_iterator,
984 typename DoFHandler<dim, spacedim>::level_cell_iterator>(
985 renumbering, start, end,
true);
987 if (result == 0)
return;
992 if (renumbering.size()!=0)
998 template <
int dim,
int spacedim,
class ITERATOR,
class ENDITERATOR>
1001 const ITERATOR &start,
1002 const ENDITERATOR &end,
1003 const bool is_level_operation)
1006 fe_collection (start->get_dof_handler().get_fe_collection ());
1010 if (fe_collection.n_blocks() == 1)
1012 new_indices.resize(0);
1018 std::vector<types::global_dof_index> local_dof_indices;
1023 std::vector<std::vector<types::global_dof_index> > block_list (fe_collection.size());
1024 for (
unsigned int f=0; f<fe_collection.size(); ++f)
1044 std::vector<std::vector<types::global_dof_index> >
1045 block_to_dof_map (fe_collection.n_blocks());
1046 for (ITERATOR cell=start; cell!=end; ++cell)
1048 if (is_level_operation)
1051 if (!cell->is_locally_owned_on_level())
1058 if (!cell->is_locally_owned())
1065 const unsigned int fe_index = cell->active_fe_index();
1066 const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
1067 local_dof_indices.resize (dofs_per_cell);
1068 cell->get_active_or_mg_dof_indices (local_dof_indices);
1069 for (
unsigned int i=0; i<dofs_per_cell; ++i)
1070 if (start->get_dof_handler().locally_owned_dofs().is_element(local_dof_indices[i]))
1071 block_to_dof_map[block_list[fe_index][i]].
1072 push_back (local_dof_indices[i]);
1087 for (
unsigned int block=0; block<fe_collection.n_blocks();
1090 std::sort (block_to_dof_map[block].begin(),
1091 block_to_dof_map[block].end());
1092 block_to_dof_map[block]
1093 .erase (std::unique (block_to_dof_map[block].begin(),
1094 block_to_dof_map[block].end()),
1095 block_to_dof_map[block].end());
1100 const unsigned int n_buckets = fe_collection.n_blocks();
1101 std::vector<types::global_dof_index> shifts(n_buckets);
1105 (&start->get_dof_handler().get_triangulation())))
1107 #ifdef DEAL_II_WITH_MPI 1108 std::vector<types::global_dof_index> local_dof_count(n_buckets);
1110 for (
unsigned int c=0; c<n_buckets; ++c)
1111 local_dof_count[c] = block_to_dof_map[c].size();
1115 std::vector<types::global_dof_index>
1116 all_dof_counts(fe_collection.n_components() *
1119 const int ierr = MPI_Allgather ( local_dof_count.data(),
1120 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
1121 all_dof_counts.data(),
1122 n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
1123 tria->get_communicator());
1126 for (
unsigned int i=0; i<n_buckets; ++i)
1127 Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
1134 for (
unsigned int c=0; c<n_buckets; ++c)
1136 shifts[c]=cumulated;
1138 shifts[c] += all_dof_counts[c+n_buckets*i];
1140 cumulated += all_dof_counts[c+n_buckets*i];
1150 for (
unsigned int c=1; c<fe_collection.n_blocks(); ++c)
1151 shifts[c] = shifts[c-1] + block_to_dof_map[c-1].size();
1161 for (
unsigned int block=0; block<fe_collection.n_blocks(); ++block)
1163 const typename std::vector<types::global_dof_index>::const_iterator
1164 begin_of_component = block_to_dof_map[block].begin(),
1165 end_of_component = block_to_dof_map[block].end();
1167 next_free_index = shifts[block];
1169 for (
typename std::vector<types::global_dof_index>::const_iterator
1170 dof_index = begin_of_component;
1171 dof_index != end_of_component; ++dof_index)
1173 Assert (start->get_dof_handler().locally_owned_dofs()
1174 .index_within_set(*dof_index)
1178 new_indices[start->get_dof_handler().locally_owned_dofs()
1179 .index_within_set(*dof_index)]
1180 = next_free_index++;
1184 return next_free_index;
1195 template <
int dim,
class CellIteratorType>
1199 const CellIteratorType &cell,
1200 const IndexSet &locally_owned_dof_indices,
1201 std::vector<types::global_dof_index> &new_indices)
1205 if (cell->has_children())
1208 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell; ++c)
1209 current_next_free_dof_offset
1210 = compute_hierarchical_recursive<dim> (current_next_free_dof_offset,
1213 locally_owned_dof_indices,
1231 if (cell->is_locally_owned())
1234 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1235 std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1236 cell->get_dof_indices (local_dof_indices);
1255 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1256 if (locally_owned_dof_indices.
is_element (local_dof_indices[i]))
1259 const unsigned int idx = locally_owned_dof_indices.
index_within_set (local_dof_indices[i]);
1262 new_indices[idx] = my_starting_index + current_next_free_dof_offset;
1263 ++current_next_free_dof_offset;
1269 return current_next_free_dof_offset;
1302 const std::vector<types::global_dof_index> &
1304 my_starting_index = std::accumulate (n_locally_owned_dofs_per_processor.begin(),
1305 n_locally_owned_dofs_per_processor.begin()
1306 + tria->locally_owned_subdomain(),
1314 #ifdef DEAL_II_WITH_P4EST 1319 for (
unsigned int c = 0; c < tria->n_cells (0); ++c)
1321 const unsigned int coarse_cell_index =
1322 tria->get_p4est_tree_to_coarse_cell_permutation() [c];
1325 this_cell (tria, 0, coarse_cell_index, &dof_handler);
1327 next_free_dof_offset = compute_hierarchical_recursive<dim> (next_free_dof_offset,
1342 cell != dof_handler.
end (0); ++cell)
1343 next_free_dof_offset = compute_hierarchical_recursive<dim> (next_free_dof_offset,
1358 (next_free_dof_offset <= dof_handler.
n_dofs())),
1362 Assert (std::find (renumbering.begin(), renumbering.end(),
1364 == renumbering.end(),
1372 template <
typename DoFHandlerType>
1375 const std::vector<bool> &selected_dofs)
1377 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1381 dof_handler.renumber_dofs(renumbering);
1386 template <
typename DoFHandlerType>
1389 const std::vector<bool> &selected_dofs,
1390 const unsigned int level)
1395 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(level),
1399 dof_handler.renumber_dofs(level, renumbering);
1404 template <
typename DoFHandlerType>
1407 const DoFHandlerType &dof_handler,
1408 const std::vector<bool> &selected_dofs)
1411 Assert (selected_dofs.size() == n_dofs,
1416 Assert (new_indices.size() == n_dofs,
1420 selected_dofs.end(),
1426 if (selected_dofs[i] ==
false)
1428 new_indices[i] = next_unselected;
1433 new_indices[i] = next_selected;
1442 template <
typename DoFHandlerType>
1445 const DoFHandlerType &dof_handler,
1446 const std::vector<bool> &selected_dofs,
1447 const unsigned int level)
1452 const unsigned int n_dofs = dof_handler.n_dofs(level);
1453 Assert (selected_dofs.size() == n_dofs,
1458 Assert (new_indices.size() == n_dofs,
1461 const unsigned int n_selected_dofs = std::count (selected_dofs.begin(),
1462 selected_dofs.end(),
1465 unsigned int next_unselected = 0;
1466 unsigned int next_selected = n_selected_dofs;
1467 for (
unsigned int i=0; i<n_dofs; ++i)
1468 if (selected_dofs[i] ==
false)
1470 new_indices[i] = next_unselected;
1475 new_indices[i] = next_selected;
1484 template <
typename DoFHandlerType>
1487 const std::vector<typename DoFHandlerType::active_cell_iterator> &cells)
1489 std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1490 std::vector<types::global_dof_index> reverse(dof.n_dofs());
1493 dof.renumber_dofs(renumbering);
1497 template <
typename DoFHandlerType>
1500 (std::vector<types::global_dof_index> &new_indices,
1501 std::vector<types::global_dof_index> &reverse,
1502 const DoFHandlerType &dof,
1503 const typename std::vector<typename DoFHandlerType::active_cell_iterator> &cells)
1505 Assert(cells.size() == dof.get_triangulation().n_active_cells(),
1507 dof.get_triangulation().n_active_cells()));
1518 Assert(new_indices.size() == n_global_dofs,
1520 Assert(reverse.size() == n_global_dofs,
1526 std::vector<bool> already_sorted(n_global_dofs,
false);
1527 std::vector<types::global_dof_index> cell_dofs;
1529 unsigned int global_index = 0;
1531 typename std::vector<typename DoFHandlerType::active_cell_iterator>::const_iterator cell;
1533 for (cell = cells.begin(); cell != cells.end(); ++cell)
1539 unsigned int n_cell_dofs = (*cell)->get_fe().n_dofs_per_cell();
1540 cell_dofs.resize(n_cell_dofs);
1542 (*cell)->get_active_or_mg_dof_indices(cell_dofs);
1548 std::sort(cell_dofs.begin(), cell_dofs.end());
1550 for (
unsigned int i=0; i<n_cell_dofs; ++i)
1552 if (!already_sorted[cell_dofs[i]])
1554 already_sorted[cell_dofs[i]] =
true;
1555 reverse[global_index++] = cell_dofs[i];
1559 Assert(global_index == n_global_dofs,
1560 ExcMessage(
"Traversing over the given set of cells did not cover all " 1561 "degrees of freedom in the DoFHandler. Does the set of cells " 1562 "not include all active cells?"));
1565 new_indices[reverse[i]] = i;
1570 template <
typename DoFHandlerType>
1572 (DoFHandlerType &dof,
1573 const unsigned int level,
1574 const typename std::vector<typename DoFHandlerType::level_cell_iterator> &cells)
1579 std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1580 std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1583 dof.renumber_dofs(level, renumbering);
1588 template <
typename DoFHandlerType>
1590 (std::vector<types::global_dof_index> &new_order,
1591 std::vector<types::global_dof_index> &reverse,
1592 const DoFHandlerType &dof,
1593 const unsigned int level,
1594 const typename std::vector<typename DoFHandlerType::level_cell_iterator> &cells)
1596 Assert(cells.size() == dof.get_triangulation().n_cells(level),
1598 dof.get_triangulation().n_cells(level)));
1599 Assert (new_order.size() == dof.n_dofs(level),
1601 Assert (reverse.size() == dof.n_dofs(level),
1604 unsigned int n_global_dofs = dof.n_dofs(level);
1605 unsigned int n_cell_dofs = dof.get_fe().n_dofs_per_cell();
1607 std::vector<bool> already_sorted(n_global_dofs,
false);
1608 std::vector<types::global_dof_index> cell_dofs(n_cell_dofs);
1612 typename std::vector<typename DoFHandlerType::level_cell_iterator>::const_iterator cell;
1614 for (cell = cells.begin(); cell != cells.end(); ++cell)
1618 (*cell)->get_active_or_mg_dof_indices(cell_dofs);
1619 std::sort(cell_dofs.begin(), cell_dofs.end());
1621 for (
unsigned int i=0; i<n_cell_dofs; ++i)
1623 if (!already_sorted[cell_dofs[i]])
1625 already_sorted[cell_dofs[i]] =
true;
1630 Assert(global_index == n_global_dofs,
1631 ExcMessage(
"Traversing over the given set of cells did not cover all " 1632 "degrees of freedom in the DoFHandler. Does the set of cells " 1633 "not include all cells of the specified level?"));
1636 new_order[reverse[i]] = i;
1641 template <
typename DoFHandlerType>
1645 const bool dof_wise_renumbering)
1647 std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1648 std::vector<types::global_dof_index> reverse(dof.n_dofs());
1650 dof_wise_renumbering);
1652 dof.renumber_dofs(renumbering);
1657 template <
typename DoFHandlerType>
1660 (std::vector<types::global_dof_index> &new_indices,
1661 std::vector<types::global_dof_index> &reverse,
1662 const DoFHandlerType &dof,
1664 const bool dof_wise_renumbering)
1667 (&dof.get_triangulation())
1671 if (dof_wise_renumbering ==
false)
1673 std::vector<typename DoFHandlerType::active_cell_iterator> ordered_cells;
1674 ordered_cells.reserve(dof.get_triangulation().n_active_cells());
1676 DoFHandlerType::space_dimension> comparator(direction);
1678 typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
1679 typename DoFHandlerType::active_cell_iterator end = dof.end();
1683 ordered_cells.push_back(p);
1686 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1698 const unsigned int n_dofs = dof.n_dofs();
1699 std::vector<std::pair<Point<DoFHandlerType::space_dimension>,
unsigned int> > support_point_list
1703 Assert (fe_collection[0].has_support_points(),
1706 for (
unsigned int comp=0; comp<fe_collection.
size(); ++comp)
1708 Assert (fe_collection[comp].has_support_points(),
1712 get_unit_support_points()));
1715 hp_fe_values (fe_collection, quadrature_collection,
1718 std::vector<bool> already_touched (n_dofs,
false);
1720 std::vector<types::global_dof_index> local_dof_indices;
1721 typename DoFHandlerType::active_cell_iterator begin = dof.begin_active();
1722 typename DoFHandlerType::active_cell_iterator end = dof.end();
1723 for ( ; begin != end; ++begin)
1725 const unsigned int dofs_per_cell = begin->get_fe().dofs_per_cell;
1726 local_dof_indices.resize (dofs_per_cell);
1727 hp_fe_values.
reinit (begin);
1730 begin->get_active_or_mg_dof_indices(local_dof_indices);
1731 const std::vector<Point<DoFHandlerType::space_dimension> > &points
1733 for (
unsigned int i=0; i<dofs_per_cell; ++i)
1734 if (!already_touched[local_dof_indices[i]])
1736 support_point_list[local_dof_indices[i]].first = points[i];
1737 support_point_list[local_dof_indices[i]].second =
1738 local_dof_indices[i];
1739 already_touched[local_dof_indices[i]] =
true;
1744 std::sort (support_point_list.begin(), support_point_list.end(),
1747 new_indices[support_point_list[i].second] = i;
1753 template <
typename DoFHandlerType>
1755 const unsigned int level,
1757 const bool dof_wise_renumbering)
1759 std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1760 std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1762 dof_wise_renumbering);
1764 dof.renumber_dofs(level, renumbering);
1769 template <
typename DoFHandlerType>
1772 (std::vector<types::global_dof_index> &new_indices,
1773 std::vector<types::global_dof_index> &reverse,
1774 const DoFHandlerType &dof,
1775 const unsigned int level,
1777 const bool dof_wise_renumbering)
1779 if (dof_wise_renumbering ==
false)
1781 std::vector<typename DoFHandlerType::level_cell_iterator> ordered_cells;
1782 ordered_cells.reserve (dof.get_triangulation().n_cells(level));
1784 DoFHandlerType::space_dimension> comparator(direction);
1786 typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
1787 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1791 ordered_cells.push_back(p);
1794 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1800 Assert (dof.get_fe().has_support_points(),
1802 const unsigned int n_dofs = dof.n_dofs(level);
1803 std::vector<std::pair<Point<DoFHandlerType::space_dimension>,
unsigned int> > support_point_list
1810 std::vector<bool> already_touched (dof.n_dofs(),
false);
1812 const unsigned int dofs_per_cell = dof.
get_fe().dofs_per_cell;
1813 std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1814 typename DoFHandlerType::level_cell_iterator begin = dof.begin(level);
1815 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1816 for ( ; begin != end; ++begin)
1819 DoFHandlerType::space_dimension>::cell_iterator &begin_tria = begin;
1820 begin->get_active_or_mg_dof_indices(local_dof_indices);
1821 fe_values.reinit (begin_tria);
1822 const std::vector<Point<DoFHandlerType::space_dimension> > &points
1823 = fe_values.get_quadrature_points ();
1824 for (
unsigned int i=0; i<dofs_per_cell; ++i)
1825 if (!already_touched[local_dof_indices[i]])
1827 support_point_list[local_dof_indices[i]].first = points[i];
1828 support_point_list[local_dof_indices[i]].second =
1829 local_dof_indices[i];
1830 already_touched[local_dof_indices[i]] =
true;
1835 std::sort (support_point_list.begin(), support_point_list.end(),
1838 new_indices[support_point_list[i].second] = i;
1864 ClockCells (
const Point<dim> ¢er,
bool counter) :
1872 template <
class DHCellIterator>
1873 bool operator () (
const DHCellIterator &c1,
1874 const DHCellIterator &c2)
const 1878 return compare (c1, c2, std::integral_constant<int, dim>());
1885 template <
class DHCellIterator,
int xdim>
1886 bool compare (
const DHCellIterator &c1,
1887 const DHCellIterator &c2,
1888 std::integral_constant<int, xdim>)
const 1892 const double s1 = std::atan2(v1[0], v1[1]);
1893 const double s2 = std::atan2(v2[0], v2[1]);
1894 return ( counter ? (s1>s2) : (s2>s1));
1902 template <
class DHCellIterator>
1903 bool compare (
const DHCellIterator &,
1904 const DHCellIterator &,
1905 std::integral_constant<int, 1>)
const 1908 ExcMessage (
"This operation only makes sense for dim>=2."));
1917 template <
typename DoFHandlerType>
1920 DoFHandlerType &dof,
1924 std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1927 dof.renumber_dofs(renumbering);
1932 template <
typename DoFHandlerType>
1935 (std::vector<types::global_dof_index> &new_indices,
1936 const DoFHandlerType &dof,
1940 std::vector<typename DoFHandlerType::active_cell_iterator> ordered_cells;
1941 ordered_cells.reserve (dof.get_triangulation().n_active_cells());
1942 internal::ClockCells<DoFHandlerType::space_dimension> comparator(center, counter);
1944 typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
1945 typename DoFHandlerType::active_cell_iterator end = dof.end();
1949 ordered_cells.push_back(p);
1952 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1954 std::vector<types::global_dof_index> reverse(new_indices.size());
1960 template <
typename DoFHandlerType>
1962 const unsigned int level,
1966 std::vector<typename DoFHandlerType::level_cell_iterator> ordered_cells;
1967 ordered_cells.reserve(dof.get_triangulation().n_active_cells());
1968 internal::ClockCells<DoFHandlerType::space_dimension> comparator(center, counter);
1970 typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
1971 typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1975 ordered_cells.push_back(p);
1978 std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1985 template <
typename DoFHandlerType>
1989 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1993 dof_handler.renumber_dofs(renumbering);
1998 template <
typename DoFHandlerType>
2001 std::vector<types::global_dof_index> &new_indices,
2002 const DoFHandlerType &dof_handler)
2005 Assert(new_indices.size() == n_dofs,
2008 for (
unsigned int i=0; i<n_dofs; ++i)
2013 ::boost::mt19937 random_number_generator;
2014 for (
unsigned int i=1; i<n_dofs; ++i)
2017 const unsigned int j
2018 = ::boost::random::uniform_int_distribution<>(0, i)(random_number_generator);
2022 std::swap (new_indices[i], new_indices[j]);
2028 template <
typename DoFHandlerType>
2033 ExcMessage(
"Parallel triangulations are already enumerated according to their MPI process id."));
2035 std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
2039 dof_handler.renumber_dofs(renumbering);
2044 template <
typename DoFHandlerType>
2047 const DoFHandlerType &dof_handler)
2050 Assert (new_dof_indices.size() == n_dofs,
2056 std::vector<types::subdomain_id> subdomain_association (n_dofs);
2058 subdomain_association);
2059 const unsigned int n_subdomains
2060 = *std::max_element (subdomain_association.begin(),
2061 subdomain_association.end()) + 1;
2070 std::fill (new_dof_indices.begin(), new_dof_indices.end(),
2075 if (subdomain_association[i] == subdomain)
2079 new_dof_indices[i] = next_free_index;
2085 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
2087 == new_dof_indices.end(),
2096 #include "dof_renumbering.inst" 2099 DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcFEHasNoSupportPoints()
types::global_dof_index size_type
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)
void hierarchical(DoFHandler< dim > &dof_handler)
cell_iterator end() const
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 >())
ActiveSelector::active_cell_iterator active_cell_iterator
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
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
static ::ExceptionBase & ExcDoFHandlerNotInitialized()
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)
const std::vector< types::global_dof_index > & n_locally_owned_dofs_per_processor() const
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
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 compute_random(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &dof_handler)
unsigned int subdomain_id
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)
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
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
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 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
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)