Reference documentation for deal.II version 8.5.1
dof_renumbering.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2016 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
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>
21 
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>
26 
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>
31 
32 #include <deal.II/grid/tria_iterator.h>
33 #include <deal.II/grid/tria.h>
34 
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>
39 
40 #include <deal.II/multigrid/mg_tools.h>
41 
42 #include <deal.II/distributed/tria.h>
43 
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
55 
56 #include <vector>
57 #include <map>
58 #include <algorithm>
59 #include <cmath>
60 #include <functional>
61 
62 
63 DEAL_II_NAMESPACE_OPEN
64 
65 namespace DoFRenumbering
66 {
67  namespace boost
68  {
69  namespace boosttypes
70  {
71  using namespace ::boost;
72  using namespace std;
73 
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;
79 
80  typedef std::pair<size_type, size_type> Pair;
81  }
82 
83 
84  namespace internal
85  {
86  template <typename DoFHandlerType>
87  void create_graph
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)
92  {
93  {
94  // create intermediate sparsity pattern
95  // (faster than directly submitting
96  // indices)
97  ConstraintMatrix constraints;
98  if (use_constraints)
99  DoFTools::make_hanging_node_constraints (dof_handler, constraints);
100  constraints.close ();
101  DynamicSparsityPattern dsp (dof_handler.n_dofs(),
102  dof_handler.n_dofs());
103  DoFTools::make_sparsity_pattern (dof_handler, dsp, constraints);
104 
105  // submit the entries to the boost graph
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);
109  }
110 
111  boosttypes::graph_traits<boosttypes::Graph>::vertex_iterator ui, ui_end;
112 
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);
116  }
117  }
118 
119 
120  template <typename DoFHandlerType>
121  void
122  Cuthill_McKee (DoFHandlerType &dof_handler,
123  const bool reversed_numbering,
124  const bool use_constraints)
125  {
126  std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
127  DoFHandlerType::invalid_dof_index);
128  compute_Cuthill_McKee(renumbering, dof_handler, reversed_numbering,
129  use_constraints);
130 
131  // actually perform renumbering;
132  // this is dimension specific and
133  // thus needs an own function
134  dof_handler.renumber_dofs (renumbering);
135  }
136 
137 
138  template <typename DoFHandlerType>
139  void
140  compute_Cuthill_McKee (std::vector<types::global_dof_index> &new_dof_indices,
141  const DoFHandlerType &dof_handler,
142  const bool reversed_numbering,
143  const bool use_constraints)
144  {
145  boosttypes::Graph
146  graph(dof_handler.n_dofs());
147  boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type
148  graph_degree;
149 
150  internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
151 
152  boosttypes::property_map<boosttypes::Graph, boosttypes::vertex_index_t>::type
153  index_map = get(::boost::vertex_index, graph);
154 
155 
156  std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
157 
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));
162  else
163  ::boost::cuthill_mckee_ordering(graph, inv_perm.begin(),
164  get(::boost::vertex_color, graph),
165  make_degree_map(graph));
166 
167  for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
168  new_dof_indices[index_map[inv_perm[c]]] = c;
169 
170  Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
171  DoFHandlerType::invalid_dof_index) == new_dof_indices.end(),
172  ExcInternalError());
173  }
174 
175 
176 
177  template <typename DoFHandlerType>
178  void
179  king_ordering (DoFHandlerType &dof_handler,
180  const bool reversed_numbering,
181  const bool use_constraints)
182  {
183  std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
184  DoFHandlerType::invalid_dof_index);
185  compute_king_ordering(renumbering, dof_handler, reversed_numbering,
186  use_constraints);
187 
188  // actually perform renumbering;
189  // this is dimension specific and
190  // thus needs an own function
191  dof_handler.renumber_dofs (renumbering);
192  }
193 
194 
195  template <typename DoFHandlerType>
196  void
197  compute_king_ordering (std::vector<types::global_dof_index> &new_dof_indices,
198  const DoFHandlerType &dof_handler,
199  const bool reversed_numbering,
200  const bool use_constraints)
201  {
202  boosttypes::Graph
203  graph(dof_handler.n_dofs());
204  boosttypes::property_map<boosttypes::Graph,boosttypes::vertex_degree_t>::type
205  graph_degree;
206 
207  internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
208 
209  boosttypes::property_map<boosttypes::Graph, boosttypes::vertex_index_t>::type
210  index_map = get(::boost::vertex_index, graph);
211 
212 
213  std::vector<boosttypes::Vertex> inv_perm(num_vertices(graph));
214 
215  if (reversed_numbering == false)
216  ::boost::king_ordering(graph, inv_perm.rbegin());
217  else
218  ::boost::king_ordering(graph, inv_perm.begin());
219 
220  for (boosttypes::size_type c = 0; c != inv_perm.size(); ++c)
221  new_dof_indices[index_map[inv_perm[c]]] = c;
222 
223  Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
224  DoFHandlerType::invalid_dof_index) == new_dof_indices.end(),
225  ExcInternalError());
226  }
227 
228 
229 
230  template <typename DoFHandlerType>
231  void
232  minimum_degree (DoFHandlerType &dof_handler,
233  const bool reversed_numbering,
234  const bool use_constraints)
235  {
236  std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
237  DoFHandlerType::invalid_dof_index);
238  compute_minimum_degree(renumbering, dof_handler, reversed_numbering,
239  use_constraints);
240 
241  // actually perform renumbering;
242  // this is dimension specific and
243  // thus needs an own function
244  dof_handler.renumber_dofs (renumbering);
245  }
246 
247 
248  template <typename DoFHandlerType>
249  void
250  compute_minimum_degree (std::vector<types::global_dof_index> &new_dof_indices,
251  const DoFHandlerType &dof_handler,
252  const bool reversed_numbering,
253  const bool use_constraints)
254  {
255  (void)use_constraints;
256  Assert (use_constraints == false, ExcNotImplemented());
257 
258  // the following code is pretty
259  // much a verbatim copy of the
260  // sample code for the
261  // minimum_degree_ordering manual
262  // page from the BOOST Graph
263  // Library
264  using namespace ::boost;
265 
266  int delta = 0;
267 
268  // must be BGL directed graph now
269  typedef adjacency_list<vecS, vecS, directedS> Graph;
270 
271  int n = dof_handler.n_dofs();
272 
273  Graph G(n);
274 
275  std::vector<::types::global_dof_index> dofs_on_this_cell;
276 
277  typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
278  endc = dof_handler.end();
279 
280  for (; cell!=endc; ++cell)
281  {
282 
283  const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
284 
285  dofs_on_this_cell.resize (dofs_per_cell);
286 
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])
291  {
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);
294  }
295  }
296 
297 
298  typedef std::vector<int> Vector;
299 
300 
301  Vector inverse_perm(n, 0);
302 
303  Vector perm(n, 0);
304 
305 
306  Vector supernode_sizes(n, 1);
307  // init has to be 1
308 
309  ::boost::property_map<Graph, vertex_index_t>::type
310  id = get(vertex_index, G);
311 
312 
313  Vector degree(n, 0);
314 
315 
316  minimum_degree_ordering
317  (G,
318  make_iterator_property_map(&degree[0], id, degree[0]),
319  &inverse_perm[0],
320  &perm[0],
321  make_iterator_property_map(&supernode_sizes[0], id, supernode_sizes[0]),
322  delta, id);
323 
324 
325  for (int i=0; i<n; ++i)
326  {
327  Assert (std::find (perm.begin(), perm.end(), i)
328  != perm.end(),
329  ExcInternalError());
330  Assert (std::find (inverse_perm.begin(), inverse_perm.end(), i)
331  != inverse_perm.end(),
332  ExcInternalError());
333  Assert (inverse_perm[perm[i]] == i, ExcInternalError());
334  }
335 
336  if (reversed_numbering == true)
337  std::copy (perm.begin(), perm.end(),
338  new_dof_indices.begin());
339  else
340  std::copy (inverse_perm.begin(), inverse_perm.end(),
341  new_dof_indices.begin());
342  }
343 
344  } // namespace boost
345 
346 
347 
348  template <typename DoFHandlerType>
349  void
350  Cuthill_McKee (DoFHandlerType &dof_handler,
351  const bool reversed_numbering,
352  const bool use_constraints,
353  const std::vector<types::global_dof_index> &starting_indices)
354  {
355  std::vector<types::global_dof_index> renumbering(dof_handler.locally_owned_dofs().n_elements(),
356  DoFHandlerType::invalid_dof_index);
357  compute_Cuthill_McKee(renumbering, dof_handler, reversed_numbering,
358  use_constraints, starting_indices);
359 
360  // actually perform renumbering;
361  // this is dimension specific and
362  // thus needs an own function
363  dof_handler.renumber_dofs (renumbering);
364  }
365 
366 
367 
368  template <typename DoFHandlerType>
369  void
370  compute_Cuthill_McKee (std::vector<types::global_dof_index> &new_indices,
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)
375  {
376  // see if there is anything to do at all or whether we can skip the work on this processor
377  if (dof_handler.locally_owned_dofs().n_elements() == 0)
378  {
379  Assert (new_indices.size() == 0, ExcInternalError());
380  return;
381  }
382 
383  // make the connection graph. in 2d/3d use an intermediate compressed
384  // sparsity pattern since the we don't have very good estimates for
385  // max_couplings_between_dofs() in 3d and this then leads to excessive
386  // memory consumption
387  //
388  // note that if constraints are not requested, then the 'constraints'
389  // object will be empty and nothing happens
390  ConstraintMatrix constraints;
391  if (use_constraints)
392  {
393  IndexSet relevant_dofs;
394  DoFTools::extract_locally_relevant_dofs(dof_handler, relevant_dofs);
395  constraints.reinit(relevant_dofs);
396  DoFTools::make_hanging_node_constraints (dof_handler, constraints);
397  }
398  constraints.close ();
399 
400  const IndexSet locally_owned = dof_handler.locally_owned_dofs();
401 
402  // otherwise compute the Cuthill-McKee permutation
403  DynamicSparsityPattern dsp (dof_handler.n_dofs(),
404  dof_handler.n_dofs(),
405  locally_owned);
406  DoFTools::make_sparsity_pattern (dof_handler, dsp, constraints);
407 
408  // constraints are not needed anymore
409  constraints.clear ();
410 
411  // If the index set is not complete, need to get indices in local index
412  // space.
413  if (locally_owned.n_elements() != locally_owned.size())
414  {
415  // Create sparsity pattern from dsp by transferring its indices to
416  // processor-local index space and doing Cuthill-McKee there
417  DynamicSparsityPattern sparsity(locally_owned.n_elements(),
418  locally_owned.n_elements());
419  std::vector<types::global_dof_index> row_entries;
420  for (unsigned int i=0; i<locally_owned.n_elements(); ++i)
421  {
422  const types::global_dof_index row = locally_owned.nth_index_in_set(i);
423  const unsigned int row_length = dsp.row_length(row);
424  row_entries.clear();
425  for (unsigned int j=0; j<row_length; ++j)
426  {
427  const unsigned int col = dsp.column_number(row, j);
428  if (col != row && locally_owned.is_element(col))
429  row_entries.push_back(locally_owned.index_within_set(col));
430  }
431  sparsity.add_entries(i, row_entries.begin(), row_entries.end(),
432  true);
433  }
434 
435  // translate starting indices from global to local indices
436  std::vector<types::global_dof_index> local_starting_indices (starting_indices.size());
437  for (unsigned int i=0; i<starting_indices.size(); ++i)
438  {
439  Assert (locally_owned.is_element (starting_indices[i]),
440  ExcMessage ("You specified global degree of freedom "
441  + Utilities::to_string(starting_indices[i]) +
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]);
445  }
446 
447  // then do the renumbering on the locally owned portion
448  AssertDimension(new_indices.size(), locally_owned.n_elements());
449  SparsityTools::reorder_Cuthill_McKee (sparsity, new_indices,
450  local_starting_indices);
451  if (reversed_numbering)
452  new_indices = Utilities::reverse_permutation (new_indices);
453 
454  // convert indices back to global index space
455  for (std::size_t i=0; i<new_indices.size(); ++i)
456  new_indices[i] = locally_owned.nth_index_in_set(new_indices[i]);
457  }
458  else
459  {
460  AssertDimension(new_indices.size(), dsp.n_rows());
461  SparsityTools::reorder_Cuthill_McKee (dsp, new_indices,
462  starting_indices);
463  if (reversed_numbering)
464  new_indices = Utilities::reverse_permutation (new_indices);
465  }
466  }
467 
468 
469 
470  template <typename DoFHandlerType>
471  void Cuthill_McKee (DoFHandlerType &dof_handler,
472  const unsigned int level,
473  const bool reversed_numbering,
474  const std::vector<types::global_dof_index> &starting_indices)
475  {
476  Assert(dof_handler.n_dofs(level) != numbers::invalid_dof_index,
478 
479  // make the connection graph
480  DynamicSparsityPattern dsp (dof_handler.n_dofs(level),
481  dof_handler.n_dofs(level));
482  MGTools::make_sparsity_pattern (dof_handler, dsp, level);
483 
484  std::vector<types::global_dof_index> new_indices(dsp.n_rows());
485  SparsityTools::reorder_Cuthill_McKee (dsp, new_indices,
486  starting_indices);
487 
488  if (reversed_numbering)
489  new_indices = Utilities::reverse_permutation (new_indices);
490 
491  // actually perform renumbering;
492  // this is dimension specific and
493  // thus needs an own function
494  dof_handler.renumber_dofs (level, new_indices);
495  }
496 
497 
498 
499  template <int dim, int spacedim>
500  void
502  const std::vector<unsigned int> &component_order_arg)
503  {
504  std::vector<types::global_dof_index> renumbering (dof_handler.n_locally_owned_dofs(),
506 
508  start = dof_handler.begin_active();
509  const typename DoFHandler<dim,spacedim>::level_cell_iterator
510  end = dof_handler.end();
511 
512  const types::global_dof_index result =
513  compute_component_wise<dim,spacedim,
515  typename DoFHandler<dim,spacedim>::level_cell_iterator>
516  (renumbering, start, end, component_order_arg, false);
517  if (result == 0)
518  return;
519 
520  // verify that the last numbered
521  // degree of freedom is either
522  // equal to the number of degrees
523  // of freedom in total (the
524  // sequential case) or in the
525  // distributed case at least
526  // makes sense
527  Assert ((result == dof_handler.n_locally_owned_dofs())
528  ||
529  ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
530  &&
531  (result <= dof_handler.n_dofs())),
533 
534  dof_handler.renumber_dofs (renumbering);
535 
536  // for (unsigned int level=0;level<dof_handler.get_triangulation().n_levels();++level)
537  // if (dof_handler.n_dofs(level) != numbers::invalid_dof_index)
538  // component_wise(dof_handler, level, component_order_arg);
539  }
540 
541 
542 
543  template <int dim>
544  void
546  const std::vector<unsigned int> &component_order_arg)
547  {
548 //TODO: Merge with previous function
549  std::vector<types::global_dof_index> renumbering (dof_handler.n_dofs(),
551 
553  start = dof_handler.begin_active();
554  const typename hp::DoFHandler<dim>::level_cell_iterator
555  end = dof_handler.end();
556 
557  const types::global_dof_index result =
558  compute_component_wise<hp::DoFHandler<dim>::dimension,hp::DoFHandler<dim>::space_dimension,
560  typename hp::DoFHandler<dim>::level_cell_iterator>
561  (renumbering, start, end, component_order_arg, false);
562 
563  if (result == 0) return;
564 
565  Assert (result == dof_handler.n_dofs(),
567 
568  dof_handler.renumber_dofs (renumbering);
569  }
570 
571 
572 
573  template <typename DoFHandlerType>
574  void
575  component_wise (DoFHandlerType &dof_handler,
576  const unsigned int level,
577  const std::vector<unsigned int> &component_order_arg)
578  {
579  Assert(dof_handler.n_dofs(level) != numbers::invalid_dof_index,
581 
582  std::vector<types::global_dof_index> renumbering (dof_handler.n_dofs(level),
583  DoFHandlerType::invalid_dof_index);
584 
585  typename DoFHandlerType::level_cell_iterator start =dof_handler.begin(level);
586  typename DoFHandlerType::level_cell_iterator end = dof_handler.end(level);
587 
588  const types::global_dof_index result =
589  compute_component_wise<DoFHandlerType::dimension, DoFHandlerType::space_dimension,
590  typename DoFHandlerType::level_cell_iterator, typename DoFHandlerType::level_cell_iterator>
591  (renumbering, start, end, component_order_arg, true);
592 
593  if (result == 0) return;
594 
595  Assert (result == dof_handler.n_dofs(level),
597 
598  if (renumbering.size()!=0)
599  dof_handler.renumber_dofs (level, renumbering);
600  }
601 
602 
603 
604  template <int dim, int spacedim, class ITERATOR, class ENDITERATOR>
606  compute_component_wise (std::vector<types::global_dof_index> &new_indices,
607  const ITERATOR &start,
608  const ENDITERATOR &end,
609  const std::vector<unsigned int> &component_order_arg,
610  bool is_level_operation)
611  {
613  fe_collection (start->get_dof_handler().get_fe ());
614 
615  // do nothing if the FE has only
616  // one component
617  if (fe_collection.n_components() == 1)
618  {
619  new_indices.resize(0);
620  return 0;
621  }
622 
623  // Copy last argument into a
624  // writable vector.
625  std::vector<unsigned int> component_order (component_order_arg);
626  // If the last argument was an
627  // empty vector, set up things to
628  // store components in the order
629  // found in the system.
630  if (component_order.size() == 0)
631  for (unsigned int i=0; i<fe_collection.n_components(); ++i)
632  component_order.push_back (i);
633 
634  Assert (component_order.size() == fe_collection.n_components(),
635  ExcDimensionMismatch(component_order.size(), fe_collection.n_components()));
636 
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()));
640 
641  // vector to hold the dof indices on
642  // the cell we visit at a time
643  std::vector<types::global_dof_index> local_dof_indices;
644 
645  // prebuilt list to which component
646  // a given dof on a cell
647  // should go. note that we get into
648  // trouble here if the shape
649  // function is not primitive, since
650  // then there is no single vector
651  // component to which it
652  // belongs. in this case, assign it
653  // to the first vector component to
654  // which it belongs
655  std::vector<std::vector<unsigned int> > component_list (fe_collection.size());
656  for (unsigned int f=0; f<fe_collection.size(); ++f)
657  {
658  const FiniteElement<dim,spacedim> &fe = fe_collection[f];
659  const unsigned int dofs_per_cell = fe.dofs_per_cell;
660  component_list[f].resize(dofs_per_cell);
661  for (unsigned int i=0; i<dofs_per_cell; ++i)
662  if (fe.is_primitive(i))
663  component_list[f][i]
664  = component_order[fe.system_to_component_index(i).first];
665  else
666  {
667  const unsigned int comp
669 
670  // then associate this degree
671  // of freedom with this
672  // component
673  component_list[f][i] = component_order[comp];
674  }
675  }
676 
677  // set up a map where for each
678  // component the respective degrees
679  // of freedom are collected.
680  //
681  // note that this map is sorted by
682  // component but that within each
683  // component it is NOT sorted by
684  // dof index. note also that some
685  // dof indices are entered
686  // multiply, so we will have to
687  // take care of that
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)
691  {
692  if (is_level_operation)
693  {
694  //we are dealing with mg dofs, skip foreign level cells:
695  if (!cell->is_locally_owned_on_level())
696  continue;
697  }
698  else
699  {
700  //we are dealing with active dofs, skip the loop if not locally
701  // owned:
702  if (!cell->is_locally_owned())
703  continue;
704  }
705  // on each cell: get dof indices
706  // and insert them into the global
707  // list using their component
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]);
716  }
717 
718  // now we've got all indices sorted
719  // into buckets labeled by their
720  // target component number. we've
721  // only got to traverse this list
722  // and assign the new indices
723  //
724  // however, we first want to sort
725  // the indices entered into the
726  // buckets to preserve the order
727  // within each component and during
728  // this also remove duplicate
729  // entries
730  //
731  // note that we no longer have to
732  // care about non-primitive shape
733  // functions since the buckets
734  // corresponding to the second and
735  // following vector components of a
736  // non-primitive FE will simply be
737  // empty, everything being shoved
738  // into the first one. The same
739  // holds if several components were
740  // joined into a single target.
741  for (unsigned int component=0; component<fe_collection.n_components();
742  ++component)
743  {
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());
750  }
751 
752  // calculate the number of locally owned
753  // DoFs per bucket
754  const unsigned int n_buckets = fe_collection.n_components();
755  std::vector<types::global_dof_index> shifts(n_buckets);
756 
758  = (dynamic_cast<const parallel::Triangulation<dim,spacedim>*>
759  (&start->get_dof_handler().get_triangulation())))
760  {
761 #ifdef DEAL_II_WITH_MPI
762  std::vector<types::global_dof_index> local_dof_count(n_buckets);
763 
764  for (unsigned int c=0; c<n_buckets; ++c)
765  local_dof_count[c] = component_to_dof_map[c].size();
766 
767 
768  // gather information from all CPUs
769  std::vector<types::global_dof_index>
770  all_dof_counts(fe_collection.n_components() *
771  Utilities::MPI::n_mpi_processes (tria->get_communicator()));
772 
773  const int ierr = MPI_Allgather ( &local_dof_count[0],
774  n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
775  &all_dof_counts[0],
776  n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
777  tria->get_communicator());
778  AssertThrowMPI(ierr);
779 
780  for (unsigned int i=0; i<n_buckets; ++i)
781  Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
782  ==
783  local_dof_count[i],
784  ExcInternalError());
785 
786  //calculate shifts
787  unsigned int cumulated = 0;
788  for (unsigned int c=0; c<n_buckets; ++c)
789  {
790  shifts[c]=cumulated;
791  for (types::subdomain_id i=0; i<tria->locally_owned_subdomain(); ++i)
792  shifts[c] += all_dof_counts[c+n_buckets*i];
793  for (unsigned int i=0; i<Utilities::MPI::n_mpi_processes (tria->get_communicator()); ++i)
794  cumulated += all_dof_counts[c+n_buckets*i];
795  }
796 #else
797  (void)tria;
798  Assert (false, ExcInternalError());
799 #endif
800  }
801  else
802  {
803  shifts[0] = 0;
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();
806  }
807 
808 
809 
810 
811  // now concatenate all the
812  // components in the order the user
813  // desired to see
814  types::global_dof_index next_free_index = 0;
815  for (unsigned int component=0; component<fe_collection.n_components(); ++component)
816  {
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();
820 
821  next_free_index = shifts[component];
822 
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)
826  {
827  Assert (start->get_dof_handler().locally_owned_dofs()
828  .index_within_set(*dof_index)
829  <
830  new_indices.size(),
831  ExcInternalError());
832  new_indices[start->get_dof_handler().locally_owned_dofs()
833  .index_within_set(*dof_index)]
834  = next_free_index++;
835  }
836  }
837 
838  return next_free_index;
839  }
840 
841 
842 
843  template <int dim, int spacedim>
844  void
846  {
847  std::vector<types::global_dof_index> renumbering (dof_handler.n_locally_owned_dofs(),
849 
851  start = dof_handler.begin_active();
852  const typename DoFHandler<dim,spacedim>::level_cell_iterator
853  end = dof_handler.end();
854 
855  const types::global_dof_index result =
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);
859  if (result == 0)
860  return;
861 
862  // verify that the last numbered
863  // degree of freedom is either
864  // equal to the number of degrees
865  // of freedom in total (the
866  // sequential case) or in the
867  // distributed case at least
868  // makes sense
869  Assert ((result == dof_handler.n_locally_owned_dofs())
870  ||
871  ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
872  &&
873  (result <= dof_handler.n_dofs())),
875 
876  dof_handler.renumber_dofs (renumbering);
877  }
878 
879 
880 
881  template <int dim, int spacedim>
882  void
884  {
885  std::vector<types::global_dof_index> renumbering (dof_handler.n_dofs(),
887 
889  start = dof_handler.begin_active();
890  const typename hp::DoFHandler<dim,spacedim>::level_cell_iterator
891  end = dof_handler.end();
892 
893  const types::global_dof_index result =
894  compute_block_wise<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator,
895  typename hp::DoFHandler<dim,spacedim>::level_cell_iterator>(renumbering,
896  start, end, false);
897 
898  if (result == 0)
899  return;
900 
901  Assert (result == dof_handler.n_dofs(),
903 
904  dof_handler.renumber_dofs (renumbering);
905  }
906 
907 
908 
909  template <int dim, int spacedim>
910  void
911  block_wise (DoFHandler<dim,spacedim> &dof_handler, const unsigned int level)
912  {
913  Assert(dof_handler.n_dofs(level) != numbers::invalid_dof_index,
915 
916  std::vector<types::global_dof_index> renumbering (dof_handler.n_dofs(level),
918 
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);
923 
924  const types::global_dof_index result =
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);
928 
929  if (result == 0) return;
930 
931  Assert (result == dof_handler.n_dofs(level),
933 
934  if (renumbering.size()!=0)
935  dof_handler.renumber_dofs (level, renumbering);
936  }
937 
938 
939 
940  template <int dim, int spacedim, class ITERATOR, class ENDITERATOR>
942  compute_block_wise (std::vector<types::global_dof_index> &new_indices,
943  const ITERATOR &start,
944  const ENDITERATOR &end,
945  const bool is_level_operation)
946  {
948  fe_collection (start->get_dof_handler().get_fe ());
949 
950  // do nothing if the FE has only
951  // one component
952  if (fe_collection.n_blocks() == 1)
953  {
954  new_indices.resize(0);
955  return 0;
956  }
957 
958  // vector to hold the dof indices on
959  // the cell we visit at a time
960  std::vector<types::global_dof_index> local_dof_indices;
961 
962  // prebuilt list to which block
963  // a given dof on a cell
964  // should go.
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)
967  {
968  const FiniteElement<dim,spacedim> &fe = fe_collection[f];
969  block_list[f].resize(fe.dofs_per_cell);
970  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
971  block_list[f][i]
972  = fe.system_to_block_index(i).first;
973  }
974 
975  // set up a map where for each
976  // block the respective degrees
977  // of freedom are collected.
978  //
979  // note that this map is sorted by
980  // block but that within each
981  // block it is NOT sorted by
982  // dof index. note also that some
983  // dof indices are entered
984  // multiply, so we will have to
985  // take care of that
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)
989  {
990  if (is_level_operation)
991  {
992  //we are dealing with mg dofs, skip foreign level cells:
993  if (!cell->is_locally_owned_on_level())
994  continue;
995  }
996  else
997  {
998  //we are dealing with active dofs, skip the loop if not locally
999  // owned:
1000  if (!cell->is_locally_owned())
1001  continue;
1002  }
1003 
1004  // on each cell: get dof indices
1005  // and insert them into the global
1006  // list using their component
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]);
1015  }
1016 
1017  // now we've got all indices sorted
1018  // into buckets labeled by their
1019  // target block number. we've
1020  // only got to traverse this list
1021  // and assign the new indices
1022  //
1023  // however, we first want to sort
1024  // the indices entered into the
1025  // buckets to preserve the order
1026  // within each component and during
1027  // this also remove duplicate
1028  // entries
1029  for (unsigned int block=0; block<fe_collection.n_blocks();
1030  ++block)
1031  {
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());
1038  }
1039 
1040  // calculate the number of locally owned
1041  // DoFs per bucket
1042  const unsigned int n_buckets = fe_collection.n_blocks();
1043  std::vector<types::global_dof_index> shifts(n_buckets);
1044 
1046  = (dynamic_cast<const parallel::Triangulation<dim,spacedim>*>
1047  (&start->get_dof_handler().get_triangulation())))
1048  {
1049 #ifdef DEAL_II_WITH_MPI
1050  std::vector<types::global_dof_index> local_dof_count(n_buckets);
1051 
1052  for (unsigned int c=0; c<n_buckets; ++c)
1053  local_dof_count[c] = block_to_dof_map[c].size();
1054 
1055 
1056  // gather information from all CPUs
1057  std::vector<types::global_dof_index>
1058  all_dof_counts(fe_collection.n_components() *
1059  Utilities::MPI::n_mpi_processes (tria->get_communicator()));
1060 
1061  const int ierr = MPI_Allgather ( &local_dof_count[0],
1062  n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
1063  &all_dof_counts[0],
1064  n_buckets, DEAL_II_DOF_INDEX_MPI_TYPE,
1065  tria->get_communicator());
1066  AssertThrowMPI(ierr);
1067 
1068  for (unsigned int i=0; i<n_buckets; ++i)
1069  Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
1070  ==
1071  local_dof_count[i],
1072  ExcInternalError());
1073 
1074  //calculate shifts
1075  types::global_dof_index cumulated = 0;
1076  for (unsigned int c=0; c<n_buckets; ++c)
1077  {
1078  shifts[c]=cumulated;
1079  for (types::subdomain_id i=0; i<tria->locally_owned_subdomain(); ++i)
1080  shifts[c] += all_dof_counts[c+n_buckets*i];
1081  for (unsigned int i=0; i<Utilities::MPI::n_mpi_processes (tria->get_communicator()); ++i)
1082  cumulated += all_dof_counts[c+n_buckets*i];
1083  }
1084 #else
1085  (void)tria;
1086  Assert (false, ExcInternalError());
1087 #endif
1088  }
1089  else
1090  {
1091  shifts[0] = 0;
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();
1094  }
1095 
1096 
1097 
1098 
1099  // now concatenate all the
1100  // components in the order the user
1101  // desired to see
1102  types::global_dof_index next_free_index = 0;
1103  for (unsigned int block=0; block<fe_collection.n_blocks(); ++block)
1104  {
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();
1108 
1109  next_free_index = shifts[block];
1110 
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)
1114  {
1115  Assert (start->get_dof_handler().locally_owned_dofs()
1116  .index_within_set(*dof_index)
1117  <
1118  new_indices.size(),
1119  ExcInternalError());
1120  new_indices[start->get_dof_handler().locally_owned_dofs()
1121  .index_within_set(*dof_index)]
1122  = next_free_index++;
1123  }
1124  }
1125 
1126  return next_free_index;
1127  }
1128 
1129 
1130 
1131  namespace
1132  {
1133  // helper function for hierarchical()
1134 
1135 // Note that this function only works for active dofs.
1136  template <int dim, class iterator>
1138  compute_hierarchical_recursive (
1139  types::global_dof_index next_free,
1140  std::vector<types::global_dof_index> &new_indices,
1141  const iterator &cell,
1142  const IndexSet &locally_owned)
1143  {
1144  if (cell->has_children())
1145  {
1146  //recursion
1147  for (unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell; ++c)
1148  next_free = compute_hierarchical_recursive<dim> (
1149  next_free,
1150  new_indices,
1151  cell->child (c),
1152  locally_owned);
1153  }
1154  else
1155  {
1156  if (cell->is_locally_owned())
1157  {
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);
1161 
1162  for (unsigned int i = 0; i < dofs_per_cell; ++i)
1163  {
1164  if (locally_owned.is_element (local_dof_indices[i]))
1165  {
1166  // this is a locally owned DoF, assign new number if not assigned a number yet
1167  unsigned int idx = locally_owned.index_within_set (local_dof_indices[i]);
1168  if (new_indices[idx] == DoFHandler<dim>::invalid_dof_index)
1169  {
1170  new_indices[idx] = locally_owned.nth_index_in_set (next_free);
1171  next_free++;
1172  }
1173  }
1174  }
1175  }
1176  }
1177  return next_free;
1178  }
1179  }
1180 
1181 
1182 
1183  template <int dim>
1184  void
1186  {
1187  std::vector<types::global_dof_index> renumbering (dof_handler.n_locally_owned_dofs(),
1189 
1191 
1192  types::global_dof_index next_free = 0;
1193  const IndexSet locally_owned = dof_handler.locally_owned_dofs();
1194 
1196  = dynamic_cast<const parallel::distributed::Triangulation<dim>*>
1197  (&dof_handler.get_triangulation());
1198 
1199  if (tria)
1200  {
1201 #ifdef DEAL_II_WITH_P4EST
1202  // this is a distributed Triangulation. We need to traverse the coarse
1203  // cells in the order p4est does
1204  for (unsigned int c = 0; c < tria->n_cells (0); ++c)
1205  {
1206  const unsigned int coarse_cell_index =
1208 
1210  this_cell (tria, 0, coarse_cell_index, &dof_handler);
1211 
1212  next_free = compute_hierarchical_recursive<dim> (next_free,
1213  renumbering,
1214  this_cell,
1215  locally_owned);
1216  }
1217 #else
1218  Assert (false, ExcNotImplemented());
1219 #endif
1220  }
1221  else
1222  {
1223  //this is not a distributed Triangulation. Traverse coarse cells in the
1224  //normal order
1225  for (cell = dof_handler.begin (0); cell != dof_handler.end (0); ++cell)
1226  next_free = compute_hierarchical_recursive<dim> (next_free,
1227  renumbering,
1228  cell,
1229  locally_owned);
1230  }
1231 
1232  // verify that the last numbered
1233  // degree of freedom is either
1234  // equal to the number of degrees
1235  // of freedom in total (the
1236  // sequential case) or in the
1237  // distributed case at least
1238  // makes sense
1239  Assert ((next_free == dof_handler.n_locally_owned_dofs())
1240  ||
1241  ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
1242  &&
1243  (next_free <= dof_handler.n_dofs())),
1245 
1246  // make sure that all local DoFs got new numbers assigned
1247  Assert (std::find (renumbering.begin(), renumbering.end(),
1249  == renumbering.end(),
1250  ExcInternalError());
1251 
1252  dof_handler.renumber_dofs(renumbering);
1253  }
1254 
1255 
1256 
1257  template <typename DoFHandlerType>
1258  void
1259  sort_selected_dofs_back (DoFHandlerType &dof_handler,
1260  const std::vector<bool> &selected_dofs)
1261  {
1262  std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1263  DoFHandlerType::invalid_dof_index);
1264  compute_sort_selected_dofs_back(renumbering, dof_handler, selected_dofs);
1265 
1266  dof_handler.renumber_dofs(renumbering);
1267  }
1268 
1269 
1270 
1271  template <typename DoFHandlerType>
1272  void
1273  sort_selected_dofs_back (DoFHandlerType &dof_handler,
1274  const std::vector<bool> &selected_dofs,
1275  const unsigned int level)
1276  {
1277  Assert(dof_handler.n_dofs(level) != numbers::invalid_dof_index,
1278  ExcNotInitialized());
1279 
1280  std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(level),
1281  DoFHandlerType::invalid_dof_index);
1282  compute_sort_selected_dofs_back(renumbering, dof_handler, selected_dofs, level);
1283 
1284  dof_handler.renumber_dofs(level, renumbering);
1285  }
1286 
1287 
1288 
1289  template <typename DoFHandlerType>
1290  void
1291  compute_sort_selected_dofs_back (std::vector<types::global_dof_index> &new_indices,
1292  const DoFHandlerType &dof_handler,
1293  const std::vector<bool> &selected_dofs)
1294  {
1295  const types::global_dof_index n_dofs = dof_handler.n_dofs();
1296  Assert (selected_dofs.size() == n_dofs,
1297  ExcDimensionMismatch (selected_dofs.size(), n_dofs));
1298 
1299  // re-sort the dofs according to
1300  // their selection state
1301  Assert (new_indices.size() == n_dofs,
1302  ExcDimensionMismatch(new_indices.size(), n_dofs));
1303 
1304  const types::global_dof_index n_selected_dofs = std::count (selected_dofs.begin(),
1305  selected_dofs.end(),
1306  false);
1307 
1308  types::global_dof_index next_unselected = 0;
1309  types::global_dof_index next_selected = n_selected_dofs;
1310  for (types::global_dof_index i=0; i<n_dofs; ++i)
1311  if (selected_dofs[i] == false)
1312  {
1313  new_indices[i] = next_unselected;
1314  ++next_unselected;
1315  }
1316  else
1317  {
1318  new_indices[i] = next_selected;
1319  ++next_selected;
1320  };
1321  Assert (next_unselected == n_selected_dofs, ExcInternalError());
1322  Assert (next_selected == n_dofs, ExcInternalError());
1323  }
1324 
1325 
1326 
1327  template <typename DoFHandlerType>
1328  void
1329  compute_sort_selected_dofs_back (std::vector<types::global_dof_index> &new_indices,
1330  const DoFHandlerType &dof_handler,
1331  const std::vector<bool> &selected_dofs,
1332  const unsigned int level)
1333  {
1334  Assert(dof_handler.n_dofs(level) != numbers::invalid_dof_index,
1335  ExcNotInitialized());
1336 
1337  const unsigned int n_dofs = dof_handler.n_dofs(level);
1338  Assert (selected_dofs.size() == n_dofs,
1339  ExcDimensionMismatch (selected_dofs.size(), n_dofs));
1340 
1341  // re-sort the dofs according to
1342  // their selection state
1343  Assert (new_indices.size() == n_dofs,
1344  ExcDimensionMismatch(new_indices.size(), n_dofs));
1345 
1346  const unsigned int n_selected_dofs = std::count (selected_dofs.begin(),
1347  selected_dofs.end(),
1348  false);
1349 
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)
1354  {
1355  new_indices[i] = next_unselected;
1356  ++next_unselected;
1357  }
1358  else
1359  {
1360  new_indices[i] = next_selected;
1361  ++next_selected;
1362  };
1363  Assert (next_unselected == n_selected_dofs, ExcInternalError());
1364  Assert (next_selected == n_dofs, ExcInternalError());
1365  }
1366 
1367 
1368 
1369  template <typename DoFHandlerType>
1370  void
1371  cell_wise (DoFHandlerType &dof,
1372  const std::vector<typename DoFHandlerType::active_cell_iterator> &cells)
1373  {
1374  std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1375  std::vector<types::global_dof_index> reverse(dof.n_dofs());
1376  compute_cell_wise(renumbering, reverse, dof, cells);
1377 
1378  dof.renumber_dofs(renumbering);
1379  }
1380 
1381 
1382  template <typename DoFHandlerType>
1383  void
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)
1389  {
1390  Assert(cells.size() == dof.get_triangulation().n_active_cells(),
1391  ExcDimensionMismatch(cells.size(),
1392  dof.get_triangulation().n_active_cells()));
1393 
1394  types::global_dof_index n_global_dofs = dof.n_dofs();
1395 
1396  // Actually, we compute the
1397  // inverse of the reordering
1398  // vector, called reverse here.
1399  // Later, irs inverse is computed
1400  // into new_indices, which is the
1401  // return argument.
1402 
1403  Assert(new_indices.size() == n_global_dofs,
1404  ExcDimensionMismatch(new_indices.size(), n_global_dofs));
1405  Assert(reverse.size() == n_global_dofs,
1406  ExcDimensionMismatch(reverse.size(), n_global_dofs));
1407 
1408  // For continuous elements, we must
1409  // make sure, that each dof is
1410  // reordered only once.
1411  std::vector<bool> already_sorted(n_global_dofs, false);
1412  std::vector<types::global_dof_index> cell_dofs;
1413 
1414  unsigned int global_index = 0;
1415 
1416  typename std::vector<typename DoFHandlerType::active_cell_iterator>::const_iterator cell;
1417 
1418  for (cell = cells.begin(); cell != cells.end(); ++cell)
1419  {
1420  // Determine the number of dofs
1421  // on this cell and reinit the
1422  // vector storing these
1423  // numbers.
1424  unsigned int n_cell_dofs = (*cell)->get_fe().n_dofs_per_cell();
1425  cell_dofs.resize(n_cell_dofs);
1426 
1427  (*cell)->get_active_or_mg_dof_indices(cell_dofs);
1428 
1429  // Sort here to make sure that
1430  // degrees of freedom inside a
1431  // single cell are in the same
1432  // order after renumbering.
1433  std::sort(cell_dofs.begin(), cell_dofs.end());
1434 
1435  for (unsigned int i=0; i<n_cell_dofs; ++i)
1436  {
1437  if (!already_sorted[cell_dofs[i]])
1438  {
1439  already_sorted[cell_dofs[i]] = true;
1440  reverse[global_index++] = cell_dofs[i];
1441  }
1442  }
1443  }
1444  Assert(global_index == n_global_dofs, ExcRenumberingIncomplete());
1445 
1446  for (types::global_dof_index i=0; i<reverse.size(); ++i)
1447  new_indices[reverse[i]] = i;
1448  }
1449 
1450 
1451 
1452  template <typename DoFHandlerType>
1453  void cell_wise
1454  (DoFHandlerType &dof,
1455  const unsigned int level,
1456  const typename std::vector<typename DoFHandlerType::level_cell_iterator> &cells)
1457  {
1458  Assert(dof.n_dofs(level) != numbers::invalid_dof_index,
1459  ExcNotInitialized());
1460 
1461  std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1462  std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1463 
1464  compute_cell_wise(renumbering, reverse, dof, level, cells);
1465  dof.renumber_dofs(level, renumbering);
1466  }
1467 
1468 
1469 
1470  template <typename DoFHandlerType>
1471  void compute_cell_wise
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)
1477  {
1478  Assert(cells.size() == dof.get_triangulation().n_cells(level),
1479  ExcDimensionMismatch(cells.size(),
1480  dof.get_triangulation().n_cells(level)));
1481  Assert (new_order.size() == dof.n_dofs(level),
1482  ExcDimensionMismatch(new_order.size(), dof.n_dofs(level)));
1483  Assert (reverse.size() == dof.n_dofs(level),
1484  ExcDimensionMismatch(reverse.size(), dof.n_dofs(level)));
1485 
1486  unsigned int n_global_dofs = dof.n_dofs(level);
1487  unsigned int n_cell_dofs = dof.get_fe().n_dofs_per_cell();
1488 
1489  std::vector<bool> already_sorted(n_global_dofs, false);
1490  std::vector<types::global_dof_index> cell_dofs(n_cell_dofs);
1491 
1492  unsigned int global_index = 0;
1493 
1494  typename std::vector<typename DoFHandlerType::level_cell_iterator>::const_iterator cell;
1495 
1496  for (cell = cells.begin(); cell != cells.end(); ++cell)
1497  {
1498  Assert ((*cell)->level() == (int) level, ExcInternalError());
1499 
1500  (*cell)->get_active_or_mg_dof_indices(cell_dofs);
1501  std::sort(cell_dofs.begin(), cell_dofs.end());
1502 
1503  for (unsigned int i=0; i<n_cell_dofs; ++i)
1504  {
1505  if (!already_sorted[cell_dofs[i]])
1506  {
1507  already_sorted[cell_dofs[i]] = true;
1508  reverse[global_index++] = cell_dofs[i];
1509  }
1510  }
1511  }
1512  Assert(global_index == n_global_dofs, ExcRenumberingIncomplete());
1513 
1514  for (types::global_dof_index i=0; i<new_order.size(); ++i)
1515  new_order[reverse[i]] = i;
1516  }
1517 
1518 
1519 
1520 
1521 
1522 
1523 
1524  template <typename DoFHandlerType>
1525  void
1527  (std::vector<types::global_dof_index> &new_indices,
1528  std::vector<types::global_dof_index> &reverse,
1529  const DoFHandlerType &dof,
1530  const Point<DoFHandlerType::space_dimension> &direction,
1531  const bool dof_wise_renumbering)
1532  {
1533  if (dof_wise_renumbering == false)
1534  {
1535  std::vector<typename DoFHandlerType::active_cell_iterator> ordered_cells;
1536  ordered_cells.reserve(dof.get_triangulation().n_active_cells());
1537  const CompareDownstream<typename DoFHandlerType::active_cell_iterator,
1538  DoFHandlerType::space_dimension> comparator(direction);
1539 
1540  typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
1541  typename DoFHandlerType::active_cell_iterator end = dof.end();
1542 
1543  while (p!=end)
1544  {
1545  ordered_cells.push_back(p);
1546  ++p;
1547  }
1548  std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1549 
1550  compute_cell_wise(new_indices, reverse, dof, ordered_cells);
1551  }
1552  else
1553  {
1554  // similar code as for
1555  // DoFTools::map_dofs_to_support_points, but
1556  // need to do this for general DoFHandlerType classes and
1557  // want to be able to sort the result
1558  // (otherwise, could use something like
1559  // DoFTools::map_support_points_to_dofs)
1560  const unsigned int n_dofs = dof.n_dofs();
1561  std::vector<std::pair<Point<DoFHandlerType::space_dimension>,unsigned int> > support_point_list
1562  (n_dofs);
1563 
1564  const hp::FECollection<DoFHandlerType::dimension> fe_collection (dof.get_fe ());
1565  Assert (fe_collection[0].has_support_points(),
1567  hp::QCollection<DoFHandlerType::dimension> quadrature_collection;
1568  for (unsigned int comp=0; comp<fe_collection.size(); ++comp)
1569  {
1570  Assert (fe_collection[comp].has_support_points(),
1572  quadrature_collection.push_back
1573  (Quadrature<DoFHandlerType::dimension> (fe_collection[comp].
1574  get_unit_support_points()));
1575  }
1577  hp_fe_values (fe_collection, quadrature_collection,
1579 
1580  std::vector<bool> already_touched (n_dofs, false);
1581 
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)
1586  {
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);
1590  const FEValues<DoFHandlerType::dimension> &fe_values =
1591  hp_fe_values.get_present_fe_values ();
1592  begin->get_active_or_mg_dof_indices(local_dof_indices);
1593  const std::vector<Point<DoFHandlerType::space_dimension> > &points
1594  = fe_values.get_quadrature_points ();
1595  for (unsigned int i=0; i<dofs_per_cell; ++i)
1596  if (!already_touched[local_dof_indices[i]])
1597  {
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;
1602  }
1603  }
1604 
1606  std::sort (support_point_list.begin(), support_point_list.end(),
1607  comparator);
1608  for (types::global_dof_index i=0; i<n_dofs; ++i)
1609  new_indices[support_point_list[i].second] = i;
1610  }
1611  }
1612 
1613 
1614 
1615  template <typename DoFHandlerType>
1616  void downstream (DoFHandlerType &dof,
1617  const unsigned int level,
1618  const Point<DoFHandlerType::space_dimension> &direction,
1619  const bool dof_wise_renumbering)
1620  {
1621  std::vector<types::global_dof_index> renumbering(dof.n_dofs(level));
1622  std::vector<types::global_dof_index> reverse(dof.n_dofs(level));
1623  compute_downstream(renumbering, reverse, dof, level, direction,
1624  dof_wise_renumbering);
1625 
1626  dof.renumber_dofs(level, renumbering);
1627  }
1628 
1629 
1630 
1631  template <typename DoFHandlerType>
1632  void
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,
1638  const Point<DoFHandlerType::space_dimension> &direction,
1639  const bool dof_wise_renumbering)
1640  {
1641  if (dof_wise_renumbering == false)
1642  {
1643  std::vector<typename DoFHandlerType::level_cell_iterator> ordered_cells;
1644  ordered_cells.reserve (dof.get_triangulation().n_cells(level));
1645  const CompareDownstream<typename DoFHandlerType::level_cell_iterator,
1646  DoFHandlerType::space_dimension> comparator(direction);
1647 
1648  typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
1649  typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1650 
1651  while (p!=end)
1652  {
1653  ordered_cells.push_back(p);
1654  ++p;
1655  }
1656  std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1657 
1658  compute_cell_wise(new_indices, reverse, dof, level, ordered_cells);
1659  }
1660  else
1661  {
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
1666  (n_dofs);
1667 
1668  Quadrature<DoFHandlerType::dimension> q_dummy(dof.get_fe().get_unit_support_points());
1671 
1672  std::vector<bool> already_touched (dof.n_dofs(), false);
1673 
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)
1679  {
1680  const typename Triangulation<DoFHandlerType::dimension,
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]])
1688  {
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;
1693  }
1694  }
1695 
1697  std::sort (support_point_list.begin(), support_point_list.end(),
1698  comparator);
1699  for (types::global_dof_index i=0; i<n_dofs; ++i)
1700  new_indices[support_point_list[i].second] = i;
1701  }
1702  }
1703 
1704 
1705 
1709  namespace internal
1710  {
1711  template <int dim>
1712  struct ClockCells
1713  {
1717  const Point<dim> &center;
1721  bool counter;
1722 
1726  ClockCells (const Point<dim> &center, bool counter) :
1727  center(center),
1728  counter(counter)
1729  {}
1730 
1734  template <class DHCellIterator>
1735  bool operator () (const DHCellIterator &c1,
1736  const DHCellIterator &c2) const
1737  {
1738  // dispatch to
1739  // dimension-dependent functions
1740  return compare (c1, c2, ::internal::int2type<dim>());
1741  }
1742 
1743  private:
1747  template <class DHCellIterator, int xdim>
1748  bool compare (const DHCellIterator &c1,
1749  const DHCellIterator &c2,
1750  ::internal::int2type<xdim>) const
1751  {
1752  const Tensor<1,dim> v1 = c1->center() - center;
1753  const Tensor<1,dim> v2 = c2->center() - center;
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));
1757  }
1758 
1759 
1764  template <class DHCellIterator>
1765  bool compare (const DHCellIterator &,
1766  const DHCellIterator &,
1767  ::internal::int2type<1>) const
1768  {
1769  Assert (dim >= 2,
1770  ExcMessage ("This operation only makes sense for dim>=2."));
1771  return false;
1772  }
1773 
1774  };
1775  }
1776 
1777 
1778 
1779  template <typename DoFHandlerType>
1780  void
1782  DoFHandlerType &dof,
1784  const bool counter)
1785  {
1786  std::vector<types::global_dof_index> renumbering(dof.n_dofs());
1787  compute_clockwise_dg(renumbering, dof, center, counter);
1788 
1789  dof.renumber_dofs(renumbering);
1790  }
1791 
1792 
1793 
1794  template <typename DoFHandlerType>
1795  void
1797  (std::vector<types::global_dof_index> &new_indices,
1798  const DoFHandlerType &dof,
1800  const bool counter)
1801  {
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);
1805 
1806  typename DoFHandlerType::active_cell_iterator p = dof.begin_active();
1807  typename DoFHandlerType::active_cell_iterator end = dof.end();
1808 
1809  while (p!=end)
1810  {
1811  ordered_cells.push_back(p);
1812  ++p;
1813  }
1814  std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1815 
1816  std::vector<types::global_dof_index> reverse(new_indices.size());
1817  compute_cell_wise(new_indices, reverse, dof, ordered_cells);
1818  }
1819 
1820 
1821 
1822  template <typename DoFHandlerType>
1823  void clockwise_dg (DoFHandlerType &dof,
1824  const unsigned int level,
1826  const bool counter)
1827  {
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);
1831 
1832  typename DoFHandlerType::level_cell_iterator p = dof.begin(level);
1833  typename DoFHandlerType::level_cell_iterator end = dof.end(level);
1834 
1835  while (p!=end)
1836  {
1837  ordered_cells.push_back(p);
1838  ++p;
1839  }
1840  std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
1841 
1842  cell_wise(dof, level, ordered_cells);
1843  }
1844 
1845 
1846 
1847  template <typename DoFHandlerType>
1848  void
1849  random (DoFHandlerType &dof_handler)
1850  {
1851  std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1852  DoFHandlerType::invalid_dof_index);
1853  compute_random(renumbering, dof_handler);
1854 
1855  dof_handler.renumber_dofs(renumbering);
1856  }
1857 
1858 
1859 
1860  template <typename DoFHandlerType>
1861  void
1863  std::vector<types::global_dof_index> &new_indices,
1864  const DoFHandlerType &dof_handler)
1865  {
1866  const types::global_dof_index n_dofs = dof_handler.n_dofs();
1867  Assert(new_indices.size() == n_dofs,
1868  ExcDimensionMismatch(new_indices.size(), n_dofs));
1869 
1870  for (unsigned int i=0; i<n_dofs; ++i)
1871  new_indices[i] = i;
1872 
1873  // shuffle the elements; the following is essentially std::shuffle (which
1874  // is new in C++11) but with a boost URNG
1875  ::boost::mt19937 random_number_generator;
1876  for (unsigned int i=1; i<n_dofs; ++i)
1877  {
1878  // get a random number between 0 and i (inclusive)
1879  const unsigned int j
1880  = ::boost::random::uniform_int_distribution<>(0, i)(random_number_generator);
1881 
1882  // if possible, swap the elements
1883  if (i != j)
1884  std::swap (new_indices[i], new_indices[j]);
1885  }
1886  }
1887 
1888 
1889 
1890  template <typename DoFHandlerType>
1891  void
1892  subdomain_wise (DoFHandlerType &dof_handler)
1893  {
1894  std::vector<types::global_dof_index> renumbering(dof_handler.n_dofs(),
1895  DoFHandlerType::invalid_dof_index);
1896  compute_subdomain_wise(renumbering, dof_handler);
1897 
1898  dof_handler.renumber_dofs(renumbering);
1899  }
1900 
1901 
1902 
1903  template <typename DoFHandlerType>
1904  void
1905  compute_subdomain_wise (std::vector<types::global_dof_index> &new_dof_indices,
1906  const DoFHandlerType &dof_handler)
1907  {
1908  const types::global_dof_index n_dofs = dof_handler.n_dofs();
1909  Assert (new_dof_indices.size() == n_dofs,
1910  ExcDimensionMismatch (new_dof_indices.size(), n_dofs));
1911 
1912  // first get the association of each dof
1913  // with a subdomain and determine the total
1914  // number of subdomain ids used
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;
1921 
1922  // then renumber the subdomains by first
1923  // looking at those belonging to subdomain
1924  // 0, then those of subdomain 1, etc. note
1925  // that the algorithm is stable, i.e. if
1926  // two dofs i,j have i<j and belong to the
1927  // same subdomain, then they will be in
1928  // this order also after reordering
1929  std::fill (new_dof_indices.begin(), new_dof_indices.end(),
1931  types::global_dof_index next_free_index = 0;
1932  for (types::subdomain_id subdomain=0; subdomain<n_subdomains; ++subdomain)
1933  for (types::global_dof_index i=0; i<n_dofs; ++i)
1934  if (subdomain_association[i] == subdomain)
1935  {
1936  Assert (new_dof_indices[i] == numbers::invalid_dof_index,
1937  ExcInternalError());
1938  new_dof_indices[i] = next_free_index;
1939  ++next_free_index;
1940  }
1941 
1942  // we should have numbered all dofs
1943  Assert (next_free_index == n_dofs, ExcInternalError());
1944  Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
1946  == new_dof_indices.end(),
1947  ExcInternalError());
1948  }
1949 
1950 } // namespace DoFRenumbering
1951 
1952 
1953 
1954 /*-------------- Explicit Instantiations -------------------------------*/
1955 #include "dof_renumbering.inst"
1956 
1957 
1958 DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcFEHasNoSupportPoints()
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1146
cell_iterator begin(const unsigned int level=0) const
Definition: dof_handler.cc:728
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
Definition: tria.cc:11237
size_type nth_index_in_set(const unsigned int local_index) const
Definition: index_set.h:1612
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 get_subdomain_association(const DoFHandlerType &dof_handler, std::vector< types::subdomain_id > &subdomain)
Definition: dof_tools.cc:1309
void hierarchical(DoFHandler< dim > &dof_handler)
cell_iterator end() const
Definition: dof_handler.cc:756
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity, const unsigned int level)
Definition: mg_tools.cc:539
void component_wise(DoFHandler< dim, spacedim > &dof_handler, const std::vector< unsigned int > &target_component=std::vector< unsigned int >())
void reorder_Cuthill_McKee(const DynamicSparsityPattern &sparsity, std::vector< DynamicSparsityPattern::size_type > &new_indices, const std::vector< DynamicSparsityPattern::size_type > &starting_indices=std::vector< DynamicSparsityPattern::size_type >())
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
Definition: dof_handler.h:228
STL namespace.
Transformed quadrature points.
static ::ExceptionBase & ExcNotInitialized()
bool is_primitive() const
Definition: fe.h:3034
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
iterator end()
Definition: point.h:89
const std::vector< types::global_dof_index > & get_p4est_tree_to_coarse_cell_permutation() const
Definition: tria.cc:3368
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:92
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:163
const ::FEValues< dim, spacedim > & get_present_fe_values() const
Definition: fe_values.h:598
size_type size() const
Definition: index_set.h:1419
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: dof_handler.cc:740
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)
Definition: fe_values.cc:144
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
Definition: types.h:88
#define Assert(cond, exc)
Definition: exceptions.h:313
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
Definition: index_set.h:1653
const ComponentMask & get_nonzero_components(const unsigned int i) const
Definition: fe.h:3012
types::global_dof_index n_dofs() const
static ::ExceptionBase & ExcRenumberingIncomplete()
void extract_locally_relevant_dofs(const DoFHandlerType &dof_handler, IndexSet &dof_set)
Definition: dof_tools.cc:980
void compute_random(std::vector< types::global_dof_index > &new_dof_indices, const DoFHandlerType &dof_handler)
iterator begin()
unsigned int subdomain_id
Definition: types.h:42
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)
Definition: mpi.cc:63
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
Definition: fe_base.h:295
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
Definition: fe.h:2839
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1211
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 > &center, 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
Definition: fe.h:2982
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
Definition: fe.h:30
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)
Definition: utilities.cc:472
static ::ExceptionBase & ExcNotImplemented()
const Triangulation< dim, spacedim > & get_triangulation() const
bool is_element(const size_type index) const
Definition: index_set.h:1489
void reinit(const IndexSet &local_constraints=IndexSet())
void subdomain_wise(DoFHandlerType &dof_handler)
void clockwise_dg(DoFHandlerType &dof_handler, const Point< DoFHandlerType::space_dimension > &center, const bool counter=false)
const types::global_dof_index invalid_dof_index
Definition: types.h:184
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
Definition: index_set.h:1560
void push_back(const Quadrature< dim > &new_quadrature)
Definition: q_collection.h:231
cell_iterator end() const
static ::ExceptionBase & ExcInternalError()
void cell_wise(DoFHandlerType &dof_handler, const std::vector< typename DoFHandlerType::active_cell_iterator > &cell_order)