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