Reference documentation for deal.II version 8.4.2
dof_handler.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2015 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/memory_consumption.h>
17 #include <deal.II/dofs/dof_handler.h>
18 #include <deal.II/dofs/dof_handler_policy.h>
19 #include <deal.II/dofs/dof_levels.h>
20 #include <deal.II/dofs/dof_faces.h>
21 #include <deal.II/dofs/dof_accessor.h>
22 #include <deal.II/grid/tria_accessor.h>
23 #include <deal.II/grid/tria_iterator.h>
24 #include <deal.II/grid/tria_levels.h>
25 #include <deal.II/grid/tria.h>
26 #include <deal.II/base/geometry_info.h>
27 #include <deal.II/fe/fe.h>
28 #include <deal.II/distributed/shared_tria.h>
29 #include <deal.II/distributed/tria.h>
30 
31 #include <set>
32 #include <algorithm>
33 
34 DEAL_II_NAMESPACE_OPEN
35 
36 
37 //TODO[WB]: do not use a plain pointer for DoFHandler::faces, but rather an
38 //unique_ptr or some such thing. alternatively, why not use the DoFFaces object
39 //right away?
40 
41 template<int dim, int spacedim>
42 const unsigned int DoFHandler<dim,spacedim>::dimension;
43 
44 template<int dim, int spacedim>
46 
47 template <int dim, int spacedim>
49 
50 template <int dim, int spacedim>
52 
53 
54 // reference the invalid_dof_index variable explicitly to work around
55 // a bug in the icc8 compiler
56 namespace internal
57 {
58  template <int dim, int spacedim>
59  const types::global_dof_index *dummy ()
60  {
62  }
63 }
64 
65 
66 
67 namespace internal
68 {
69  template<int dim, int spacedim>
70  std::string policy_to_string(const ::internal::DoFHandler::Policy::PolicyBase<dim,spacedim> &policy)
71  {
72  std::string policy_name;
73  if (dynamic_cast<const typename ::internal::DoFHandler::Policy::Sequential<dim,spacedim>*>(&policy))
74  policy_name = "Policy::Sequential<";
75  else if (dynamic_cast<const typename ::internal::DoFHandler::Policy::ParallelDistributed<dim,spacedim>*>(&policy))
76  policy_name = "Policy::ParallelDistributed<";
77  else if (dynamic_cast<const typename ::internal::DoFHandler::Policy::ParallelShared<dim,spacedim>*>(&policy))
78  policy_name = "Policy::ParallelShared<";
79  else
80  AssertThrow(false, ExcNotImplemented());
81  policy_name += Utilities::int_to_string(dim)+
82  ","+Utilities::int_to_string(spacedim)+">";
83  return policy_name;
84  }
85 
86 
87  namespace DoFHandler
88  {
89  // access class
90  // ::DoFHandler instead of
91  // namespace internal::DoFHandler
92  using ::DoFHandler;
93 
94 
100  {
105  template <int spacedim>
106  static
107  unsigned int
109  {
110  return std::min(static_cast<types::global_dof_index>(3*dof_handler.selected_fe->dofs_per_vertex +
111  2*dof_handler.selected_fe->dofs_per_line),
112  dof_handler.n_dofs());
113  }
114 
115 
116 
117  template <int spacedim>
118  static
119  unsigned int
121  {
122 
123  // get these numbers by drawing pictures
124  // and counting...
125  // example:
126  // | | |
127  // --x-----x--x--X--
128  // | | | |
129  // | x--x--x
130  // | | | |
131  // --x--x--*--x--x--
132  // | | | |
133  // x--x--x |
134  // | | | |
135  // --X--x--x-----x--
136  // | | |
137  // x = vertices connected with center vertex *;
138  // = total of 19
139  // (the X vertices are connected with * if
140  // the vertices adjacent to X are hanging
141  // nodes)
142  // count lines -> 28 (don't forget to count
143  // mother and children separately!)
144  types::global_dof_index max_couplings;
145  switch (dof_handler.tria->max_adjacent_cells())
146  {
147  case 4:
148  max_couplings=19*dof_handler.selected_fe->dofs_per_vertex +
149  28*dof_handler.selected_fe->dofs_per_line +
150  8*dof_handler.selected_fe->dofs_per_quad;
151  break;
152  case 5:
153  max_couplings=21*dof_handler.selected_fe->dofs_per_vertex +
154  31*dof_handler.selected_fe->dofs_per_line +
155  9*dof_handler.selected_fe->dofs_per_quad;
156  break;
157  case 6:
158  max_couplings=28*dof_handler.selected_fe->dofs_per_vertex +
159  42*dof_handler.selected_fe->dofs_per_line +
160  12*dof_handler.selected_fe->dofs_per_quad;
161  break;
162  case 7:
163  max_couplings=30*dof_handler.selected_fe->dofs_per_vertex +
164  45*dof_handler.selected_fe->dofs_per_line +
165  13*dof_handler.selected_fe->dofs_per_quad;
166  break;
167  case 8:
168  max_couplings=37*dof_handler.selected_fe->dofs_per_vertex +
169  56*dof_handler.selected_fe->dofs_per_line +
170  16*dof_handler.selected_fe->dofs_per_quad;
171  break;
172 
173  // the following numbers are not based on actual counting but by
174  // extrapolating the number sequences from the previous ones (for
175  // example, for dofs_per_vertex, the sequence above is 19, 21, 28,
176  // 30, 37, and is continued as follows):
177  case 9:
178  max_couplings=39*dof_handler.selected_fe->dofs_per_vertex +
179  59*dof_handler.selected_fe->dofs_per_line +
180  17*dof_handler.selected_fe->dofs_per_quad;
181  break;
182  case 10:
183  max_couplings=46*dof_handler.selected_fe->dofs_per_vertex +
184  70*dof_handler.selected_fe->dofs_per_line +
185  20*dof_handler.selected_fe->dofs_per_quad;
186  break;
187  case 11:
188  max_couplings=48*dof_handler.selected_fe->dofs_per_vertex +
189  73*dof_handler.selected_fe->dofs_per_line +
190  21*dof_handler.selected_fe->dofs_per_quad;
191  break;
192  case 12:
193  max_couplings=55*dof_handler.selected_fe->dofs_per_vertex +
194  84*dof_handler.selected_fe->dofs_per_line +
195  24*dof_handler.selected_fe->dofs_per_quad;
196  break;
197  case 13:
198  max_couplings=57*dof_handler.selected_fe->dofs_per_vertex +
199  87*dof_handler.selected_fe->dofs_per_line +
200  25*dof_handler.selected_fe->dofs_per_quad;
201  break;
202  case 14:
203  max_couplings=63*dof_handler.selected_fe->dofs_per_vertex +
204  98*dof_handler.selected_fe->dofs_per_line +
205  28*dof_handler.selected_fe->dofs_per_quad;
206  break;
207  case 15:
208  max_couplings=65*dof_handler.selected_fe->dofs_per_vertex +
209  103*dof_handler.selected_fe->dofs_per_line +
210  29*dof_handler.selected_fe->dofs_per_quad;
211  break;
212  case 16:
213  max_couplings=72*dof_handler.selected_fe->dofs_per_vertex +
214  114*dof_handler.selected_fe->dofs_per_line +
215  32*dof_handler.selected_fe->dofs_per_quad;
216  break;
217 
218  default:
219  Assert (false, ExcNotImplemented());
220  max_couplings=0;
221  }
222  return std::min(max_couplings,dof_handler.n_dofs());
223  }
224 
225 
226  template <int spacedim>
227  static
228  unsigned int
230  {
231 //TODO:[?] Invent significantly better estimates than the ones in this function
232 
233  // doing the same thing here is a
234  // rather complicated thing, compared
235  // to the 2d case, since it is hard
236  // to draw pictures with several
237  // refined hexahedra :-) so I
238  // presently only give a coarse
239  // estimate for the case that at most
240  // 8 hexes meet at each vertex
241  //
242  // can anyone give better estimate
243  // here?
244  const unsigned int max_adjacent_cells
245  = dof_handler.tria->max_adjacent_cells();
246 
247  types::global_dof_index max_couplings;
248  if (max_adjacent_cells <= 8)
249  max_couplings=7*7*7*dof_handler.selected_fe->dofs_per_vertex +
250  7*6*7*3*dof_handler.selected_fe->dofs_per_line +
251  9*4*7*3*dof_handler.selected_fe->dofs_per_quad +
252  27*dof_handler.selected_fe->dofs_per_hex;
253  else
254  {
255  Assert (false, ExcNotImplemented());
256  max_couplings=0;
257  }
258 
259  return std::min(max_couplings,dof_handler.n_dofs());
260  }
261 
262 
272  template <int spacedim>
273  static
275  {
276  dof_handler.vertex_dofs
277  .resize(dof_handler.tria->n_vertices() *
278  dof_handler.selected_fe->dofs_per_vertex,
280 
281  for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
282  {
283  dof_handler.levels
284  .push_back (new internal::DoFHandler::DoFLevel<1>);
285 
286  dof_handler.levels.back()->dof_object.dofs
287  .resize (dof_handler.tria->n_raw_cells(i) *
288  dof_handler.selected_fe->dofs_per_line,
290 
291  dof_handler.levels.back()->cell_dof_indices_cache
292  .resize (dof_handler.tria->n_raw_cells(i) *
293  dof_handler.selected_fe->dofs_per_cell,
295  }
296  }
297 
298 
299  template <int spacedim>
300  static
301  void reserve_space (DoFHandler<2,spacedim> &dof_handler)
302  {
303  dof_handler.vertex_dofs
304  .resize(dof_handler.tria->n_vertices() *
305  dof_handler.selected_fe->dofs_per_vertex,
307 
308  for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
309  {
310  dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<2>);
311 
312  dof_handler.levels.back()->dof_object.dofs
313  .resize (dof_handler.tria->n_raw_cells(i) *
314  dof_handler.selected_fe->dofs_per_quad,
316 
317  dof_handler.levels.back()->cell_dof_indices_cache
318  .resize (dof_handler.tria->n_raw_cells(i) *
319  dof_handler.selected_fe->dofs_per_cell,
321  }
322 
323  dof_handler.faces = new internal::DoFHandler::DoFFaces<2>;
324  // avoid access to n_raw_lines when there are no cells
325  if (dof_handler.tria->n_cells() > 0)
326  {
327  dof_handler.faces->lines.dofs
328  .resize (dof_handler.tria->n_raw_lines() *
329  dof_handler.selected_fe->dofs_per_line,
331  }
332  }
333 
334 
335  template <int spacedim>
336  static
337  void reserve_space (DoFHandler<3,spacedim> &dof_handler)
338  {
339  dof_handler.vertex_dofs
340  .resize(dof_handler.tria->n_vertices() *
341  dof_handler.selected_fe->dofs_per_vertex,
343 
344  for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
345  {
346  dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<3>);
347 
348  dof_handler.levels.back()->dof_object.dofs
349  .resize (dof_handler.tria->n_raw_cells(i) *
350  dof_handler.selected_fe->dofs_per_hex,
352 
353  dof_handler.levels.back()->cell_dof_indices_cache
354  .resize (dof_handler.tria->n_raw_cells(i) *
355  dof_handler.selected_fe->dofs_per_cell,
357  }
358  dof_handler.faces = new internal::DoFHandler::DoFFaces<3>;
359 
360  // avoid access to n_raw_lines when there are no cells
361  if (dof_handler.tria->n_cells() > 0)
362  {
363  dof_handler.faces->lines.dofs
364  .resize (dof_handler.tria->n_raw_lines() *
365  dof_handler.selected_fe->dofs_per_line,
367  dof_handler.faces->quads.dofs
368  .resize (dof_handler.tria->n_raw_quads() *
369  dof_handler.selected_fe->dofs_per_quad,
371  }
372  }
373 
374  template<int spacedim>
375  static
376  void reserve_space_mg (DoFHandler<1, spacedim> &dof_handler)
377  {
378  Assert (dof_handler.get_triangulation().n_levels () > 0, ExcMessage ("Invalid triangulation"));
379  dof_handler.clear_mg_space ();
380 
381  const ::Triangulation<1, spacedim> &tria = dof_handler.get_triangulation();
382  const unsigned int &dofs_per_line = dof_handler.get_fe ().dofs_per_line;
383  const unsigned int &n_levels = tria.n_levels ();
384 
385  for (unsigned int i = 0; i < n_levels; ++i)
386  {
387  dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<1>);
388  dof_handler.mg_levels.back ()->dof_object.dofs = std::vector<types::global_dof_index> (tria.n_raw_lines (i) * dofs_per_line, DoFHandler<1>::invalid_dof_index);
389  }
390 
391  const unsigned int &n_vertices = tria.n_vertices ();
392 
393  dof_handler.mg_vertex_dofs.resize (n_vertices);
394 
395  std::vector<unsigned int> max_level (n_vertices, 0);
396  std::vector<unsigned int> min_level (n_vertices, n_levels);
397 
398  for (typename ::Triangulation<1, spacedim>::cell_iterator cell = tria.begin (); cell != tria.end (); ++cell)
399  {
400  const unsigned int level = cell->level ();
401 
402  for (unsigned int vertex = 0; vertex < GeometryInfo<1>::vertices_per_cell; ++vertex)
403  {
404  const unsigned int vertex_index = cell->vertex_index (vertex);
405 
406  if (min_level[vertex_index] > level)
407  min_level[vertex_index] = level;
408 
409  if (max_level[vertex_index] < level)
410  max_level[vertex_index] = level;
411  }
412  }
413 
414  for (unsigned int vertex = 0; vertex < n_vertices; ++vertex)
415  if (tria.vertex_used (vertex))
416  {
417  Assert (min_level[vertex] < n_levels, ExcInternalError ());
418  Assert (max_level[vertex] >= min_level[vertex], ExcInternalError ());
419  dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex], max_level[vertex], dof_handler.get_fe ().dofs_per_vertex);
420  }
421 
422  else
423  {
424  Assert (min_level[vertex] == n_levels, ExcInternalError ());
425  Assert (max_level[vertex] == 0, ExcInternalError ());
426  dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
427  }
428  }
429 
430  template<int spacedim>
431  static
432  void reserve_space_mg (DoFHandler<2, spacedim> &dof_handler)
433  {
434  Assert (dof_handler.get_triangulation().n_levels () > 0, ExcMessage ("Invalid triangulation"));
435  dof_handler.clear_mg_space ();
436 
437  const ::FiniteElement<2, spacedim> &fe = dof_handler.get_fe ();
438  const ::Triangulation<2, spacedim> &tria = dof_handler.get_triangulation();
439  const unsigned int &n_levels = tria.n_levels ();
440 
441  for (unsigned int i = 0; i < n_levels; ++i)
442  {
443  dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<2>);
444  dof_handler.mg_levels.back ()->dof_object.dofs = std::vector<types::global_dof_index> (tria.n_raw_quads (i) * fe.dofs_per_quad, DoFHandler<2>::invalid_dof_index);
445  }
446 
447  dof_handler.mg_faces = new internal::DoFHandler::DoFFaces<2>;
448  dof_handler.mg_faces->lines.dofs = std::vector<types::global_dof_index> (tria.n_raw_lines () * fe.dofs_per_line, DoFHandler<2>::invalid_dof_index);
449 
450  const unsigned int &n_vertices = tria.n_vertices ();
451 
452  dof_handler.mg_vertex_dofs.resize (n_vertices);
453 
454  std::vector<unsigned int> max_level (n_vertices, 0);
455  std::vector<unsigned int> min_level (n_vertices, n_levels);
456 
457  for (typename ::Triangulation<2, spacedim>::cell_iterator cell = tria.begin (); cell != tria.end (); ++cell)
458  {
459  const unsigned int level = cell->level ();
460 
461  for (unsigned int vertex = 0; vertex < GeometryInfo<2>::vertices_per_cell; ++vertex)
462  {
463  const unsigned int vertex_index = cell->vertex_index (vertex);
464 
465  if (min_level[vertex_index] > level)
466  min_level[vertex_index] = level;
467 
468  if (max_level[vertex_index] < level)
469  max_level[vertex_index] = level;
470  }
471  }
472 
473  for (unsigned int vertex = 0; vertex < n_vertices; ++vertex)
474  if (tria.vertex_used (vertex))
475  {
476  Assert (min_level[vertex] < n_levels, ExcInternalError ());
477  Assert (max_level[vertex] >= min_level[vertex], ExcInternalError ());
478  dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex], max_level[vertex], fe.dofs_per_vertex);
479  }
480 
481  else
482  {
483  Assert (min_level[vertex] == n_levels, ExcInternalError ());
484  Assert (max_level[vertex] == 0, ExcInternalError ());
485  dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
486  }
487  }
488 
489  template<int spacedim>
490  static
491  void reserve_space_mg (DoFHandler<3, spacedim> &dof_handler)
492  {
493  Assert (dof_handler.get_triangulation().n_levels () > 0, ExcMessage ("Invalid triangulation"));
494  dof_handler.clear_mg_space ();
495 
496  const ::FiniteElement<3, spacedim> &fe = dof_handler.get_fe ();
497  const ::Triangulation<3, spacedim> &tria = dof_handler.get_triangulation();
498  const unsigned int &n_levels = tria.n_levels ();
499 
500  for (unsigned int i = 0; i < n_levels; ++i)
501  {
502  dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<3>);
503  dof_handler.mg_levels.back ()->dof_object.dofs = std::vector<types::global_dof_index> (tria.n_raw_hexs (i) * fe.dofs_per_hex, DoFHandler<3>::invalid_dof_index);
504  }
505 
506  dof_handler.mg_faces = new internal::DoFHandler::DoFFaces<3>;
507  dof_handler.mg_faces->lines.dofs = std::vector<types::global_dof_index> (tria.n_raw_lines () * fe.dofs_per_line, DoFHandler<3>::invalid_dof_index);
508  dof_handler.mg_faces->quads.dofs = std::vector<types::global_dof_index> (tria.n_raw_quads () * fe.dofs_per_quad, DoFHandler<3>::invalid_dof_index);
509 
510  const unsigned int &n_vertices = tria.n_vertices ();
511 
512  dof_handler.mg_vertex_dofs.resize (n_vertices);
513 
514  std::vector<unsigned int> max_level (n_vertices, 0);
515  std::vector<unsigned int> min_level (n_vertices, n_levels);
516 
517  for (typename ::Triangulation<3, spacedim>::cell_iterator cell = tria.begin (); cell != tria.end (); ++cell)
518  {
519  const unsigned int level = cell->level ();
520 
521  for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_cell; ++vertex)
522  {
523  const unsigned int vertex_index = cell->vertex_index (vertex);
524 
525  if (min_level[vertex_index] > level)
526  min_level[vertex_index] = level;
527 
528  if (max_level[vertex_index] < level)
529  max_level[vertex_index] = level;
530  }
531  }
532 
533  for (unsigned int vertex = 0; vertex < n_vertices; ++vertex)
534  if (tria.vertex_used (vertex))
535  {
536  Assert (min_level[vertex] < n_levels, ExcInternalError ());
537  Assert (max_level[vertex] >= min_level[vertex], ExcInternalError ());
538  dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex], max_level[vertex], fe.dofs_per_vertex);
539  }
540 
541  else
542  {
543  Assert (min_level[vertex] == n_levels, ExcInternalError ());
544  Assert (max_level[vertex] == 0, ExcInternalError ());
545  dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
546  }
547  }
548 
549  template<int spacedim>
550  static
551  types::global_dof_index distribute_dofs_on_cell (typename DoFHandler<1, spacedim>::cell_iterator &cell, types::global_dof_index next_free_dof)
552  {
553  const FiniteElement<1, spacedim> &fe = cell->get_fe ();
554 
555  if (fe.dofs_per_vertex > 0)
556  for (unsigned int vertex = 0; vertex < GeometryInfo<1>::vertices_per_cell; ++vertex)
557  {
558  typename DoFHandler<1, spacedim>::cell_iterator neighbor = cell->neighbor (vertex);
559 
560  if (neighbor.state () == IteratorState::valid)
561  if (neighbor->user_flag_set () && (neighbor->level () == cell->level ()))
562  {
563  if (vertex == 0)
564  for (unsigned int dof = 0; dof < fe.dofs_per_vertex; ++dof)
565  cell->set_mg_vertex_dof_index (cell->level (), 0, dof, neighbor->mg_vertex_dof_index (cell->level (), 1, dof));
566 
567  else
568  for (unsigned int dof = 0; dof < fe.dofs_per_vertex; ++dof)
569  cell->set_mg_vertex_dof_index (cell->level (), 1, dof, neighbor->mg_vertex_dof_index (cell->level (), 0, dof));
570 
571  continue;
572  }
573 
574  for (unsigned int dof = 0; dof < fe.dofs_per_vertex; ++dof)
575  cell->set_mg_vertex_dof_index (cell->level (), vertex, dof, next_free_dof++);
576  }
577 
578  if (fe.dofs_per_line > 0)
579  for (unsigned int dof = 0; dof < fe.dofs_per_line; ++dof)
580  cell->set_mg_dof_index (cell->level (), dof, next_free_dof++);
581 
582  cell->set_user_flag ();
583  return next_free_dof;
584  }
585 
586  template<int spacedim>
587  static
588  types::global_dof_index distribute_dofs_on_cell (typename DoFHandler<2, spacedim>::cell_iterator &cell, types::global_dof_index next_free_dof)
589  {
590  const FiniteElement<2, spacedim> &fe = cell->get_fe ();
591 
592  if (fe.dofs_per_vertex > 0)
593  for (unsigned int vertex = 0; vertex < GeometryInfo<2>::vertices_per_cell; ++vertex)
594  if (cell->mg_vertex_dof_index (cell->level (), vertex, 0) == DoFHandler<2>::invalid_dof_index)
595  for (unsigned int dof = 0; dof < fe.dofs_per_vertex; ++dof)
596  cell->set_mg_vertex_dof_index (cell->level (), vertex, dof, next_free_dof++);
597 
598  if (fe.dofs_per_line > 0)
599  for (unsigned int face = 0; face < GeometryInfo<2>::faces_per_cell; ++face)
600  {
601  typename DoFHandler<2, spacedim>::line_iterator line = cell->line (face);
602 
603  if (line->mg_dof_index (cell->level (), 0) == DoFHandler<2>::invalid_dof_index)
604  for (unsigned int dof = 0; dof < fe.dofs_per_line; ++dof)
605  line->set_mg_dof_index (cell->level (), dof, next_free_dof++);
606  }
607 
608  if (fe.dofs_per_quad > 0)
609  for (unsigned int dof = 0; dof < fe.dofs_per_quad; ++dof)
610  cell->set_mg_dof_index (cell->level (), dof, next_free_dof++);
611 
612  cell->set_user_flag ();
613  return next_free_dof;
614  }
615 
616  template<int spacedim>
617  static
618  types::global_dof_index distribute_dofs_on_cell (typename DoFHandler<3, spacedim>::cell_iterator &cell, types::global_dof_index next_free_dof)
619  {
620  const FiniteElement<3, spacedim> &fe = cell->get_fe ();
621 
622  if (fe.dofs_per_vertex > 0)
623  for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_cell; ++vertex)
624  if (cell->mg_vertex_dof_index (cell->level (), vertex, 0) == DoFHandler<3>::invalid_dof_index)
625  for (unsigned int dof = 0; dof < fe.dofs_per_vertex; ++dof)
626  cell->set_mg_vertex_dof_index (cell->level (), vertex, dof, next_free_dof++);
627 
628  if (fe.dofs_per_line > 0)
629  for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_cell; ++line)
630  {
631  typename DoFHandler<3, spacedim>::line_iterator line_it = cell->line (line);
632 
633  if (line_it->mg_dof_index (cell->level (), 0) == DoFHandler<3>::invalid_dof_index)
634  for (unsigned int dof = 0; dof < fe.dofs_per_line; ++dof)
635  line_it->set_mg_dof_index (cell->level (), dof, next_free_dof++);
636  }
637 
638  if (fe.dofs_per_quad > 0)
639  for (unsigned int face = 0; face < GeometryInfo<3>::quads_per_cell; ++face)
640  {
641  typename DoFHandler<3, spacedim>::quad_iterator quad = cell->quad (face);
642 
643  if (quad->mg_dof_index (cell->level (), 0) == DoFHandler<3>::invalid_dof_index)
644  for (unsigned int dof = 0; dof < fe.dofs_per_quad; ++dof)
645  quad->set_mg_dof_index (cell->level (), dof, next_free_dof++);
646  }
647 
648  if (fe.dofs_per_hex > 0)
649  for (unsigned int dof = 0; dof < fe.dofs_per_hex; ++dof)
650  cell->set_mg_dof_index (cell->level (), dof, next_free_dof++);
651 
652  cell->set_user_flag ();
653  return next_free_dof;
654  }
655 
656  template<int spacedim>
657  static
659  get_dof_index (
660  const DoFHandler<1, spacedim> &dof_handler,
663  const unsigned int obj_index,
664  const unsigned int fe_index,
665  const unsigned int local_index,
666  const int2type<1>)
667  {
668  return mg_level.dof_object.get_dof_index (dof_handler, obj_index, fe_index, local_index);
669  }
670 
671  template<int spacedim>
672  static
674  get_dof_index (const DoFHandler<2, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<2> &, internal::DoFHandler::DoFFaces<2> &mg_faces, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const int2type<1>)
675  {
676  return mg_faces.lines.get_dof_index (dof_handler, obj_index, fe_index, local_index);
677  }
678 
679  template<int spacedim>
680  static
682  get_dof_index (const DoFHandler<2, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<2> &mg_level, internal::DoFHandler::DoFFaces<2> &, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const int2type<2>)
683  {
684  return mg_level.dof_object.get_dof_index (dof_handler, obj_index, fe_index, local_index);
685  }
686 
687  template<int spacedim>
688  static
690  get_dof_index (const DoFHandler<3, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<3> &, internal::DoFHandler::DoFFaces<3> &mg_faces, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const int2type<1>)
691  {
692  return mg_faces.lines.get_dof_index (dof_handler, obj_index, fe_index, local_index);
693  }
694 
695  template<int spacedim>
696  static
698  get_dof_index (const DoFHandler<3, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<3> &, internal::DoFHandler::DoFFaces<3> &mg_faces, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const int2type<2>)
699  {
700  return mg_faces.quads.get_dof_index (dof_handler, obj_index, fe_index, local_index);
701  }
702 
703  template<int spacedim>
704  static
706  get_dof_index (const DoFHandler<3, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<3> &mg_level, internal::DoFHandler::DoFFaces<3> &, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const int2type<3>)
707  {
708  return mg_level.dof_object.get_dof_index (dof_handler, obj_index, fe_index, local_index);
709  }
710 
711  template<int spacedim>
712  static
713  void set_dof_index (const DoFHandler<1, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<1> &mg_level, internal::DoFHandler::DoFFaces<1> &, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index, const int2type<1>)
714  {
715  mg_level.dof_object.set_dof_index (dof_handler, obj_index, fe_index, local_index, global_index);
716  }
717 
718  template<int spacedim>
719  static
720  void set_dof_index (const DoFHandler<2, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<2> &, internal::DoFHandler::DoFFaces<2> &mg_faces, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index, const int2type<1>)
721  {
722  mg_faces.lines.set_dof_index (dof_handler, obj_index, fe_index, local_index, global_index);
723  }
724 
725  template<int spacedim>
726  static
727  void set_dof_index (const DoFHandler<2, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<2> &mg_level, internal::DoFHandler::DoFFaces<2> &, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index, const int2type<2>)
728  {
729  mg_level.dof_object.set_dof_index (dof_handler, obj_index, fe_index, local_index, global_index);
730  }
731 
732  template<int spacedim>
733  static
734  void set_dof_index (const DoFHandler<3, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<3> &, internal::DoFHandler::DoFFaces<3> &mg_faces, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index, const int2type<1>)
735  {
736  mg_faces.lines.set_dof_index (dof_handler, obj_index, fe_index, local_index, global_index);
737  }
738 
739  template<int spacedim>
740  static
741  void set_dof_index (const DoFHandler<3, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<3> &, internal::DoFHandler::DoFFaces<3> &mg_faces, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index, const int2type<2>)
742  {
743  mg_faces.quads.set_dof_index (dof_handler, obj_index, fe_index, local_index, global_index);
744  }
745 
746  template<int spacedim>
747  static
748  void set_dof_index (const DoFHandler<3, spacedim> &dof_handler, internal::DoFHandler::DoFLevel<3> &mg_level, internal::DoFHandler::DoFFaces<3> &, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index, const int2type<3>)
749  {
750  mg_level.dof_object.set_dof_index (dof_handler, obj_index, fe_index, local_index, global_index);
751  }
752  };
753  }
754 }
755 
756 
757 
758 template<int dim, int spacedim>
760  :
761  tria(&tria, typeid(*this).name()),
762  selected_fe(0, typeid(*this).name()),
763  faces(NULL),
764  mg_faces (NULL)
765 {
766  // decide whether we need a
767  // sequential or a parallel
768  // distributed policy
769  if (dynamic_cast<const parallel::shared::Triangulation< dim, spacedim>*>
770  (&tria)
771  != 0)
773  else if (dynamic_cast<const parallel::distributed::Triangulation< dim, spacedim >*>
774  (&tria)
775  == 0)
777  else
779 }
780 
781 
782 template<int dim, int spacedim>
784  :
785  tria(0, typeid(*this).name()),
786  selected_fe(0, typeid(*this).name()),
787  faces(NULL),
788  mg_faces (NULL)
789 {}
790 
791 
792 template <int dim, int spacedim>
794 {
795  // release allocated memory
796  clear ();
797 }
798 
799 
800 template<int dim, int spacedim>
801 void
804  const FiniteElement<dim,spacedim> &fe)
805 {
806  tria = &t;
807  faces = 0;
809 
810  // decide whether we need a
811  // sequential or a parallel
812  // distributed policy
813  if (dynamic_cast<const parallel::shared::Triangulation< dim, spacedim>*>
814  (&t)
815  != 0)
817  else if (dynamic_cast<const parallel::distributed::Triangulation< dim, spacedim >*>
818  (&t)
819  == 0)
821  else
823 
824  distribute_dofs(fe);
825 }
826 
827 
828 
829 /*------------------------ Cell iterator functions ------------------------*/
830 
831 template <int dim, int spacedim>
833 DoFHandler<dim,spacedim>::begin (const unsigned int level) const
834 {
835  typename Triangulation<dim,spacedim>::cell_iterator cell = this->get_triangulation().begin(level);
836  if (cell == this->get_triangulation().end(level))
837  return end(level);
838  return cell_iterator (*cell, this);
839 }
840 
841 
842 
843 template <int dim, int spacedim>
845 DoFHandler<dim,spacedim>::begin_active (const unsigned int level) const
846 {
847  // level is checked in begin
848  cell_iterator i = begin (level);
849  if (i.state() != IteratorState::valid)
850  return i;
851  while (i->has_children())
852  if ((++i).state() != IteratorState::valid)
853  return i;
854  return i;
855 }
856 
857 
858 
859 template <int dim, int spacedim>
862 {
863  return cell_iterator (&this->get_triangulation(),
864  -1,
865  -1,
866  this);
867 }
868 
869 
870 template <int dim, int spacedim>
872 DoFHandler<dim,spacedim>::end (const unsigned int level) const
873 {
874  typename Triangulation<dim,spacedim>::cell_iterator cell = this->get_triangulation().end(level);
875  if (cell.state() != IteratorState::valid)
876  return end();
877  return cell_iterator (*cell, this);
878 }
879 
880 
881 template <int dim, int spacedim>
883 DoFHandler<dim, spacedim>::end_active (const unsigned int level) const
884 {
885  typename Triangulation<dim,spacedim>::cell_iterator cell = this->get_triangulation().end_active(level);
886  if (cell.state() != IteratorState::valid)
887  return active_cell_iterator(end());
888  return active_cell_iterator (*cell, this);
889 }
890 
891 
892 
893 template <int dim, int spacedim>
894 typename DoFHandler<dim, spacedim>::level_cell_iterator
895 DoFHandler<dim, spacedim>::begin_mg (const unsigned int level) const
896 {
897  // Assert(this->has_level_dofs(), ExcMessage("You can only iterate over mg "
898  // "levels if mg dofs got distributed."));
899  typename Triangulation<dim,spacedim>::cell_iterator cell = this->get_triangulation().begin(level);
900  if (cell == this->get_triangulation().end(level))
901  return end_mg(level);
902  return level_cell_iterator (*cell, this);
903 }
904 
905 
906 template <int dim, int spacedim>
907 typename DoFHandler<dim, spacedim>::level_cell_iterator
908 DoFHandler<dim, spacedim>::end_mg (const unsigned int level) const
909 {
910  // Assert(this->has_level_dofs(), ExcMessage("You can only iterate over mg "
911  // "levels if mg dofs got distributed."));
912  typename Triangulation<dim,spacedim>::cell_iterator cell = this->get_triangulation().end(level);
913  if (cell.state() != IteratorState::valid)
914  return end();
915  return level_cell_iterator (*cell, this);
916 }
917 
918 
919 template <int dim, int spacedim>
920 typename DoFHandler<dim, spacedim>::level_cell_iterator
922 {
923  return level_cell_iterator (&this->get_triangulation(), -1, -1, this);
924 }
925 
926 
927 
928 template <int dim, int spacedim>
931 {
932  return
934  (begin(), end());
935 }
936 
937 
938 template <int dim, int spacedim>
941 {
942  return
944  (begin_active(), end());
945 }
946 
947 
948 
949 template <int dim, int spacedim>
952 {
953  return
955  (begin_mg(), end_mg());
956 }
957 
958 
959 
960 
961 template <int dim, int spacedim>
964 {
965  return
967  (begin(level), end(level));
968 }
969 
970 
971 
972 template <int dim, int spacedim>
975 {
976  return
978  (begin_active(level), end_active(level));
979 }
980 
981 
982 
983 template <int dim, int spacedim>
986 {
987  return
989  (begin_mg(level), end_mg(level));
990 }
991 
992 
993 
994 //---------------------------------------------------------------------------
995 
996 
997 
998 template <>
1000 {
1001  return 2*get_fe().dofs_per_vertex;
1002 }
1003 
1004 
1005 
1006 template <>
1008 {
1009  // check that only boundary
1010  // indicators 0 and 1 are allowed
1011  // in 1d
1012  for (FunctionMap::const_iterator i=boundary_ids.begin();
1013  i!=boundary_ids.end(); ++i)
1014  Assert ((i->first == 0) || (i->first == 1),
1015  ExcInvalidBoundaryIndicator());
1016 
1017  return boundary_ids.size()*get_fe().dofs_per_vertex;
1018 }
1019 
1020 
1021 
1022 template <>
1023 types::global_dof_index DoFHandler<1>::n_boundary_dofs (const std::set<types::boundary_id> &boundary_ids) const
1024 {
1025  // check that only boundary
1026  // indicators 0 and 1 are allowed
1027  // in 1d
1028  for (std::set<types::boundary_id>::const_iterator i=boundary_ids.begin();
1029  i!=boundary_ids.end(); ++i)
1030  Assert ((*i == 0) || (*i == 1),
1031  ExcInvalidBoundaryIndicator());
1032 
1033  return boundary_ids.size()*get_fe().dofs_per_vertex;
1034 }
1035 
1036 
1037 template <>
1039 {
1040  return 2*get_fe().dofs_per_vertex;
1041 }
1042 
1043 
1044 
1045 template <>
1047 {
1048  // check that only boundary
1049  // indicators 0 and 1 are allowed
1050  // in 1d
1051  for (FunctionMap::const_iterator i=boundary_ids.begin();
1052  i!=boundary_ids.end(); ++i)
1053  Assert ((i->first == 0) || (i->first == 1),
1054  ExcInvalidBoundaryIndicator());
1055 
1056  return boundary_ids.size()*get_fe().dofs_per_vertex;
1057 }
1058 
1059 
1060 
1061 template <>
1062 types::global_dof_index DoFHandler<1,2>::n_boundary_dofs (const std::set<types::boundary_id> &boundary_ids) const
1063 {
1064  // check that only boundary
1065  // indicators 0 and 1 are allowed
1066  // in 1d
1067  for (std::set<types::boundary_id>::const_iterator i=boundary_ids.begin();
1068  i!=boundary_ids.end(); ++i)
1069  Assert ((*i == 0) || (*i == 1),
1070  ExcInvalidBoundaryIndicator());
1071 
1072  return boundary_ids.size()*get_fe().dofs_per_vertex;
1073 }
1074 
1075 
1076 
1077 template<int dim, int spacedim>
1079 {
1080  std::set<int> boundary_dofs;
1081 
1082  const unsigned int dofs_per_face = get_fe().dofs_per_face;
1083  std::vector<types::global_dof_index> dofs_on_face(dofs_per_face);
1084 
1085  // loop over all faces of all cells
1086  // and see whether they are at a
1087  // boundary. note (i) that we visit
1088  // interior faces twice (which we
1089  // don't care about) but exterior
1090  // faces only once as is
1091  // appropriate, and (ii) that we
1092  // need not take special care of
1093  // single lines (using
1094  // @p{cell->has_boundary_lines}),
1095  // since we do not support
1096  // boundaries of dimension dim-2,
1097  // and so every boundary line is
1098  // also part of a boundary face.
1100  endc = end();
1101  for (; cell!=endc; ++cell)
1102  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
1103  if (cell->at_boundary(f))
1104  {
1105  cell->face(f)->get_dof_indices (dofs_on_face);
1106  for (unsigned int i=0; i<dofs_per_face; ++i)
1107  boundary_dofs.insert(dofs_on_face[i]);
1108  }
1109 
1110  return boundary_dofs.size();
1111 }
1112 
1113 
1114 
1115 template<int dim, int spacedim>
1118 {
1119  Assert (boundary_ids.find(numbers::internal_face_boundary_id) == boundary_ids.end(),
1120  ExcInvalidBoundaryIndicator());
1121 
1122  std::set<int> boundary_dofs;
1123 
1124  const unsigned int dofs_per_face = get_fe().dofs_per_face;
1125  std::vector<types::global_dof_index> dofs_on_face(dofs_per_face);
1126 
1127  // same as in the previous
1128  // function, but with an additional
1129  // check for the boundary indicator
1131  endc = end();
1132  for (; cell!=endc; ++cell)
1133  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
1134  if (cell->at_boundary(f)
1135  &&
1136  (boundary_ids.find(cell->face(f)->boundary_id()) !=
1137  boundary_ids.end()))
1138  {
1139  cell->face(f)->get_dof_indices (dofs_on_face);
1140  for (unsigned int i=0; i<dofs_per_face; ++i)
1141  boundary_dofs.insert(dofs_on_face[i]);
1142  }
1143 
1144  return boundary_dofs.size();
1145 }
1146 
1147 
1148 
1149 template<int dim, int spacedim>
1151 DoFHandler<dim,spacedim>::n_boundary_dofs (const std::set<types::boundary_id> &boundary_ids) const
1152 {
1153  Assert (boundary_ids.find (numbers::internal_face_boundary_id) == boundary_ids.end(),
1154  ExcInvalidBoundaryIndicator());
1155 
1156  std::set<int> boundary_dofs;
1157 
1158  const unsigned int dofs_per_face = get_fe().dofs_per_face;
1159  std::vector<types::global_dof_index> dofs_on_face(dofs_per_face);
1160 
1161  // same as in the previous
1162  // function, but with a different
1163  // check for the boundary indicator
1165  endc = end();
1166  for (; cell!=endc; ++cell)
1167  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
1168  if (cell->at_boundary(f)
1169  &&
1170  (std::find (boundary_ids.begin(),
1171  boundary_ids.end(),
1172  cell->face(f)->boundary_id()) !=
1173  boundary_ids.end()))
1174  {
1175  cell->face(f)->get_dof_indices (dofs_on_face);
1176  for (unsigned int i=0; i<dofs_per_face; ++i)
1177  boundary_dofs.insert(dofs_on_face[i]);
1178  }
1179 
1180  return boundary_dofs.size();
1181 }
1182 
1183 
1184 
1185 template<int dim, int spacedim>
1186 std::size_t
1188 {
1189  std::size_t mem = (MemoryConsumption::memory_consumption (tria) +
1195  sizeof (number_cache) +
1198  for (unsigned int i=0; i<levels.size(); ++i)
1200 
1201  for (unsigned int level = 0; level < mg_levels.size (); ++level)
1202  mem += mg_levels[level]->memory_consumption ();
1203 
1204  if (mg_faces != 0)
1205  mem += MemoryConsumption::memory_consumption (*mg_faces);
1206 
1207  for (unsigned int i = 0; i < mg_vertex_dofs.size (); ++i)
1208  mem += sizeof (MGVertexDoFs) + (1 + mg_vertex_dofs[i].get_finest_level () - mg_vertex_dofs[i].get_coarsest_level ()) * sizeof (types::global_dof_index);
1209 
1210  return mem;
1211 }
1212 
1213 
1214 
1215 template<int dim, int spacedim>
1217 {
1218  selected_fe = &ff;
1219 
1220  // delete all levels and set them
1221  // up newly. note that we still
1222  // have to allocate space for all
1223  // degrees of freedom on this mesh
1224  // (including ghost and cells that
1225  // are entirely stored on different
1226  // processors), though we may not
1227  // assign numbers to some of them
1228  // (i.e. they will remain at
1229  // invalid_dof_index). We need to
1230  // allocate the space because we
1231  // will want to be able to query
1232  // the dof_indices on each cell,
1233  // and simply be told that we don't
1234  // know them on some cell (i.e. get
1235  // back invalid_dof_index)
1236  clear_space ();
1238 
1239  // hand things off to the policy
1240  policy->distribute_dofs (*this,number_cache);
1241 
1242  // initialize the block info object
1243  // only if this is a sequential
1244  // triangulation. it doesn't work
1245  // correctly yet if it is parallel
1246  if (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&*tria) == 0)
1247  block_info_object.initialize(*this, false, true);
1248 }
1249 
1250 
1251 template<int dim, int spacedim>
1253 {
1254  (void)fe;
1255  Assert(levels.size()>0, ExcMessage("Distribute active DoFs using distribute_dofs() before calling distribute_mg_dofs()."));
1256 
1257  const FiniteElement<dim, spacedim> *old_fe = selected_fe;
1258  (void)old_fe;
1259  Assert(old_fe == &fe, ExcMessage("You are required to use the same FE for level and active DoFs!") );
1260 
1261  clear_mg_space();
1262 
1263  internal::DoFHandler::Implementation::reserve_space_mg (*this);
1265  if (!dist_tr)
1266  mg_number_cache.resize((*tria).n_levels());
1267  else
1268  mg_number_cache.resize(dist_tr->n_global_levels());
1269 
1270  policy->distribute_mg_dofs (*this, mg_number_cache);
1271 
1272  // initialize the block info object
1273  // only if this is a sequential
1274  // triangulation. it doesn't work
1275  // correctly yet if it is parallel
1276  if (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&*tria) == 0)
1277  block_info_object.initialize (*this, true, false);
1278 }
1279 
1280 template<int dim, int spacedim>
1282 {
1283  //TODO: move this to distribute_mg_dofs and remove function
1284 }
1285 
1286 template<int dim, int spacedim>
1288 {
1289  for (unsigned int i = 0; i < mg_levels.size (); ++i)
1290  delete mg_levels[i];
1291 
1292  mg_levels.clear ();
1293  delete mg_faces;
1294  mg_faces = NULL;
1295 
1296  std::vector<MGVertexDoFs> tmp;
1297 
1298  std::swap (mg_vertex_dofs, tmp);
1299 
1300  mg_number_cache.clear();
1301 }
1302 
1303 
1304 template<int dim, int spacedim>
1306 {
1308 }
1309 
1310 
1311 
1312 template<int dim, int spacedim>
1314 {
1315  // release lock to old fe
1316  selected_fe = 0;
1317 
1318  // release memory
1319  clear_space ();
1320  clear_mg_space ();
1321 }
1322 
1323 
1324 
1325 template <int dim, int spacedim>
1326 void
1327 DoFHandler<dim,spacedim>::renumber_dofs (const std::vector<types::global_dof_index> &new_numbers)
1328 {
1329  Assert(levels.size()>0, ExcMessage("You need to distribute DoFs before you can renumber them."));
1330 
1331  Assert (new_numbers.size() == n_locally_owned_dofs(),
1332  ExcRenumberingIncomplete());
1333 
1334 #ifdef DEBUG
1335  // assert that the new indices are
1336  // consecutively numbered if we are
1337  // working on a single
1338  // processor. this doesn't need to
1339  // hold in the case of a parallel
1340  // mesh since we map the interval
1341  // [0...n_dofs()) into itself but
1342  // only globally, not on each
1343  // processor
1344  if (n_locally_owned_dofs() == n_dofs())
1345  {
1346  std::vector<types::global_dof_index> tmp(new_numbers);
1347  std::sort (tmp.begin(), tmp.end());
1348  std::vector<types::global_dof_index>::const_iterator p = tmp.begin();
1350  for (; p!=tmp.end(); ++p, ++i)
1351  Assert (*p == i, ExcNewNumbersNotConsecutive(i));
1352  }
1353  else
1354  for (types::global_dof_index i=0; i<new_numbers.size(); ++i)
1355  Assert (new_numbers[i] < n_dofs(),
1356  ExcMessage ("New DoF index is not less than the total number of dofs."));
1357 #endif
1358 
1359  policy->renumber_dofs (new_numbers, *this,number_cache);
1360 }
1361 
1362 
1363 template <int dim, int spacedim>
1364 void
1366  const std::vector<types::global_dof_index> &)
1367 {
1368  Assert(false, ExcNotImplemented());
1369 }
1370 
1371 
1372 template<>
1373 void DoFHandler<1>::renumber_dofs (const unsigned int level,
1374  const std::vector<types::global_dof_index> &new_numbers)
1375 {
1376  Assert(mg_levels.size()>0 && levels.size()>0,
1377  ExcMessage("You need to distribute active and level DoFs before you can renumber level DoFs."));
1378  Assert (new_numbers.size() == n_dofs(level), DoFHandler<1>::ExcRenumberingIncomplete());
1379 
1380  // note that we can not use cell iterators
1381  // in this function since then we would
1382  // renumber the dofs on the interface of
1383  // two cells more than once. Anyway, this
1384  // ways it's not only more correct but also
1385  // faster
1386  for (std::vector<MGVertexDoFs>::iterator i=mg_vertex_dofs.begin();
1387  i!=mg_vertex_dofs.end(); ++i)
1388  // if the present vertex lives on
1389  // the present level
1390  if ((i->get_coarsest_level() <= level) &&
1391  (i->get_finest_level() >= level))
1392  for (unsigned int d=0; d<this->get_fe().dofs_per_vertex; ++d)
1393  i->set_index (level, d, new_numbers[i->get_index (level, d)]);
1394 
1395  for (std::vector<types::global_dof_index>::iterator i=mg_levels[level]->dof_object.dofs.begin();
1396  i!=mg_levels[level]->dof_object.dofs.end(); ++i)
1397  {
1399  {
1400  Assert(*i<new_numbers.size(), ExcInternalError());
1401  *i = new_numbers[*i];
1402  }
1403  }
1404 }
1405 
1406 
1407 
1408 template<>
1409 void DoFHandler<2>::renumber_dofs (const unsigned int level,
1410  const std::vector<types::global_dof_index> &new_numbers)
1411 {
1412  Assert(mg_levels.size()>0 && levels.size()>0,
1413  ExcMessage("You need to distribute active and level DoFs before you can renumber level DoFs."));
1414  Assert (new_numbers.size() == n_dofs(level),
1416 
1417  for (std::vector<MGVertexDoFs>::iterator i=mg_vertex_dofs.begin();
1418  i!=mg_vertex_dofs.end(); ++i)
1419  // if the present vertex lives on
1420  // the present level
1421  if ((i->get_coarsest_level() <= level) &&
1422  (i->get_finest_level() >= level))
1423  for (unsigned int d=0; d<this->get_fe().dofs_per_vertex; ++d)
1424  i->set_index (level, d, new_numbers[i->get_index (level, d)]);
1425 
1426  if (this->get_fe().dofs_per_line > 0)
1427  {
1428  // save user flags as they will be modified
1429  std::vector<bool> user_flags;
1430  this->get_triangulation().save_user_flags(user_flags);
1431  const_cast<Triangulation<2> &>(this->get_triangulation()).clear_user_flags ();
1432 
1433  // flag all lines adjacent to cells of the current
1434  // level, as those lines logically belong to the same
1435  // level as the cell, at least for for isotropic
1436  // refinement
1437  for (level_cell_iterator cell = begin(level); cell != end(level); ++cell)
1438  for (unsigned int line=0; line < GeometryInfo<2>::faces_per_cell; ++line)
1439  cell->face(line)->set_user_flag();
1440 
1441  for (cell_iterator cell = begin(); cell != end(); ++cell)
1442  for (unsigned int l=0; l<GeometryInfo<2>::lines_per_cell; ++l)
1443  if (cell->line(l)->user_flag_set())
1444  {
1445  for (unsigned int d=0; d<this->get_fe().dofs_per_line; ++d)
1446  cell->line(l)->set_mg_dof_index (level, d,
1447  new_numbers[cell->line(l)->mg_dof_index(level, d)]);
1448  cell->line(l)->clear_user_flag();
1449  }
1450  // finally, restore user flags
1451  const_cast<Triangulation<2> &>(this->get_triangulation()).load_user_flags (user_flags);
1452  }
1453 
1454  for (std::vector<types::global_dof_index>::iterator i=mg_levels[level]->dof_object.dofs.begin();
1455  i!=mg_levels[level]->dof_object.dofs.end(); ++i)
1456  {
1458  {
1459  Assert(*i<new_numbers.size(), ExcInternalError());
1460  *i = new_numbers[*i];
1461  }
1462  }
1463 }
1464 
1465 
1466 
1467 template<>
1468 void DoFHandler<3>::renumber_dofs (const unsigned int level,
1469  const std::vector<types::global_dof_index> &new_numbers)
1470 {
1471  Assert(mg_levels.size()>0 && levels.size()>0,
1472  ExcMessage("You need to distribute active and level DoFs before you can renumber level DoFs."));
1473  Assert (new_numbers.size() == n_dofs(level),
1475 
1476  for (std::vector<MGVertexDoFs>::iterator i=mg_vertex_dofs.begin();
1477  i!=mg_vertex_dofs.end(); ++i)
1478  // if the present vertex lives on
1479  // the present level
1480  if ((i->get_coarsest_level() <= level) &&
1481  (i->get_finest_level() >= level))
1482  for (unsigned int d=0; d<this->get_fe().dofs_per_vertex; ++d)
1483  i->set_index (level, d, new_numbers[i->get_index (level, d)]);
1484 
1485  // LINE DoFs
1486  if (this->get_fe().dofs_per_line > 0)
1487  {
1488  // save user flags as they will be modified
1489  std::vector<bool> user_flags;
1490  this->get_triangulation().save_user_flags(user_flags);
1491  const_cast<Triangulation<3> &>(this->get_triangulation()).clear_user_flags ();
1492 
1493  // flag all lines adjacent to cells of the current
1494  // level, as those lines logically belong to the same
1495  // level as the cell, at least for for isotropic
1496  // refinement
1497  for (level_cell_iterator cell = begin(level) ; cell != end(level) ; ++cell)
1498  for (unsigned int line=0; line < GeometryInfo<3>::lines_per_cell; ++line)
1499  cell->line(line)->set_user_flag();
1500 
1501 
1502  for (cell_iterator cell = begin(level); cell != end(level); ++cell)
1503  for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
1504  if (cell->line(l)->user_flag_set())
1505  {
1506  for (unsigned int d=0; d<this->get_fe().dofs_per_line; ++d)
1507  cell->line(l)->set_mg_dof_index (level, d,
1508  new_numbers[cell->line(l)->mg_dof_index(level, d)]);
1509  cell->line(l)->clear_user_flag();
1510  }
1511  // finally, restore user flags
1512  const_cast<Triangulation<3> &>(this->get_triangulation()).load_user_flags (user_flags);
1513  }
1514 
1515  // QUAD DoFs
1516  if (this->get_fe().dofs_per_quad > 0)
1517  {
1518  // save user flags as they will be modified
1519  std::vector<bool> user_flags;
1520  this->get_triangulation().save_user_flags(user_flags);
1521  const_cast<Triangulation<3> &>(this->get_triangulation()).clear_user_flags ();
1522 
1523  // flag all quads adjacent to cells of the current
1524  // level, as those lines logically belong to the same
1525  // level as the cell, at least for for isotropic
1526  // refinement
1527  for (level_cell_iterator cell = begin(level) ; cell != end(level); ++cell)
1528  for (unsigned int quad=0; quad < GeometryInfo<3>::faces_per_cell; ++quad)
1529  cell->face(quad)->set_user_flag();
1530 
1531  for (cell_iterator cell = begin(level); cell != end(level); ++cell)
1532  for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
1533  if (cell->quad(q)->user_flag_set())
1534  {
1535  for (unsigned int d=0; d<this->get_fe().dofs_per_quad; ++d)
1536  cell->quad(q)->set_mg_dof_index (level, d,
1537  new_numbers[cell->quad(q)->mg_dof_index(level, d)]);
1538  cell->quad(q)->clear_user_flag();
1539  }
1540  // finally, restore user flags
1541  const_cast<Triangulation<3> &>(this->get_triangulation()).load_user_flags (user_flags);
1542  }
1543 
1544  //HEX DoFs
1545  for (std::vector<types::global_dof_index>::iterator i=mg_levels[level]->dof_object.dofs.begin();
1546  i!=mg_levels[level]->dof_object.dofs.end(); ++i)
1547  {
1549  {
1550  Assert(*i<new_numbers.size(), ExcInternalError());
1551  *i = new_numbers[*i];
1552  }
1553  }
1554 }
1555 
1556 
1557 
1558 
1559 template <int dim, int spacedim>
1560 unsigned int
1562 {
1564 }
1565 
1566 
1567 
1568 template <int dim, int spacedim>
1569 unsigned int
1571 {
1572  switch (dim)
1573  {
1574  case 1:
1575  return get_fe().dofs_per_vertex;
1576  case 2:
1577  return (3*get_fe().dofs_per_vertex +
1578  2*get_fe().dofs_per_line);
1579  case 3:
1580  // we need to take refinement of
1581  // one boundary face into
1582  // consideration here; in fact,
1583  // this function returns what
1584  // #max_coupling_between_dofs<2>
1585  // returns
1586  //
1587  // we assume here, that only four
1588  // faces meet at the boundary;
1589  // this assumption is not
1590  // justified and needs to be
1591  // fixed some time. fortunately,
1592  // omitting it for now does no
1593  // harm since the matrix will cry
1594  // foul if its requirements are
1595  // not satisfied
1596  return (19*get_fe().dofs_per_vertex +
1597  28*get_fe().dofs_per_line +
1598  8*get_fe().dofs_per_quad);
1599  default:
1600  Assert (false, ExcNotImplemented());
1602  }
1603 }
1604 
1605 
1606 
1607 template<int dim, int spacedim>
1609 {
1610  for (unsigned int i=0; i<levels.size(); ++i)
1611  delete levels[i];
1612  levels.resize (0);
1613 
1614  delete faces;
1615  faces = 0;
1616 
1617  std::vector<types::global_dof_index> tmp;
1618  std::swap (vertex_dofs, tmp);
1619 
1620  number_cache.clear ();
1621 }
1622 
1623 template<int dim, int spacedim>
1624 template<int structdim>
1627  const unsigned int obj_level,
1628  const unsigned int obj_index,
1629  const unsigned int fe_index,
1630  const unsigned int local_index) const
1631 {
1632  return internal::DoFHandler::Implementation::get_dof_index (*this, *this->mg_levels[obj_level],
1633  *this->mg_faces, obj_index,
1634  fe_index, local_index,
1636 }
1637 
1638 template<int dim, int spacedim>
1639 template<int structdim>
1640 void DoFHandler<dim, spacedim>::set_dof_index (const unsigned int obj_level, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index) const
1641 {
1642  internal::DoFHandler::Implementation::set_dof_index (*this, *this->mg_levels[obj_level], *this->mg_faces, obj_index, fe_index, local_index, global_index, internal::int2type<structdim> ());
1643 }
1644 
1645 
1646 template<int dim, int spacedim>
1647 DoFHandler<dim, spacedim>::MGVertexDoFs::MGVertexDoFs (): coarsest_level (numbers::invalid_unsigned_int), finest_level (0), indices (0), indices_offset (0)
1648 {
1649 }
1650 
1651 
1652 template<int dim, int spacedim>
1654 {
1655  delete[] indices;
1656  delete[] indices_offset;
1657 }
1658 
1659 template<int dim, int spacedim>
1660 void DoFHandler<dim, spacedim>::MGVertexDoFs::init (const unsigned int cl, const unsigned int fl, const unsigned int dofs_per_vertex)
1661 {
1662  if (indices != 0)
1663  {
1664  delete[] indices;
1665  indices = 0;
1666  }
1667 
1668  if (indices_offset != 0)
1669  {
1670  delete[] indices_offset;
1671  indices_offset = 0;
1672  }
1673 
1674  coarsest_level = cl;
1675  finest_level = fl;
1676 
1677  if (cl > fl)
1678  return;
1679 
1680  const unsigned int n_levels = finest_level - coarsest_level + 1;
1681  const unsigned int n_indices = n_levels * dofs_per_vertex;
1682 
1683  indices = new types::global_dof_index[n_indices];
1684  Assert (indices != 0, ExcNoMemory ());
1685 
1686  for (unsigned int i = 0; i < n_indices; ++i)
1688 
1689  indices_offset = new types::global_dof_index[n_levels];
1690  Assert (indices != 0, ExcNoMemory ());
1691 
1692  for (unsigned int i = 0; i < n_levels; ++i)
1693  indices_offset[i] = i * dofs_per_vertex;
1694 }
1695 
1696 template<int dim, int spacedim>
1698 {
1699  return coarsest_level;
1700 }
1701 
1702 template<int dim, int spacedim>
1704 {
1705  return finest_level;
1706 }
1707 
1708 
1709 /*-------------- Explicit Instantiations -------------------------------*/
1710 #include "dof_handler.inst"
1711 
1712 
1713 DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
Definition: dof_handler.cc:974
unsigned int max_couplings_between_dofs() const
unsigned int get_coarsest_level() const
std::vector< MGVertexDoFs > mg_vertex_dofs
Definition: dof_handler.h:1062
level_cell_iterator end_mg() const
Definition: dof_handler.cc:921
static const unsigned int invalid_unsigned_int
Definition: types.h:164
cell_iterator begin(const unsigned int level=0) const
Definition: dof_handler.cc:833
::FunctionMap< dim >::type FunctionMap
Definition: dof_handler.h:264
std::vector<::internal::DoFHandler::NumberCache > mg_number_cache
Definition: dof_handler.h:945
types::global_dof_index * indices
Definition: dof_handler.h:1021
::ExceptionBase & ExcMessage(std::string arg1)
cell_iterator end() const
Definition: dof_handler.cc:861
virtual void clear()
const unsigned int dofs_per_quad
Definition: fe_base.h:238
SmartPointer< const FiniteElement< dim, spacedim >, DoFHandler< dim, spacedim > > selected_fe
Definition: dof_handler.h:925
IteratorRange< level_cell_iterator > mg_cell_iterators_on_level(const unsigned int level) const
Definition: dof_handler.cc:985
std::vector<::internal::DoFHandler::DoFLevel< dim > * > levels
Definition: dof_handler.h:1068
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:221
SmartPointer< const Triangulation< dim, spacedim >, DoFHandler< dim, spacedim > > tria
Definition: dof_handler.h:914
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
virtual std::size_t memory_consumption() const
::internal::DoFHandler::NumberCache number_cache
Definition: dof_handler.h:940
void initialize(const Triangulation< dim, spacedim > &tria, const FiniteElement< dim, spacedim > &fe)
Definition: dof_handler.cc:802
const FiniteElement< dim, spacedim > & get_fe() const
const unsigned int dofs_per_line
Definition: fe_base.h:232
virtual void distribute_mg_dofs(const FiniteElement< dim, spacedim > &fe)
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: dof_handler.cc:845
BlockInfo block_info_object
Definition: dof_handler.h:908
unsigned int n_locally_owned_dofs() const
ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:249
unsigned int global_dof_index
Definition: types.h:88
types::global_dof_index * indices_offset
Definition: dof_handler.h:1028
const unsigned int dofs_per_hex
Definition: fe_base.h:244
#define Assert(cond, exc)
Definition: exceptions.h:294
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: dof_handler.cc:940
void set_dof_index(const ::DoFHandler< dh_dim, spacedim > &dof_handler, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index)
Definition: dof_objects.cc:41
active_cell_iterator end_active(const unsigned int level) const
Definition: dof_handler.cc:883
types::global_dof_index n_boundary_dofs() const
types::global_dof_index n_dofs() const
level_cell_iterator begin_mg(const unsigned int level=0) const
Definition: dof_handler.cc:895
::internal::DoFHandler::DoFFaces< dim > * faces
Definition: dof_handler.h:1077
internal::DoFHandler::DoFObjects< 1 > lines
Definition: dof_faces.h:116
DoFObjects< dim > dof_object
Definition: dof_levels.h:82
unsigned int get_finest_level() const
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:82
virtual unsigned int n_global_levels() const
Definition: tria_base.cc:114
virtual ~DoFHandler()
Definition: dof_handler.cc:793
void initialize(const DoFHandler< dim, spacedim > &, bool levels_only=false, bool active_only=false)
Fill the object with values describing block structure of the DoFHandler.
Definition: block_info.cc:28
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
void initialize_local_block_info()
static unsigned int max_couplings_between_dofs(const DoFHandler< 1, spacedim > &dof_handler)
Definition: dof_handler.cc:108
internal::DoFHandler::DoFObjects< 1 > lines
Definition: dof_faces.h:146
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void initialize_local(const DoFHandler< dim, spacedim > &)
Initialize block structure on cells and compute renumbering between cell dofs and block cell dofs...
Definition: block_info.cc:56
IteratorRange< level_cell_iterator > mg_cell_iterators() const
Definition: dof_handler.cc:951
unsigned int coarsest_level
Definition: dof_handler.h:1010
void clear_space()
internal::DoFHandler::DoFObjects< 2 > quads
Definition: dof_faces.h:151
void init(const unsigned int coarsest_level, const unsigned int finest_level, const unsigned int dofs_per_vertex)
virtual void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
types::global_dof_index get_dof_index(const ::DoFHandler< dh_dim, spacedim > &dof_handler, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index) const
Definition: dof_objects.h:189
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
Definition: dof_handler.cc:963
const Triangulation< dim, spacedim > & get_triangulation() const
Iterator points to a valid object.
const unsigned int dofs_per_vertex
Definition: fe_base.h:226
const types::boundary_id internal_face_boundary_id
Definition: types.h:210
types::global_dof_index n_global_dofs
Definition: number_cache.h:57
unsigned int max_couplings_between_boundary_dofs() const
IteratorState::IteratorStates state() const
static void reserve_space(DoFHandler< 1, spacedim > &dof_handler)
Definition: dof_handler.cc:274
IteratorRange< cell_iterator > cell_iterators() const
Definition: dof_handler.cc:930
std::vector< types::global_dof_index > vertex_dofs
Definition: dof_handler.h:1056