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> 28 #ifdef DEAL_II_WITH_P4EST 29 # include <p4est_bits.h> 30 # include <p4est_extended.h> 31 # include <p4est_vtk.h> 32 # include <p4est_ghost.h> 33 # include <p4est_communication.h> 34 # include <p4est_iterate.h> 36 # include <p8est_bits.h> 37 # include <p8est_extended.h> 38 # include <p8est_vtk.h> 39 # include <p8est_ghost.h> 40 # include <p8est_communication.h> 41 # include <p8est_iterate.h> 50 DEAL_II_NAMESPACE_OPEN
53 #ifdef DEAL_II_WITH_P4EST 71 int (&quadrant_compare) (
const void *v1,
const void *v2);
125 void (&connectivity_destroy) (p4est_connectivity_t *connectivity);
134 p4est_init_t init_fn,
142 int refine_recursive,
143 p4est_refine_t refine_fn,
144 p4est_init_t init_fn);
148 int coarsen_recursive,
149 p4est_coarsen_t coarsen_fn,
150 p4est_init_t init_fn);
155 p4est_init_t init_fn);
157 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 160 int partition_for_coarsening,
161 p4est_weight_t weight_fn);
165 int partition_for_coarsening,
166 p4est_weight_t weight_fn);
170 void (&save) (
const char *filename,
174 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 194 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 196 int (&connectivity_save) (
const char *filename,
200 void (&connectivity_save) (
const char *filename,
207 #if DEAL_II_P4EST_VERSION_GTE(1,0,0,0) 211 #elif DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 214 long unsigned *length);
227 const char *baseName);
239 p4est_init_t init_fn,
248 static const unsigned max_level;
252 = p4est_quadrant_compare;
256 = p4est_quadrant_childrenv;
260 = p4est_quadrant_overlaps_tree;
265 = p4est_quadrant_set_morton;
269 = p4est_quadrant_is_equal;
273 = p4est_quadrant_is_sibling;
277 = p4est_quadrant_is_ancestor;
281 = p4est_quadrant_ancestor_id;
287 = p4est_comm_find_owner;
293 = p4est_connectivity_new;
295 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,1) 302 = p4est_connectivity_join_faces;
306 = p4est_connectivity_destroy;
314 p4est_init_t init_fn,
322 int refine_recursive,
323 p4est_refine_t refine_fn,
324 p4est_init_t init_fn)
328 int coarsen_recursive,
329 p4est_coarsen_t coarsen_fn,
330 p4est_init_t init_fn)
335 p4est_init_t init_fn)
338 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 340 int partition_for_coarsening,
341 p4est_weight_t weight_fn)
342 = p4est_partition_ext;
345 int partition_for_coarsening,
346 p4est_weight_t weight_fn)
347 = p4est_partition_ext;
355 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 359 std::size_t data_size,
370 std::size_t data_size,
377 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 380 = p4est_connectivity_save;
384 = p4est_connectivity_save;
389 = p4est_connectivity_is_valid;
391 #if DEAL_II_P4EST_VERSION_GTE(1,0,0,0) 395 = p4est_connectivity_load;
396 #elif DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 399 long unsigned *length)
400 = p4est_connectivity_load;
405 = p4est_connectivity_load;
413 const char *baseName)
414 = p4est_vtk_write_file;
421 = p4est_ghost_destroy;
425 p4est_init_t init_fn,
433 = p4est_connectivity_memory_used;
440 int (&quadrant_compare) (
const void *v1,
const void *v2);
494 void (&connectivity_destroy) (p8est_connectivity_t *connectivity);
503 p8est_init_t init_fn,
511 int refine_recursive,
512 p8est_refine_t refine_fn,
513 p8est_init_t init_fn);
517 int coarsen_recursive,
518 p8est_coarsen_t coarsen_fn,
519 p8est_init_t init_fn);
524 p8est_init_t init_fn);
526 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 529 int partition_for_coarsening,
530 p8est_weight_t weight_fn);
534 int partition_for_coarsening,
535 p8est_weight_t weight_fn);
539 void (&save) (
const char *filename,
543 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 547 std::size_t data_size,
557 std::size_t data_size,
563 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 565 int (&connectivity_save) (
const char *filename,
569 void (&connectivity_save) (
const char *filename,
576 #if DEAL_II_P4EST_VERSION_GTE(1,0,0,0) 580 #elif DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 583 long unsigned *length);
596 const char *baseName);
608 p8est_init_t init_fn,
617 static const unsigned max_level;
622 = p8est_quadrant_compare;
626 = p8est_quadrant_childrenv;
630 = p8est_quadrant_overlaps_tree;
635 = p8est_quadrant_set_morton;
639 = p8est_quadrant_is_equal;
643 = p8est_quadrant_is_sibling;
647 = p8est_quadrant_is_ancestor;
651 = p8est_quadrant_ancestor_id;
657 = p8est_comm_find_owner;
665 = p8est_connectivity_new;
668 = p8est_connectivity_destroy;
670 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,1) 677 = p8est_connectivity_join_faces;
686 p8est_init_t init_fn,
694 int refine_recursive,
695 p8est_refine_t refine_fn,
696 p8est_init_t init_fn)
700 int coarsen_recursive,
701 p8est_coarsen_t coarsen_fn,
702 p8est_init_t init_fn)
707 p8est_init_t init_fn)
710 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 712 int partition_for_coarsening,
713 p8est_weight_t weight_fn)
714 = p8est_partition_ext;
717 int partition_for_coarsening,
718 p8est_weight_t weight_fn)
719 = p8est_partition_ext;
727 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 731 std::size_t data_size,
742 std::size_t data_size,
749 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 752 = p8est_connectivity_save;
756 = p8est_connectivity_save;
761 = p8est_connectivity_is_valid;
763 #if DEAL_II_P4EST_VERSION_GTE(1,0,0,0) 767 = p8est_connectivity_load;
768 #elif DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 771 long unsigned *length)
772 = p8est_connectivity_load;
777 = p8est_connectivity_load;
785 const char *baseName)
786 = p8est_vtk_write_file;
793 = p8est_ghost_destroy;
797 p8est_init_t init_fn,
805 = p8est_connectivity_memory_used;
812 init_quadrant_children
817 for (
unsigned int c=0;
818 c<GeometryInfo<dim>::max_children_per_cell; ++c)
822 P4EST_QUADRANT_INIT(&p4est_children[c]);
825 P8EST_QUADRANT_INIT(&p4est_children[c]);
828 Assert (
false, ExcNotImplemented());
845 P4EST_QUADRANT_INIT(&quad);
848 P8EST_QUADRANT_INIT(&quad);
851 Assert (
false, ExcNotImplemented());
882 template <
int dim>
struct iter;
884 template <>
struct iter<2>
886 typedef p4est_iter_corner_info_t corner_info;
887 typedef p4est_iter_corner_side_t corner_side;
888 typedef p4est_iter_corner_t corner_iter;
889 typedef p4est_iter_face_info_t face_info;
890 typedef p4est_iter_face_side_t face_side;
891 typedef p4est_iter_face_t face_iter;
894 template <>
struct iter<3>
896 typedef p8est_iter_corner_info_t corner_info;
897 typedef p8est_iter_corner_side_t corner_side;
898 typedef p8est_iter_corner_t corner_iter;
899 typedef p8est_iter_edge_info_t edge_info;
900 typedef p8est_iter_edge_side_t edge_side;
901 typedef p8est_iter_edge_t edge_iter;
902 typedef p8est_iter_face_info_t face_info;
903 typedef p8est_iter_face_side_t face_side;
904 typedef p8est_iter_face_t face_iter;
913 template <
int dim,
int spacedim>
916 std::vector<unsigned int> &vertex_touch_count,
917 std::vector<std::list<
921 vertex_touch_count.resize (triangulation.
n_vertices());
922 vertex_to_cell.resize (triangulation.
n_vertices());
926 cell != triangulation.
end(); ++cell)
927 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
929 ++vertex_touch_count[cell->vertex_index(v)];
930 vertex_to_cell[cell->vertex_index(v)]
931 .push_back (std::make_pair (cell, v));
937 template <
int dim,
int spacedim>
940 std::vector<unsigned int> &edge_touch_count,
941 std::vector<std::list<
952 cell != triangulation.
end(); ++cell)
953 for (
unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
955 ++edge_touch_count[cell->line(l)->index()];
956 edge_to_cell[cell->line(l)->index()]
957 .push_back (std::make_pair (cell, l));
967 template <
int dim,
int spacedim>
970 const std::vector<unsigned int> &vertex_touch_count,
971 const std::vector<std::list<
974 const std::vector<types::global_dof_index> &coarse_cell_to_p4est_tree_permutation,
975 const bool set_vertex_info,
992 if (set_vertex_info ==
true)
993 for (
unsigned int v=0; v<triangulation.
n_vertices(); ++v)
995 connectivity->vertices[3*v ] = triangulation.
get_vertices()[v][0];
996 connectivity->vertices[3*v+1] = triangulation.
get_vertices()[v][1];
997 connectivity->vertices[3*v+2] = (spacedim == 2 ?
1010 endc = triangulation.
end();
1011 for (; cell != endc; ++cell)
1014 index = coarse_cell_to_p4est_tree_permutation[cell->index()];
1016 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
1018 if (set_vertex_info ==
true)
1025 for (
unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
1026 if (cell->face(f)->at_boundary() ==
false)
1028 = coarse_cell_to_p4est_tree_permutation[cell->neighbor(f)->index()];
1031 = coarse_cell_to_p4est_tree_permutation[cell->index()];
1035 for (
unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
1036 if (cell->face(f)->at_boundary() ==
false)
1043 = cell->neighbor_of_neighbor (f);
1062 connectivity->tree_to_face[index*6 + f]
1063 = cell->neighbor_of_neighbor (f);
1065 unsigned int face_idx_list[2] =
1066 {f, cell->neighbor_of_neighbor (f)};
1068 cell_list[2] = {cell, cell->neighbor(f)};
1069 unsigned int smaller_idx = 0;
1071 if (f>cell->neighbor_of_neighbor (f))
1074 unsigned int larger_idx = (smaller_idx+1) % 2;
1082 unsigned int g_idx =
1083 cell_list[smaller_idx]->vertex_index(
1085 face_idx_list[smaller_idx],
1087 cell_list[smaller_idx]->face_orientation(face_idx_list[smaller_idx]),
1088 cell_list[smaller_idx]->face_flip(face_idx_list[smaller_idx]),
1089 cell_list[smaller_idx]->face_rotation(face_idx_list[smaller_idx]))
1094 for (
unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
1098 cell_list[larger_idx]->vertex_index(
1100 face_idx_list[larger_idx],
1111 connectivity->tree_to_face[index*6 + f] += 6*v;
1116 Assert (
false, ExcNotImplemented());
1124 connectivity->ctt_offset[0] = 0;
1125 std::partial_sum (vertex_touch_count.begin(),
1126 vertex_touch_count.end(),
1127 &connectivity->ctt_offset[1]);
1130 num_vtt = std::accumulate (vertex_touch_count.begin(),
1131 vertex_touch_count.end(),
1136 ExcInternalError());
1138 for (
unsigned int v=0; v<triangulation.
n_vertices(); ++v)
1140 Assert (vertex_to_cell[v].size() == vertex_touch_count[v],
1141 ExcInternalError());
1143 typename std::list<std::pair
1145 unsigned int> >::const_iterator
1146 p = vertex_to_cell[v].begin();
1147 for (
unsigned int c=0; c<vertex_touch_count[v]; ++c, ++p)
1149 connectivity->corner_to_tree[connectivity->ctt_offset[v]+c]
1150 = coarse_cell_to_p4est_tree_permutation[p->first->index()];
1151 connectivity->corner_to_corner[connectivity->ctt_offset[v]+c]
1159 template <
int dim,
int spacedim>
1164 Assert (coarse_grid_cell < parallel_forest->connectivity->num_trees,
1165 ExcInternalError());
1166 return ((coarse_grid_cell >= parallel_forest->first_local_tree)
1168 (coarse_grid_cell <= parallel_forest->last_local_tree));
1172 template <
int dim,
int spacedim>
1176 if (cell->has_children())
1177 for (
unsigned int c=0; c<cell->n_children(); ++c)
1178 delete_all_children_and_self<dim,spacedim> (cell->child(c));
1180 cell->set_coarsen_flag ();
1185 template <
int dim,
int spacedim>
1189 if (cell->has_children())
1190 for (
unsigned int c=0; c<cell->n_children(); ++c)
1191 delete_all_children_and_self<dim,spacedim> (cell->child(c));
1195 template <
int dim,
int spacedim>
1203 const std::vector<std::vector<bool> > &marked_vertices)
1210 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
1212 if (marked_vertices[dealii_cell->level()][dealii_cell->vertex_index(v)])
1225 Assert((owner!=-2) && (owner!=-1),
ExcMessage(
"p4est should know the owner."));
1226 dealii_cell->set_level_subdomain_id(owner);
1231 if (dealii_cell->has_children ())
1234 p4est_child[GeometryInfo<dim>::max_children_per_cell];
1235 for (
unsigned int c=0;
1236 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1240 P4EST_QUADRANT_INIT(&p4est_child[c]);
1243 P8EST_QUADRANT_INIT(&p4est_child[c]);
1246 Assert (
false, ExcNotImplemented());
1254 for (
unsigned int c=0;
1255 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1257 determine_level_subdomain_id_recursively <dim,spacedim> (tree,tree_index,
1258 dealii_cell->child(c),
1268 template <
int dim,
int spacedim>
1277 if (sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
1283 delete_all_children<dim,spacedim> (dealii_cell);
1284 if (!dealii_cell->has_children())
1285 dealii_cell->set_subdomain_id(my_subdomain);
1294 if (dealii_cell->has_children () ==
false)
1295 dealii_cell->set_refine_flag ();
1299 p4est_child[GeometryInfo<dim>::max_children_per_cell];
1300 for (
unsigned int c=0;
1301 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1305 P4EST_QUADRANT_INIT(&p4est_child[c]);
1308 P8EST_QUADRANT_INIT(&p4est_child[c]);
1311 Assert (
false, ExcNotImplemented());
1319 for (
unsigned int c=0;
1320 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1330 delete_all_children<dim,spacedim> (dealii_cell->child(c));
1331 dealii_cell->child(c)
1338 match_tree_recursively<dim,spacedim> (tree,
1339 dealii_cell->child(c),
1349 template <
int dim,
int spacedim>
1351 match_quadrant (const ::Triangulation<dim,spacedim> *tria,
1352 unsigned int dealii_index,
1354 unsigned int ghost_owner)
1357 int l = ghost_quadrant.level;
1359 for (i = 0; i < l; i++)
1362 if (cell->has_children () ==
false)
1364 cell->clear_coarsen_flag();
1365 cell->set_refine_flag ();
1370 dealii_index = cell->child_index(child_id);
1374 if (cell->has_children())
1375 delete_all_children<dim,spacedim> (cell);
1378 cell->clear_coarsen_flag();
1379 cell->set_subdomain_id(ghost_owner);
1385 template <
int dim,
int spacedim>
1390 const typename std::list<std::pair<
unsigned int,
typename std_cxx11::function<
1392 typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
1394 > > > &attached_data_pack_callbacks)
1396 typedef std::list<std::pair<
unsigned int,
typename std_cxx11::function<
1398 typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
1400 > > > callback_list_t;
1402 int idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
1412 bool p4est_has_children = (idx == -1);
1414 if (p4est_has_children && dealii_cell->has_children())
1418 p4est_child[GeometryInfo<dim>::max_children_per_cell];
1419 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1423 P4EST_QUADRANT_INIT(&p4est_child[c]);
1426 P8EST_QUADRANT_INIT(&p4est_child[c]);
1429 Assert (
false, ExcNotImplemented());
1435 for (
unsigned int c=0;
1436 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1438 attach_mesh_data_recursively<dim,spacedim> (tree,
1439 dealii_cell->child(c),
1441 attached_data_pack_callbacks);
1444 else if (!p4est_has_children && !dealii_cell->has_children())
1449 sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), idx)
1453 for (
typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
1454 it != attached_data_pack_callbacks.end();
1457 void *ptr =
static_cast<char *
>(q->p.user_data) + (*it).first;
1458 ((*it).second)(dealii_cell,
1463 else if (p4est_has_children)
1470 p4est_child[GeometryInfo<dim>::max_children_per_cell];
1471 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1475 P4EST_QUADRANT_INIT(&p4est_child[c]);
1478 P8EST_QUADRANT_INIT(&p4est_child[c]);
1481 Assert (
false, ExcNotImplemented());
1486 int child0_idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
1489 Assert(child0_idx != -1,
ExcMessage(
"the first child should exist as an active quadrant!"));
1493 sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), child0_idx)
1497 for (
typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
1498 it != attached_data_pack_callbacks.end();
1501 void *ptr =
static_cast<char *
>(q->p.user_data) + (*it).first;
1503 ((*it).second)(dealii_cell,
1509 for (
unsigned int i=1; i<GeometryInfo<dim>::max_children_per_cell; ++i)
1511 int child_idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
1515 sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), child_idx)
1527 sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), idx)
1531 for (
typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
1532 it != attached_data_pack_callbacks.end();
1535 void *ptr =
static_cast<char *
>(q->p.user_data) + (*it).first;
1536 ((*it).second)(dealii_cell,
1543 template <
int dim,
int spacedim>
1549 std::vector<unsigned int> &weight)
1551 const int idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
1561 const bool p4est_has_children = (idx == -1);
1563 if (p4est_has_children && dealii_cell->has_children())
1567 p4est_child[GeometryInfo<dim>::max_children_per_cell];
1568 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1572 P4EST_QUADRANT_INIT(&p4est_child[c]);
1575 P8EST_QUADRANT_INIT(&p4est_child[c]);
1578 Assert (
false, ExcNotImplemented());
1584 for (
unsigned int c=0;
1585 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1587 get_cell_weights_recursively<dim,spacedim> (tree,
1588 dealii_cell->child(c),
1594 else if (!p4est_has_children && !dealii_cell->has_children())
1597 weight.push_back(1000);
1601 else if (p4est_has_children)
1604 unsigned int parent_weight(1000);
1608 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1611 weight.push_back(parent_weight);
1617 weight.push_back(1000);
1624 template <
int dim,
int spacedim>
1630 const unsigned int offset,
1631 const typename std_cxx11::function<
1635 int idx = sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
1646 const bool p4est_has_children = (idx == -1);
1647 if (p4est_has_children)
1649 Assert(dealii_cell->has_children(), ExcInternalError());
1653 p4est_child[GeometryInfo<dim>::max_children_per_cell];
1654 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1658 P4EST_QUADRANT_INIT(&p4est_child[c]);
1661 P8EST_QUADRANT_INIT(&p4est_child[c]);
1664 Assert (
false, ExcNotImplemented());
1670 for (
unsigned int c=0;
1671 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1673 post_mesh_data_recursively<dim,spacedim> (tree,
1674 dealii_cell->child(c),
1683 Assert(! dealii_cell->has_children(), ExcInternalError());
1687 sc_array_index (const_cast<sc_array_t *>(&tree.quadrants), idx)
1690 void *ptr =
static_cast<char *
>(q->p.user_data) + offset;
1691 typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus
1692 status = *
static_cast< 1693 typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus *
1699 unpack_callback(dealii_cell, status, ptr);
1704 unpack_callback(parent_cell, status, ptr);
1709 unpack_callback(dealii_cell, status, ptr);
1729 template <
int dim,
int spacedim>
1730 class RefineAndCoarsenList
1734 const std::vector<types::global_dof_index> &p4est_tree_to_coarse_cell_permutation,
1761 bool pointers_are_at_end ()
const;
1764 std::vector<typename internal::p4est::types<dim>::quadrant> refine_list;
1765 typename std::vector<typename internal::p4est::types<dim>::quadrant>::const_iterator current_refine_pointer;
1767 std::vector<typename internal::p4est::types<dim>::quadrant> coarsen_list;
1768 typename std::vector<typename internal::p4est::types<dim>::quadrant>::const_iterator current_coarsen_pointer;
1772 const unsigned int myid);
1777 template <
int dim,
int spacedim>
1779 RefineAndCoarsenList<dim,spacedim>::
1780 pointers_are_at_end ()
const 1782 return ((current_refine_pointer == refine_list.end())
1784 (current_coarsen_pointer == coarsen_list.end()));
1789 template <
int dim,
int spacedim>
1790 RefineAndCoarsenList<dim,spacedim>::
1792 const std::vector<types::global_dof_index> &p4est_tree_to_coarse_cell_permutation,
1796 unsigned int n_refine_flags = 0,
1797 n_coarsen_flags = 0;
1798 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
1800 cell != triangulation.
end(); ++cell)
1803 if (cell->subdomain_id() != my_subdomain)
1806 if (cell->refine_flag_set())
1808 else if (cell->coarsen_flag_set())
1812 refine_list.reserve (n_refine_flags);
1813 coarsen_list.reserve (n_coarsen_flags);
1823 for (
unsigned int c=0; c<triangulation.
n_cells(0); ++c)
1825 unsigned int coarse_cell_index =
1826 p4est_tree_to_coarse_cell_permutation[c];
1829 cell (&triangulation, 0, coarse_cell_index);
1836 p4est_cell.p.which_tree = c;
1837 build_lists (cell, p4est_cell, my_subdomain);
1841 Assert(refine_list.size() == n_refine_flags,
1842 ExcInternalError());
1843 Assert(coarsen_list.size() == n_coarsen_flags,
1844 ExcInternalError());
1847 for (
unsigned int i=1; i<refine_list.size(); ++i)
1848 Assert (refine_list[i].p.which_tree >=
1849 refine_list[i-1].p.which_tree,
1850 ExcInternalError());
1851 for (
unsigned int i=1; i<coarsen_list.size(); ++i)
1852 Assert (coarsen_list[i].p.which_tree >=
1853 coarsen_list[i-1].p.which_tree,
1854 ExcInternalError());
1856 current_refine_pointer = refine_list.begin();
1857 current_coarsen_pointer = coarsen_list.begin();
1862 template <
int dim,
int spacedim>
1864 RefineAndCoarsenList<dim,spacedim>::
1869 if (!cell->has_children())
1871 if (cell->subdomain_id() == my_subdomain)
1873 if (cell->refine_flag_set())
1874 refine_list.push_back (p4est_cell);
1875 else if (cell->coarsen_flag_set())
1876 coarsen_list.push_back (p4est_cell);
1882 p4est_child[GeometryInfo<dim>::max_children_per_cell];
1883 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
1887 P4EST_QUADRANT_INIT(&p4est_child[c]);
1890 P8EST_QUADRANT_INIT(&p4est_child[c]);
1893 Assert (
false, ExcNotImplemented());
1898 for (
unsigned int c=0;
1899 c<GeometryInfo<dim>::max_children_per_cell; ++c)
1901 p4est_child[c].p.which_tree = p4est_cell.p.which_tree;
1902 build_lists (cell->child(c),
1910 template <
int dim,
int spacedim>
1912 RefineAndCoarsenList<dim,spacedim>::
1917 RefineAndCoarsenList<dim,spacedim> *this_object
1918 =
reinterpret_cast<RefineAndCoarsenList<dim,spacedim>*
>(forest->user_pointer);
1922 if (this_object->current_refine_pointer == this_object->refine_list.end())
1925 Assert (coarse_cell_index <=
1926 this_object->current_refine_pointer->p.which_tree,
1927 ExcInternalError());
1931 if (coarse_cell_index <
1932 this_object->current_refine_pointer->p.which_tree)
1936 Assert (coarse_cell_index <=
1937 this_object->current_refine_pointer->p.which_tree,
1938 ExcInternalError());
1943 quadrant_compare (quadrant,
1944 &*this_object->current_refine_pointer) <= 0,
1945 ExcInternalError());
1949 quadrant_is_equal (quadrant, &*this_object->current_refine_pointer))
1951 ++this_object->current_refine_pointer;
1961 template <
int dim,
int spacedim>
1963 RefineAndCoarsenList<dim,spacedim>::
1968 RefineAndCoarsenList<dim,spacedim> *this_object
1969 =
reinterpret_cast<RefineAndCoarsenList<dim,spacedim>*
>(forest->user_pointer);
1973 if (this_object->current_coarsen_pointer ==
1974 this_object->coarsen_list.end())
1977 Assert (coarse_cell_index <=
1978 this_object->current_coarsen_pointer->p.which_tree,
1979 ExcInternalError());
1983 if (coarse_cell_index <
1984 this_object->current_coarsen_pointer->p.which_tree)
1988 Assert (coarse_cell_index <=
1989 this_object->current_coarsen_pointer->p.which_tree,
1990 ExcInternalError());
1995 quadrant_compare (children[0],
1996 &*this_object->current_coarsen_pointer) <= 0,
1997 ExcInternalError());
2002 quadrant_is_equal (children[0],
2003 &*this_object->current_coarsen_pointer))
2006 ++this_object->current_coarsen_pointer;
2010 for (
unsigned int c=1; c<GeometryInfo<dim>::max_children_per_cell; ++c)
2013 quadrant_is_equal (children[c],
2014 &*this_object->current_coarsen_pointer),
2015 ExcInternalError());
2016 ++this_object->current_coarsen_pointer;
2034 template <
int dim,
int spacedim>
2035 class PartitionWeights
2043 PartitionWeights (
const std::vector<unsigned int> &cell_weights);
2059 std::vector<unsigned int> cell_weights_list;
2060 std::vector<unsigned int>::const_iterator current_pointer;
2064 template <
int dim,
int spacedim>
2065 PartitionWeights<dim,spacedim>::
2066 PartitionWeights (
const std::vector<unsigned int> &cell_weights)
2068 cell_weights_list(cell_weights)
2072 current_pointer = cell_weights_list.begin();
2076 template <
int dim,
int spacedim>
2078 PartitionWeights<dim,spacedim>::
2087 PartitionWeights<dim,spacedim> *this_object
2088 =
reinterpret_cast<PartitionWeights<dim,spacedim>*
>(forest->user_pointer);
2090 Assert (this_object->current_pointer >= this_object->cell_weights_list.begin(),
2091 ExcInternalError());
2092 Assert (this_object->current_pointer < this_object->cell_weights_list.end(),
2093 ExcInternalError());
2096 return *this_object->current_pointer++;
2103 namespace distributed
2109 template <
int dim,
int spacedim>
2112 const typename ::Triangulation<dim,spacedim>::MeshSmoothing smooth_grid,
2120 settings(settings_),
2121 triangulation_has_content (false),
2123 parallel_forest (0),
2124 refinement_in_progress (false),
2125 attached_data_size(0),
2126 n_attached_datas(0),
2127 n_attached_deserialize(0)
2134 template <
int dim,
int spacedim>
2140 ExcInternalError());
2141 Assert (connectivity == 0, ExcInternalError());
2142 Assert (parallel_forest == 0, ExcInternalError());
2149 template <
int dim,
int spacedim>
2161 catch (
const typename ::Triangulation<dim,spacedim>::DistortedCellList &)
2194 namespace CommunicateLocallyMovedVertices
2203 template <
int dim,
int spacedim>
2207 std::vector<unsigned int> tree_index;
2209 std::vector<typename ::internal::p4est::types<dim>::quadrant> quadrants;
2212 std::vector<unsigned int> vertex_indices;
2215 std::vector<::Point<spacedim> >
vertices;
2219 std::vector<unsigned int * > first_vertex_indices;
2220 std::vector<::Point<spacedim>* > first_vertices;
2222 unsigned int bytes_for_buffer ()
const 2224 return (
sizeof(
unsigned int) +
2225 tree_index.size() *
sizeof(
unsigned int) +
2226 quadrants.size() *
sizeof(typename ::internal::p4est
2227 ::types<dim>::quadrant) +
2229 vertex_indices.size() *
sizeof(
unsigned int);
2232 void pack_data (std::vector<char> &buffer)
const 2234 buffer.resize(bytes_for_buffer());
2236 char *ptr = &buffer[0];
2238 const unsigned int num_cells = tree_index.size();
2239 std::memcpy(ptr, &num_cells,
sizeof(
unsigned int));
2240 ptr +=
sizeof(
unsigned int);
2244 num_cells*
sizeof(
unsigned int));
2245 ptr += num_cells*
sizeof(
unsigned int);
2249 num_cells *
sizeof(typename ::internal::p4est::
2250 types<dim>::quadrant));
2251 ptr += num_cells*
sizeof(typename ::internal::p4est::types<dim>::
2256 vertex_indices.size() *
sizeof(
unsigned int));
2257 ptr += vertex_indices.size() *
sizeof(
unsigned int);
2264 Assert (ptr == &buffer[0]+buffer.size(),
2265 ExcInternalError());
2269 void unpack_data (
const std::vector<char> &buffer)
2271 const char *ptr = &buffer[0];
2273 memcpy(&cells, ptr,
sizeof(
unsigned int));
2274 ptr +=
sizeof(
unsigned int);
2276 tree_index.resize(cells);
2277 memcpy(&tree_index[0],ptr,
sizeof(
unsigned int)*cells);
2278 ptr +=
sizeof(
unsigned int)*cells;
2280 quadrants.resize(cells);
2281 memcpy(&quadrants[0],ptr,
2282 sizeof(typename ::internal::p4est::types<dim>::quadrant)*cells);
2283 ptr +=
sizeof(typename ::internal::p4est::types<dim>::quadrant)*cells;
2285 vertex_indices.clear();
2286 first_vertex_indices.resize(cells);
2287 std::vector<unsigned int> n_vertices_on_cell(cells);
2288 std::vector<unsigned int> first_indices (cells);
2289 for (
unsigned int c=0; c<cells; ++c)
2294 const unsigned int *
const vertex_index
2295 =
reinterpret_cast<const unsigned int *const
>(ptr);
2296 first_indices[c] = vertex_indices.size();
2297 vertex_indices.push_back(*vertex_index);
2298 n_vertices_on_cell[c] = *vertex_index;
2299 ptr +=
sizeof(
unsigned int);
2301 vertex_indices.resize(vertex_indices.size() + n_vertices_on_cell[c]);
2302 memcpy(&vertex_indices[vertex_indices.size() - n_vertices_on_cell[c]],
2303 ptr, n_vertices_on_cell[c]*
sizeof(
unsigned int));
2304 ptr += n_vertices_on_cell[c]*
sizeof(
unsigned int);
2306 for (
unsigned int c=0; c<cells; ++c)
2307 first_vertex_indices[c] = &vertex_indices[first_indices[c]];
2310 first_vertices.resize(cells);
2311 for (
unsigned int c=0; c<cells; ++c)
2314 const ::Point<spacedim> *
const vertex
2315 =
reinterpret_cast<const ::Point<spacedim> * const
>(ptr);
2316 first_indices[c] = vertices.size();
2317 vertices.push_back(*vertex);
2319 vertices.resize(vertices.size() + n_vertices_on_cell[c]-1);
2320 memcpy(&vertices[vertices.size() - (n_vertices_on_cell[c]-1)],
2324 for (
unsigned int c=0; c<cells; ++c)
2325 first_vertices[c] = &vertices[first_indices[c]];
2327 Assert (ptr == &buffer[0]+buffer.size(),
2328 ExcInternalError());
2346 template <
int dim,
int spacedim>
2349 const unsigned int tree_index,
2351 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell,
2352 const std::map<
unsigned int, std::set<::types::subdomain_id> > &vertices_with_ghost_neighbors,
2353 const std::vector<bool> &vertex_locally_moved,
2358 if (dealii_cell->has_children())
2360 typename ::internal::p4est::types<dim>::quadrant
2361 p4est_child[GeometryInfo<dim>::max_children_per_cell];
2362 ::internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
2365 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
2366 fill_vertices_recursively<dim,spacedim>(tria,
2368 dealii_cell->child(c),
2370 vertices_with_ghost_neighbors,
2371 vertex_locally_moved,
2383 if (dealii_cell->is_locally_owned())
2385 std::set<::types::subdomain_id> send_to;
2386 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
2388 const std::map<unsigned int, std::set<::types::subdomain_id> >::const_iterator
2389 neighbor_subdomains_of_vertex
2390 = vertices_with_ghost_neighbors.find (dealii_cell->vertex_index(v));
2392 if (neighbor_subdomains_of_vertex
2393 != vertices_with_ghost_neighbors.end())
2395 Assert(neighbor_subdomains_of_vertex->second.size()!=0,
2396 ExcInternalError());
2397 send_to.insert(neighbor_subdomains_of_vertex->second.begin(),
2398 neighbor_subdomains_of_vertex->second.end());
2402 if (send_to.size() > 0)
2404 std::vector<unsigned int> vertex_indices;
2405 std::vector<::Point<spacedim> > local_vertices;
2406 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
2407 if (vertex_locally_moved[dealii_cell->vertex_index(v)])
2409 vertex_indices.push_back(v);
2410 local_vertices.push_back(dealii_cell->vertex(v));
2413 if (vertex_indices.size()>0)
2414 for (std::set<::types::subdomain_id>::iterator it=send_to.begin();
2415 it!=send_to.end(); ++it)
2417 const ::types::subdomain_id subdomain = *it;
2421 const typename std::map<::types::subdomain_id, CellInfo<dim, spacedim> >::iterator
2423 = needs_to_get_cell.insert (std::make_pair(subdomain,
2424 CellInfo<dim,spacedim>()))
2427 p->second.tree_index.push_back(tree_index);
2428 p->second.quadrants.push_back(p4est_cell);
2430 p->second.vertex_indices.push_back(vertex_indices.size());
2431 p->second.vertex_indices.insert(p->second.vertex_indices.end(),
2432 vertex_indices.begin(),
2433 vertex_indices.end());
2435 p->second.vertices.insert(p->second.vertices.end(),
2436 local_vertices.begin(),
2437 local_vertices.end());
2454 template <
int dim,
int spacedim>
2456 set_vertices_recursively (
2458 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell,
2460 const typename ::internal::p4est::types<dim>::quadrant &quadrant,
2461 const ::Point<spacedim> *
const vertices,
2462 const unsigned int *
const vertex_indices)
2464 if (::internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
2466 Assert(!dealii_cell->is_artificial(), ExcInternalError());
2467 Assert(!dealii_cell->has_children(), ExcInternalError());
2468 Assert(!dealii_cell->is_locally_owned(), ExcInternalError());
2470 const unsigned int n_vertices = vertex_indices[0];
2474 dealii_cell->vertex(vertex_indices[i+1]) = vertices[i];
2479 if (! dealii_cell->has_children())
2482 if (! ::internal::p4est::quadrant_is_ancestor<dim> (p4est_cell, quadrant))
2485 typename ::internal::p4est::types<dim>::quadrant
2486 p4est_child[GeometryInfo<dim>::max_children_per_cell];
2487 ::internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
2489 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
2490 set_vertices_recursively<dim,spacedim> (tria, p4est_child[c],
2491 dealii_cell->child(c),
2500 template <
int dim,
int spacedim>
2512 if (parallel_forest != 0)
2515 parallel_forest = 0;
2518 if (connectivity != 0)
2524 coarse_cell_to_p4est_tree_permutation.resize (0);
2525 p4est_tree_to_coarse_cell_permutation.resize (0);
2534 template <
int dim,
int spacedim>
2547 bool have_coarser_cell =
false;
2551 if (cell->is_locally_owned())
2553 have_coarser_cell =
true;
2563 template <
int dim,
int spacedim>
2569 coarse_cell_to_p4est_tree_permutation.resize (this->
n_cells(0));
2572 coarse_cell_to_p4est_tree_permutation);
2574 p4est_tree_to_coarse_cell_permutation
2580 template <
int dim,
int spacedim>
2584 Assert (parallel_forest != 0,
2585 ExcMessage (
"Can't produce output when no forest is created yet."));
2591 template <
int dim,
int spacedim>
2597 ExcMessage (
"not all SolutionTransfer's got deserialized after the last load()"));
2598 int real_data_size = 0;
2604 if (this->my_subdomain==0)
2606 std::string fname=std::string(filename)+
".info";
2607 std::ofstream f(fname.c_str());
2608 f <<
"version nproc attached_bytes n_attached_objs n_coarse_cells" << std::endl
2611 << real_data_size <<
" " 2633 void *userptr = parallel_forest->user_pointer;
2635 parallel_forest->user_pointer = userptr;
2639 template <
int dim,
int spacedim>
2643 const bool autopartition)
2645 Assert(this->
n_cells()>0,
ExcMessage(
"load() only works if the Triangulation already contains a coarse mesh!"));
2655 parallel_forest = 0;
2659 unsigned int version, numcpus, attached_size, attached_count, n_coarse_cells;
2661 std::string fname=std::string(filename)+
".info";
2662 std::ifstream f(fname.c_str());
2663 std::string firstline;
2664 getline(f, firstline);
2665 f >> version >> numcpus >> attached_size >> attached_count >> n_coarse_cells;
2668 Assert(version == 2,
ExcMessage(
"Incompatible version found in .info file."));
2670 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 2673 ExcMessage(
"parallel::distributed::Triangulation::load() only supports loading " 2674 "saved data with a greater or equal number of processes than were used to " 2675 "save() when using p4est 0.3.4.2."));
2682 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,3) 2685 attached_size, attached_size>0,
2690 (void)autopartition;
2693 attached_size, attached_size>0,
2723 template <
int dim,
int spacedim>
2727 Assert (parallel_forest != 0,
2728 ExcMessage (
"Can't produce a check sum when no forest is created yet."));
2729 return ::internal::p4est::functions<dim>::checksum (parallel_forest);
2732 template <
int dim,
int spacedim>
2746 cell = this->
begin();
2747 cell != this->
end();
2751 this->number_cache.level_ghost_owners.insert(cell->level_subdomain_id());
2758 template <
int dim,
int spacedim>
2759 typename ::internal::p4est::types<dim>::tree *
2763 const unsigned int tree_index
2764 = coarse_cell_to_p4est_tree_permutation[dealii_coarse_cell_index];
2765 typename ::internal::p4est::types<dim>::tree *tree
2766 =
static_cast<typename ::internal::p4est::types<dim>::tree *
> 2767 (sc_array_index (parallel_forest->trees,
2779 const unsigned int dim = 2, spacedim = 2;
2787 std::vector<unsigned int> vertex_touch_count;
2790 std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
2793 get_vertex_to_cell_mappings (*
this,
2796 const ::internal::p4est::types<2>::locidx
2797 num_vtt = std::accumulate (vertex_touch_count.begin(),
2798 vertex_touch_count.end(),
2804 const bool set_vertex_info
2819 set_vertex_and_cell_info (*
this,
2822 coarse_cell_to_p4est_tree_permutation,
2826 Assert (p4est_connectivity_is_valid (connectivity) == 1,
2827 ExcInternalError());
2850 const unsigned int dim = 2, spacedim = 3;
2858 std::vector<unsigned int> vertex_touch_count;
2861 std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
2864 get_vertex_to_cell_mappings (*
this,
2867 const ::internal::p4est::types<2>::locidx
2868 num_vtt = std::accumulate (vertex_touch_count.begin(),
2869 vertex_touch_count.end(),
2875 const bool set_vertex_info
2890 set_vertex_and_cell_info (*
this,
2893 coarse_cell_to_p4est_tree_permutation,
2897 Assert (p4est_connectivity_is_valid (connectivity) == 1,
2898 ExcInternalError());
2919 const int dim = 3, spacedim = 3;
2927 std::vector<unsigned int> vertex_touch_count;
2930 std::pair<Triangulation<3>::active_cell_iterator,
2933 get_vertex_to_cell_mappings (*
this,
2936 const ::internal::p4est::types<2>::locidx
2937 num_vtt = std::accumulate (vertex_touch_count.begin(),
2938 vertex_touch_count.end(),
2941 std::vector<unsigned int> edge_touch_count;
2944 std::pair<Triangulation<3>::active_cell_iterator,
2947 get_edge_to_cell_mappings (*
this,
2950 const ::internal::p4est::types<2>::locidx
2951 num_ett = std::accumulate (edge_touch_count.begin(),
2952 edge_touch_count.end(),
2956 const bool set_vertex_info
2973 set_vertex_and_cell_info (*
this,
2976 coarse_cell_to_p4est_tree_permutation,
3005 const unsigned int deal_to_p4est_line_index[12]
3006 = { 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11 } ;
3008 for (Triangulation<dim,spacedim>::active_cell_iterator
3010 cell != this->
end(); ++cell)
3013 index = coarse_cell_to_p4est_tree_permutation[cell->index()];
3014 for (
unsigned int e=0; e<GeometryInfo<3>::lines_per_cell; ++e)
3016 deal_to_p4est_line_index[e]]
3017 = cell->line(e)->index();
3022 connectivity->ett_offset[0] = 0;
3023 std::partial_sum (edge_touch_count.begin(),
3024 edge_touch_count.end(),
3025 &connectivity->ett_offset[1]);
3027 Assert (connectivity->ett_offset[this->n_active_lines()] ==
3029 ExcInternalError());
3033 Assert (edge_to_cell[v].size() == edge_touch_count[v],
3034 ExcInternalError());
3037 <Triangulation<dim,spacedim>::active_cell_iterator,
3038 unsigned int> >::const_iterator
3039 p = edge_to_cell[v].begin();
3040 for (
unsigned int c=0; c<edge_touch_count[v]; ++c, ++p)
3042 connectivity->edge_to_tree[connectivity->ett_offset[v]+c]
3043 = coarse_cell_to_p4est_tree_permutation[p->first->index()];
3044 connectivity->edge_to_edge[connectivity->ett_offset[v]+c]
3045 = deal_to_p4est_line_index[p->second];
3049 Assert (p8est_connectivity_is_valid (connectivity) == 1,
3050 ExcInternalError());
3085 template <
typename ITERATOR>
3088 std::vector<unsigned int> &topological_vertex_numbering)
3090 const unsigned int dim = ITERATOR::AccessorType::dimension;
3095 if (periodic.
cell[0]->has_children() &&
3096 periodic.
cell[1]->has_children())
3102 for (
unsigned int cf=0; cf<periodic.
cell[0]->face(periodic.
face_idx[0])->n_children(); ++cf)
3104 const unsigned int child_index_0 =
3110 periodic_child.
cell[0] = periodic.
cell[0]->child(child_index_0);
3115 const unsigned int child_index_1 =
3119 periodic_child.
cell[1] = periodic.
cell[1]->child(child_index_1);
3123 identify_periodic_vertices_recursively (periodic_child,
3124 topological_vertex_numbering);
3128 for (
unsigned int v=0; v<
GeometryInfo<dim-1>::vertices_per_cell; ++v)
3132 const unsigned int vface0 =
3136 const unsigned int vi0 = topological_vertex_numbering[periodic.
cell[0]->face(periodic.
face_idx[0])->vertex_index(vface0)];
3137 const unsigned int vi1 = topological_vertex_numbering[periodic.
cell[1]->face(periodic.
face_idx[1])->vertex_index(v)];
3138 const unsigned int min_index = std::min(vi0, vi1);
3139 topological_vertex_numbering[periodic.
cell[0]->face(periodic.
face_idx[0])->vertex_index(vface0)]
3140 = topological_vertex_numbering[periodic.
cell[1]->face(periodic.
face_idx[1])->vertex_index(v)]
3149 template <
int dim,
int spacedim>
3150 bool enforce_mesh_balance_over_periodic_boundaries
3157 std::vector<bool> flags_before[2];
3161 std::vector<unsigned int> topological_vertex_numbering(tria.
n_vertices());
3162 for (
unsigned int i=0; i<topological_vertex_numbering.size(); ++i)
3163 topological_vertex_numbering[i] = i;
3167 topological_vertex_numbering);
3172 bool continue_iterating =
true;
3173 std::vector<int> vertex_level(tria.
n_vertices());
3174 while (continue_iterating)
3178 std::fill (vertex_level.begin(), vertex_level.end(), 0);
3179 typename Triangulation<dim,spacedim>::active_cell_iterator
3181 for (; cell!=endc; ++cell)
3183 if (cell->refine_flag_set())
3184 for (
unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
3186 vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]]
3187 = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]],
3189 else if (!cell->coarsen_flag_set())
3190 for (
unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
3192 vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]]
3193 = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]],
3203 Assert (cell->coarsen_flag_set(), ExcInternalError());
3204 for (
unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
3206 vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]]
3207 = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]],
3212 continue_iterating =
false;
3223 for (cell=tria.
last_active(); cell != endc; --cell)
3224 if (cell->refine_flag_set() ==
false)
3226 for (
unsigned int vertex=0;
3227 vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
3228 if (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]] >=
3232 cell->clear_coarsen_flag();
3237 if (vertex_level[topological_vertex_numbering[cell->vertex_index(vertex)]] >
3240 cell->set_refine_flag();
3241 continue_iterating =
true;
3243 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
3245 vertex_level[topological_vertex_numbering[cell->vertex_index(v)]]
3246 = std::max (vertex_level[topological_vertex_numbering[cell->vertex_index(v)]],
3258 cell!=tria.
end(); ++cell)
3264 const unsigned int n_children=cell->n_children();
3265 unsigned int flagged_children=0;
3266 for (
unsigned int child=0; child<n_children; ++child)
3267 if (cell->child(child)->active() &&
3268 cell->child(child)->coarsen_flag_set())
3273 if (flagged_children < n_children)
3274 for (
unsigned int child=0; child<n_children; ++child)
3275 if (cell->child(child)->active())
3276 cell->child(child)->clear_coarsen_flag();
3279 std::vector<bool> flags_after[2];
3282 return ((flags_before[0] != flags_after[0]) ||
3283 (flags_before[1] != flags_after[1]));
3289 template <
int dim,
int spacedim>
3293 std::vector<bool> flags_before[2];
3297 bool mesh_changed =
false;
3305 mesh_changed = enforce_mesh_balance_over_periodic_boundaries(*
this,
3308 while (mesh_changed);
3312 std::vector<bool> flags_after[2];
3315 return ((flags_before[0] != flags_after[0]) ||
3316 (flags_before[1] != flags_after[1]));
3321 template <
int dim,
int spacedim>
3344 bool mesh_changed =
false;
3357 cell != this->
end();
3360 cell->set_coarsen_flag();
3391 typename ::internal::p4est::types<dim>::
3392 balance_type(P4EST_CONNECT_CORNER)
3394 typename ::internal::p4est::types<dim>::
3395 balance_type(P8EST_CONNECT_CORNER)));
3403 cell = this->
begin(0);
3404 cell != this->
end(0);
3411 cell = this->
begin(0);
3412 cell != this->
end(0);
3418 if (tree_exists_locally<dim,spacedim>(parallel_forest,
3419 coarse_cell_to_p4est_tree_permutation[cell->index()])
3422 delete_all_children<dim,spacedim> (cell);
3423 if (!cell->has_children())
3432 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3433 typename ::internal::p4est::types<dim>::tree *tree =
3436 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3438 match_tree_recursively<dim,spacedim> (*tree, cell,
3448 typename ::internal::p4est::types<dim>::quadrant *quadr;
3449 unsigned int ghost_owner=0;
3450 typename ::internal::p4est::types<dim>::topidx ghost_tree=0;
3452 for (
unsigned int g_idx=0; g_idx<
parallel_ghost->ghosts.elem_count; ++g_idx)
3454 while (g_idx >= (
unsigned int)
parallel_ghost->proc_offsets[ghost_owner+1])
3456 while (g_idx >= (
unsigned int)
parallel_ghost->tree_offsets[ghost_tree+1])
3459 quadr =
static_cast<typename ::internal::p4est::types<dim>::quadrant *
> 3462 unsigned int coarse_cell_index =
3463 p4est_tree_to_coarse_cell_permutation[ghost_tree];
3465 match_quadrant<dim,spacedim> (
this, coarse_cell_index, *quadr, ghost_owner);
3472 mesh_changed =
false;
3473 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3475 cell != this->
end();
3477 if (cell->refine_flag_set() || cell->coarsen_flag_set())
3479 mesh_changed =
true;
3501 while (mesh_changed);
3505 unsigned int num_ghosts = 0;
3507 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3509 cell != this->
end();
3512 if (cell->subdomain_id() != this->my_subdomain
3526 if (
settings & construct_multigrid_hierarchy)
3532 for (
unsigned int lvl=this->
n_levels(); lvl>0; )
3550 std::vector<std::vector<bool> > marked_vertices(this->
n_levels());
3551 for (
unsigned int lvl=0; lvl < this->
n_levels(); ++lvl)
3556 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3557 const unsigned int tree_index
3558 = coarse_cell_to_p4est_tree_permutation[cell->index()];
3559 typename ::internal::p4est::types<dim>::tree *tree =
3562 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3564 determine_level_subdomain_id_recursively<dim,spacedim> (*tree, tree_index, cell,
3572 for (
unsigned int lvl=this->
n_levels(); lvl>0;)
3577 if (cell->has_children())
3578 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
3585 mark = cell->child(0)->level_subdomain_id();
3587 cell->set_level_subdomain_id(mark);
3606 for (
unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
3608 if (cell->face(f)->at_boundary() || cell->neighbor(f)->level() >= cell->level())
3613 if (cell_level_mine && !neighbor_level_mine)
3616 Assert(cell->neighbor(f)->active(), ExcInternalError());
3619 || cell->neighbor(f)->level_subdomain_id() == cell->neighbor(f)->subdomain_id(), ExcInternalError());
3620 cell->neighbor(f)->set_level_subdomain_id(cell->neighbor(f)->subdomain_id());
3622 else if (!cell_level_mine && neighbor_level_mine)
3625 Assert(cell->active(), ExcInternalError());
3628 || cell->level_subdomain_id() == cell->subdomain_id(), ExcInternalError());
3629 cell->set_level_subdomain_id(cell->subdomain_id());
3646 (void)total_local_cells;
3649 Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
3653 Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) <=
3655 ExcInternalError());
3658 unsigned int n_owned = 0;
3659 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3661 cell != this->
end(); ++cell)
3667 Assert(static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
3668 n_owned, ExcInternalError());
3677 template <
int dim,
int spacedim>
3690 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3692 cell != this->
end(); ++cell)
3693 if (cell->is_locally_owned() && cell->refine_flag_set())
3694 Assert (cell->refine_flag_set() ==
3696 ExcMessage (
"This class does not support anisotropic refinement"));
3703 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3708 ExcMessage(
"Fatal Error: maximum refinement level of p4est reached."));
3718 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3720 cell != this->
end(); ++cell)
3721 if (cell->is_ghost() || cell->is_artificial())
3723 cell->clear_refine_flag ();
3724 cell->clear_coarsen_flag ();
3730 RefineAndCoarsenList<dim,spacedim>
3731 refine_and_coarsen_list (*
this,
3732 p4est_tree_to_coarse_cell_permutation,
3733 this->my_subdomain);
3739 Assert (parallel_forest->user_pointer ==
this,
3740 ExcInternalError());
3741 parallel_forest->user_pointer = &refine_and_coarsen_list;
3749 refine (parallel_forest,
false,
3750 &RefineAndCoarsenList<dim,spacedim>::refine_callback,
3753 coarsen (parallel_forest,
false,
3754 &RefineAndCoarsenList<dim,spacedim>::coarsen_callback,
3758 Assert (refine_and_coarsen_list.pointers_are_at_end(),
3759 ExcInternalError());
3762 parallel_forest->user_pointer =
this;
3770 typename ::internal::p4est::types<dim>::
3771 balance_type(P4EST_CONNECT_FULL)
3773 typename ::internal::p4est::types<dim>::
3774 balance_type(P8EST_CONNECT_FULL)),
3787 partition (parallel_forest,
3795 PartitionWeights<dim,spacedim> partition_weights (cell_weights);
3799 Assert (parallel_forest->user_pointer ==
this,
3800 ExcInternalError());
3801 parallel_forest->user_pointer = &partition_weights;
3806 &PartitionWeights<dim,spacedim>::cell_weight);
3809 parallel_forest->user_pointer =
this;
3816 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3818 cell != this->
end(); ++cell)
3820 cell->clear_refine_flag();
3821 cell->clear_coarsen_flag();
3836 refinement_in_progress =
false;
3841 template <
int dim,
int spacedim>
3847 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3849 cell != this->
end(); ++cell)
3850 if (cell->is_locally_owned())
3852 !cell->refine_flag_set() && !cell->coarsen_flag_set(),
3853 ExcMessage (
"Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition()."));
3876 PartitionWeights<dim,spacedim> partition_weights (cell_weights);
3880 Assert (parallel_forest->user_pointer ==
this,
3881 ExcInternalError());
3882 parallel_forest->user_pointer = &partition_weights;
3887 &PartitionWeights<dim,spacedim>::cell_weight);
3890 parallel_forest->user_pointer =
this;
3912 template <
int dim,
int spacedim>
3918 ExcDimensionMismatch(vertex_locally_moved.size(),
3922 const std::vector<bool> locally_owned_vertices
3924 for (
unsigned int i=0; i<locally_owned_vertices.size(); ++i)
3925 Assert ((vertex_locally_moved[i] ==
false)
3927 (locally_owned_vertices[i] ==
true),
3928 ExcMessage (
"The vertex_locally_moved argument must not " 3929 "contain vertices that are not locally owned"));
3933 std::map<unsigned int, std::set<::types::subdomain_id> >
3934 vertices_with_ghost_neighbors;
3939 for (
typename Triangulation<dim,spacedim>::active_cell_iterator
3942 if (cell->is_ghost())
3943 for (
unsigned int vertex_no=0;
3944 vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
3946 const unsigned int process_local_vertex_no = cell->vertex_index(vertex_no);
3947 vertices_with_ghost_neighbors[process_local_vertex_no].insert
3948 (cell->subdomain_id());
3954 std::map<::types::subdomain_id, CommunicateLocallyMovedVertices::CellInfo<dim,spacedim> > cellmap_t;
3955 cellmap_t needs_to_get_cells;
3958 cell = this->
begin(0);
3959 cell != this->
end(0);
3962 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3963 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3965 CommunicateLocallyMovedVertices::fill_vertices_recursively<dim,spacedim>
3970 vertices_with_ghost_neighbors,
3971 vertex_locally_moved,
3972 needs_to_get_cells);
3976 std::vector<std::vector<char> > sendbuffers (needs_to_get_cells.size());
3977 std::vector<std::vector<char> >::iterator buffer = sendbuffers.begin();
3978 std::vector<MPI_Request> requests (needs_to_get_cells.size());
3979 std::vector<unsigned int> destinations;
3983 for (
typename cellmap_t::iterator it=needs_to_get_cells.begin();
3984 it!=needs_to_get_cells.end();
3985 ++it, ++buffer, ++idx)
3987 const unsigned int num_cells = it->second.tree_index.size();
3989 destinations.push_back(it->first);
3991 Assert(num_cells==it->second.quadrants.size(), ExcInternalError());
3992 Assert(num_cells>0, ExcInternalError());
4001 it->second.pack_data (*buffer);
4002 MPI_Isend(&(*buffer)[0], buffer->size(),
4003 MPI_BYTE, it->first,
4007 Assert(destinations.size()==needs_to_get_cells.size(), ExcInternalError());
4011 const std::vector<unsigned int> senders
4016 std::vector<char> receive;
4017 CommunicateLocallyMovedVertices::CellInfo<dim,spacedim> cellinfo;
4018 for (
unsigned int i=0; i<senders.size(); ++i)
4023 MPI_Get_count(&status, MPI_BYTE, &len);
4024 receive.resize(len);
4026 char *ptr = &receive[0];
4027 MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
4028 this->get_communicator(), &status);
4030 cellinfo.unpack_data(receive);
4031 const unsigned int cells = cellinfo.tree_index.size();
4032 for (
unsigned int c=0; c<cells; ++c)
4034 typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator
4039 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
4040 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4042 CommunicateLocallyMovedVertices::set_vertices_recursively<dim,spacedim> (*
this,
4045 cellinfo.quadrants[c],
4046 cellinfo.first_vertices[c],
4047 cellinfo.first_vertex_indices[c]);
4053 if (requests.size() > 0)
4054 MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
4059 ExcInternalError());
4062 template <
int dim,
int spacedim>
4068 void *)> &pack_callback)
4072 ExcMessage(
"register_data_attach(), not all data has been unpacked last time?"));
4078 std::pair<unsigned int, pack_callback_t> (offset, pack_callback)
4085 template <
int dim,
int spacedim>
4091 const void *)> &unpack_callback)
4094 ExcMessage (
"invalid offset in notify_ready_to_unpack()"));
4096 ExcMessage (
"invalid offset in notify_ready_to_unpack()"));
4101 cell = this->
begin (0);
4102 cell != this->
end (0);
4106 if (tree_exists_locally<dim, spacedim> (parallel_forest,
4107 coarse_cell_to_p4est_tree_permutation[cell->index() ])
4111 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
4112 typename ::internal::p4est::types<dim>::tree *tree =
4115 ::internal::p4est::init_coarse_quadrant<dim> (p4est_coarse_cell);
4119 post_mesh_data_recursively<dim, spacedim> (*tree,
4147 void *userptr = parallel_forest->user_pointer;
4149 parallel_forest->user_pointer = userptr;
4154 template <
int dim,
int spacedim>
4155 const std::vector<types::global_dof_index> &
4158 return p4est_tree_to_coarse_cell_permutation;
4163 template <
int dim,
int spacedim>
4164 const std::vector<types::global_dof_index> &
4178 template <
int dim,
int spacedim>
4181 typename ::parallel::distributed::Triangulation<dim,spacedim> *triangulation;
4183 std::map<unsigned int, std::set<::types::subdomain_id> >
4184 *vertices_with_ghost_neighbors;
4192 template <
int dim,
int spacedim>
4195 (typename ::internal::p4est::iter<dim>::corner_info *info,
4199 int nsides = info->sides.elem_count;
4200 typename ::internal::p4est::iter<dim>::corner_side *sides =
4201 (typename ::internal::p4est::iter<dim>::corner_side *)
4202 (info->sides.array);
4203 FindGhosts<dim,spacedim> *fg =
static_cast<FindGhosts<dim,spacedim> *
>(user_data);
4204 sc_array_t *subids = fg->subids;
4205 typename ::parallel::distributed::Triangulation<dim,spacedim> *triangulation = fg->triangulation;
4208 std::map<unsigned int, std::set<::types::subdomain_id> >
4209 *vertices_with_ghost_neighbors = fg->vertices_with_ghost_neighbors;
4211 subids->elem_count = 0;
4212 for (i = 0; i < nsides; i++)
4214 if (sides[i].is_ghost)
4216 typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator cell = cell_from_quad (triangulation, sides[i].treeid, *(sides[i].quad));
4217 Assert (cell->is_ghost(),
ExcMessage (
"ghost quad did not find ghost cell"));
4220 *subid = cell->subdomain_id();
4224 if (!subids->elem_count)
4229 nsubs = (int) subids->elem_count;
4232 for (i = 0; i < nsides; i++)
4234 if (!sides[i].is_ghost)
4236 typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator cell = cell_from_quad (triangulation, sides[i].treeid, *(sides[i].quad));
4240 for (j = 0; j < nsubs; j++)
4242 (*vertices_with_ghost_neighbors)[cell->vertex_index(sides[i].corner)]
4243 .insert (subdomain_ids[j]);
4248 subids->elem_count = 0;
4254 template <
int dim,
int spacedim>
4257 (typename ::internal::p4est::iter<dim>::edge_info *info,
4261 int nsides = info->sides.elem_count;
4262 typename ::internal::p4est::iter<dim>::edge_side *sides =
4263 (typename ::internal::p4est::iter<dim>::edge_side *)
4264 (info->sides.array);
4265 FindGhosts<dim,spacedim> *fg =
static_cast<FindGhosts<dim,spacedim> *
>(user_data);
4266 sc_array_t *subids = fg->subids;
4267 typename ::parallel::distributed::Triangulation<dim,spacedim> *triangulation = fg->triangulation;
4270 std::map<unsigned int, std::set<::types::subdomain_id> >
4271 *vertices_with_ghost_neighbors = fg->vertices_with_ghost_neighbors;
4273 subids->elem_count = 0;
4274 for (i = 0; i < nsides; i++)
4276 if (sides[i].is_hanging)
4278 for (j = 0; j < 2; j++)
4280 if (sides[i].is.hanging.is_ghost[j])
4282 typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator cell = cell_from_quad (triangulation, sides[i].treeid, *(sides[i].is.hanging.quad[j]));
4285 *subid = cell->subdomain_id();
4291 if (!subids->elem_count)
4296 nsubs = (int) subids->elem_count;
4299 for (i = 0; i < nsides; i++)
4301 if (sides[i].is_hanging)
4303 for (j = 0; j < 2; j++)
4305 if (!sides[i].is.hanging.is_ghost[j])
4307 typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator cell = cell_from_quad (triangulation, sides[i].treeid, *(sides[i].is.hanging.quad[j]));
4309 for (k = 0; k < nsubs; k++)
4311 (*vertices_with_ghost_neighbors)[cell->vertex_index(p8est_edge_corners[sides[i].edge][1^j])]
4312 .insert (subdomain_ids[k]);
4319 subids->elem_count = 0;
4325 template <
int dim,
int spacedim>
4328 (typename ::internal::p4est::iter<dim>::face_info *info,
4332 int nsides = info->sides.elem_count;
4333 typename ::internal::p4est::iter<dim>::face_side *sides =
4334 (typename ::internal::p4est::iter<dim>::face_side *)
4335 (info->sides.array);
4336 FindGhosts<dim,spacedim> *fg =
static_cast<FindGhosts<dim,spacedim> *
>(user_data);
4337 sc_array_t *subids = fg->subids;
4338 typename ::parallel::distributed::Triangulation<dim,spacedim> *triangulation = fg->triangulation;
4341 std::map<unsigned int, std::set<::types::subdomain_id> >
4342 *vertices_with_ghost_neighbors = fg->vertices_with_ghost_neighbors;
4343 int limit = (dim == 2) ? 2 : 4;
4345 subids->elem_count = 0;
4346 for (i = 0; i < nsides; i++)
4348 if (sides[i].is_hanging)
4350 for (j = 0; j < limit; j++)
4352 if (sides[i].is.hanging.is_ghost[j])
4354 typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator cell = cell_from_quad (triangulation, sides[i].treeid, *(sides[i].is.hanging.quad[j]));
4357 *subid = cell->subdomain_id();
4363 if (!subids->elem_count)
4368 nsubs = (int) subids->elem_count;
4371 for (i = 0; i < nsides; i++)
4373 if (sides[i].is_hanging)
4375 for (j = 0; j < limit; j++)
4377 if (!sides[i].is.hanging.is_ghost[j])
4379 typename ::parallel::distributed::Triangulation<dim,spacedim>::cell_iterator cell = cell_from_quad (triangulation, sides[i].treeid, *(sides[i].is.hanging.quad[j]));
4381 for (k = 0; k < nsubs; k++)
4385 (*vertices_with_ghost_neighbors)[cell->vertex_index(p4est_face_corners[sides[i].face][(limit - 1)^j])]
4386 .insert (subdomain_ids[k]);
4390 (*vertices_with_ghost_neighbors)[cell->vertex_index(p8est_face_corners[sides[i].face][(limit - 1)^j])]
4391 .insert (subdomain_ids[k]);
4399 subids->elem_count = 0;
4412 template <
typename ITERATOR>
4415 const int target_level,
4416 std::vector<bool> &active_vertices_on_level)
4418 if (periodic.
cell[0]->level() > target_level)
4421 const unsigned int dim = ITERATOR::AccessorType::dimension;
4424 if (periodic.
cell[0]->level() < target_level &&
4425 periodic.
cell[0]->has_children() &&
4426 periodic.
cell[1]->has_children())
4432 for (
unsigned int cf=0; cf<periodic.
cell[0]->face(periodic.
face_idx[0])->n_children(); ++cf)
4434 const unsigned int child_index_0 =
4440 periodic_child.
cell[0] = periodic.
cell[0]->child(child_index_0);
4445 const unsigned int child_index_1 =
4449 periodic_child.
cell[1] = periodic.
cell[1]->child(child_index_1);
4453 mark_periodic_vertices_recursively (periodic_child, target_level,
4454 active_vertices_on_level);
4459 if (periodic.
cell[0]->level() != target_level)
4462 for (
unsigned int v=0; v<
GeometryInfo<dim-1>::vertices_per_cell; ++v)
4466 const unsigned int vface0 =
4470 if (active_vertices_on_level[periodic.
cell[0]->face(periodic.
face_idx[0])->vertex_index(vface0)] ||
4471 active_vertices_on_level[periodic.
cell[1]->face(periodic.
face_idx[1])->vertex_index(v)])
4472 active_vertices_on_level[periodic.
cell[0]->face(periodic.
face_idx[0])->vertex_index(vface0)]
4473 = active_vertices_on_level[periodic.
cell[1]->face(periodic.
face_idx[1])->vertex_index(v)]
4484 template <
typename ITERATOR>
4487 const int target_level,
4488 std::map<
unsigned int, std::set<::types::subdomain_id> > &vertices_with_ghost_neighbors)
4490 if (periodic.
cell[0]->level() > target_level)
4495 if (periodic.
cell[0]->level() < target_level &&
4496 periodic.
cell[0]->has_children() &&
4497 periodic.
cell[1]->has_children())
4503 for (
unsigned int cf=0; cf<periodic.
cell[0]->face(periodic.
face_idx[0])->n_children(); ++cf)
4506 for (; c<periodic.
cell[0]->n_children(); ++c)
4508 if (periodic.
cell[0]->child(c)->face(periodic.
face_idx[0]) ==
4509 periodic.
cell[0]->face(periodic.
face_idx[0])->child(cf))
4514 periodic_child.
cell[0] = periodic.
cell[0]->child(c);
4518 for (; c<periodic.
cell[1]->n_children(); ++c)
4520 if (periodic.
cell[1]->child(c)->face(periodic.
face_idx[1]) ==
4521 periodic.
cell[1]->face(periodic.
face_idx[1])->child(cf))
4526 periodic_child.
cell[1] = periodic.
cell[1]->child(c);
4530 set_periodic_ghost_neighbors_recursively (periodic_child, target_level,
4531 vertices_with_ghost_neighbors);
4536 if (periodic.
cell[0]->level() != target_level)
4543 ExcNotImplemented());
4545 for (
unsigned int v=0; v<
GeometryInfo<ITERATOR::AccessorType::dimension-1>::vertices_per_cell; ++v)
4548 idx0 = periodic.
cell[0]->face(periodic.
face_idx[0])->vertex_index(v),
4549 idx1 = periodic.
cell[1]->face(periodic.
face_idx[1])->vertex_index(v);
4550 if (vertices_with_ghost_neighbors.find(idx0) !=
4551 vertices_with_ghost_neighbors.end())
4552 vertices_with_ghost_neighbors[idx1].
4553 insert(vertices_with_ghost_neighbors[idx0].
begin(),
4554 vertices_with_ghost_neighbors[idx0].end());
4555 if (vertices_with_ghost_neighbors.find(idx1) !=
4556 vertices_with_ghost_neighbors.end())
4557 vertices_with_ghost_neighbors[idx0].
4558 insert(vertices_with_ghost_neighbors[idx1].
begin(),
4559 vertices_with_ghost_neighbors[idx1].end());
4570 template <
int dim,
int spacedim>
4574 (std::map<
unsigned int, std::set<::types::subdomain_id> >
4575 &vertices_with_ghost_neighbors)
4577 Assert (dim>1, ExcNotImplemented());
4579 FindGhosts<dim,spacedim> fg;
4581 fg.triangulation =
this;
4582 fg.vertices_with_ghost_neighbors = &vertices_with_ghost_neighbors;
4592 static_cast<void *>(&fg),
4593 NULL, find_ghosts_face<2,spacedim>, find_ghosts_corner<2,spacedim>);
4599 static_cast<void *>(&fg),
4600 NULL, find_ghosts_face<3,spacedim>, find_ghosts_edge<3,spacedim>, find_ghosts_corner<3,spacedim>);
4604 Assert (
false, ExcNotImplemented());
4607 sc_array_destroy (fg.subids);
4616 template <
int dim,
int spacedim>
4620 (
const unsigned int level,
4621 std::map<
unsigned int, std::set<::types::subdomain_id> >
4622 &vertices_with_ghost_neighbors)
4624 const std::vector<bool> locally_active_vertices =
4627 if (cell->level_subdomain_id() != ::numbers::artificial_subdomain_id
4629 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
4630 if (locally_active_vertices[cell->vertex_index(v)])
4631 vertices_with_ghost_neighbors[cell->vertex_index(v)]
4632 .insert (cell->level_subdomain_id());
4636 level, vertices_with_ghost_neighbors);
4641 template<
int dim,
int spacedim>
4646 Assert (dim>1, ExcNotImplemented());
4648 std::vector<bool> marked_vertices(this->
n_vertices(),
false);
4651 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
4652 marked_vertices[cell->vertex_index(v)] =
true;
4656 level, marked_vertices);
4658 return marked_vertices;
4663 template<
int dim,
int spacedim>
4669 #if DEAL_II_P4EST_VERSION_GTE(0,3,4,1) 4673 ExcMessage (
"The triangulation is refined!"));
4675 typedef std::vector<GridTools::PeriodicFacePair<cell_iterator> >
4677 typename FaceVector::const_iterator it, periodic_end;
4678 it = periodicity_vector.begin();
4679 periodic_end = periodicity_vector.end();
4681 for (; it<periodic_end; ++it)
4685 const unsigned int face_left = it->face_idx[0];
4686 const unsigned int face_right = it->face_idx[1];
4689 const unsigned int tree_left
4690 = coarse_cell_to_p4est_tree_permutation[std::distance(this->
begin(),
4692 const unsigned int tree_right
4693 = coarse_cell_to_p4est_tree_permutation[std::distance(this->
begin(),
4703 unsigned int p4est_orientation = 0;
4705 p4est_orientation = it->orientation[1];
4708 const unsigned int face_idx_list[] = {face_left, face_right};
4709 const cell_iterator cell_list[] = {first_cell, second_cell};
4710 unsigned int lower_idx, higher_idx;
4711 if (face_left<=face_right)
4723 unsigned int first_p4est_idx_on_cell = p8est_face_corners[face_idx_list[lower_idx]][0];
4725 for (
unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
4727 const unsigned int first_dealii_idx_on_cell
4729 (face_idx_list[lower_idx], i,
4730 cell_list[lower_idx]->face_orientation(face_idx_list[lower_idx]),
4731 cell_list[lower_idx]->face_flip(face_idx_list[lower_idx]),
4732 cell_list[lower_idx]->face_rotation(face_idx_list[lower_idx]));
4733 if (first_p4est_idx_on_cell == first_dealii_idx_on_cell)
4735 first_dealii_idx_on_face = i;
4741 const unsigned int left_to_right [8][4] = {{0,2,1,3},{0,1,2,3},{3,1,2,0},{3,2,1,0},
4742 {2,3,0,1},{1,3,0,2},{1,0,3,2},{2,0,3,1}
4744 const unsigned int right_to_left [8][4] = {{0,2,1,3},{0,1,2,3},{3,1,2,0},{3,2,1,0},
4745 {2,3,0,1},{2,0,3,1},{1,0,3,2},{1,3,0,2}
4747 const unsigned int second_dealii_idx_on_face
4748 = lower_idx==0?left_to_right[it->orientation.to_ulong()][first_dealii_idx_on_face]:
4749 right_to_left[it->orientation.to_ulong()][first_dealii_idx_on_face];
4750 const unsigned int second_dealii_idx_on_cell
4752 (face_idx_list[higher_idx], second_dealii_idx_on_face,
4753 cell_list[higher_idx]->face_orientation(face_idx_list[higher_idx]),
4754 cell_list[higher_idx]->face_flip(face_idx_list[higher_idx]),
4755 cell_list[higher_idx]->face_rotation(face_idx_list[higher_idx]));
4757 const unsigned int second_p4est_idx_on_face
4758 = p8est_corner_face_corners[second_dealii_idx_on_cell][face_idx_list[higher_idx]];
4759 p4est_orientation = second_p4est_idx_on_face;
4773 (connectivity) == 1, ExcInternalError());
4801 periodicity_vector.begin(),
4802 periodicity_vector.end());
4811 template <
int dim,
int spacedim>
4833 template <
int dim,
int spacedim>
4837 return ::internal::p4est::functions<dim>::forest_memory_used(parallel_forest)
4843 template <
int dim,
int spacedim>
4853 catch (
const typename ::Triangulation<dim,spacedim>::DistortedCellList &)
4865 Assert (old_tria.n_levels() == 1,
4866 ExcMessage (
"Parallel distributed triangulations can only be copied, " 4867 "if they are not refined!"));
4869 if (const ::parallel::distributed::Triangulation<dim,spacedim> *
4870 old_tria_x =
dynamic_cast<const ::parallel::distributed::Triangulation<dim,spacedim> *
>(&old_tria))
4872 Assert (!old_tria_x->refinement_in_progress,
4873 ExcMessage (
"Parallel distributed triangulations can only " 4874 "be copied, if no refinement is in progress!"));
4879 coarse_cell_to_p4est_tree_permutation = old_tria_x->coarse_cell_to_p4est_tree_permutation;
4880 p4est_tree_to_coarse_cell_permutation = old_tria_x->p4est_tree_to_coarse_cell_permutation;
4908 template <
int dim,
int spacedim>
4924 void *userptr = parallel_forest->user_pointer;
4928 parallel_forest->user_pointer = userptr;
4935 cell = this->
begin(0);
4936 cell != this->
end(0);
4940 if (tree_exists_locally<dim,spacedim>(parallel_forest,
4941 coarse_cell_to_p4est_tree_permutation[cell->index()])
4945 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
4946 typename ::internal::p4est::types<dim>::tree *tree =
4949 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4951 attach_mesh_data_recursively<dim,spacedim>(*tree,
4958 template <
int dim,
int spacedim>
4959 std::vector<unsigned int>
4968 std::vector<unsigned int> weights;
4977 for (
unsigned int c=0; c<this->
n_cells(0); ++c)
4980 if (tree_exists_locally<dim,spacedim>(parallel_forest,c) ==
false)
4983 const unsigned int coarse_cell_index =
4984 p4est_tree_to_coarse_cell_permutation[c];
4987 dealii_coarse_cell (
this, 0, coarse_cell_index);
4989 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
4994 p4est_coarse_cell.p.which_tree = c;
4996 const typename ::internal::p4est::types<dim>::tree *tree =
4999 get_cell_weights_recursively<dim,spacedim>(*tree,
5009 template <
int dim,
int spacedim>
5010 typename ::Triangulation<dim,spacedim>::cell_iterator
5012 (typename ::parallel::distributed::Triangulation<dim,spacedim> *triangulation,
5013 typename ::internal::p4est::types<dim>::topidx treeidx,
5014 typename ::internal::p4est::types<dim>::quadrant &quad)
5016 int i, l = quad.level;
5019 triangulation->get_p4est_tree_to_coarse_cell_permutation()[treeidx];
5021 for (i = 0; i < l; i++)
5023 typename ::Triangulation<dim,spacedim>::cell_iterator cell (triangulation, i, dealii_index);
5025 Assert (cell->has_children (),
ExcMessage (
"p4est quadrant does not correspond to a cell!"));
5026 dealii_index = cell->child_index(child_id);
5029 typename ::Triangulation<dim,spacedim>::cell_iterator out_cell (triangulation, l, dealii_index);
5036 template <
int spacedim>
5043 Assert (
false, ExcNotImplemented());
5047 template <
int spacedim>
5050 Assert (
false, ExcNotImplemented());
5055 template <
int spacedim>
5058 (
const std::vector<bool> &)
5060 Assert (
false, ExcNotImplemented());
5064 template <
int spacedim>
5065 const std::vector<types::global_dof_index> &
5068 static std::vector<types::global_dof_index> a;
5072 template <
int spacedim>
5076 (std::map<
unsigned int, std::set<::types::subdomain_id> >
5079 Assert (
false, ExcNotImplemented());
5082 template <
int spacedim>
5086 (
const unsigned int ,
5087 std::map<
unsigned int, std::set<::types::subdomain_id> >
5090 Assert (
false, ExcNotImplemented());
5093 template <
int spacedim>
5098 Assert (
false, ExcNotImplemented());
5099 return std::vector<bool>();
5105 #else // DEAL_II_WITH_P4EST 5109 namespace distributed
5111 template <
int dim,
int spacedim>
5116 Assert (
false, ExcNotImplemented());
5121 #endif // DEAL_II_WITH_P4EST 5127 #include "tria.inst" 5130 DEAL_II_NAMESPACE_CLOSE
unsigned int n_active_cells() const
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria)
std::vector< unsigned int > get_cell_weights()
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)
unsigned int n_vertices() const
static const unsigned int invalid_unsigned_int
std::vector< bool > mark_locally_active_vertices_on_level(const unsigned int level) const
void fill_vertices_with_ghost_neighbors(std::map< unsigned int, std::set<::types::subdomain_id > > &vertices_with_ghost_neighbors)
types::subdomain_id my_subdomain
unsigned int register_data_attach(const std::size_t size, const std_cxx11::function< void(const cell_iterator &, const CellStatus, void *)> &pack_callback)
unsigned int n_cells() const
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria)
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)
std::vector< Point< spacedim > > vertices
::ExceptionBase & ExcMessage(std::string arg1)
virtual std::size_t memory_consumption() const
boost::signals2::signal< unsigned int(const cell_iterator &, const CellStatus), CellWeightSum< unsigned int > > cell_weight
bool triangulation_has_content
virtual void copy_triangulation(const Triangulation< dim, spacedim > &old_tria)
unsigned int attached_data_size
active_cell_iterator begin_active(const unsigned int level=0) const
void notify_ready_to_unpack(const unsigned int offset, const std_cxx11::function< void(const cell_iterator &, const CellStatus, const void *)> &unpack_callback)
void copy_new_triangulation_to_p4est(::internal::int2type< 2 >)
#define AssertThrow(cond, exc)
void fill_level_vertices_with_ghost_neighbors(const unsigned int level, std::map< unsigned int, std::set<::types::subdomain_id > > &vertices_with_ghost_neighbors)
MPI_Comm mpi_communicator
virtual std::size_t memory_consumption_p4est() const
void load(const char *filename, const bool autopartition=true)
callback_list_t attached_data_pack_callbacks
cell_iterator begin(const unsigned int level=0) const
const std::vector< types::global_dof_index > & get_p4est_tree_to_coarse_cell_permutation() const
void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator > > &)
typename ::internal::p4est::types< dim >::ghost * parallel_ghost
unsigned int n_levels() const
typename ::internal::p4est::types< dim >::forest * parallel_forest
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
virtual bool prepare_coarsening_and_refinement()
cell_iterator end() const
virtual void execute_coarsening_and_refinement()
unsigned int n_active_lines() const
virtual bool prepare_coarsening_and_refinement()
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
T sum(const T &t, const MPI_Comm &mpi_communicator)
unsigned int global_dof_index
static unsigned int child_cell_on_face(const RefinementCase< dim > &ref_case, const unsigned int face, const unsigned int subface, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false, const RefinementCase< dim-1 > &face_refinement_case=RefinementCase< dim-1 >::isotropic_refinement)
#define Assert(cond, exc)
virtual void update_number_cache()
const std::vector< types::global_dof_index > & get_coarse_cell_to_p4est_tree_permutation() const
virtual MPI_Comm get_communicator() const
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
void save_coarsen_flags(std::ostream &out) const
const std::vector< Point< spacedim > > & get_vertices() const
virtual bool has_hanging_nodes() const
virtual std::size_t memory_consumption() const
void save_refine_flags(std::ostream &out) const
void save(const char *filename) const
typename ::internal::p4est::types< dim >::tree * init_tree(const int dealii_coarse_cell_index) const
virtual void execute_coarsening_and_refinement()
std::vector< unsigned int > invert_permutation(const std::vector< unsigned int > &permutation)
unsigned int subdomain_id
virtual unsigned int n_global_levels() const
bool refinement_in_progress
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
::Triangulation< dim, spacedim >::active_cell_iterator active_cell_iterator
const types::subdomain_id artificial_subdomain_id
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void communicate_locally_moved_vertices(const std::vector< bool > &vertex_locally_moved)
const std::vector< bool > & get_used_vertices() const
unsigned int get_checksum() const
MeshSmoothing smooth_grid
unsigned int n_attached_datas
void setup_coarse_cell_to_p4est_tree_permutation()
::Triangulation< dim, spacedim >::cell_iterator cell_iterator
std::vector< GridTools::PeriodicFacePair< cell_iterator > > periodic_face_pairs_level_0
active_cell_iterator last_active() const
Triangulation(MPI_Comm mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const Settings settings=default_setting)
unsigned int n_attached_deserialize
types::subdomain_id locally_owned_subdomain() const
virtual void update_number_cache()
std::vector< unsigned int > compute_point_to_point_communication_pattern(const MPI_Comm &mpi_comm, const std::vector< unsigned int > &destinations)
void copy_local_forest_to_triangulation()
T max(const T &t, const MPI_Comm &mpi_communicator)
std::vector< types::global_dof_index > coarse_cell_to_p4est_tree_permutation
void write_mesh_vtk(const char *file_basename) const