Reference documentation for deal.II version 8.5.1
tria.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2008 - 2017 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 
17 #include <deal.II/base/utilities.h>
18 #include <deal.II/base/memory_consumption.h>
19 #include <deal.II/base/logstream.h>
20 #include <deal.II/lac/sparsity_tools.h>
21 #include <deal.II/lac/dynamic_sparsity_pattern.h>
22 #include <deal.II/grid/tria.h>
23 #include <deal.II/grid/tria_accessor.h>
24 #include <deal.II/grid/tria_iterator.h>
25 #include <deal.II/grid/grid_tools.h>
26 #include <deal.II/distributed/tria.h>
27 #include <deal.II/distributed/p4est_wrappers.h>
28 
29 #include <algorithm>
30 #include <numeric>
31 #include <iostream>
32 #include <fstream>
33 
34 
35 DEAL_II_NAMESPACE_OPEN
36 
37 
38 #ifdef DEAL_II_WITH_P4EST
39 
40 namespace
41 {
42  template <int dim, int spacedim>
43  void
44  get_vertex_to_cell_mappings (const Triangulation<dim,spacedim> &triangulation,
45  std::vector<unsigned int> &vertex_touch_count,
46  std::vector<std::list<
47  std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
48  &vertex_to_cell)
49  {
50  vertex_touch_count.resize (triangulation.n_vertices());
51  vertex_to_cell.resize (triangulation.n_vertices());
52 
54  cell = triangulation.begin_active();
55  cell != triangulation.end(); ++cell)
56  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
57  {
58  ++vertex_touch_count[cell->vertex_index(v)];
59  vertex_to_cell[cell->vertex_index(v)]
60  .push_back (std::make_pair (cell, v));
61  }
62  }
63 
64 
65 
66  template <int dim, int spacedim>
67  void
68  get_edge_to_cell_mappings (const Triangulation<dim,spacedim> &triangulation,
69  std::vector<unsigned int> &edge_touch_count,
70  std::vector<std::list<
71  std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
72  &edge_to_cell)
73  {
74  Assert (triangulation.n_levels() == 1, ExcInternalError());
75 
76  edge_touch_count.resize (triangulation.n_active_lines());
77  edge_to_cell.resize (triangulation.n_active_lines());
78 
80  cell = triangulation.begin_active();
81  cell != triangulation.end(); ++cell)
82  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
83  {
84  ++edge_touch_count[cell->line(l)->index()];
85  edge_to_cell[cell->line(l)->index()]
86  .push_back (std::make_pair (cell, l));
87  }
88  }
89 
90 
91 
96  template <int dim, int spacedim>
97  void
98  set_vertex_and_cell_info (const Triangulation<dim,spacedim> &triangulation,
99  const std::vector<unsigned int> &vertex_touch_count,
100  const std::vector<std::list<
101  std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
102  &vertex_to_cell,
103  const std::vector<types::global_dof_index> &coarse_cell_to_p4est_tree_permutation,
104  const bool set_vertex_info,
105  typename internal::p4est::types<dim>::connectivity *connectivity)
106  {
107  // copy the vertices into the connectivity structure. the triangulation
108  // exports the array of vertices, but some of the entries are sometimes
109  // unused; this shouldn't be the case for a newly created triangulation,
110  // but make sure
111  //
112  // note that p4est stores coordinates as a triplet of values even in 2d
113  Assert (triangulation.get_used_vertices().size() ==
114  triangulation.get_vertices().size(),
115  ExcInternalError());
116  Assert (std::find (triangulation.get_used_vertices().begin(),
117  triangulation.get_used_vertices().end(),
118  false)
119  == triangulation.get_used_vertices().end(),
120  ExcInternalError());
121  if (set_vertex_info == true)
122  for (unsigned int v=0; v<triangulation.n_vertices(); ++v)
123  {
124  connectivity->vertices[3*v ] = triangulation.get_vertices()[v][0];
125  connectivity->vertices[3*v+1] = triangulation.get_vertices()[v][1];
126  connectivity->vertices[3*v+2] = (spacedim == 2 ?
127  0
128  :
129  triangulation.get_vertices()[v][2]);
130  }
131 
132  // next store the tree_to_vertex indices (each tree is here only a single
133  // cell in the coarse mesh). p4est requires vertex numbering in clockwise
134  // orientation
135  //
136  // while we're at it, also copy the neighborship information between cells
138  cell = triangulation.begin_active(),
139  endc = triangulation.end();
140  for (; cell != endc; ++cell)
141  {
142  const unsigned int
143  index = coarse_cell_to_p4est_tree_permutation[cell->index()];
144 
145  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
146  {
147  if (set_vertex_info == true)
148  connectivity->tree_to_vertex[index*GeometryInfo<dim>::vertices_per_cell+v] = cell->vertex_index(v);
149  connectivity->tree_to_corner[index*GeometryInfo<dim>::vertices_per_cell+v] = cell->vertex_index(v);
150  }
151 
152  // neighborship information. if a cell is at a boundary, then enter
153  // the index of the cell itself here
154  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
155  if (cell->face(f)->at_boundary() == false)
156  connectivity->tree_to_tree[index*GeometryInfo<dim>::faces_per_cell + f]
157  = coarse_cell_to_p4est_tree_permutation[cell->neighbor(f)->index()];
158  else
159  connectivity->tree_to_tree[index*GeometryInfo<dim>::faces_per_cell + f]
160  = coarse_cell_to_p4est_tree_permutation[cell->index()];
161 
162  // fill tree_to_face, which is essentially neighbor_to_neighbor;
163  // however, we have to remap the resulting face number as well
164  for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
165  if (cell->face(f)->at_boundary() == false)
166  {
167  switch (dim)
168  {
169  case 2:
170  {
171  connectivity->tree_to_face[index*GeometryInfo<dim>::faces_per_cell + f]
172  = cell->neighbor_of_neighbor (f);
173  break;
174  }
175 
176  case 3:
177  {
178  /*
179  * The values for tree_to_face are in 0..23 where ttf % 6
180  * gives the face number and ttf / 4 the face orientation
181  * code. The orientation is determined as follows. Let
182  * my_face and other_face be the two face numbers of the
183  * connecting trees in 0..5. Then the first face vertex of
184  * the lower of my_face and other_face connects to a face
185  * vertex numbered 0..3 in the higher of my_face and
186  * other_face. The face orientation is defined as this
187  * number. If my_face == other_face, treating either of
188  * both faces as the lower one leads to the same result.
189  */
190 
191  connectivity->tree_to_face[index*6 + f]
192  = cell->neighbor_of_neighbor (f);
193 
194  unsigned int face_idx_list[2] =
195  {f, cell->neighbor_of_neighbor (f)};
197  cell_list[2] = {cell, cell->neighbor(f)};
198  unsigned int smaller_idx = 0;
199 
200  if (f>cell->neighbor_of_neighbor (f))
201  smaller_idx = 1;
202 
203  unsigned int larger_idx = (smaller_idx+1) % 2;
204  //smaller = *_list[smaller_idx]
205  //larger = *_list[larger_idx]
206 
207  unsigned int v = 0;
208 
209  // global vertex index of vertex 0 on face of cell with
210  // smaller local face index
211  unsigned int g_idx =
212  cell_list[smaller_idx]->vertex_index(
214  face_idx_list[smaller_idx],
215  0,
216  cell_list[smaller_idx]->face_orientation(face_idx_list[smaller_idx]),
217  cell_list[smaller_idx]->face_flip(face_idx_list[smaller_idx]),
218  cell_list[smaller_idx]->face_rotation(face_idx_list[smaller_idx]))
219  );
220 
221  // loop over vertices on face from other cell and compare
222  // global vertex numbers
223  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
224  {
225  unsigned int idx
226  =
227  cell_list[larger_idx]->vertex_index(
229  face_idx_list[larger_idx],
230  i)
231  );
232 
233  if (idx==g_idx)
234  {
235  v = i;
236  break;
237  }
238  }
239 
240  connectivity->tree_to_face[index*6 + f] += 6*v;
241  break;
242  }
243 
244  default:
245  Assert (false, ExcNotImplemented());
246  }
247  }
248  else
249  connectivity->tree_to_face[index*GeometryInfo<dim>::faces_per_cell + f] = f;
250  }
251 
252  // now fill the vertex information
253  connectivity->ctt_offset[0] = 0;
254  std::partial_sum (vertex_touch_count.begin(),
255  vertex_touch_count.end(),
256  &connectivity->ctt_offset[1]);
257 
259  num_vtt = std::accumulate (vertex_touch_count.begin(),
260  vertex_touch_count.end(),
261  0);
262  (void)num_vtt;
263  Assert (connectivity->ctt_offset[triangulation.n_vertices()] ==
264  num_vtt,
265  ExcInternalError());
266 
267  for (unsigned int v=0; v<triangulation.n_vertices(); ++v)
268  {
269  Assert (vertex_to_cell[v].size() == vertex_touch_count[v],
270  ExcInternalError());
271 
272  typename std::list<std::pair
274  unsigned int> >::const_iterator
275  p = vertex_to_cell[v].begin();
276  for (unsigned int c=0; c<vertex_touch_count[v]; ++c, ++p)
277  {
278  connectivity->corner_to_tree[connectivity->ctt_offset[v]+c]
279  = coarse_cell_to_p4est_tree_permutation[p->first->index()];
280  connectivity->corner_to_corner[connectivity->ctt_offset[v]+c]
281  = p->second;
282  }
283  }
284  }
285 
286 
287 
288  template <int dim, int spacedim>
289  bool
290  tree_exists_locally (const typename internal::p4est::types<dim>::forest *parallel_forest,
291  const typename internal::p4est::types<dim>::topidx coarse_grid_cell)
292  {
293  Assert (coarse_grid_cell < parallel_forest->connectivity->num_trees,
294  ExcInternalError());
295  return ((coarse_grid_cell >= parallel_forest->first_local_tree)
296  &&
297  (coarse_grid_cell <= parallel_forest->last_local_tree));
298  }
299 
300 
301  template <int dim, int spacedim>
302  void
303  delete_all_children_and_self (const typename Triangulation<dim,spacedim>::cell_iterator &cell)
304  {
305  if (cell->has_children())
306  for (unsigned int c=0; c<cell->n_children(); ++c)
307  delete_all_children_and_self<dim,spacedim> (cell->child(c));
308  else
309  cell->set_coarsen_flag ();
310  }
311 
312 
313 
314  template <int dim, int spacedim>
315  void
316  delete_all_children (const typename Triangulation<dim,spacedim>::cell_iterator &cell)
317  {
318  if (cell->has_children())
319  for (unsigned int c=0; c<cell->n_children(); ++c)
320  delete_all_children_and_self<dim,spacedim> (cell->child(c));
321  }
322 
323 
324  template <int dim, int spacedim>
325  void
326  determine_level_subdomain_id_recursively (const typename internal::p4est::types<dim>::tree &tree,
327  const typename internal::p4est::types<dim>::locidx &tree_index,
328  const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
329  const typename internal::p4est::types<dim>::quadrant &p4est_cell,
330  typename internal::p4est::types<dim>::forest &forest,
331  const types::subdomain_id my_subdomain,
332  const std::vector<std::vector<bool> > &marked_vertices)
333  {
334  if (dealii_cell->level_subdomain_id()==numbers::artificial_subdomain_id)
335  {
336  //important: only assign the level_subdomain_id if it is a ghost cell
337  // even though we could fill in all.
338  bool used = false;
339  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
340  {
341  if (marked_vertices[dealii_cell->level()][dealii_cell->vertex_index(v)])
342  {
343  used = true;
344  break;
345  }
346  }
347 
348  // Special case: if this cell is active we might be a ghost neighbor
349  // to a locally owned cell across a vertex that is finer.
350  // Example (M= my, O=dealii_cell, owned by somebody else):
351  // *------*
352  // | |
353  // | O |
354  // | |
355  // *---*---*------*
356  // | M | M |
357  // *---*---*
358  // | | M |
359  // *---*---*
360  if (!used && dealii_cell->active() && dealii_cell->is_artificial()==false
361  && dealii_cell->level()+1<static_cast<int>(marked_vertices.size()))
362  {
363  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
364  {
365  if (marked_vertices[dealii_cell->level()+1][dealii_cell->vertex_index(v)])
366  {
367  used = true;
368  break;
369  }
370  }
371  }
372 
373  // Like above, but now the other way around
374  if (!used && dealii_cell->active() && dealii_cell->is_artificial()==false
375  && dealii_cell->level()>0)
376  {
377  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
378  {
379  if (marked_vertices[dealii_cell->level()-1][dealii_cell->vertex_index(v)])
380  {
381  used = true;
382  break;
383  }
384  }
385  }
386 
387  if (used)
388  {
390  tree_index,
391  &p4est_cell,
392  my_subdomain);
393  Assert((owner!=-2) && (owner!=-1), ExcMessage("p4est should know the owner."));
394  dealii_cell->set_level_subdomain_id(owner);
395  }
396 
397  }
398 
399  if (dealii_cell->has_children ())
400  {
403  for (unsigned int c=0;
404  c<GeometryInfo<dim>::max_children_per_cell; ++c)
405  switch (dim)
406  {
407  case 2:
408  P4EST_QUADRANT_INIT(&p4est_child[c]);
409  break;
410  case 3:
411  P8EST_QUADRANT_INIT(&p4est_child[c]);
412  break;
413  default:
414  Assert (false, ExcNotImplemented());
415  }
416 
417 
419  quadrant_childrenv (&p4est_cell,
420  p4est_child);
421 
422  for (unsigned int c=0;
423  c<GeometryInfo<dim>::max_children_per_cell; ++c)
424  {
425  determine_level_subdomain_id_recursively <dim,spacedim> (tree,tree_index,
426  dealii_cell->child(c),
427  p4est_child[c],
428  forest,
429  my_subdomain,
430  marked_vertices);
431  }
432  }
433  }
434 
435 
436  template <int dim, int spacedim>
437  void
438  match_tree_recursively (const typename internal::p4est::types<dim>::tree &tree,
439  const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
440  const typename internal::p4est::types<dim>::quadrant &p4est_cell,
441  const typename internal::p4est::types<dim>::forest &forest,
442  const types::subdomain_id my_subdomain)
443  {
444  // check if this cell exists in the local p4est cell
445  if (sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
446  &p4est_cell,
448  != -1)
449  {
450  // yes, cell found in local part of p4est
451  delete_all_children<dim,spacedim> (dealii_cell);
452  if (!dealii_cell->has_children())
453  dealii_cell->set_subdomain_id(my_subdomain);
454  }
455  else
456  {
457  // no, cell not found in local part of p4est. this means that the
458  // local part is more refined than the current cell. if this cell has
459  // no children of its own, we need to refine it, and if it does
460  // already have children then loop over all children and see if they
461  // are locally available as well
462  if (dealii_cell->has_children () == false)
463  dealii_cell->set_refine_flag ();
464  else
465  {
468  for (unsigned int c=0;
469  c<GeometryInfo<dim>::max_children_per_cell; ++c)
470  switch (dim)
471  {
472  case 2:
473  P4EST_QUADRANT_INIT(&p4est_child[c]);
474  break;
475  case 3:
476  P8EST_QUADRANT_INIT(&p4est_child[c]);
477  break;
478  default:
479  Assert (false, ExcNotImplemented());
480  }
481 
482 
484  quadrant_childrenv (&p4est_cell,
485  p4est_child);
486 
487  for (unsigned int c=0;
488  c<GeometryInfo<dim>::max_children_per_cell; ++c)
490  quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree *>(&tree),
491  &p4est_child[c])
492  == false)
493  {
494  // no, this child is locally not available in the p4est.
495  // delete all its children but, because this may not be
496  // successfull, make sure to mark all children recursively
497  // as not local.
498  delete_all_children<dim,spacedim> (dealii_cell->child(c));
499  dealii_cell->child(c)
500  ->recursively_set_subdomain_id(numbers::artificial_subdomain_id);
501  }
502  else
503  {
504  // at least some part of the tree rooted in this child is
505  // locally available
506  match_tree_recursively<dim,spacedim> (tree,
507  dealii_cell->child(c),
508  p4est_child[c],
509  forest,
510  my_subdomain);
511  }
512  }
513  }
514  }
515 
516 
517  template <int dim, int spacedim>
518  void
519  match_quadrant (const ::Triangulation<dim,spacedim> *tria,
520  unsigned int dealii_index,
521  typename internal::p4est::types<dim>::quadrant &ghost_quadrant,
522  types::subdomain_id ghost_owner)
523  {
524  int i, child_id;
525  int l = ghost_quadrant.level;
526 
527  for (i = 0; i < l; i++)
528  {
529  typename Triangulation<dim,spacedim>::cell_iterator cell (tria, i, dealii_index);
530  if (cell->has_children () == false)
531  {
532  cell->clear_coarsen_flag();
533  cell->set_refine_flag ();
534  return;
535  }
536 
537  child_id = internal::p4est::functions<dim>::quadrant_ancestor_id (&ghost_quadrant, i + 1);
538  dealii_index = cell->child_index(child_id);
539  }
540 
541  typename Triangulation<dim,spacedim>::cell_iterator cell (tria, l, dealii_index);
542  if (cell->has_children())
543  delete_all_children<dim,spacedim> (cell);
544  else
545  {
546  cell->clear_coarsen_flag();
547  cell->set_subdomain_id(ghost_owner);
548  }
549  }
550 
551 
552 
553  template <int dim, int spacedim>
554  void
555  attach_mesh_data_recursively (const typename internal::p4est::types<dim>::tree &tree,
556  const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
557  const typename internal::p4est::types<dim>::quadrant &p4est_cell,
558  const typename std::list<std::pair<unsigned int, typename std_cxx11::function<
560  typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
561  void *)
562  > > > &attached_data_pack_callbacks)
563  {
564  typedef std::list<std::pair<unsigned int, typename std_cxx11::function<
566  typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
567  void *)
568  > > > callback_list_t;
569 
570  int idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
571  &p4est_cell,
573 
574  if (idx == -1 && (internal::p4est::functions<dim>::
575  quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree *>(&tree),
576  &p4est_cell)
577  == false))
578  return; //this quadrant and none of its children belongs to us.
579 
580  bool p4est_has_children = (idx == -1);
581 
582  if (p4est_has_children && dealii_cell->has_children())
583  {
584  //recurse further
587  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
588  switch (dim)
589  {
590  case 2:
591  P4EST_QUADRANT_INIT(&p4est_child[c]);
592  break;
593  case 3:
594  P8EST_QUADRANT_INIT(&p4est_child[c]);
595  break;
596  default:
597  Assert (false, ExcNotImplemented());
598  }
599 
601  quadrant_childrenv (&p4est_cell, p4est_child);
602 
603  for (unsigned int c=0;
604  c<GeometryInfo<dim>::max_children_per_cell; ++c)
605  {
606  attach_mesh_data_recursively<dim,spacedim> (tree,
607  dealii_cell->child(c),
608  p4est_child[c],
609  attached_data_pack_callbacks);
610  }
611  }
612  else if (!p4est_has_children && !dealii_cell->has_children())
613  {
614  //this active cell didn't change
616  q = static_cast<typename internal::p4est::types<dim>::quadrant *> (
617  sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), idx)
618  );
619  *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus *>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_PERSIST;
620 
621  for (typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
622  it != attached_data_pack_callbacks.end();
623  ++it)
624  {
625  void *ptr = static_cast<char *>(q->p.user_data) + (*it).first; //add offset
626  ((*it).second)(dealii_cell,
628  ptr);
629  }
630  }
631  else if (p4est_has_children)
632  {
633  //this cell got refined
634 
635  //attach to the first child, because we can only attach to active
636  // quadrants
639  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
640  switch (dim)
641  {
642  case 2:
643  P4EST_QUADRANT_INIT(&p4est_child[c]);
644  break;
645  case 3:
646  P8EST_QUADRANT_INIT(&p4est_child[c]);
647  break;
648  default:
649  Assert (false, ExcNotImplemented());
650  }
651 
653  quadrant_childrenv (&p4est_cell, p4est_child);
654  int child0_idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
655  &p4est_child[0],
657  Assert(child0_idx != -1, ExcMessage("the first child should exist as an active quadrant!"));
658 
660  q = static_cast<typename internal::p4est::types<dim>::quadrant *> (
661  sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), child0_idx)
662  );
663  *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus *>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_REFINE;
664 
665  for (typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
666  it != attached_data_pack_callbacks.end();
667  ++it)
668  {
669  void *ptr = static_cast<char *>(q->p.user_data) + (*it).first; //add offset
670 
671  ((*it).second)(dealii_cell,
673  ptr);
674  }
675 
676  //mark other children as invalid, so that unpack only happens once
677  for (unsigned int i=1; i<GeometryInfo<dim>::max_children_per_cell; ++i)
678  {
679  int child_idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
680  &p4est_child[i],
682  q = static_cast<typename internal::p4est::types<dim>::quadrant *> (
683  sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), child_idx)
684  );
685  *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus *>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_INVALID;
686  }
687 
688 
689  }
690  else
691  {
692  //its children got coarsened into this cell
694  q = static_cast<typename internal::p4est::types<dim>::quadrant *> (
695  sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), idx)
696  );
697  *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus *>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_COARSEN;
698 
699  for (typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
700  it != attached_data_pack_callbacks.end();
701  ++it)
702  {
703  void *ptr = static_cast<char *>(q->p.user_data) + (*it).first; //add offset
704  ((*it).second)(dealii_cell,
706  ptr);
707  }
708  }
709  }
710 
711  template <int dim, int spacedim>
712  void
713  get_cell_weights_recursively (const typename internal::p4est::types<dim>::tree &tree,
714  const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
715  const typename internal::p4est::types<dim>::quadrant &p4est_cell,
716  const typename Triangulation<dim,spacedim>::Signals &signals,
717  std::vector<unsigned int> &weight)
718  {
719  const int idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
720  &p4est_cell,
722 
723  if (idx == -1 && (internal::p4est::functions<dim>::
724  quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree *>(&tree),
725  &p4est_cell)
726  == false))
727  return; // This quadrant and none of its children belongs to us.
728 
729  const bool p4est_has_children = (idx == -1);
730 
731  if (p4est_has_children && dealii_cell->has_children())
732  {
733  //recurse further
736  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
737  switch (dim)
738  {
739  case 2:
740  P4EST_QUADRANT_INIT(&p4est_child[c]);
741  break;
742  case 3:
743  P8EST_QUADRANT_INIT(&p4est_child[c]);
744  break;
745  default:
746  Assert (false, ExcNotImplemented());
747  }
748 
750  quadrant_childrenv (&p4est_cell, p4est_child);
751 
752  for (unsigned int c=0;
753  c<GeometryInfo<dim>::max_children_per_cell; ++c)
754  {
755  get_cell_weights_recursively<dim,spacedim> (tree,
756  dealii_cell->child(c),
757  p4est_child[c],
758  signals,
759  weight);
760  }
761  }
762  else if (!p4est_has_children && !dealii_cell->has_children())
763  {
764  // This active cell didn't change
765  weight.push_back(1000);
766  weight.back() += signals.cell_weight(dealii_cell,
768  }
769  else if (p4est_has_children)
770  {
771  // This cell will be refined
772  unsigned int parent_weight(1000);
773  parent_weight += signals.cell_weight(dealii_cell,
775 
776  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
777  {
778  // We assign the weight of the parent cell equally to all children
779  weight.push_back(parent_weight);
780  }
781  }
782  else
783  {
784  // This cell's children will be coarsened into this cell
785  weight.push_back(1000);
786  weight.back() += signals.cell_weight(dealii_cell,
788  }
789  }
790 
791 
792  template <int dim, int spacedim>
793  void
794  post_mesh_data_recursively (const typename internal::p4est::types<dim>::tree &tree,
795  const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
796  const typename Triangulation<dim,spacedim>::cell_iterator &parent_cell,
797  const typename internal::p4est::types<dim>::quadrant &p4est_cell,
798  const unsigned int offset,
799  const typename std_cxx11::function<
800  void(typename parallel::distributed::Triangulation<dim,spacedim>::cell_iterator, typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus, void *)
801  > &unpack_callback)
802  {
803  int idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
804  &p4est_cell,
806  if (idx == -1 && (internal::p4est::functions<dim>::
807  quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree *>(&tree),
808  &p4est_cell)
809  == false))
810  // this quadrant and none of its children belong to us.
811  return;
812 
813 
814  const bool p4est_has_children = (idx == -1);
815  if (p4est_has_children)
816  {
817  Assert(dealii_cell->has_children(), ExcInternalError());
818 
819  //recurse further
822  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
823  switch (dim)
824  {
825  case 2:
826  P4EST_QUADRANT_INIT(&p4est_child[c]);
827  break;
828  case 3:
829  P8EST_QUADRANT_INIT(&p4est_child[c]);
830  break;
831  default:
832  Assert (false, ExcNotImplemented());
833  }
834 
836  quadrant_childrenv (&p4est_cell, p4est_child);
837 
838  for (unsigned int c=0;
839  c<GeometryInfo<dim>::max_children_per_cell; ++c)
840  {
841  post_mesh_data_recursively<dim,spacedim> (tree,
842  dealii_cell->child(c),
843  dealii_cell,
844  p4est_child[c],
845  offset,
846  unpack_callback);
847  }
848  }
849  else
850  {
851  Assert(! dealii_cell->has_children(), ExcInternalError());
852 
854  q = static_cast<typename internal::p4est::types<dim>::quadrant *> (
855  sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), idx)
856  );
857 
858  void *ptr = static_cast<char *>(q->p.user_data) + offset;
859  typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus
860  status = * static_cast<
861  typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus *
862  >(q->p.user_data);
863  switch (status)
864  {
866  {
867  unpack_callback(dealii_cell, status, ptr);
868  break;
869  }
871  {
872  unpack_callback(parent_cell, status, ptr);
873  break;
874  }
876  {
877  unpack_callback(dealii_cell, status, ptr);
878  break;
879  }
881  {
882  break;
883  }
884  default:
885  Assert (false, ExcInternalError());
886  }
887  }
888  }
889 
890 
891 
897  template <int dim, int spacedim>
898  class RefineAndCoarsenList
899  {
900  public:
901  RefineAndCoarsenList (const Triangulation<dim,spacedim> &triangulation,
902  const std::vector<types::global_dof_index> &p4est_tree_to_coarse_cell_permutation,
903  const types::subdomain_id my_subdomain);
904 
913  static
914  int
915  refine_callback (typename internal::p4est::types<dim>::forest *forest,
916  typename internal::p4est::types<dim>::topidx coarse_cell_index,
917  typename internal::p4est::types<dim>::quadrant *quadrant);
918 
923  static
924  int
925  coarsen_callback (typename internal::p4est::types<dim>::forest *forest,
926  typename internal::p4est::types<dim>::topidx coarse_cell_index,
927  typename internal::p4est::types<dim>::quadrant *children[]);
928 
929  bool pointers_are_at_end () const;
930 
931  private:
932  std::vector<typename internal::p4est::types<dim>::quadrant> refine_list;
933  typename std::vector<typename internal::p4est::types<dim>::quadrant>::const_iterator current_refine_pointer;
934 
935  std::vector<typename internal::p4est::types<dim>::quadrant> coarsen_list;
936  typename std::vector<typename internal::p4est::types<dim>::quadrant>::const_iterator current_coarsen_pointer;
937 
938  void build_lists (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
939  const typename internal::p4est::types<dim>::quadrant &p4est_cell,
940  const types::subdomain_id myid);
941  };
942 
943 
944 
945  template <int dim, int spacedim>
946  bool
947  RefineAndCoarsenList<dim,spacedim>::
948  pointers_are_at_end () const
949  {
950  return ((current_refine_pointer == refine_list.end())
951  &&
952  (current_coarsen_pointer == coarsen_list.end()));
953  }
954 
955 
956 
957  template <int dim, int spacedim>
958  RefineAndCoarsenList<dim,spacedim>::
959  RefineAndCoarsenList (const Triangulation<dim,spacedim> &triangulation,
960  const std::vector<types::global_dof_index> &p4est_tree_to_coarse_cell_permutation,
961  const types::subdomain_id my_subdomain)
962  {
963  // count how many flags are set and allocate that much memory
964  unsigned int n_refine_flags = 0,
965  n_coarsen_flags = 0;
967  cell = triangulation.begin_active();
968  cell != triangulation.end(); ++cell)
969  {
970  //skip cells that are not local
971  if (cell->subdomain_id() != my_subdomain)
972  continue;
973 
974  if (cell->refine_flag_set())
975  ++n_refine_flags;
976  else if (cell->coarsen_flag_set())
977  ++n_coarsen_flags;
978  }
979 
980  refine_list.reserve (n_refine_flags);
981  coarsen_list.reserve (n_coarsen_flags);
982 
983 
984  // now build the lists of cells that are flagged. note that p4est will
985  // traverse its cells in the order in which trees appear in the
986  // forest. this order is not the same as the order of coarse cells in the
987  // deal.II Triangulation because we have translated everything by the
988  // coarse_cell_to_p4est_tree_permutation permutation. in order to make
989  // sure that the output array is already in the correct order, traverse
990  // our coarse cells in the same order in which p4est will:
991  for (unsigned int c=0; c<triangulation.n_cells(0); ++c)
992  {
993  unsigned int coarse_cell_index =
994  p4est_tree_to_coarse_cell_permutation[c];
995 
997  cell (&triangulation, 0, coarse_cell_index);
998 
999  typename internal::p4est::types<dim>::quadrant p4est_cell;
1001  quadrant_set_morton (&p4est_cell,
1002  /*level=*/0,
1003  /*index=*/0);
1004  p4est_cell.p.which_tree = c;
1005  build_lists (cell, p4est_cell, my_subdomain);
1006  }
1007 
1008 
1009  Assert(refine_list.size() == n_refine_flags,
1010  ExcInternalError());
1011  Assert(coarsen_list.size() == n_coarsen_flags,
1012  ExcInternalError());
1013 
1014  // make sure that our ordering in fact worked
1015  for (unsigned int i=1; i<refine_list.size(); ++i)
1016  Assert (refine_list[i].p.which_tree >=
1017  refine_list[i-1].p.which_tree,
1018  ExcInternalError());
1019  for (unsigned int i=1; i<coarsen_list.size(); ++i)
1020  Assert (coarsen_list[i].p.which_tree >=
1021  coarsen_list[i-1].p.which_tree,
1022  ExcInternalError());
1023 
1024  current_refine_pointer = refine_list.begin();
1025  current_coarsen_pointer = coarsen_list.begin();
1026  }
1027 
1028 
1029 
1030  template <int dim, int spacedim>
1031  void
1032  RefineAndCoarsenList<dim,spacedim>::
1033  build_lists (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
1034  const typename internal::p4est::types<dim>::quadrant &p4est_cell,
1035  const types::subdomain_id my_subdomain)
1036  {
1037  if (!cell->has_children())
1038  {
1039  if (cell->subdomain_id() == my_subdomain)
1040  {
1041  if (cell->refine_flag_set())
1042  refine_list.push_back (p4est_cell);
1043  else if (cell->coarsen_flag_set())
1044  coarsen_list.push_back (p4est_cell);
1045  }
1046  }
1047  else
1048  {
1051  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1052  switch (dim)
1053  {
1054  case 2:
1055  P4EST_QUADRANT_INIT(&p4est_child[c]);
1056  break;
1057  case 3:
1058  P8EST_QUADRANT_INIT(&p4est_child[c]);
1059  break;
1060  default:
1061  Assert (false, ExcNotImplemented());
1062  }
1064  quadrant_childrenv (&p4est_cell,
1065  p4est_child);
1066  for (unsigned int c=0;
1067  c<GeometryInfo<dim>::max_children_per_cell; ++c)
1068  {
1069  p4est_child[c].p.which_tree = p4est_cell.p.which_tree;
1070  build_lists (cell->child(c),
1071  p4est_child[c],
1072  my_subdomain);
1073  }
1074  }
1075  }
1076 
1077 
1078  template <int dim, int spacedim>
1079  int
1080  RefineAndCoarsenList<dim,spacedim>::
1081  refine_callback (typename internal::p4est::types<dim>::forest *forest,
1082  typename internal::p4est::types<dim>::topidx coarse_cell_index,
1083  typename internal::p4est::types<dim>::quadrant *quadrant)
1084  {
1085  RefineAndCoarsenList<dim,spacedim> *this_object
1086  = reinterpret_cast<RefineAndCoarsenList<dim,spacedim>*>(forest->user_pointer);
1087 
1088  // if there are no more cells in our list the current cell can't be
1089  // flagged for refinement
1090  if (this_object->current_refine_pointer == this_object->refine_list.end())
1091  return false;
1092 
1093  Assert (coarse_cell_index <=
1094  this_object->current_refine_pointer->p.which_tree,
1095  ExcInternalError());
1096 
1097  // if p4est hasn't yet reached the tree of the next flagged cell the
1098  // current cell can't be flagged for refinement
1099  if (coarse_cell_index <
1100  this_object->current_refine_pointer->p.which_tree)
1101  return false;
1102 
1103  // now we're in the right tree in the forest
1104  Assert (coarse_cell_index <=
1105  this_object->current_refine_pointer->p.which_tree,
1106  ExcInternalError());
1107 
1108  // make sure that the p4est loop over cells hasn't gotten ahead of our own
1109  // pointer
1111  quadrant_compare (quadrant,
1112  &*this_object->current_refine_pointer) <= 0,
1113  ExcInternalError());
1114 
1115  // now, if the p4est cell is one in the list, it is supposed to be refined
1117  quadrant_is_equal (quadrant, &*this_object->current_refine_pointer))
1118  {
1119  ++this_object->current_refine_pointer;
1120  return true;
1121  }
1122 
1123  // p4est cell is not in list
1124  return false;
1125  }
1126 
1127 
1128 
1129  template <int dim, int spacedim>
1130  int
1131  RefineAndCoarsenList<dim,spacedim>::
1132  coarsen_callback (typename internal::p4est::types<dim>::forest *forest,
1133  typename internal::p4est::types<dim>::topidx coarse_cell_index,
1134  typename internal::p4est::types<dim>::quadrant *children[])
1135  {
1136  RefineAndCoarsenList<dim,spacedim> *this_object
1137  = reinterpret_cast<RefineAndCoarsenList<dim,spacedim>*>(forest->user_pointer);
1138 
1139  // if there are no more cells in our list the current cell can't be
1140  // flagged for coarsening
1141  if (this_object->current_coarsen_pointer ==
1142  this_object->coarsen_list.end())
1143  return false;
1144 
1145  Assert (coarse_cell_index <=
1146  this_object->current_coarsen_pointer->p.which_tree,
1147  ExcInternalError());
1148 
1149  // if p4est hasn't yet reached the tree of the next flagged cell the
1150  // current cell can't be flagged for coarsening
1151  if (coarse_cell_index <
1152  this_object->current_coarsen_pointer->p.which_tree)
1153  return false;
1154 
1155  // now we're in the right tree in the forest
1156  Assert (coarse_cell_index <=
1157  this_object->current_coarsen_pointer->p.which_tree,
1158  ExcInternalError());
1159 
1160  // make sure that the p4est loop over cells hasn't gotten ahead of our own
1161  // pointer
1163  quadrant_compare (children[0],
1164  &*this_object->current_coarsen_pointer) <= 0,
1165  ExcInternalError());
1166 
1167  // now, if the p4est cell is one in the list, it is supposed to be
1168  // coarsened
1170  quadrant_is_equal (children[0],
1171  &*this_object->current_coarsen_pointer))
1172  {
1173  // move current pointer one up
1174  ++this_object->current_coarsen_pointer;
1175 
1176  // note that the next 3 cells in our list need to correspond to the
1177  // other siblings of the cell we have just found
1178  for (unsigned int c=1; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1179  {
1181  quadrant_is_equal (children[c],
1182  &*this_object->current_coarsen_pointer),
1183  ExcInternalError());
1184  ++this_object->current_coarsen_pointer;
1185  }
1186 
1187  return true;
1188  }
1189 
1190  // p4est cell is not in list
1191  return false;
1192  }
1193 
1194 
1195 
1202  template <int dim, int spacedim>
1203  class PartitionWeights
1204  {
1205  public:
1211  PartitionWeights (const std::vector<unsigned int> &cell_weights);
1212 
1220  static
1221  int
1222  cell_weight (typename internal::p4est::types<dim>::forest *forest,
1223  typename internal::p4est::types<dim>::topidx coarse_cell_index,
1224  typename internal::p4est::types<dim>::quadrant *quadrant);
1225 
1226  private:
1227  std::vector<unsigned int> cell_weights_list;
1228  std::vector<unsigned int>::const_iterator current_pointer;
1229  };
1230 
1231 
1232  template <int dim, int spacedim>
1233  PartitionWeights<dim,spacedim>::
1234  PartitionWeights (const std::vector<unsigned int> &cell_weights)
1235  :
1236  cell_weights_list(cell_weights)
1237  {
1238  // set the current pointer to the first element of the list, given that
1239  // we will walk through it sequentially
1240  current_pointer = cell_weights_list.begin();
1241  }
1242 
1243 
1244  template <int dim, int spacedim>
1245  int
1246  PartitionWeights<dim,spacedim>::
1247  cell_weight (typename internal::p4est::types<dim>::forest *forest,
1250  {
1251  // the function gets two additional arguments, but we don't need them
1252  // since we know in which order p4est will walk through the cells
1253  // and have already built our weight lists in this order
1254 
1255  PartitionWeights<dim,spacedim> *this_object
1256  = reinterpret_cast<PartitionWeights<dim,spacedim>*>(forest->user_pointer);
1257 
1258  Assert (this_object->current_pointer >= this_object->cell_weights_list.begin(),
1259  ExcInternalError());
1260  Assert (this_object->current_pointer < this_object->cell_weights_list.end(),
1261  ExcInternalError());
1262 
1263  // get the weight, increment the pointer, and return the weight
1264  return *this_object->current_pointer++;
1265  }
1266 }
1267 
1268 
1269 namespace parallel
1270 {
1271  namespace distributed
1272  {
1273 
1274  /* ---------------------- class Triangulation<dim,spacedim> ------------------------------ */
1275 
1276 
1277  template <int dim, int spacedim>
1279  Triangulation (MPI_Comm mpi_communicator,
1280  const typename ::Triangulation<dim,spacedim>::MeshSmoothing smooth_grid,
1281  const Settings settings_)
1282  :
1283  // Do not check for distorted cells.
1284  // For multigrid, we need limit_level_difference_at_vertices
1285  // to make sure the transfer operators only need to consider two levels.
1286  ::parallel::Triangulation<dim,spacedim>
1287  (mpi_communicator,
1288  (settings_ & construct_multigrid_hierarchy) ?
1289  static_cast<typename ::Triangulation<dim,spacedim>::MeshSmoothing>
1290  (smooth_grid | Triangulation<dim,spacedim>::limit_level_difference_at_vertices) :
1291  smooth_grid,
1292  false),
1293  settings(settings_),
1294  triangulation_has_content (false),
1295  connectivity (0),
1296  parallel_forest (0),
1297  refinement_in_progress (false),
1298  attached_data_size(0),
1299  n_attached_datas(0),
1300  n_attached_deserialize(0)
1301  {
1302  parallel_ghost = 0;
1303  }
1304 
1305 
1306 
1307  template <int dim, int spacedim>
1309  {
1310  clear ();
1311 
1312  Assert (triangulation_has_content == false,
1313  ExcInternalError());
1314  Assert (connectivity == 0, ExcInternalError());
1315  Assert (parallel_forest == 0, ExcInternalError());
1316  Assert (refinement_in_progress == false, ExcInternalError());
1317  }
1318 
1319 
1320 
1321 
1322  template <int dim, int spacedim>
1323  void
1325  create_triangulation (const std::vector<Point<spacedim> > &vertices,
1326  const std::vector<CellData<dim> > &cells,
1327  const SubCellData &subcelldata)
1328  {
1329  try
1330  {
1332  create_triangulation (vertices, cells, subcelldata);
1333  }
1334  catch (const typename ::Triangulation<dim,spacedim>::DistortedCellList &)
1335  {
1336  // the underlying triangulation should not be checking for distorted
1337  // cells
1338  Assert (false, ExcInternalError());
1339  }
1340 
1341  // note that now we have some content in the p4est objects and call the
1342  // functions that do the actual work (which are dimension dependent, so
1343  // separate)
1344  triangulation_has_content = true;
1345 
1346  setup_coarse_cell_to_p4est_tree_permutation ();
1347 
1348  copy_new_triangulation_to_p4est (::internal::int2type<dim>());
1349 
1350  try
1351  {
1352  copy_local_forest_to_triangulation ();
1353  }
1354  catch (const typename Triangulation<dim>::DistortedCellList &)
1355  {
1356  // the underlying triangulation should not be checking for distorted
1357  // cells
1358  Assert (false, ExcInternalError());
1359  }
1360 
1361  this->update_number_cache ();
1362  this->update_periodic_face_map();
1363  }
1364 
1365 
1366  // This anonymous namespace contains utility for
1367  // the function Triangulation::communicate_locally_moved_vertices
1368  namespace CommunicateLocallyMovedVertices
1369  {
1370  namespace
1371  {
1377  template <int dim, int spacedim>
1378  struct CellInfo
1379  {
1380  // store all the tree_indices we send/receive consecutively (n_cells entries)
1381  std::vector<unsigned int> tree_index;
1382  // store all the quadrants we send/receive consecutively (n_cells entries)
1383  std::vector<typename ::internal::p4est::types<dim>::quadrant> quadrants;
1384  // store for each cell the number of vertices we send/receive
1385  // and then the vertex indices (for each cell: n_vertices+1 entries)
1386  std::vector<unsigned int> vertex_indices;
1387  // store for each cell the vertices we send/receive
1388  // (for each cell n_vertices entries)
1389  std::vector<::Point<spacedim> > vertices;
1390  // for receiving and unpacking data we need to store pointers to the
1391  // first vertex and vertex_index on each cell additionally
1392  // both vectors have as many entries as there are cells
1393  std::vector<unsigned int * > first_vertex_indices;
1394  std::vector<::Point<spacedim>* > first_vertices;
1395 
1396  unsigned int bytes_for_buffer () const
1397  {
1398  return (sizeof(unsigned int) +
1399  tree_index.size() * sizeof(unsigned int) +
1400  quadrants.size() * sizeof(typename ::internal::p4est
1401  ::types<dim>::quadrant) +
1402  vertices.size() * sizeof(::Point<spacedim>)) +
1403  vertex_indices.size() * sizeof(unsigned int);
1404  }
1405 
1406  void pack_data (std::vector<char> &buffer) const
1407  {
1408  buffer.resize(bytes_for_buffer());
1409 
1410  char *ptr = &buffer[0];
1411 
1412  const unsigned int num_cells = tree_index.size();
1413  std::memcpy(ptr, &num_cells, sizeof(unsigned int));
1414  ptr += sizeof(unsigned int);
1415 
1416  std::memcpy(ptr,
1417  &tree_index[0],
1418  num_cells*sizeof(unsigned int));
1419  ptr += num_cells*sizeof(unsigned int);
1420 
1421  std::memcpy(ptr,
1422  &quadrants[0],
1423  num_cells * sizeof(typename ::internal::p4est::
1424  types<dim>::quadrant));
1425  ptr += num_cells*sizeof(typename ::internal::p4est::types<dim>::
1426  quadrant);
1427 
1428  std::memcpy(ptr,
1429  &vertex_indices[0],
1430  vertex_indices.size() * sizeof(unsigned int));
1431  ptr += vertex_indices.size() * sizeof(unsigned int);
1432 
1433  std::memcpy(ptr,
1434  &vertices[0],
1435  vertices.size() * sizeof(::Point<spacedim>));
1436  ptr += vertices.size() * sizeof(::Point<spacedim>);
1437 
1438  Assert (ptr == &buffer[0]+buffer.size(),
1439  ExcInternalError());
1440 
1441  }
1442 
1443  void unpack_data (const std::vector<char> &buffer)
1444  {
1445  const char *ptr = &buffer[0];
1446  unsigned int cells;
1447  memcpy(&cells, ptr, sizeof(unsigned int));
1448  ptr += sizeof(unsigned int);
1449 
1450  tree_index.resize(cells);
1451  memcpy(&tree_index[0],ptr,sizeof(unsigned int)*cells);
1452  ptr += sizeof(unsigned int)*cells;
1453 
1454  quadrants.resize(cells);
1455  memcpy(&quadrants[0],ptr,
1456  sizeof(typename ::internal::p4est::types<dim>::quadrant)*cells);
1457  ptr += sizeof(typename ::internal::p4est::types<dim>::quadrant)*cells;
1458 
1459  vertex_indices.clear();
1460  first_vertex_indices.resize(cells);
1461  std::vector<unsigned int> n_vertices_on_cell(cells);
1462  std::vector<unsigned int> first_indices (cells);
1463  for (unsigned int c=0; c<cells; ++c)
1464  {
1465  // The first 'vertex index' is the number of vertices.
1466  // Additionally, we need to store the pointer to this
1467  // vertex index with respect to the std::vector
1468  const unsigned int *const vertex_index
1469  = reinterpret_cast<const unsigned int *const>(ptr);
1470  first_indices[c] = vertex_indices.size();
1471  vertex_indices.push_back(*vertex_index);
1472  n_vertices_on_cell[c] = *vertex_index;
1473  ptr += sizeof(unsigned int);
1474  // Now copy all the 'real' vertex_indices
1475  vertex_indices.resize(vertex_indices.size() + n_vertices_on_cell[c]);
1476  memcpy(&vertex_indices[vertex_indices.size() - n_vertices_on_cell[c]],
1477  ptr, n_vertices_on_cell[c]*sizeof(unsigned int));
1478  ptr += n_vertices_on_cell[c]*sizeof(unsigned int);
1479  }
1480  for (unsigned int c=0; c<cells; ++c)
1481  first_vertex_indices[c] = &vertex_indices[first_indices[c]];
1482 
1483  vertices.clear();
1484  first_vertices.resize(cells);
1485  for (unsigned int c=0; c<cells; ++c)
1486  {
1487  // We need to store a pointer to the first vertex.
1488  const ::Point<spacedim> *const vertex
1489  = reinterpret_cast<const ::Point<spacedim> * const>(ptr);
1490  first_indices[c] = vertices.size();
1491  vertices.push_back(*vertex);
1492  ptr += sizeof(::Point<spacedim>);
1493  vertices.resize(vertices.size() + n_vertices_on_cell[c]-1);
1494  memcpy(&vertices[vertices.size() - (n_vertices_on_cell[c]-1)],
1495  ptr, (n_vertices_on_cell[c]-1)*sizeof(::Point<spacedim>));
1496  ptr += (n_vertices_on_cell[c]-1)*sizeof(::Point<spacedim>);
1497  }
1498  for (unsigned int c=0; c<cells; ++c)
1499  first_vertices[c] = &vertices[first_indices[c]];
1500 
1501  Assert (ptr == &buffer[0]+buffer.size(),
1502  ExcInternalError());
1503  }
1504  };
1505 
1506 
1507 
1508  // This function is responsible for gathering the information
1509  // we want to send to each process.
1510  // For each dealii cell on the coarsest level the corresponding
1511  // p4est_cell has to be provided when calling this function.
1512  // By recursing through all children we consider each active cell.
1513  // vertices_with_ghost_neighbors tells us which vertices
1514  // are in the ghost layer and for which processes they might
1515  // be interesting.
1516  // Whether a vertex has actually been updated locally is
1517  // stored in vertex_locally_moved. Only those are considered
1518  // for sending.
1519  // The gathered information is saved into needs_to_get_cell.
1520  template <int dim, int spacedim>
1521  void
1522  fill_vertices_recursively (const typename parallel::distributed::Triangulation<dim,spacedim> &tria,
1523  const unsigned int tree_index,
1524  const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
1525  const typename ::internal::p4est::types<dim>::quadrant &p4est_cell,
1526  const std::map<unsigned int, std::set<::types::subdomain_id> > &vertices_with_ghost_neighbors,
1527  const std::vector<bool> &vertex_locally_moved,
1528  std::map<::types::subdomain_id, CellInfo<dim, spacedim> > &needs_to_get_cell)
1529  {
1530  // see if we have to
1531  // recurse...
1532  if (dealii_cell->has_children())
1533  {
1534  typename ::internal::p4est::types<dim>::quadrant
1536  ::internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
1537 
1538 
1539  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1540  fill_vertices_recursively<dim,spacedim>(tria,
1541  tree_index,
1542  dealii_cell->child(c),
1543  p4est_child[c],
1544  vertices_with_ghost_neighbors,
1545  vertex_locally_moved,
1546  needs_to_get_cell);
1547  return;
1548  }
1549 
1550  // We're at a leaf cell. If the cell is locally owned, we may
1551  // have to send its vertices to other processors if any of
1552  // its vertices is adjacent to a ghost cell and has been moved
1553  //
1554  // If one of the vertices of the cell is interesting,
1555  // send all moved vertices of the cell to all processors
1556  // adjacent to all cells adjacent to this vertex
1557  if (dealii_cell->is_locally_owned())
1558  {
1559  std::set<::types::subdomain_id> send_to;
1560  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
1561  {
1562  const std::map<unsigned int, std::set<::types::subdomain_id> >::const_iterator
1563  neighbor_subdomains_of_vertex
1564  = vertices_with_ghost_neighbors.find (dealii_cell->vertex_index(v));
1565 
1566  if (neighbor_subdomains_of_vertex
1567  != vertices_with_ghost_neighbors.end())
1568  {
1569  Assert(neighbor_subdomains_of_vertex->second.size()!=0,
1570  ExcInternalError());
1571  send_to.insert(neighbor_subdomains_of_vertex->second.begin(),
1572  neighbor_subdomains_of_vertex->second.end());
1573  }
1574  }
1575 
1576  if (send_to.size() > 0)
1577  {
1578  std::vector<unsigned int> vertex_indices;
1579  std::vector<::Point<spacedim> > local_vertices;
1580  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
1581  if (vertex_locally_moved[dealii_cell->vertex_index(v)])
1582  {
1583  vertex_indices.push_back(v);
1584  local_vertices.push_back(dealii_cell->vertex(v));
1585  }
1586 
1587  if (vertex_indices.size()>0)
1588  for (std::set<::types::subdomain_id>::iterator it=send_to.begin();
1589  it!=send_to.end(); ++it)
1590  {
1591  const ::types::subdomain_id subdomain = *it;
1592 
1593  // get an iterator to what needs to be sent to that
1594  // subdomain (if already exists), or create such an object
1595  const typename std::map<::types::subdomain_id, CellInfo<dim, spacedim> >::iterator
1596  p
1597  = needs_to_get_cell.insert (std::make_pair(subdomain,
1598  CellInfo<dim,spacedim>()))
1599  .first;
1600 
1601  p->second.tree_index.push_back(tree_index);
1602  p->second.quadrants.push_back(p4est_cell);
1603 
1604  p->second.vertex_indices.push_back(vertex_indices.size());
1605  p->second.vertex_indices.insert(p->second.vertex_indices.end(),
1606  vertex_indices.begin(),
1607  vertex_indices.end());
1608 
1609  p->second.vertices.insert(p->second.vertices.end(),
1610  local_vertices.begin(),
1611  local_vertices.end());
1612  }
1613  }
1614  }
1615  }
1616 
1617 
1618 
1619  // After the cell data has been received this function is responsible
1620  // for moving the vertices in the corresponding ghost layer locally.
1621  // As in fill_vertices_recursively for each dealii cell on the
1622  // coarsest level the corresponding p4est_cell has to be provided
1623  // when calling this function. By recursing through through all
1624  // children we consider each active cell.
1625  // Additionally, we need to give a pointer to the first vertex indices
1626  // and vertices. Since the first information saved in vertex_indices
1627  // is the number of vertices this all the information we need.
1628  template <int dim, int spacedim>
1629  void
1630  set_vertices_recursively (
1632  const typename ::internal::p4est::types<dim>::quadrant &p4est_cell,
1633  const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
1634  const typename ::internal::p4est::types<dim>::quadrant &quadrant,
1635  const ::Point<spacedim> *const vertices,
1636  const unsigned int *const vertex_indices)
1637  {
1638  if (::internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
1639  {
1640  Assert(!dealii_cell->is_artificial(), ExcInternalError());
1641  Assert(!dealii_cell->has_children(), ExcInternalError());
1642  Assert(!dealii_cell->is_locally_owned(), ExcInternalError());
1643 
1644  const unsigned int n_vertices = vertex_indices[0];
1645 
1646  // update dof indices of cell
1647  for (unsigned int i=0; i<n_vertices; ++i)
1648  dealii_cell->vertex(vertex_indices[i+1]) = vertices[i];
1649 
1650  return;
1651  }
1652 
1653  if (! dealii_cell->has_children())
1654  return;
1655 
1656  if (! ::internal::p4est::quadrant_is_ancestor<dim> (p4est_cell, quadrant))
1657  return;
1658 
1659  typename ::internal::p4est::types<dim>::quadrant
1661  ::internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
1662 
1663  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1664  set_vertices_recursively<dim,spacedim> (tria, p4est_child[c],
1665  dealii_cell->child(c),
1666  quadrant, vertices,
1667  vertex_indices);
1668  }
1669  }
1670  }
1671 
1672 
1673 
1674  template <int dim, int spacedim>
1675  void
1677  {
1678  triangulation_has_content = false;
1679 
1680  if (parallel_ghost != 0)
1681  {
1683  parallel_ghost = 0;
1684  }
1685 
1686  if (parallel_forest != 0)
1687  {
1689  parallel_forest = 0;
1690  }
1691 
1692  if (connectivity != 0)
1693  {
1695  connectivity = 0;
1696  }
1697 
1698  coarse_cell_to_p4est_tree_permutation.resize (0);
1699  p4est_tree_to_coarse_cell_permutation.resize (0);
1700 
1702 
1703  this->update_number_cache ();
1704  }
1705 
1706  template <int dim, int spacedim>
1707  bool
1709  {
1710  if (this->n_global_levels()<=1)
1711  return false; // can not have hanging nodes without refined cells
1712 
1713  // if there are any active cells with level less than n_global_levels()-1, then
1714  // there is obviously also one with level n_global_levels()-1, and
1715  // consequently there must be a hanging node somewhere.
1716  //
1717  // The problem is that we cannot just ask for the first active cell, but
1718  // instead need to filter over locally owned cells.
1719  bool have_coarser_cell = false;
1720  for (typename Triangulation<dim, spacedim>::active_cell_iterator cell = this->begin_active(this->n_global_levels()-2);
1721  cell != this->end(this->n_global_levels()-2);
1722  ++cell)
1723  if (cell->is_locally_owned())
1724  {
1725  have_coarser_cell = true;
1726  break;
1727  }
1728 
1729  // return true if at least one process has a coarser cell
1730  return 0<Utilities::MPI::max(have_coarser_cell?1:0, this->mpi_communicator);
1731  }
1732 
1733 
1734 
1735  template <int dim, int spacedim>
1736  void
1738  {
1739  DynamicSparsityPattern cell_connectivity;
1740  GridTools::get_vertex_connectivity_of_cells (*this, cell_connectivity);
1741  coarse_cell_to_p4est_tree_permutation.resize (this->n_cells(0));
1743  reorder_hierarchical (cell_connectivity,
1744  coarse_cell_to_p4est_tree_permutation);
1745 
1746  p4est_tree_to_coarse_cell_permutation
1747  = Utilities::invert_permutation (coarse_cell_to_p4est_tree_permutation);
1748  }
1749 
1750 
1751 
1752  template <int dim, int spacedim>
1753  void
1754  Triangulation<dim,spacedim>::write_mesh_vtk (const char *file_basename) const
1755  {
1756  Assert (parallel_forest != 0,
1757  ExcMessage ("Can't produce output when no forest is created yet."));
1759  vtk_write_file (parallel_forest, 0, file_basename);
1760  }
1761 
1762 
1763  template <int dim, int spacedim>
1764  void
1766  save(const char *filename) const
1767  {
1768  Assert(n_attached_deserialize==0,
1769  ExcMessage ("not all SolutionTransfer's got deserialized after the last load()"));
1770  int real_data_size = 0;
1771  if (attached_data_size>0)
1772  real_data_size = attached_data_size+sizeof(CellStatus);
1773 
1774  Assert(this->n_cells()>0, ExcMessage("Can not save() an empty Triangulation."));
1775 
1776  if (this->my_subdomain==0)
1777  {
1778  std::string fname=std::string(filename)+".info";
1779  std::ofstream f(fname.c_str());
1780  f << "version nproc attached_bytes n_attached_objs n_coarse_cells" << std::endl
1781  << 2 << " "
1782  << Utilities::MPI::n_mpi_processes (this->mpi_communicator) << " "
1783  << real_data_size << " "
1784  << attached_data_pack_callbacks.size() << " "
1785  << this->n_cells(0)
1786  << std::endl;
1787  }
1788 
1789  if (attached_data_size>0)
1790  {
1792  ->attach_mesh_data();
1793  }
1794 
1795  ::internal::p4est::functions<dim>::save(filename, parallel_forest, attached_data_size>0);
1796 
1799 
1800  tria->n_attached_datas = 0;
1801  tria->attached_data_size = 0;
1802  tria->attached_data_pack_callbacks.clear();
1803 
1804  // and release the data
1805  void *userptr = parallel_forest->user_pointer;
1806  ::internal::p4est::functions<dim>::reset_data (parallel_forest, 0, NULL, NULL);
1807  parallel_forest->user_pointer = userptr;
1808  }
1809 
1810 
1811  template <int dim, int spacedim>
1812  void
1814  load (const char *filename,
1815  const bool autopartition)
1816  {
1817  Assert(this->n_cells()>0, ExcMessage("load() only works if the Triangulation already contains a coarse mesh!"));
1818  Assert(this->n_levels()==1, ExcMessage("Triangulation may only contain coarse cells when calling load()."));
1819 
1820 
1821  if (parallel_ghost != 0)
1822  {
1824  parallel_ghost = 0;
1825  }
1827  parallel_forest = 0;
1829  connectivity = 0;
1830 
1831  unsigned int version, numcpus, attached_size, attached_count, n_coarse_cells;
1832  {
1833  std::string fname=std::string(filename)+".info";
1834  std::ifstream f(fname.c_str());
1835  std::string firstline;
1836  getline(f, firstline); //skip first line
1837  f >> version >> numcpus >> attached_size >> attached_count >> n_coarse_cells;
1838  }
1839 
1840  Assert(version == 2, ExcMessage("Incompatible version found in .info file."));
1841  Assert(this->n_cells(0) == n_coarse_cells, ExcMessage("Number of coarse cells differ!"));
1842 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
1843 #else
1844  AssertThrow(numcpus <= Utilities::MPI::n_mpi_processes (this->mpi_communicator),
1845  ExcMessage("parallel::distributed::Triangulation::load() only supports loading "
1846  "saved data with a greater or equal number of processes than were used to "
1847  "save() when using p4est 0.3.4.2."));
1848 #endif
1849 
1850  attached_data_size = 0;
1851  n_attached_datas = 0;
1852  n_attached_deserialize = attached_count;
1853 
1854 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3)
1856  filename, this->mpi_communicator,
1857  attached_size, attached_size>0,
1858  autopartition, 0,
1859  this,
1860  &connectivity);
1861 #else
1862  (void)autopartition;
1863  parallel_forest = ::internal::p4est::functions<dim>::load (
1864  filename, this->mpi_communicator,
1865  attached_size, attached_size>0,
1866  this,
1867  &connectivity);
1868 #endif
1869  if (numcpus != Utilities::MPI::n_mpi_processes (this->mpi_communicator))
1870  // We are changing the number of CPUs so we need to repartition.
1871  // Note that p4est actually distributes the cells between the changed
1872  // number of CPUs and so everything works without this call, but
1873  // this command changes the distribution for some reason, so we
1874  // will leave it in here.
1875  repartition();
1876 
1877  try
1878  {
1879  copy_local_forest_to_triangulation ();
1880  }
1881  catch (const typename Triangulation<dim>::DistortedCellList &)
1882  {
1883  // the underlying
1884  // triangulation should not
1885  // be checking for
1886  // distorted cells
1887  Assert (false, ExcInternalError());
1888  }
1889 
1890  this->update_number_cache ();
1891  this->update_periodic_face_map();
1892  }
1893 
1894 
1895 
1896  template <int dim, int spacedim>
1897  unsigned int
1899  {
1900  Assert (parallel_forest != 0,
1901  ExcMessage ("Can't produce a check sum when no forest is created yet."));
1902  return ::internal::p4est::functions<dim>::checksum (parallel_forest);
1903  }
1904 
1905  template <int dim, int spacedim>
1906  void
1909  {
1911 
1912  if (this->n_levels() == 0)
1913  return;
1914 
1915  if (settings & construct_multigrid_hierarchy)
1916  {
1917  // find level ghost owners
1919  cell = this->begin();
1920  cell != this->end();
1921  ++cell)
1922  if (cell->level_subdomain_id() != numbers::artificial_subdomain_id
1923  && cell->level_subdomain_id() != this->locally_owned_subdomain())
1924  this->number_cache.level_ghost_owners.insert(cell->level_subdomain_id());
1925 
1926 #ifdef DEBUG
1927  // Check that level_ghost_owners is symmetric by sending a message
1928  // to everyone
1929  {
1930  int ierr = MPI_Barrier(this->mpi_communicator);
1931  AssertThrowMPI(ierr);
1932 
1933  // important: preallocate to avoid (re)allocation:
1934  std::vector<MPI_Request> requests (this->number_cache.level_ghost_owners.size());
1935  int dummy = 0;
1936  unsigned int req_counter = 0;
1937 
1938  for (std::set<types::subdomain_id>::iterator it = this->number_cache.level_ghost_owners.begin();
1939  it != this->number_cache.level_ghost_owners.end();
1940  ++it, ++req_counter)
1941  {
1942  Assert (typeid(types::subdomain_id)
1943  == typeid(unsigned int),
1944  ExcNotImplemented());
1945  ierr = MPI_Isend(&dummy, 1, MPI_UNSIGNED,
1946  *it, 9001, this->mpi_communicator,
1947  &requests[req_counter]);
1948  AssertThrowMPI(ierr);
1949  }
1950 
1951  for (std::set<types::subdomain_id>::iterator it = this->number_cache.level_ghost_owners.begin();
1952  it != this->number_cache.level_ghost_owners.end();
1953  ++it)
1954  {
1955  Assert (typeid(types::subdomain_id)
1956  == typeid(unsigned int),
1957  ExcNotImplemented());
1958  unsigned int dummy;
1959  ierr = MPI_Recv(&dummy, 1, MPI_UNSIGNED,
1960  *it, 9001, this->mpi_communicator,
1961  MPI_STATUS_IGNORE);
1962  AssertThrowMPI(ierr);
1963  }
1964 
1965  if (requests.size() > 0)
1966  {
1967  ierr = MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
1968  AssertThrowMPI(ierr);
1969  }
1970 
1971  ierr = MPI_Barrier(this->mpi_communicator);
1972  AssertThrowMPI(ierr);
1973  }
1974 #endif
1975 
1976  Assert(this->number_cache.level_ghost_owners.size() < Utilities::MPI::n_mpi_processes(this->mpi_communicator),
1977  ExcInternalError());
1978  }
1979  }
1980 
1981 
1982  template <int dim, int spacedim>
1983  typename ::internal::p4est::types<dim>::tree *
1985  init_tree(const int dealii_coarse_cell_index) const
1986  {
1987  const unsigned int tree_index
1988  = coarse_cell_to_p4est_tree_permutation[dealii_coarse_cell_index];
1989  typename ::internal::p4est::types<dim>::tree *tree
1990  = static_cast<typename ::internal::p4est::types<dim>::tree *>
1991  (sc_array_index (parallel_forest->trees,
1992  tree_index));
1993 
1994  return tree;
1995  }
1996 
1997 
1998 
1999  template <>
2000  void
2002  {
2003  const unsigned int dim = 2, spacedim = 2;
2004  Assert (this->n_cells(0) > 0, ExcInternalError());
2005  Assert (this->n_levels() == 1, ExcInternalError());
2006 
2007  // data structures that counts how many cells touch each vertex
2008  // (vertex_touch_count), and which cells touch a given vertex (together
2009  // with the local numbering of that vertex within the cells that touch
2010  // it)
2011  std::vector<unsigned int> vertex_touch_count;
2012  std::vector<
2013  std::list<
2014  std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
2015  unsigned int> > >
2016  vertex_to_cell;
2017  get_vertex_to_cell_mappings (*this,
2018  vertex_touch_count,
2019  vertex_to_cell);
2020  const ::internal::p4est::types<2>::locidx
2021  num_vtt = std::accumulate (vertex_touch_count.begin(),
2022  vertex_touch_count.end(),
2023  0);
2024 
2025  // now create a connectivity object with the right sizes for all
2026  // arrays. set vertex information only in debug mode (saves a few bytes
2027  // in optimized mode)
2028  const bool set_vertex_info
2029 #ifdef DEBUG
2030  = true
2031 #else
2032  = false
2033 #endif
2034  ;
2035 
2036  connectivity
2038  connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
2039  this->n_cells(0),
2040  this->n_vertices(),
2041  num_vtt);
2042 
2043  set_vertex_and_cell_info (*this,
2044  vertex_touch_count,
2045  vertex_to_cell,
2046  coarse_cell_to_p4est_tree_permutation,
2047  set_vertex_info,
2048  connectivity);
2049 
2050  Assert (p4est_connectivity_is_valid (connectivity) == 1,
2051  ExcInternalError());
2052 
2053  // now create a forest out of the connectivity data structure
2054  parallel_forest
2056  new_forest (this->mpi_communicator,
2057  connectivity,
2058  /* minimum initial number of quadrants per tree */ 0,
2059  /* minimum level of upfront refinement */ 0,
2060  /* use uniform upfront refinement */ 1,
2061  /* user_data_size = */ 0,
2062  /* user_data_constructor = */ NULL,
2063  /* user_pointer */ this);
2064  }
2065 
2066 
2067 
2068  // TODO: This is a verbatim copy of the 2,2 case. However, we can't just
2069  // specialize the dim template argument, but let spacedim open
2070  template <>
2071  void
2073  {
2074  const unsigned int dim = 2, spacedim = 3;
2075  Assert (this->n_cells(0) > 0, ExcInternalError());
2076  Assert (this->n_levels() == 1, ExcInternalError());
2077 
2078  // data structures that counts how many cells touch each vertex
2079  // (vertex_touch_count), and which cells touch a given vertex (together
2080  // with the local numbering of that vertex within the cells that touch
2081  // it)
2082  std::vector<unsigned int> vertex_touch_count;
2083  std::vector<
2084  std::list<
2085  std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
2086  unsigned int> > >
2087  vertex_to_cell;
2088  get_vertex_to_cell_mappings (*this,
2089  vertex_touch_count,
2090  vertex_to_cell);
2091  const ::internal::p4est::types<2>::locidx
2092  num_vtt = std::accumulate (vertex_touch_count.begin(),
2093  vertex_touch_count.end(),
2094  0);
2095 
2096  // now create a connectivity object with the right sizes for all
2097  // arrays. set vertex information only in debug mode (saves a few bytes
2098  // in optimized mode)
2099  const bool set_vertex_info
2100 #ifdef DEBUG
2101  = true
2102 #else
2103  = false
2104 #endif
2105  ;
2106 
2107  connectivity
2109  connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
2110  this->n_cells(0),
2111  this->n_vertices(),
2112  num_vtt);
2113 
2114  set_vertex_and_cell_info (*this,
2115  vertex_touch_count,
2116  vertex_to_cell,
2117  coarse_cell_to_p4est_tree_permutation,
2118  set_vertex_info,
2119  connectivity);
2120 
2121  Assert (p4est_connectivity_is_valid (connectivity) == 1,
2122  ExcInternalError());
2123 
2124  // now create a forest out of the connectivity data structure
2125  parallel_forest
2127  new_forest (this->mpi_communicator,
2128  connectivity,
2129  /* minimum initial number of quadrants per tree */ 0,
2130  /* minimum level of upfront refinement */ 0,
2131  /* use uniform upfront refinement */ 1,
2132  /* user_data_size = */ 0,
2133  /* user_data_constructor = */ NULL,
2134  /* user_pointer */ this);
2135  }
2136 
2137 
2138 
2139  template <>
2140  void
2142  {
2143  const int dim = 3, spacedim = 3;
2144  Assert (this->n_cells(0) > 0, ExcInternalError());
2145  Assert (this->n_levels() == 1, ExcInternalError());
2146 
2147  // data structures that counts how many cells touch each vertex
2148  // (vertex_touch_count), and which cells touch a given vertex (together
2149  // with the local numbering of that vertex within the cells that touch
2150  // it)
2151  std::vector<unsigned int> vertex_touch_count;
2152  std::vector<
2153  std::list<
2154  std::pair<Triangulation<3>::active_cell_iterator,
2155  unsigned int> > >
2156  vertex_to_cell;
2157  get_vertex_to_cell_mappings (*this,
2158  vertex_touch_count,
2159  vertex_to_cell);
2160  const ::internal::p4est::types<2>::locidx
2161  num_vtt = std::accumulate (vertex_touch_count.begin(),
2162  vertex_touch_count.end(),
2163  0);
2164 
2165  std::vector<unsigned int> edge_touch_count;
2166  std::vector<
2167  std::list<
2168  std::pair<Triangulation<3>::active_cell_iterator,
2169  unsigned int> > >
2170  edge_to_cell;
2171  get_edge_to_cell_mappings (*this,
2172  edge_touch_count,
2173  edge_to_cell);
2174  const ::internal::p4est::types<2>::locidx
2175  num_ett = std::accumulate (edge_touch_count.begin(),
2176  edge_touch_count.end(),
2177  0);
2178 
2179  // now create a connectivity object with the right sizes for all arrays
2180  const bool set_vertex_info
2181 #ifdef DEBUG
2182  = true
2183 #else
2184  = false
2185 #endif
2186  ;
2187 
2188  connectivity
2190  connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
2191  this->n_cells(0),
2192  this->n_active_lines(),
2193  num_ett,
2194  this->n_vertices(),
2195  num_vtt);
2196 
2197  set_vertex_and_cell_info (*this,
2198  vertex_touch_count,
2199  vertex_to_cell,
2200  coarse_cell_to_p4est_tree_permutation,
2201  set_vertex_info,
2202  connectivity);
2203 
2204  // next to tree-to-edge
2205  // data. note that in p4est lines
2206  // are ordered as follows
2207  // *---3---* *---3---*
2208  // /| | / /|
2209  // 6 | 11 6 7 11
2210  // / 10 | / / |
2211  // * | | *---2---* |
2212  // | *---1---* | | *
2213  // | / / | 9 /
2214  // 8 4 5 8 | 5
2215  // |/ / | |/
2216  // *---0---* *---0---*
2217  // whereas in deal.II they are like this:
2218  // *---7---* *---7---*
2219  // /| | / /|
2220  // 4 | 11 4 5 11
2221  // / 10 | / / |
2222  // * | | *---6---* |
2223  // | *---3---* | | *
2224  // | / / | 9 /
2225  // 8 0 1 8 | 1
2226  // |/ / | |/
2227  // *---2---* *---2---*
2228 
2229  const unsigned int deal_to_p4est_line_index[12]
2230  = { 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11 } ;
2231 
2233  cell = this->begin_active();
2234  cell != this->end(); ++cell)
2235  {
2236  const unsigned int
2237  index = coarse_cell_to_p4est_tree_permutation[cell->index()];
2238  for (unsigned int e=0; e<GeometryInfo<3>::lines_per_cell; ++e)
2239  connectivity->tree_to_edge[index*GeometryInfo<3>::lines_per_cell+
2240  deal_to_p4est_line_index[e]]
2241  = cell->line(e)->index();
2242  }
2243 
2244  // now also set edge-to-tree
2245  // information
2246  connectivity->ett_offset[0] = 0;
2247  std::partial_sum (edge_touch_count.begin(),
2248  edge_touch_count.end(),
2249  &connectivity->ett_offset[1]);
2250 
2251  Assert (connectivity->ett_offset[this->n_active_lines()] ==
2252  num_ett,
2253  ExcInternalError());
2254 
2255  for (unsigned int v=0; v<this->n_active_lines(); ++v)
2256  {
2257  Assert (edge_to_cell[v].size() == edge_touch_count[v],
2258  ExcInternalError());
2259 
2260  std::list<std::pair
2262  unsigned int> >::const_iterator
2263  p = edge_to_cell[v].begin();
2264  for (unsigned int c=0; c<edge_touch_count[v]; ++c, ++p)
2265  {
2266  connectivity->edge_to_tree[connectivity->ett_offset[v]+c]
2267  = coarse_cell_to_p4est_tree_permutation[p->first->index()];
2268  connectivity->edge_to_edge[connectivity->ett_offset[v]+c]
2269  = deal_to_p4est_line_index[p->second];
2270  }
2271  }
2272 
2273  Assert (p8est_connectivity_is_valid (connectivity) == 1,
2274  ExcInternalError());
2275 
2276  // now create a forest out of the connectivity data structure
2277  parallel_forest
2279  new_forest (this->mpi_communicator,
2280  connectivity,
2281  /* minimum initial number of quadrants per tree */ 0,
2282  /* minimum level of upfront refinement */ 0,
2283  /* use uniform upfront refinement */ 1,
2284  /* user_data_size = */ 0,
2285  /* user_data_constructor = */ NULL,
2286  /* user_pointer */ this);
2287  }
2288 
2289 
2290 
2291  namespace
2292  {
2293  // ensures the 2:1 mesh balance for periodic boundary conditions in the
2294  // artificial cell layer (the active cells are taken care of by p4est)
2295  template <int dim, int spacedim>
2296  bool enforce_mesh_balance_over_periodic_boundaries
2298  {
2299  if (tria.get_periodic_face_map().size()==0)
2300  return false;
2301 
2302  std::vector<bool> flags_before[2];
2303  tria.save_coarsen_flags (flags_before[0]);
2304  tria.save_refine_flags (flags_before[1]);
2305 
2306  std::vector<unsigned int> topological_vertex_numbering(tria.n_vertices());
2307  for (unsigned int i=0; i<topological_vertex_numbering.size(); ++i)
2308  topological_vertex_numbering[i] = i;
2309  // combine vertices that have different locations (and thus, different
2310  // vertex_index) but represent the same topological entity over periodic
2311  // boundaries. The vector topological_vertex_numbering contains a linear
2312  // map from 0 to n_vertices at input and at output relates periodic
2313  // vertices with only one vertex index. The output is used to always
2314  // identify the same vertex according to the periodicity, e.g. when
2315  // finding the maximum cell level around a vertex.
2316  //
2317  // Example: On a 3D cell with vertices numbered from 0 to 7 and periodic
2318  // boundary conditions in x direction, the vector
2319  // topological_vertex_numbering will contain the numbers
2320  // {0,0,2,2,4,4,6,6} (because the vertex pairs {0,1}, {2,3}, {4,5},
2321  // {6,7} belong together, respectively). If periodicity is set in x and
2322  // z direction, the output is {0,0,2,2,0,0,2,2}, and if periodicity is
2323  // in all directions, the output is simply {0,0,0,0,0,0,0,0}.
2324  typedef typename Triangulation<dim, spacedim>::cell_iterator cell_iterator;
2325  typename std::map<std::pair<cell_iterator, unsigned int>,
2326  std::pair<std::pair<cell_iterator,unsigned int>, std::bitset<3> > >::const_iterator it;
2327  for (it = tria.get_periodic_face_map().begin(); it!= tria.get_periodic_face_map().end(); ++it)
2328  {
2329  const cell_iterator &cell_1 = it->first.first;
2330  const unsigned int face_no_1 = it->first.second;
2331  const cell_iterator &cell_2 = it->second.first.first;
2332  const unsigned int face_no_2 = it->second.first.second;
2333  const std::bitset<3> face_orientation = it->second.second;
2334 
2335  if (cell_1->level() == cell_2->level())
2336  {
2337  for (unsigned int v=0; v<GeometryInfo<dim-1>::vertices_per_cell; ++v)
2338  {
2339  // take possible non-standard orientation of face on cell[0] into
2340  // account
2341  const unsigned int vface0 =
2343  face_orientation[1],
2344  face_orientation[2]);
2345  const unsigned int vi0 = topological_vertex_numbering[cell_1->face(face_no_1)->vertex_index(vface0)];
2346  const unsigned int vi1 = topological_vertex_numbering[cell_2->face(face_no_2)->vertex_index(v)];
2347  const unsigned int min_index = std::min(vi0, vi1);
2348  topological_vertex_numbering[cell_1->face(face_no_1)->vertex_index(vface0)]
2349  = topological_vertex_numbering[cell_2->face(face_no_2)->vertex_index(v)]
2350  = min_index;
2351  }
2352  }
2353  }
2354 
2355  // There must not be any chains!
2356  for (unsigned int i=0; i<topological_vertex_numbering.size(); ++i)
2357  {
2358  const unsigned int j = topological_vertex_numbering[i];
2359  if (j != i)
2360  Assert(topological_vertex_numbering[j] == j,
2361  ExcInternalError());
2362  }
2363 
2364 
2365  // this code is replicated from grid/tria.cc but using an indirection
2366  // for periodic boundary conditions
2367  bool continue_iterating = true;
2368  std::vector<int> vertex_level(tria.n_vertices());
2369  while (continue_iterating)
2370  {
2371  // store highest level one of the cells adjacent to a vertex
2372  // belongs to
2373  std::fill (vertex_level.begin(), vertex_level.end(), 0);
2375  cell = tria.begin_active(), endc = tria.end();
2376  for (; cell!=endc; ++cell)
2377  {
2378  if (cell->refine_flag_set())
2379  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
2380  ++vertex)
2381  vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]]
2382  = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]],
2383  cell->level()+1);
2384  else if (!cell->coarsen_flag_set())
2385  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
2386  ++vertex)
2387  vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]]
2388  = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]],
2389  cell->level());
2390  else
2391  {
2392  // if coarsen flag is set then tentatively assume
2393  // that the cell will be coarsened. this isn't
2394  // always true (the coarsen flag could be removed
2395  // again) and so we may make an error here. we try
2396  // to correct this by iterating over the entire
2397  // process until we are converged
2398  Assert (cell->coarsen_flag_set(), ExcInternalError());
2399  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
2400  ++vertex)
2401  vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]]
2402  = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]],
2403  cell->level()-1);
2404  }
2405  }
2406 
2407  continue_iterating = false;
2408 
2409  // loop over all cells in reverse order. do so because we
2410  // can then update the vertex levels on the adjacent
2411  // vertices and maybe already flag additional cells in this
2412  // loop
2413  //
2414  // note that not only may we have to add additional
2415  // refinement flags, but we will also have to remove
2416  // coarsening flags on cells adjacent to vertices that will
2417  // see refinement
2418  for (cell=tria.last_active(); cell != endc; --cell)
2419  if (cell->refine_flag_set() == false)
2420  {
2421  for (unsigned int vertex=0;
2422  vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
2423  if (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]] >=
2424  cell->level()+1)
2425  {
2426  // remove coarsen flag...
2427  cell->clear_coarsen_flag();
2428 
2429  // ...and if necessary also refine the current
2430  // cell, at the same time updating the level
2431  // information about vertices
2432  if (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]] >
2433  cell->level()+1)
2434  {
2435  cell->set_refine_flag();
2436  continue_iterating = true;
2437 
2438  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
2439  ++v)
2440  vertex_level[topological_vertex_numbering[cell->vertex_index(v)]]
2441  = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(v)]],
2442  cell->level()+1);
2443  }
2444 
2445  // continue and see whether we may, for example,
2446  // go into the inner 'if' above based on a
2447  // different vertex
2448  }
2449  }
2450 
2451  // clear coarsen flag if not all children were marked
2452  for (typename Triangulation<dim,spacedim>::cell_iterator cell = tria.begin();
2453  cell!=tria.end(); ++cell)
2454  {
2455  // nothing to do if we are already on the finest level
2456  if (cell->active())
2457  continue;
2458 
2459  const unsigned int n_children=cell->n_children();
2460  unsigned int flagged_children=0;
2461  for (unsigned int child=0; child<n_children; ++child)
2462  if (cell->child(child)->active() &&
2463  cell->child(child)->coarsen_flag_set())
2464  ++flagged_children;
2465 
2466  // if not all children were flagged for coarsening, remove
2467  // coarsen flags
2468  if (flagged_children < n_children)
2469  for (unsigned int child=0; child<n_children; ++child)
2470  if (cell->child(child)->active())
2471  cell->child(child)->clear_coarsen_flag();
2472  }
2473  }
2474  std::vector<bool> flags_after[2];
2475  tria.save_coarsen_flags (flags_after[0]);
2476  tria.save_refine_flags (flags_after[1]);
2477  return ((flags_before[0] != flags_after[0]) ||
2478  (flags_before[1] != flags_after[1]));
2479  }
2480  }
2481 
2482 
2483 
2484  template <int dim, int spacedim>
2485  bool
2487  {
2488  std::vector<bool> flags_before[2];
2489  this->save_coarsen_flags (flags_before[0]);
2490  this->save_refine_flags (flags_before[1]);
2491 
2492  bool mesh_changed = false;
2493  do
2494  {
2496  this->update_periodic_face_map();
2497  // enforce 2:1 mesh balance over periodic boundaries
2498  if (this->smooth_grid &
2500  mesh_changed = enforce_mesh_balance_over_periodic_boundaries(*this);
2501  }
2502  while (mesh_changed);
2503 
2504  // check if any of the refinement flags were changed during this
2505  // function and return that value
2506  std::vector<bool> flags_after[2];
2507  this->save_coarsen_flags (flags_after[0]);
2508  this->save_refine_flags (flags_after[1]);
2509  return ((flags_before[0] != flags_after[0]) ||
2510  (flags_before[1] != flags_after[1]));
2511  }
2512 
2513 
2514 
2515  template <int dim, int spacedim>
2516  void
2518  {
2519  // disable mesh smoothing for recreating the deal.II triangulation,
2520  // otherwise we might not be able to reproduce the p4est mesh
2521  // exactly. We restore the original smoothing at the end of this
2522  // function. Note that the smoothing flag is used in the normal
2523  // refinement process.
2525  save_smooth = this->smooth_grid;
2526 
2527  // We will refine manually to match the p4est further down, which
2528  // obeys a level difference of 2 at each vertex (see the balance call
2529  // to p4est). We can disable this here so we store fewer artificial
2530  // cells (in some cases).
2531  // For geometric multigrid it turns out that
2532  // we will miss level cells at shared vertices if we ignore this.
2533  // See tests/mpi/mg_06. In particular, the flag is still necessary
2534  // even though we force it for the original smooth_grid in the constructor.
2535  if (settings & construct_multigrid_hierarchy)
2537  else
2538  this->smooth_grid = ::Triangulation<dim,spacedim>::none;
2539 
2540  bool mesh_changed = false;
2541 
2542  // remove all deal.II refinements. Note that we could skip this and
2543  // start from our current state, because the algorithm later coarsens as
2544  // necessary. This has the advantage of being faster when large parts
2545  // of the local partition changes (likely) and gives a deterministic
2546  // ordering of the cells (useful for snapshot/resume).
2547  // TODO: is there a more efficient way to do this?
2548  if (settings & mesh_reconstruction_after_repartitioning)
2549  while (this->begin_active()->level() > 0)
2550  {
2552  cell = this->begin_active();
2553  cell != this->end();
2554  ++cell)
2555  {
2556  cell->set_coarsen_flag();
2557  }
2558 
2559  this->prepare_coarsening_and_refinement();
2560  const bool saved_refinement_in_progress = refinement_in_progress;
2561  refinement_in_progress = true;
2562 
2563  try
2564  {
2565  this->execute_coarsening_and_refinement();
2566  }
2567  catch (const typename Triangulation<dim, spacedim>::DistortedCellList &)
2568  {
2569  // the underlying triangulation should not be checking for
2570  // distorted cells
2571  Assert (false, ExcInternalError());
2572  }
2573 
2574  refinement_in_progress = saved_refinement_in_progress;
2575  }
2576 
2577 
2578  // query p4est for the ghost cells
2579  if (parallel_ghost != 0)
2580  {
2582  parallel_ghost = 0;
2583  }
2584  parallel_ghost = ::internal::p4est::functions<dim>::ghost_new (parallel_forest,
2585  (dim == 2
2586  ?
2587  typename ::internal::p4est::types<dim>::
2588  balance_type(P4EST_CONNECT_CORNER)
2589  :
2590  typename ::internal::p4est::types<dim>::
2591  balance_type(P8EST_CONNECT_CORNER)));
2592 
2593  Assert (parallel_ghost, ExcInternalError());
2594 
2595 
2596  // set all cells to artificial. we will later set it to the correct
2597  // subdomain in match_tree_recursively
2599  cell = this->begin(0);
2600  cell != this->end(0);
2601  ++cell)
2602  cell->recursively_set_subdomain_id(numbers::artificial_subdomain_id);
2603 
2604  do
2605  {
2607  cell = this->begin(0);
2608  cell != this->end(0);
2609  ++cell)
2610  {
2611  // if this processor stores no part of the forest that comes out
2612  // of this coarse grid cell, then we need to delete all children
2613  // of this cell (the coarse grid cell remains)
2614  if (tree_exists_locally<dim,spacedim>(parallel_forest,
2615  coarse_cell_to_p4est_tree_permutation[cell->index()])
2616  == false)
2617  {
2618  delete_all_children<dim,spacedim> (cell);
2619  if (!cell->has_children())
2620  cell->set_subdomain_id (numbers::artificial_subdomain_id);
2621  }
2622 
2623  else
2624  {
2625  // this processor stores at least a part of the tree that
2626  // comes out of this cell.
2627 
2628  typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
2629  typename ::internal::p4est::types<dim>::tree *tree =
2630  init_tree(cell->index());
2631 
2632  ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
2633 
2634  match_tree_recursively<dim,spacedim> (*tree, cell,
2635  p4est_coarse_cell,
2636  *parallel_forest,
2637  this->my_subdomain);
2638  }
2639  }
2640 
2641  // check mesh for ghostcells, refine as necessary. iterate over
2642  // every ghostquadrant, find corresponding deal coarsecell and
2643  // recurse.
2644  typename ::internal::p4est::types<dim>::quadrant *quadr;
2645  types::subdomain_id ghost_owner=0;
2646  typename ::internal::p4est::types<dim>::topidx ghost_tree=0;
2647 
2648  for (unsigned int g_idx=0; g_idx<parallel_ghost->ghosts.elem_count; ++g_idx)
2649  {
2650  while (g_idx >= (unsigned int)parallel_ghost->proc_offsets[ghost_owner+1])
2651  ++ghost_owner;
2652  while (g_idx >= (unsigned int)parallel_ghost->tree_offsets[ghost_tree+1])
2653  ++ghost_tree;
2654 
2655  quadr = static_cast<typename ::internal::p4est::types<dim>::quadrant *>
2656  ( sc_array_index(&parallel_ghost->ghosts, g_idx) );
2657 
2658  unsigned int coarse_cell_index =
2659  p4est_tree_to_coarse_cell_permutation[ghost_tree];
2660 
2661  match_quadrant<dim,spacedim> (this, coarse_cell_index, *quadr, ghost_owner);
2662  }
2663 
2664  // fix all the flags to make sure we have a consistent mesh
2665  this->prepare_coarsening_and_refinement ();
2666 
2667  // see if any flags are still set
2668  mesh_changed = false;
2670  cell = this->begin_active();
2671  cell != this->end();
2672  ++cell)
2673  if (cell->refine_flag_set() || cell->coarsen_flag_set())
2674  {
2675  mesh_changed = true;
2676  break;
2677  }
2678 
2679  // actually do the refinement but prevent the refinement hook below
2680  // from taking over
2681  const bool saved_refinement_in_progress = refinement_in_progress;
2682  refinement_in_progress = true;
2683 
2684  try
2685  {
2686  this->execute_coarsening_and_refinement();
2687  }
2688  catch (const typename Triangulation<dim,spacedim>::DistortedCellList &)
2689  {
2690  // the underlying triangulation should not be checking for
2691  // distorted cells
2692  Assert (false, ExcInternalError());
2693  }
2694 
2695  refinement_in_progress = saved_refinement_in_progress;
2696  }
2697  while (mesh_changed);
2698 
2699 #ifdef DEBUG
2700  // check if correct number of ghosts is created
2701  unsigned int num_ghosts = 0;
2702 
2704  cell = this->begin_active();
2705  cell != this->end();
2706  ++cell)
2707  {
2708  if (cell->subdomain_id() != this->my_subdomain
2709  &&
2710  cell->subdomain_id() != numbers::artificial_subdomain_id)
2711  ++num_ghosts;
2712  }
2713 
2714  Assert( num_ghosts == parallel_ghost->ghosts.elem_count, ExcInternalError());
2715 #endif
2716 
2717 
2718 
2719  // fill level_subdomain_ids for geometric multigrid
2720  // the level ownership of a cell is defined as the owner if the cell is active or as the owner of child(0)
2721  // we need this information for all our ancestors and the same-level neighbors of our own cells (=level ghosts)
2722  if (settings & construct_multigrid_hierarchy)
2723  {
2724  // step 1: We set our own ids all the way down and all the others to
2725  // -1. Note that we do not fill other cells we could figure out the
2726  // same way, because we might accidentally set an id for a cell that
2727  // is not a ghost cell.
2728  for (unsigned int lvl=this->n_levels(); lvl>0; )
2729  {
2730  --lvl;
2731  typename Triangulation<dim,spacedim>::cell_iterator cell, endc = this->end(lvl);
2732  for (cell = this->begin(lvl); cell!=endc; ++cell)
2733  {
2734  if ((!cell->has_children() && cell->subdomain_id()==this->locally_owned_subdomain())
2735  || (cell->has_children() && cell->child(0)->level_subdomain_id()==this->locally_owned_subdomain()))
2736  cell->set_level_subdomain_id(this->locally_owned_subdomain());
2737  else
2738  {
2739  //not our cell
2740  cell->set_level_subdomain_id(numbers::artificial_subdomain_id);
2741  }
2742  }
2743  }
2744 
2745  //step 2: make sure all the neighbors to our level_cells exist. Need
2746  //to look up in p4est...
2747  std::vector<std::vector<bool> > marked_vertices(this->n_levels());
2748  for (unsigned int lvl=0; lvl < this->n_levels(); ++lvl)
2749  marked_vertices[lvl] = mark_locally_active_vertices_on_level(lvl);
2750 
2751  for (typename Triangulation<dim,spacedim>::cell_iterator cell = this->begin(0); cell!=this->end(0); ++cell)
2752  {
2753  typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
2754  const unsigned int tree_index
2755  = coarse_cell_to_p4est_tree_permutation[cell->index()];
2756  typename ::internal::p4est::types<dim>::tree *tree =
2757  init_tree(cell->index());
2758 
2759  ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
2760 
2761  determine_level_subdomain_id_recursively<dim,spacedim> (*tree, tree_index, cell,
2762  p4est_coarse_cell,
2763  *parallel_forest,
2764  this->my_subdomain,
2765  marked_vertices);
2766  }
2767 
2768  //step 3: make sure we have the parent of our level cells
2769  for (unsigned int lvl=this->n_levels(); lvl>0;)
2770  {
2771  --lvl;
2772  typename Triangulation<dim,spacedim>::cell_iterator cell, endc = this->end(lvl);
2773  for (cell = this->begin(lvl); cell!=endc; ++cell)
2774  {
2775  if (cell->has_children())
2776  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
2777  {
2778  if (cell->child(c)->level_subdomain_id()==this->locally_owned_subdomain())
2779  {
2780  //at least one of the children belongs to us, so
2781  //make sure we set the level subdomain id
2782  const types::subdomain_id mark =
2783  cell->child(0)->level_subdomain_id();
2784  Assert(mark != numbers::artificial_subdomain_id, ExcInternalError()); //we should know the child(0)
2785  cell->set_level_subdomain_id(mark);
2786  break;
2787  }
2788  }
2789  }
2790  }
2791 
2792  }
2793 
2794 
2795 
2796  // check that our local copy has exactly as many cells as the p4est
2797  // original (at least if we are on only one processor); for parallel
2798  // computations, we want to check that we have at least as many as p4est
2799  // stores locally (in the future we should check that we have exactly as
2800  // many non-artificial cells as parallel_forest->local_num_quadrants)
2801  {
2802  const unsigned int total_local_cells = this->n_active_cells();
2803  (void)total_local_cells;
2804 
2805  if (Utilities::MPI::n_mpi_processes (this->mpi_communicator) == 1)
2806  Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
2807  total_local_cells,
2808  ExcInternalError())
2809  else
2810  Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) <=
2811  total_local_cells,
2812  ExcInternalError());
2813 
2814  // count the number of owned, active cells and compare with p4est.
2815  unsigned int n_owned = 0;
2817  cell = this->begin_active();
2818  cell != this->end(); ++cell)
2819  {
2820  if (cell->subdomain_id() == this->my_subdomain)
2821  ++n_owned;
2822  }
2823 
2824  Assert(static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
2825  n_owned, ExcInternalError());
2826 
2827  }
2828 
2829  this->smooth_grid = save_smooth;
2830  }
2831 
2832 
2833 
2834  template <int dim, int spacedim>
2835  void
2837  {
2838  // first make sure that recursive calls are handled correctly
2839  if (refinement_in_progress == true)
2840  {
2842  return;
2843  }
2844 
2845  // do not allow anisotropic refinement
2846 #ifdef DEBUG
2848  cell = this->begin_active();
2849  cell != this->end(); ++cell)
2850  if (cell->is_locally_owned() && cell->refine_flag_set())
2851  Assert (cell->refine_flag_set() ==
2853  ExcMessage ("This class does not support anisotropic refinement"));
2854 #endif
2855 
2856 
2857  // safety check: p4est has an upper limit on the level of a cell
2858  if (this->n_levels()==::internal::p4est::functions<dim>::max_level)
2859  {
2861  cell = this->begin_active(::internal::p4est::functions<dim>::max_level-1);
2862  cell != this->end(::internal::p4est::functions<dim>::max_level-1); ++cell)
2863  {
2864  AssertThrow(!(cell->refine_flag_set()),
2865  ExcMessage("Fatal Error: maximum refinement level of p4est reached."));
2866  }
2867  }
2868 
2869  // now do the work we're supposed to do when we are in charge
2870  refinement_in_progress = true;
2871  this->prepare_coarsening_and_refinement ();
2872 
2873  // make sure all flags are cleared on cells we don't own, since nothing
2874  // good can come of that if they are still around
2876  cell = this->begin_active();
2877  cell != this->end(); ++cell)
2878  if (cell->is_ghost() || cell->is_artificial())
2879  {
2880  cell->clear_refine_flag ();
2881  cell->clear_coarsen_flag ();
2882  }
2883 
2884 
2885  // count how many cells will be refined and coarsened, and allocate that
2886  // much memory
2887  RefineAndCoarsenList<dim,spacedim>
2888  refine_and_coarsen_list (*this,
2889  p4est_tree_to_coarse_cell_permutation,
2890  this->my_subdomain);
2891 
2892  // copy refine and coarsen flags into p4est and execute the refinement
2893  // and coarsening. this uses the refine_and_coarsen_list just built,
2894  // which is communicated to the callback functions through
2895  // p4est's user_pointer object
2896  Assert (parallel_forest->user_pointer == this,
2897  ExcInternalError());
2898  parallel_forest->user_pointer = &refine_and_coarsen_list;
2899 
2900  if (parallel_ghost != 0)
2901  {
2903  parallel_ghost = 0;
2904  }
2906  refine (parallel_forest, /* refine_recursive */ false,
2907  &RefineAndCoarsenList<dim,spacedim>::refine_callback,
2908  /*init_callback=*/NULL);
2910  coarsen (parallel_forest, /* coarsen_recursive */ false,
2911  &RefineAndCoarsenList<dim,spacedim>::coarsen_callback,
2912  /*init_callback=*/NULL);
2913 
2914  // make sure all cells in the lists have been consumed
2915  Assert (refine_and_coarsen_list.pointers_are_at_end(),
2916  ExcInternalError());
2917 
2918  // reset the pointer
2919  parallel_forest->user_pointer = this;
2920 
2921  // enforce 2:1 hanging node condition
2923  balance (parallel_forest,
2924  /* face and corner balance */
2925  (dim == 2
2926  ?
2927  typename ::internal::p4est::types<dim>::
2928  balance_type(P4EST_CONNECT_FULL)
2929  :
2930  typename ::internal::p4est::types<dim>::
2931  balance_type(P8EST_CONNECT_FULL)),
2932  /*init_callback=*/NULL);
2933 
2934  // before repartitioning the mesh let others attach mesh related info
2935  // (such as SolutionTransfer data) to the p4est
2936  attach_mesh_data();
2937 
2938  if (!(settings & no_automatic_repartitioning))
2939  {
2940  // partition the new mesh between all processors. If cell weights have
2941  // not been given balance the number of cells.
2942  if (this->signals.cell_weight.num_slots() == 0)
2944  partition (parallel_forest,
2945  /* prepare coarsening */ 1,
2946  /* weight_callback */ NULL);
2947  else
2948  {
2949  // get cell weights for a weighted repartitioning.
2950  const std::vector<unsigned int> cell_weights = get_cell_weights();
2951 
2952  PartitionWeights<dim,spacedim> partition_weights (cell_weights);
2953 
2954  // attach (temporarily) a pointer to the cell weights through p4est's
2955  // user_pointer object
2956  Assert (parallel_forest->user_pointer == this,
2957  ExcInternalError());
2958  parallel_forest->user_pointer = &partition_weights;
2959 
2961  partition (parallel_forest,
2962  /* prepare coarsening */ 1,
2963  /* weight_callback */ &PartitionWeights<dim,spacedim>::cell_weight);
2964 
2965  // reset the user pointer to its previous state
2966  parallel_forest->user_pointer = this;
2967  }
2968  }
2969 
2970  // finally copy back from local part of tree to deal.II
2971  // triangulation. before doing so, make sure there are no refine or
2972  // coarsen flags pending
2974  cell = this->begin_active();
2975  cell != this->end(); ++cell)
2976  {
2977  cell->clear_refine_flag();
2978  cell->clear_coarsen_flag();
2979  }
2980 
2981  try
2982  {
2983  copy_local_forest_to_triangulation ();
2984  }
2985  catch (const typename Triangulation<dim>::DistortedCellList &)
2986  {
2987  // the underlying triangulation should not be checking for distorted
2988  // cells
2989  Assert (false, ExcInternalError());
2990  }
2991 
2992 #ifdef DEBUG
2993  // Check that we know the level subdomain ids of all our neighbors. This
2994  // also involves coarser cells that share a vertex if they are active.
2995  //
2996  // Example (M= my, O=other):
2997  // *------*
2998  // | |
2999  // | O |
3000  // | |
3001  // *---*---*------*
3002  // | M | M |
3003  // *---*---*
3004  // | | M |
3005  // *---*---*
3006  // ^- the parent can be owned by somebody else, so O is not a neighbor
3007  // one level coarser
3008  if (settings & construct_multigrid_hierarchy)
3009  {
3010  for (unsigned int lvl=0; lvl<this->n_global_levels(); ++lvl)
3011  {
3012  std::vector<bool> active_verts = this->mark_locally_active_vertices_on_level(lvl);
3013 
3014  const unsigned int maybe_coarser_lvl = (lvl>0) ? (lvl-1) : lvl;
3015  typename Triangulation<dim, spacedim>::cell_iterator cell = this->begin(maybe_coarser_lvl),
3016  endc = this->end(lvl);
3017  for (; cell != endc; ++cell)
3018  if (cell->level() == static_cast<int>(lvl) || cell->active())
3019  {
3020  const bool is_level_artificial =
3021  (cell->level_subdomain_id() == numbers::artificial_subdomain_id);
3022  bool need_to_know = false;
3023  for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
3024  ++vertex)
3025  if (active_verts[cell->vertex_index(vertex)])
3026  {
3027  need_to_know = true;
3028  break;
3029  }
3030 
3031  Assert(!need_to_know || !is_level_artificial,
3032  ExcMessage("Internal error: the owner of cell"
3033  + cell->id().to_string()
3034  + " is unknown even though it is needed for geometric multigrid."));
3035  }
3036  }
3037  }
3038 #endif
3039 
3040  refinement_in_progress = false;
3041  this->update_number_cache ();
3042  this->update_periodic_face_map();
3043  }
3044 
3045  template <int dim, int spacedim>
3046  void
3048  {
3049 
3050 #ifdef DEBUG
3052  cell = this->begin_active();
3053  cell != this->end(); ++cell)
3054  if (cell->is_locally_owned())
3055  Assert (
3056  !cell->refine_flag_set() && !cell->coarsen_flag_set(),
3057  ExcMessage ("Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition()."));
3058 #endif
3059 
3060  refinement_in_progress = true;
3061 
3062  // before repartitioning the mesh let others attach mesh related info
3063  // (such as SolutionTransfer data) to the p4est
3064  attach_mesh_data();
3065 
3066  if (this->signals.cell_weight.num_slots() == 0)
3067  {
3068  // no cell weights given -- call p4est's 'partition' without a
3069  // callback for cell weights
3071  partition (parallel_forest,
3072  /* prepare coarsening */ 1,
3073  /* weight_callback */ NULL);
3074  }
3075  else
3076  {
3077  // get cell weights for a weighted repartitioning.
3078  const std::vector<unsigned int> cell_weights = get_cell_weights();
3079 
3080  PartitionWeights<dim,spacedim> partition_weights (cell_weights);
3081 
3082  // attach (temporarily) a pointer to the cell weights through p4est's
3083  // user_pointer object
3084  Assert (parallel_forest->user_pointer == this,
3085  ExcInternalError());
3086  parallel_forest->user_pointer = &partition_weights;
3087 
3089  partition (parallel_forest,
3090  /* prepare coarsening */ 1,
3091  /* weight_callback */ &PartitionWeights<dim,spacedim>::cell_weight);
3092 
3093  // reset the user pointer to its previous state
3094  parallel_forest->user_pointer = this;
3095  }
3096 
3097  try
3098  {
3099  copy_local_forest_to_triangulation ();
3100  }
3101  catch (const typename Triangulation<dim>::DistortedCellList &)
3102  {
3103  // the underlying triangulation should not be checking for distorted
3104  // cells
3105  Assert (false, ExcInternalError());
3106  }
3107 
3108  refinement_in_progress = false;
3109 
3110  // update how many cells, edges, etc, we store locally
3111  this->update_number_cache ();
3112  this->update_periodic_face_map();
3113  }
3114 
3115 
3116 
3117  template <int dim, int spacedim>
3118  void
3120  communicate_locally_moved_vertices (const std::vector<bool> &vertex_locally_moved)
3121  {
3122  Assert (vertex_locally_moved.size() == this->n_vertices(),
3123  ExcDimensionMismatch(vertex_locally_moved.size(),
3124  this->n_vertices()));
3125 #ifdef DEBUG
3126  {
3127  const std::vector<bool> locally_owned_vertices
3129  for (unsigned int i=0; i<locally_owned_vertices.size(); ++i)
3130  Assert ((vertex_locally_moved[i] == false)
3131  ||
3132  (locally_owned_vertices[i] == true),
3133  ExcMessage ("The vertex_locally_moved argument must not "
3134  "contain vertices that are not locally owned"));
3135  }
3136 #endif
3137 
3138  std::map<unsigned int, std::set<::types::subdomain_id> >
3139  vertices_with_ghost_neighbors;
3140 
3141  // First find out which process should receive which vertices.
3142  // these are specifically the ones that sit on ghost cells and,
3143  // among these, the ones that we own locally
3145  cell=this->begin_active(); cell!=this->end();
3146  ++cell)
3147  if (cell->is_ghost())
3148  for (unsigned int vertex_no=0;
3149  vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
3150  {
3151  const unsigned int process_local_vertex_no = cell->vertex_index(vertex_no);
3152  vertices_with_ghost_neighbors[process_local_vertex_no].insert
3153  (cell->subdomain_id());
3154  }
3155 
3156  // now collect cells and their vertices
3157  // for the interested neighbors
3158  typedef
3159  std::map<::types::subdomain_id, CommunicateLocallyMovedVertices::CellInfo<dim,spacedim> > cellmap_t;
3160  cellmap_t needs_to_get_cells;
3161 
3163  cell = this->begin(0);
3164  cell != this->end(0);
3165  ++cell)
3166  {
3167  typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3168  ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3169 
3170  CommunicateLocallyMovedVertices::fill_vertices_recursively<dim,spacedim>
3171  (*this,
3172  this->get_coarse_cell_to_p4est_tree_permutation()[cell->index()],
3173  cell,
3174  p4est_coarse_cell,
3175  vertices_with_ghost_neighbors,
3176  vertex_locally_moved,
3177  needs_to_get_cells);
3178  }
3179 
3180  // sending
3181  std::vector<std::vector<char> > sendbuffers (needs_to_get_cells.size());
3182  std::vector<std::vector<char> >::iterator buffer = sendbuffers.begin();
3183  std::vector<MPI_Request> requests (needs_to_get_cells.size());
3184  std::vector<unsigned int> destinations;
3185 
3186  unsigned int idx=0;
3187 
3188  for (typename cellmap_t::iterator it=needs_to_get_cells.begin();
3189  it!=needs_to_get_cells.end();
3190  ++it, ++buffer, ++idx)
3191  {
3192  const unsigned int num_cells = it->second.tree_index.size();
3193  (void)num_cells;
3194  destinations.push_back(it->first);
3195 
3196  Assert(num_cells==it->second.quadrants.size(), ExcInternalError());
3197  Assert(num_cells>0, ExcInternalError());
3198 
3199  // pack all the data into
3200  // the buffer for this
3201  // recipient and send
3202  // it. keep data around
3203  // till we can make sure
3204  // that the packet has been
3205  // received
3206  it->second.pack_data (*buffer);
3207  const int ierr = MPI_Isend(&(*buffer)[0], buffer->size(),
3208  MPI_BYTE, it->first,
3209  123, this->get_communicator(), &requests[idx]);
3210  AssertThrowMPI(ierr);
3211  }
3212 
3213  Assert(destinations.size()==needs_to_get_cells.size(), ExcInternalError());
3214 
3215  // collect the neighbors
3216  // that are going to send stuff to us
3217  const std::vector<unsigned int> senders
3219  (this->get_communicator(), destinations);
3220 
3221  // receive ghostcelldata
3222  std::vector<char> receive;
3223  CommunicateLocallyMovedVertices::CellInfo<dim,spacedim> cellinfo;
3224  for (unsigned int i=0; i<senders.size(); ++i)
3225  {
3226  MPI_Status status;
3227  int len;
3228  int ierr = MPI_Probe(MPI_ANY_SOURCE, 123, this->get_communicator(), &status);
3229  AssertThrowMPI(ierr);
3230  ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3231  AssertThrowMPI(ierr);
3232  receive.resize(len);
3233 
3234  char *ptr = &receive[0];
3235  ierr = MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
3236  this->get_communicator(), &status);
3237  AssertThrowMPI(ierr);
3238 
3239  cellinfo.unpack_data(receive);
3240  const unsigned int cells = cellinfo.tree_index.size();
3241  for (unsigned int c=0; c<cells; ++c)
3242  {
3243  typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator
3244  cell (this,
3245  0,
3246  this->get_p4est_tree_to_coarse_cell_permutation()[cellinfo.tree_index[c]]);
3247 
3248  typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3249  ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3250 
3251  CommunicateLocallyMovedVertices::set_vertices_recursively<dim,spacedim> (*this,
3252  p4est_coarse_cell,
3253  cell,
3254  cellinfo.quadrants[c],
3255  cellinfo.first_vertices[c],
3256  cellinfo.first_vertex_indices[c]);
3257  }
3258  }
3259 
3260  // complete all sends, so that we can
3261  // safely destroy the buffers.
3262  if (requests.size() > 0)
3263  {
3264  const int ierr = MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
3265  AssertThrowMPI(ierr);
3266  }
3267 
3268  //check all msgs got sent and received
3269  Assert(Utilities::MPI::sum(needs_to_get_cells.size(), this->get_communicator())
3270  == Utilities::MPI::sum(senders.size(), this->get_communicator()),
3271  ExcInternalError());
3272  }
3273 
3274  template <int dim, int spacedim>
3275  unsigned int
3277  register_data_attach (const std::size_t size,
3278  const std_cxx11::function<void(const cell_iterator &,
3279  const CellStatus,
3280  void *)> &pack_callback)
3281  {
3282  Assert(size>0, ExcMessage("register_data_attach(), size==0"));
3283  Assert(attached_data_pack_callbacks.size()==n_attached_datas,
3284  ExcMessage("register_data_attach(), not all data has been unpacked last time?"));
3285 
3286  unsigned int offset = attached_data_size+sizeof(CellStatus);
3287  ++n_attached_datas;
3288  attached_data_size+=size;
3289  attached_data_pack_callbacks.push_back(
3290  std::pair<unsigned int, pack_callback_t> (offset, pack_callback)
3291  );
3292  return offset;
3293  }
3294 
3295 
3296 
3297  template <int dim, int spacedim>
3298  void
3300  notify_ready_to_unpack (const unsigned int offset,
3301  const std_cxx11::function<void (const cell_iterator &,
3302  const CellStatus,
3303  const void *)> &unpack_callback)
3304  {
3305  Assert (offset >= sizeof(CellStatus),
3306  ExcMessage ("invalid offset in notify_ready_to_unpack()"));
3307  Assert (offset < sizeof(CellStatus)+attached_data_size,
3308  ExcMessage ("invalid offset in notify_ready_to_unpack()"));
3309  Assert (n_attached_datas > 0, ExcMessage ("notify_ready_to_unpack() called too often"));
3310 
3311  // Recurse over p4est and hand the caller the data back
3313  cell = this->begin (0);
3314  cell != this->end (0);
3315  ++cell)
3316  {
3317  //skip coarse cells, that are not ours
3318  if (tree_exists_locally<dim, spacedim> (parallel_forest,
3319  coarse_cell_to_p4est_tree_permutation[cell->index() ])
3320  == false)
3321  continue;
3322 
3323  typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3324  typename ::internal::p4est::types<dim>::tree *tree =
3325  init_tree (cell->index());
3326 
3327  ::internal::p4est::init_coarse_quadrant<dim> (p4est_coarse_cell);
3328 
3329  // parent_cell is not correct here, but is only used in a refined
3330  // cell
3331  post_mesh_data_recursively<dim, spacedim> (*tree,
3332  cell,
3333  cell,
3334  p4est_coarse_cell,
3335  offset,
3336  unpack_callback);
3337  }
3338 
3339  --n_attached_datas;
3340  if (n_attached_deserialize > 0)
3341  {
3342  --n_attached_deserialize;
3343  attached_data_pack_callbacks.pop_front();
3344  }
3345 
3346  // important: only remove data if we are not in the deserialization
3347  // process. There, each SolutionTransfer registers and unpacks before
3348  // the next one does this, so n_attached_datas is only 1 here. This
3349  // would destroy the saved data before the second SolutionTransfer can
3350  // get it. This created a bug that is documented in
3351  // tests/mpi/p4est_save_03 with more than one SolutionTransfer.
3352  if (!n_attached_datas && n_attached_deserialize == 0)
3353  {
3354  // everybody got his data, time for cleanup!
3355  attached_data_size = 0;
3356  attached_data_pack_callbacks.clear();
3357 
3358  // and release the data
3359  void *userptr = parallel_forest->user_pointer;
3360  ::internal::p4est::functions<dim>::reset_data (parallel_forest, 0, NULL, NULL);
3361  parallel_forest->user_pointer = userptr;
3362  }
3363  }
3364 
3365 
3366  template <int dim, int spacedim>
3367  const std::vector<types::global_dof_index> &
3369  {
3370  return p4est_tree_to_coarse_cell_permutation;
3371  }
3372 
3373 
3374 
3375  template <int dim, int spacedim>
3376  const std::vector<types::global_dof_index> &
3378  {
3379  return coarse_cell_to_p4est_tree_permutation;
3380  }
3381 
3382 
3387  template <int dim, int spacedim>
3388  void
3391  (std::map<unsigned int, std::set<::types::subdomain_id> >
3392  &vertices_with_ghost_neighbors)
3393  {
3394  Assert (dim>1, ExcNotImplemented());
3395 
3397  fg.subids = sc_array_new (sizeof (::types::subdomain_id));
3398  fg.triangulation = this;
3399  fg.vertices_with_ghost_neighbors = &vertices_with_ghost_neighbors;
3400 
3401  ::internal::p4est::functions<dim>::template iterate<spacedim> (this->parallel_forest,
3402  this->parallel_ghost,
3403  static_cast<void *>(&fg));
3404 
3405  sc_array_destroy (fg.subids);
3406  }
3407 
3408 
3409 
3414  template <int dim, int spacedim>
3415  void
3418  (const int level,
3419  std::map<unsigned int, std::set<::types::subdomain_id> >
3420  &vertices_with_ghost_neighbors)
3421  {
3422  const std::vector<bool> locally_active_vertices =
3423  mark_locally_active_vertices_on_level(level);
3424  cell_iterator cell = this->begin(level),
3425  endc = this->end(level);
3426  for ( ; cell != endc; ++cell)
3427  if (cell->level_subdomain_id() != ::numbers::artificial_subdomain_id
3428  && cell->level_subdomain_id() != this->locally_owned_subdomain())
3429  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
3430  if (locally_active_vertices[cell->vertex_index(v)])
3431  vertices_with_ghost_neighbors[cell->vertex_index(v)]
3432  .insert (cell->level_subdomain_id());
3433 
3434  //now for the vertices on periodic faces
3435  typename std::map<std::pair<cell_iterator, unsigned int>,
3436  std::pair<std::pair<cell_iterator,unsigned int>, std::bitset<3> > >::const_iterator it;
3437 
3438  for (it = this->get_periodic_face_map().begin(); it!= this->get_periodic_face_map().end(); ++it)
3439  {
3440  const cell_iterator &cell_1 = it->first.first;
3441  const unsigned int face_no_1 = it->first.second;
3442  const cell_iterator &cell_2 = it->second.first.first;
3443  const unsigned int face_no_2 = it->second.first.second;
3444  const std::bitset<3> face_orientation = it->second.second;
3445 
3446  if (cell_1->level() == level &&
3447  cell_2->level() == level)
3448  {
3449  for (unsigned int v=0; v<GeometryInfo<dim-1>::vertices_per_cell; ++v)
3450  {
3451  // take possible non-standard orientation of faces into account
3452  const unsigned int vface0 =
3454  face_orientation[1],
3455  face_orientation[2]);
3456  const unsigned int idx0 = cell_1->face(face_no_1)->vertex_index(vface0);
3457  const unsigned int idx1 = cell_2->face(face_no_2)->vertex_index(v);
3458  if (vertices_with_ghost_neighbors.find(idx0) != vertices_with_ghost_neighbors.end())
3459  vertices_with_ghost_neighbors[idx1].insert(vertices_with_ghost_neighbors[idx0].begin(),
3460  vertices_with_ghost_neighbors[idx0].end());
3461  if (vertices_with_ghost_neighbors.find(idx1) != vertices_with_ghost_neighbors.end())
3462  vertices_with_ghost_neighbors[idx0].insert(vertices_with_ghost_neighbors[idx1].begin(),
3463  vertices_with_ghost_neighbors[idx1].end());
3464  }
3465  }
3466  }
3467  }
3468 
3469 
3470 
3471  template<int dim, int spacedim>
3472  std::vector<bool>
3475  {
3476  Assert (dim>1, ExcNotImplemented());
3477 
3478  std::vector<bool> marked_vertices(this->n_vertices(), false);
3479  cell_iterator cell = this->begin(level),
3480  endc = this->end(level);
3481  for ( ; cell != endc; ++cell)
3482  if (cell->level_subdomain_id() == this->locally_owned_subdomain())
3483  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
3484  marked_vertices[cell->vertex_index(v)] = true;
3485 
3491  typename std::map<std::pair<cell_iterator, unsigned int>,
3492  std::pair<std::pair<cell_iterator,unsigned int>, std::bitset<3> > >::const_iterator it;
3493 
3494  for (it = this->get_periodic_face_map().begin(); it!= this->get_periodic_face_map().end(); ++it)
3495  {
3496  const cell_iterator &cell_1 = it->first.first;
3497  const unsigned int face_no_1 = it->first.second;
3498  const cell_iterator &cell_2 = it->second.first.first;
3499  const unsigned int face_no_2 = it->second.first.second;
3500  const std::bitset<3> &face_orientation = it->second.second;
3501 
3502  if (cell_1->level() == level &&
3503  cell_2->level() == level)
3504  {
3505  for (unsigned int v=0; v<GeometryInfo<dim-1>::vertices_per_cell; ++v)
3506  {
3507  // take possible non-standard orientation of faces into account
3508  const unsigned int vface0 =
3510  face_orientation[1],
3511  face_orientation[2]);
3512  if (marked_vertices[cell_1->face(face_no_1)->vertex_index(vface0)] ||
3513  marked_vertices[cell_2->face(face_no_2)->vertex_index(v)])
3514  marked_vertices[cell_1->face(face_no_1)->vertex_index(vface0)]
3515  = marked_vertices[cell_2->face(face_no_2)->vertex_index(v)]
3516  = true;
3517  }
3518  }
3519  }
3520 
3521  return marked_vertices;
3522  }
3523 
3524 
3525 
3526  template<int dim, int spacedim>
3527  void
3530  periodicity_vector)
3531  {
3532 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,1)
3533  Assert (triangulation_has_content == true,
3534  ExcMessage ("The triangulation is empty!"));
3535  Assert (this->n_levels() == 1,
3536  ExcMessage ("The triangulation is refined!"));
3537 
3538  typedef std::vector<GridTools::PeriodicFacePair<cell_iterator> >
3539  FaceVector;
3540  typename FaceVector::const_iterator it, periodic_end;
3541  it = periodicity_vector.begin();
3542  periodic_end = periodicity_vector.end();
3543 
3544  for (; it<periodic_end; ++it)
3545  {
3546  const cell_iterator first_cell = it->cell[0];
3547  const cell_iterator second_cell = it->cell[1];
3548  const unsigned int face_left = it->face_idx[0];
3549  const unsigned int face_right = it->face_idx[1];
3550 
3551  //respective cells of the matching faces in p4est
3552  const unsigned int tree_left
3553  = coarse_cell_to_p4est_tree_permutation[std::distance(this->begin(),
3554  first_cell)];
3555  const unsigned int tree_right
3556  = coarse_cell_to_p4est_tree_permutation[std::distance(this->begin(),
3557  second_cell)];
3558 
3559  // p4est wants to know which corner the first corner on
3560  // the face with the lower id is mapped to on the face with
3561  // with the higher id. For d==2 there are only two possibilities
3562  // that are determined by it->orientation[1].
3563  // For d==3 we have to use GridTools::OrientationLookupTable.
3564  // The result is given below.
3565 
3566  unsigned int p4est_orientation = 0;
3567  if (dim==2)
3568  p4est_orientation = it->orientation[1];
3569  else
3570  {
3571  const unsigned int face_idx_list[] = {face_left, face_right};
3572  const cell_iterator cell_list[] = {first_cell, second_cell};
3573  unsigned int lower_idx, higher_idx;
3574  if (face_left<=face_right)
3575  {
3576  higher_idx = 1;
3577  lower_idx = 0;
3578  }
3579  else
3580  {
3581  higher_idx = 0;
3582  lower_idx = 1;
3583  }
3584 
3585  // get the cell index of the first index on the face with the lower id
3586  unsigned int first_p4est_idx_on_cell = p8est_face_corners[face_idx_list[lower_idx]][0];
3587  unsigned int first_dealii_idx_on_face = numbers::invalid_unsigned_int;
3588  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
3589  {
3590  const unsigned int first_dealii_idx_on_cell
3592  (face_idx_list[lower_idx], i,
3593  cell_list[lower_idx]->face_orientation(face_idx_list[lower_idx]),
3594  cell_list[lower_idx]->face_flip(face_idx_list[lower_idx]),
3595  cell_list[lower_idx]->face_rotation(face_idx_list[lower_idx]));
3596  if (first_p4est_idx_on_cell == first_dealii_idx_on_cell)
3597  {
3598  first_dealii_idx_on_face = i;
3599  break;
3600  }
3601  }
3602  Assert( first_dealii_idx_on_face != numbers::invalid_unsigned_int, ExcInternalError());
3603  // Now map dealii_idx_on_face according to the orientation
3604  const unsigned int left_to_right [8][4] = {{0,2,1,3},{0,1,2,3},{3,1,2,0},{3,2,1,0},
3605  {2,3,0,1},{1,3,0,2},{1,0,3,2},{2,0,3,1}
3606  };
3607  const unsigned int right_to_left [8][4] = {{0,2,1,3},{0,1,2,3},{3,1,2,0},{3,2,1,0},
3608  {2,3,0,1},{2,0,3,1},{1,0,3,2},{1,3,0,2}
3609  };
3610  const unsigned int second_dealii_idx_on_face
3611  = lower_idx==0?left_to_right[it->orientation.to_ulong()][first_dealii_idx_on_face]:
3612  right_to_left[it->orientation.to_ulong()][first_dealii_idx_on_face];
3613  const unsigned int second_dealii_idx_on_cell
3615  (face_idx_list[higher_idx], second_dealii_idx_on_face,
3616  cell_list[higher_idx]->face_orientation(face_idx_list[higher_idx]),
3617  cell_list[higher_idx]->face_flip(face_idx_list[higher_idx]),
3618  cell_list[higher_idx]->face_rotation(face_idx_list[higher_idx]));
3619  //map back to p4est
3620  const unsigned int second_p4est_idx_on_face
3621  = p8est_corner_face_corners[second_dealii_idx_on_cell][face_idx_list[higher_idx]];
3622  p4est_orientation = second_p4est_idx_on_face;
3623  }
3624 
3626  connectivity_join_faces (connectivity,
3627  tree_left,
3628  tree_right,
3629  face_left,
3630  face_right,
3631  p4est_orientation);
3632  }
3633 
3634 
3636  (connectivity) == 1, ExcInternalError());
3637 
3638  // now create a forest out of the connectivity data structure
3640  parallel_forest
3642  new_forest (this->mpi_communicator,
3643  connectivity,
3644  /* minimum initial number of quadrants per tree */ 0,
3645  /* minimum level of upfront refinement */ 0,
3646  /* use uniform upfront refinement */ 1,
3647  /* user_data_size = */ 0,
3648  /* user_data_constructor = */ NULL,
3649  /* user_pointer */ this);
3650 
3651 
3652  try
3653  {
3654  copy_local_forest_to_triangulation ();
3655  }
3656  catch (const typename Triangulation<dim>::DistortedCellList &)
3657  {
3658  // the underlying triangulation should not be checking for distorted
3659  // cells
3660  Assert (false, ExcInternalError());
3661  }
3662 
3663  //finally call the base class for storing the periodicity information
3665 #else
3666  Assert(false, ExcMessage ("Need p4est version >= 0.3.4.1!"));
3667 #endif
3668  }
3669 
3670 
3671 
3672  template <int dim, int spacedim>
3673  std::size_t
3675  {
3676  std::size_t mem=
3678  + MemoryConsumption::memory_consumption(triangulation_has_content)
3680  + MemoryConsumption::memory_consumption(parallel_forest)
3681  + MemoryConsumption::memory_consumption(refinement_in_progress)
3682  + MemoryConsumption::memory_consumption(attached_data_size)
3683  + MemoryConsumption::memory_consumption(n_attached_datas)
3684 // + MemoryConsumption::memory_consumption(attached_data_pack_callbacks) //TODO[TH]: how?
3685  + MemoryConsumption::memory_consumption(coarse_cell_to_p4est_tree_permutation)
3686  + MemoryConsumption::memory_consumption(p4est_tree_to_coarse_cell_permutation)
3687  + memory_consumption_p4est();
3688 
3689  return mem;
3690  }
3691 
3692 
3693 
3694  template <int dim, int spacedim>
3695  std::size_t
3697  {
3698  return ::internal::p4est::functions<dim>::forest_memory_used(parallel_forest)
3700  }
3701 
3702 
3703 
3704  template <int dim, int spacedim>
3705  void
3707  copy_triangulation (const ::Triangulation<dim, spacedim> &other_tria)
3708  {
3709  try
3710  {
3712  }
3713  catch (const typename ::Triangulation<dim,spacedim>::DistortedCellList &)
3714  {
3715  // the underlying triangulation should not be checking for distorted
3716  // cells
3717  Assert (false, ExcInternalError());
3718  }
3719 
3720  // note that now we have some content in the p4est objects and call the
3721  // functions that do the actual work (which are dimension dependent, so
3722  // separate)
3723  triangulation_has_content = true;
3724 
3725  Assert (other_tria.n_levels() == 1,
3726  ExcMessage ("Parallel distributed triangulations can only be copied, "
3727  "if they are not refined!"));
3728 
3729  if (const ::parallel::distributed::Triangulation<dim,spacedim> *
3730  other_tria_x = dynamic_cast<const ::parallel::distributed::Triangulation<dim,spacedim> *>(&other_tria))
3731  {
3732  Assert (!other_tria_x->refinement_in_progress,
3733  ExcMessage ("Parallel distributed triangulations can only "
3734  "be copied, if no refinement is in progress!"));
3735 
3736  coarse_cell_to_p4est_tree_permutation = other_tria_x->coarse_cell_to_p4est_tree_permutation;
3737  p4est_tree_to_coarse_cell_permutation = other_tria_x->p4est_tree_to_coarse_cell_permutation;
3738  attached_data_size = other_tria_x->attached_data_size;
3739  n_attached_datas = other_tria_x->n_attached_datas;
3740 
3741  settings = other_tria_x->settings;
3742  }
3743  else
3744  {
3745  setup_coarse_cell_to_p4est_tree_permutation ();
3746  }
3747 
3748  copy_new_triangulation_to_p4est (::internal::int2type<dim>());
3749 
3750  try
3751  {
3752  copy_local_forest_to_triangulation ();
3753  }
3754  catch (const typename Triangulation<dim>::DistortedCellList &)
3755  {
3756  // the underlying triangulation should not be checking for distorted
3757  // cells
3758  Assert (false, ExcInternalError());
3759  }
3760 
3761  this->update_number_cache ();
3762  this->update_periodic_face_map();
3763  }
3764 
3765 
3766  template <int dim, int spacedim>
3767  void
3770  {
3771  // determine size of memory in bytes to attach to each cell. This needs
3772  // to be constant because of p4est.
3773  if (attached_data_size==0)
3774  {
3775  Assert(n_attached_datas==0, ExcInternalError());
3776 
3777  //nothing to do
3778  return;
3779  }
3780 
3781  // realloc user_data in p4est
3782  void *userptr = parallel_forest->user_pointer;
3784  attached_data_size+sizeof(CellStatus),
3785  NULL, NULL);
3786  parallel_forest->user_pointer = userptr;
3787 
3788 
3789  // Recurse over p4est and Triangulation
3790  // to find refined/coarsened/kept
3791  // cells. Then query and attach the data.
3793  cell = this->begin(0);
3794  cell != this->end(0);
3795  ++cell)
3796  {
3797  //skip coarse cells, that are not ours
3798  if (tree_exists_locally<dim,spacedim>(parallel_forest,
3799  coarse_cell_to_p4est_tree_permutation[cell->index()])
3800  == false)
3801  continue;
3802 
3803  typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3804  typename ::internal::p4est::types<dim>::tree *tree =
3805  init_tree(cell->index());
3806 
3807  ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3808 
3809  attach_mesh_data_recursively<dim,spacedim>(*tree,
3810  cell,
3811  p4est_coarse_cell,
3812  attached_data_pack_callbacks);
3813  }
3814  }
3815 
3816  template <int dim, int spacedim>
3817  std::vector<unsigned int>
3820  {
3821  // Allocate the space for the weights. In fact we do not know yet, how
3822  // many cells we own after the refinement (only p4est knows that
3823  // at this point). We simply reserve n_active_cells space and if many
3824  // more cells are refined than coarsened than additional reallocation
3825  // will be done inside get_cell_weights_recursively.
3826  std::vector<unsigned int> weights;
3827  weights.reserve(this->n_active_cells());
3828 
3829  // Recurse over p4est and Triangulation
3830  // to find refined/coarsened/kept
3831  // cells. Then append cell_weight.
3832  // Note that we need to follow the p4est ordering
3833  // instead of the deal.II ordering to get the cell_weights
3834  // in the same order p4est will encounter them during repartitioning.
3835  for (unsigned int c=0; c<this->n_cells(0); ++c)
3836  {
3837  // skip coarse cells, that are not ours
3838  if (tree_exists_locally<dim,spacedim>(parallel_forest,c) == false)
3839  continue;
3840 
3841  const unsigned int coarse_cell_index =
3842  p4est_tree_to_coarse_cell_permutation[c];
3843 
3845  dealii_coarse_cell (this, 0, coarse_cell_index);
3846 
3847  typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3849  quadrant_set_morton (&p4est_coarse_cell,
3850  /*level=*/0,
3851  /*index=*/0);
3852  p4est_coarse_cell.p.which_tree = c;
3853 
3854  const typename ::internal::p4est::types<dim>::tree *tree =
3855  init_tree(coarse_cell_index);
3856 
3857  get_cell_weights_recursively<dim,spacedim>(*tree,
3858  dealii_coarse_cell,
3859  p4est_coarse_cell,
3860  this->signals,
3861  weights);
3862  }
3863 
3864  return weights;
3865  }
3866 
3867 
3868 
3869  template <int spacedim>
3871  :
3872  ::parallel::Triangulation<1,spacedim>(MPI_COMM_WORLD,
3873  typename ::Triangulation<1,spacedim>::MeshSmoothing(),
3874  false)
3875  {
3876  Assert (false, ExcNotImplemented());
3877  }
3878 
3879 
3880  template <int spacedim>
3882  {
3883  Assert (false, ExcNotImplemented());
3884  }
3885 
3886 
3887 
3888  template <int spacedim>
3889  void
3891  (const std::vector<bool> &/*vertex_locally_moved*/)
3892  {
3893  Assert (false, ExcNotImplemented());
3894  }
3895 
3896 
3897  template <int spacedim>
3898  const std::vector<types::global_dof_index> &
3900  {
3901  static std::vector<types::global_dof_index> a;
3902  return a;
3903  }
3904 
3905  template <int spacedim>
3906  void
3909  (std::map<unsigned int, std::set<::types::subdomain_id> >
3910  &/*vertices_with_ghost_neighbors*/)
3911  {
3912  Assert (false, ExcNotImplemented());
3913  }
3914 
3915  template <int spacedim>
3916  void
3919  (const unsigned int /*level*/,
3920  std::map<unsigned int, std::set<::types::subdomain_id> >
3921  &/*vertices_with_ghost_neighbors*/)
3922  {
3923  Assert (false, ExcNotImplemented());
3924  }
3925 
3926  template <int spacedim>
3927  std::vector<bool>
3929  mark_locally_active_vertices_on_level (const unsigned int) const
3930  {
3931  Assert (false, ExcNotImplemented());
3932  return std::vector<bool>();
3933  }
3934  }
3935 }
3936 
3937 
3938 #else // DEAL_II_WITH_P4EST
3939 
3940 namespace parallel
3941 {
3942  namespace distributed
3943  {
3944  template <int dim, int spacedim>
3946  :
3947  ::parallel::Triangulation<dim,spacedim>(MPI_COMM_SELF)
3948  {
3949  Assert (false, ExcNotImplemented());
3950  }
3951  }
3952 }
3953 
3954 #endif // DEAL_II_WITH_P4EST
3955 
3956 
3957 
3958 
3959 /*-------------- Explicit Instantiations -------------------------------*/
3960 #include "tria.inst"
3961 
3962 
3963 DEAL_II_NAMESPACE_CLOSE
static unsigned int standard_to_real_face_vertex(const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
Definition: tria.cc:9315
unsigned int n_vertices() const
static const unsigned int invalid_unsigned_int
Definition: types.h:170
void fill_vertices_with_ghost_neighbors(std::map< unsigned int, std::set<::types::subdomain_id > > &vertices_with_ghost_neighbors)
Definition: tria.cc:3391
virtual bool has_hanging_nodes() const
Definition: tria.cc:11366
unsigned int n_cells() const
Definition: tria.cc:11237
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria)
Definition: tria_base.cc:63
static unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
boost::signals2::signal< unsigned int(const cell_iterator &, const CellStatus), CellWeightSum< unsigned int > > cell_weight
Definition: tria.h:2177
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:10668
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
callback_list_t attached_data_pack_callbacks
Definition: tria.h:791
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:10648
const std::vector< types::global_dof_index > & get_p4est_tree_to_coarse_cell_permutation() const
Definition: tria.cc:3368
unsigned int n_levels() const
void fill_level_vertices_with_ghost_neighbors(const int level, std::map< unsigned int, std::set<::types::subdomain_id > > &vertices_with_ghost_neighbors)
Definition: tria.cc:3418
void get_vertex_connectivity_of_cells(const Triangulation< dim, spacedim > &triangulation, DynamicSparsityPattern &connectivity)
Definition: grid_tools.cc:2030
cell_iterator end() const
Definition: tria.cc:10736
virtual void execute_coarsening_and_refinement()
Definition: tria.cc:11899
unsigned int n_active_lines() const
Definition: tria.cc:11459
virtual bool prepare_coarsening_and_refinement()
Definition: tria.cc:12592
static ::ExceptionBase & ExcMessage(std::string arg1)
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
Definition: tria.cc:8948
T sum(const T &t, const MPI_Comm &mpi_communicator)
#define Assert(cond, exc)
Definition: exceptions.h:313
virtual void update_number_cache()
Definition: tria_base.cc:154
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void load(Archive &ar, const unsigned int version)
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
Definition: tria.cc:9401
void save_coarsen_flags(std::ostream &out) const
Definition: tria.cc:9706
const std::vector< Point< spacedim > > & get_vertices() const
virtual std::size_t memory_consumption() const
Definition: tria_base.cc:88
void save_refine_flags(std::ostream &out) const
Definition: tria.cc:9641
virtual ~Triangulation()
Definition: tria.cc:9050
virtual std::size_t memory_consumption() const
Definition: tria.cc:13555
void save(Archive &ar, const unsigned int version) const
std::vector< unsigned int > invert_permutation(const std::vector< unsigned int > &permutation)
Definition: utilities.cc:486
unsigned int subdomain_id
Definition: types.h:42
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
Definition: mpi.cc:63
::Triangulation< dim, spacedim >::active_cell_iterator active_cell_iterator
Definition: tria.h:285
void reorder_hierarchical(const DynamicSparsityPattern &sparsity, std::vector< DynamicSparsityPattern::size_type > &new_indices)
const types::subdomain_id artificial_subdomain_id
Definition: types.h:261
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void communicate_locally_moved_vertices(const std::vector< bool > &vertex_locally_moved)
Definition: tria.cc:3120
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1211
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator > > &)
Definition: tria.cc:11874
const std::vector< bool > & get_used_vertices() const
Definition: tria.cc:11782
::Triangulation< dim, spacedim >::cell_iterator cell_iterator
Definition: tria.h:265
static ::ExceptionBase & ExcNotImplemented()
std::vector< bool > get_locally_owned_vertices(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2172
active_cell_iterator last_active() const
Definition: tria.cc:10715
Triangulation(MPI_Comm mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const Settings settings=default_setting)
Definition: tria.cc:1279
std::vector< unsigned int > compute_point_to_point_communication_pattern(const MPI_Comm &mpi_comm, const std::vector< unsigned int > &destinations)
Definition: mpi.cc:93
void clear()
Definition: tensor.h:1072
std::vector< bool > mark_locally_active_vertices_on_level(const int level) const
Definition: tria.cc:3474
T max(const T &t, const MPI_Comm &mpi_communicator)
virtual void clear()
Definition: tria.cc:9080
const std::map< std::pair< cell_iterator, unsigned int >, std::pair< std::pair< cell_iterator, unsigned int >, std::bitset< 3 > > > & get_periodic_face_map() const
Definition: tria.cc:11890
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcInternalError()