896 point_matrix(2, alpha) = cell_vertices[alpha](1);
897 point_matrix(3, alpha) =
898 cell_vertices[alpha](0) * cell_vertices[alpha](1);
905 quadrant_mapping_matrix.invert(point_matrix);
909 for (
unsigned int alpha = 0;
910 alpha < GeometryInfo<dim>::vertices_per_cell;
914 point_matrix(0, alpha) = 1;
915 point_matrix(1, alpha) = cell_vertices[alpha](0);
916 point_matrix(2, alpha) = cell_vertices[alpha](1);
917 point_matrix(3, alpha) = cell_vertices[alpha](2);
918 point_matrix(4, alpha) =
919 cell_vertices[alpha](0) * cell_vertices[alpha](1);
920 point_matrix(5, alpha) =
921 cell_vertices[alpha](1) * cell_vertices[alpha](2);
922 point_matrix(6, alpha) =
923 cell_vertices[alpha](0) * cell_vertices[alpha](2);
924 point_matrix(7, alpha) = cell_vertices[alpha](0) *
925 cell_vertices[alpha](1) *
926 cell_vertices[alpha](2);
933 quadrant_mapping_matrix.invert(point_matrix);
936 is_reference_mapping_initialized =
true;
943 PartitionSearch<2>::QuadrantData::set_cell_vertices(
948 quad_length_on_level)
950 constexpr unsigned int dim = 2;
954 double corner_point[dim + 1] = {0};
957 const auto copy_vertex = [&](
unsigned int vertex_index) ->
void {
959 for (
unsigned int d = 0;
d < dim; ++
d)
961 cell_vertices[vertex_index](
d) = corner_point[d];
971 unsigned int vertex_index = 0;
972 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
973 forest->connectivity, which_tree, quadrant->x, quadrant->y, corner_point);
976 copy_vertex(vertex_index);
982 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
983 forest->connectivity,
985 quadrant->x + quad_length_on_level,
990 copy_vertex(vertex_index);
996 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
997 forest->connectivity,
1000 quadrant->y + quad_length_on_level,
1004 copy_vertex(vertex_index);
1010 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1011 forest->connectivity,
1013 quadrant->x + quad_length_on_level,
1014 quadrant->y + quad_length_on_level,
1018 copy_vertex(vertex_index);
1020 are_vertices_initialized =
true;
1027 PartitionSearch<3>::QuadrantData::set_cell_vertices(
1032 quad_length_on_level)
1034 constexpr unsigned int dim = 3;
1036 double corner_point[dim] = {0};
1039 auto copy_vertex = [&](
unsigned int vertex_index) ->
void {
1041 for (
unsigned int d = 0;
d < dim; ++
d)
1043 cell_vertices[vertex_index](
d) = corner_point[d];
1045 corner_point[
d] = 0;
1053 unsigned int vertex_index = 0;
1054 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1055 forest->connectivity,
1063 copy_vertex(vertex_index);
1070 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1071 forest->connectivity,
1073 quadrant->x + quad_length_on_level,
1079 copy_vertex(vertex_index);
1085 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1086 forest->connectivity,
1089 quadrant->y + quad_length_on_level,
1094 copy_vertex(vertex_index);
1100 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1101 forest->connectivity,
1103 quadrant->x + quad_length_on_level,
1104 quadrant->y + quad_length_on_level,
1109 copy_vertex(vertex_index);
1115 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1116 forest->connectivity,
1120 quadrant->z + quad_length_on_level,
1124 copy_vertex(vertex_index);
1130 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1131 forest->connectivity,
1133 quadrant->x + quad_length_on_level,
1135 quadrant->z + quad_length_on_level,
1139 copy_vertex(vertex_index);
1145 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1146 forest->connectivity,
1149 quadrant->y + quad_length_on_level,
1150 quadrant->z + quad_length_on_level,
1154 copy_vertex(vertex_index);
1160 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1161 forest->connectivity,
1163 quadrant->x + quad_length_on_level,
1164 quadrant->y + quad_length_on_level,
1165 quadrant->z + quad_length_on_level,
1169 copy_vertex(vertex_index);
1172 are_vertices_initialized =
true;
1182 template <
int dim,
int spacedim>
1183 class RefineAndCoarsenList
1186 RefineAndCoarsenList(
const Triangulation<dim, spacedim> &triangulation,
1187 const std::vector<types::global_dof_index>
1188 &p4est_tree_to_coarse_cell_permutation,
1201 typename internal::p4est::types<dim>::forest *forest,
1202 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1203 typename internal::p4est::types<dim>::quadrant *quadrant);
1211 typename internal::p4est::types<dim>::forest *forest,
1212 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1213 typename internal::p4est::types<dim>::quadrant *children[]);
1216 pointers_are_at_end()
const;
1219 std::vector<typename internal::p4est::types<dim>::quadrant> refine_list;
1220 typename std::vector<typename internal::p4est::types<dim>::quadrant>::
1221 const_iterator current_refine_pointer;
1223 std::vector<typename internal::p4est::types<dim>::quadrant> coarsen_list;
1224 typename std::vector<typename internal::p4est::types<dim>::quadrant>::
1225 const_iterator current_coarsen_pointer;
1230 const typename internal::p4est::types<dim>::quadrant &p4est_cell,
1236 template <
int dim,
int spacedim>
1238 RefineAndCoarsenList<dim, spacedim>::pointers_are_at_end()
const
1240 return ((current_refine_pointer == refine_list.end()) &&
1241 (current_coarsen_pointer == coarsen_list.end()));
1246 template <
int dim,
int spacedim>
1247 RefineAndCoarsenList<dim, spacedim>::RefineAndCoarsenList(
1249 const std::vector<types::global_dof_index>
1250 &p4est_tree_to_coarse_cell_permutation,
1254 unsigned int n_refine_flags = 0, n_coarsen_flags = 0;
1258 if (cell->subdomain_id() != my_subdomain)
1261 if (cell->refine_flag_set())
1263 else if (cell->coarsen_flag_set())
1267 refine_list.reserve(n_refine_flags);
1268 coarsen_list.reserve(n_coarsen_flags);
1278 for (
unsigned int c = 0; c < triangulation.
n_cells(0); ++c)
1280 unsigned int coarse_cell_index =
1281 p4est_tree_to_coarse_cell_permutation[c];
1284 &triangulation, 0, coarse_cell_index);
1286 typename internal::p4est::types<dim>::quadrant p4est_cell;
1287 internal::p4est::functions<dim>::quadrant_set_morton(&p4est_cell,
1290 p4est_cell.p.which_tree = c;
1291 build_lists(cell, p4est_cell, my_subdomain);
1299 for (
unsigned int i = 1; i < refine_list.size(); ++i)
1300 Assert(refine_list[i].p.which_tree >= refine_list[i - 1].p.which_tree,
1302 for (
unsigned int i = 1; i < coarsen_list.size(); ++i)
1303 Assert(coarsen_list[i].p.which_tree >= coarsen_list[i - 1].p.which_tree,
1306 current_refine_pointer = refine_list.begin();
1307 current_coarsen_pointer = coarsen_list.begin();
1312 template <
int dim,
int spacedim>
1314 RefineAndCoarsenList<dim, spacedim>::build_lists(
1316 const typename internal::p4est::types<dim>::quadrant &p4est_cell,
1324 refine_list.push_back(p4est_cell);
1326 coarsen_list.push_back(p4est_cell);
1331 typename internal::p4est::types<dim>::quadrant
1333 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1335 internal::p4est::functions<dim>::quadrant_init(p4est_child[c]);
1336 internal::p4est::functions<dim>::quadrant_childrenv(&p4est_cell,
1338 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1341 p4est_child[c].p.which_tree = p4est_cell.p.which_tree;
1342 build_lists(cell->
child(c), p4est_child[c], my_subdomain);
1348 template <
int dim,
int spacedim>
1350 RefineAndCoarsenList<dim, spacedim>::refine_callback(
1351 typename internal::p4est::types<dim>::forest *forest,
1352 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1353 typename internal::p4est::types<dim>::quadrant *quadrant)
1355 RefineAndCoarsenList<dim, spacedim> *this_object =
1356 reinterpret_cast<RefineAndCoarsenList<dim, spacedim> *
>(
1357 forest->user_pointer);
1361 if (this_object->current_refine_pointer == this_object->refine_list.end())
1364 Assert(coarse_cell_index <=
1365 this_object->current_refine_pointer->p.which_tree,
1370 if (coarse_cell_index < this_object->current_refine_pointer->p.which_tree)
1374 Assert(coarse_cell_index <=
1375 this_object->current_refine_pointer->p.which_tree,
1380 Assert(internal::p4est::functions<dim>::quadrant_compare(
1381 quadrant, &*this_object->current_refine_pointer) <= 0,
1385 if (internal::p4est::functions<dim>::quadrant_is_equal(
1386 quadrant, &*this_object->current_refine_pointer))
1388 ++this_object->current_refine_pointer;
1398 template <
int dim,
int spacedim>
1400 RefineAndCoarsenList<dim, spacedim>::coarsen_callback(
1401 typename internal::p4est::types<dim>::forest *forest,
1402 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1403 typename internal::p4est::types<dim>::quadrant *children[])
1405 RefineAndCoarsenList<dim, spacedim> *this_object =
1406 reinterpret_cast<RefineAndCoarsenList<dim, spacedim> *
>(
1407 forest->user_pointer);
1411 if (this_object->current_coarsen_pointer == this_object->coarsen_list.end())
1414 Assert(coarse_cell_index <=
1415 this_object->current_coarsen_pointer->p.which_tree,
1420 if (coarse_cell_index < this_object->current_coarsen_pointer->p.which_tree)
1424 Assert(coarse_cell_index <=
1425 this_object->current_coarsen_pointer->p.which_tree,
1430 Assert(internal::p4est::functions<dim>::quadrant_compare(
1431 children[0], &*this_object->current_coarsen_pointer) <= 0,
1436 if (internal::p4est::functions<dim>::quadrant_is_equal(
1437 children[0], &*this_object->current_coarsen_pointer))
1440 ++this_object->current_coarsen_pointer;
1444 for (
unsigned int c = 1; c < GeometryInfo<dim>::max_children_per_cell;
1447 Assert(internal::p4est::functions<dim>::quadrant_is_equal(
1448 children[c], &*this_object->current_coarsen_pointer),
1450 ++this_object->current_coarsen_pointer;
1468 template <
int dim,
int spacedim>
1469 class PartitionWeights
1477 explicit PartitionWeights(
const std::vector<unsigned int> &cell_weights);
1487 cell_weight(
typename internal::p4est::types<dim>::forest *forest,
1488 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1489 typename internal::p4est::types<dim>::quadrant *quadrant);
1492 std::vector<unsigned int> cell_weights_list;
1493 std::vector<unsigned int>::const_iterator current_pointer;
1497 template <
int dim,
int spacedim>
1498 PartitionWeights<dim, spacedim>::PartitionWeights(
1499 const std::vector<unsigned int> &cell_weights)
1500 : cell_weights_list(cell_weights)
1504 current_pointer = cell_weights_list.begin();
1508 template <
int dim,
int spacedim>
1510 PartitionWeights<dim, spacedim>::cell_weight(
1511 typename internal::p4est::types<dim>::forest *forest,
1512 typename internal::p4est::types<dim>::topidx,
1513 typename internal::p4est::types<dim>::quadrant *)
1519 PartitionWeights<dim, spacedim> *this_object =
1520 reinterpret_cast<PartitionWeights<dim, spacedim> *
>(forest->user_pointer);
1522 Assert(this_object->current_pointer >=
1523 this_object->cell_weights_list.begin(),
1525 Assert(this_object->current_pointer < this_object->cell_weights_list.end(),
1531 const unsigned int weight = *this_object->current_pointer;
1532 ++this_object->current_pointer;
1534 Assert(weight <
static_cast<unsigned int>(std::numeric_limits<int>::max()),
1535 ExcMessage(
"p4est uses 'signed int' to represent the partition "
1536 "weights for cells. The weight provided here exceeds "
1537 "the maximum value represented as a 'signed int'."));
1538 return static_cast<int>(weight);
1541 template <
int dim,
int spacedim>
1542 using cell_relation_t =
typename std::pair<
1543 typename ::Triangulation<dim, spacedim>::cell_iterator,
1555 template <
int dim,
int spacedim>
1557 add_single_cell_relation(
1558 std::vector<cell_relation_t<dim, spacedim>> &cell_rel,
1559 const typename ::internal::p4est::types<dim>::tree &tree,
1560 const unsigned int idx,
1564 const unsigned int local_quadrant_index = tree.quadrants_offset + idx;
1570 cell_rel[local_quadrant_index] = std::make_pair(dealii_cell, status);
1584 template <
int dim,
int spacedim>
1586 update_cell_relations_recursively(
1587 std::vector<cell_relation_t<dim, spacedim>> &cell_rel,
1588 const typename ::internal::p4est::types<dim>::tree &tree,
1590 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell)
1593 const int idx = sc_array_bsearch(
1594 const_cast<sc_array_t *
>(&tree.quadrants),
1596 ::internal::p4est::functions<dim>::quadrant_compare);
1598 (::internal::p4est::functions<dim>::quadrant_overlaps_tree(
1599 const_cast<typename ::internal::p4est::types<dim>::tree *
>(
1601 &p4est_cell) ==
false))
1606 const bool p4est_has_children = (idx == -1);
1610 typename ::internal::p4est::types<dim>::quadrant
1613 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1615 internal::p4est::functions<dim>::quadrant_init(p4est_child[c]);
1617 ::internal::p4est::functions<dim>::quadrant_childrenv(
1618 &p4est_cell, p4est_child);
1620 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1623 update_cell_relations_recursively<dim, spacedim>(
1624 cell_rel, tree, dealii_cell->
child(c), p4est_child[c]);
1627 else if (!p4est_has_children && !dealii_cell->
has_children())
1631 add_single_cell_relation<dim, spacedim>(
1634 else if (p4est_has_children)
1642 typename ::internal::p4est::types<dim>::quadrant
1644 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1646 internal::p4est::functions<dim>::quadrant_init(p4est_child[c]);
1648 ::internal::p4est::functions<dim>::quadrant_childrenv(
1649 &p4est_cell, p4est_child);
1657 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
1660 child_idx = sc_array_bsearch(
1661 const_cast<sc_array_t *
>(&tree.quadrants),
1663 ::internal::p4est::functions<dim>::quadrant_compare);
1668 add_single_cell_relation<dim, spacedim>(
1669 cell_rel, tree, child_idx, dealii_cell, cell_status);
1677 add_single_cell_relation<dim, spacedim>(
1694 template <
int dim,
int spacedim>
1723 template <
int dim,
int spacedim>
1745 template <
int dim,
int spacedim>
1758 const typename ::Triangulation<dim, spacedim>::DistortedCellList
1769 "The class parallel::distributed::Triangulation only supports meshes "
1770 "consisting only of hypercube-like cells."));
1785 catch (
const typename Triangulation<dim>::DistortedCellList &)
1798 template <
int dim,
int spacedim>
1809 template <
int dim,
int spacedim>
1845 template <
int dim,
int spacedim>
1856 template <
int dim,
int spacedim>
1867 template <
int dim,
int spacedim>
1873 *previous_global_first_quadrant)
1881 this->data_serializer.sizes_fixed_cumulative.back());
1884 typename ::internal::p4est::types<dim>::transfer_context
1889 previous_global_first_quadrant,
1892 this->data_serializer.dest_data_fixed.data(),
1893 this->data_serializer.src_data_fixed.data(),
1894 this->data_serializer.sizes_fixed_cumulative.back());
1906 previous_global_first_quadrant,
1909 this->data_serializer.dest_sizes_variable.data(),
1910 this->data_serializer.src_sizes_variable.data(),
1911 sizeof(
unsigned int));
1925 this->data_serializer.dest_sizes_variable.end(),
1926 std::vector<int>::size_type(0)));
1931 previous_global_first_quadrant,
1934 this->data_serializer.dest_data_variable.data(),
1935 this->data_serializer.dest_sizes_variable.data(),
1936 this->data_serializer.src_data_variable.data(),
1937 this->data_serializer.src_sizes_variable.data());
1949 template <
int dim,
int spacedim>
1967 template <
int dim,
int spacedim>
1970 const
std::
string &file_basename)
const
1973 ExcMessage(
"Can't produce output when no forest is created yet."));
1977 "To use this function the triangulation's flag "
1978 "Settings::communicate_vertices_to_p4est must be set."));
1986 template <
int dim,
int spacedim>
1989 const
std::
string &file_basename)
const
1994 "Not all SolutionTransfer objects have been deserialized after the last call to load()."));
1996 ExcMessage(
"Can not save() an empty Triangulation."));
2002 this->
signals.pre_distributed_save();
2004 if (this->my_subdomain == 0)
2006 std::string fname = file_basename +
".info";
2007 std::ofstream f(fname);
2008 f <<
"version nproc n_attached_fixed_size_objs n_attached_variable_size_objs n_coarse_cells"
2014 << this->
n_cells(0) << std::endl;
2020 Assert((cell_rel.second ==
2035 this->
signals.post_distributed_save();
2040 template <
int dim,
int spacedim>
2047 "load() only works if the Triangulation already contains a coarse mesh!"));
2051 "Triangulation may only contain coarse cells when calling load()."));
2057 this->
signals.pre_distributed_load();
2071 unsigned int version, numcpus, attached_count_fixed,
2072 attached_count_variable, n_coarse_cells;
2074 std::string fname = std::string(file_basename) +
".info";
2075 std::ifstream f(fname);
2077 std::string firstline;
2078 getline(f, firstline);
2079 f >> version >> numcpus >> attached_count_fixed >>
2080 attached_count_variable >> n_coarse_cells;
2084 ExcMessage(
"Incompatible version found in .info file."));
2086 ExcMessage(
"Number of coarse cells differ!"));
2092 attached_count_fixed + attached_count_variable;
2095 file_basename.c_str(),
2096 this->mpi_communicator,
2116 catch (
const typename Triangulation<dim>::DistortedCellList &)
2128 attached_count_fixed,
2129 attached_count_variable);
2132 this->
signals.post_distributed_load();
2140 template <
int dim,
int spacedim>
2143 const typename ::
internal::p4est::
types<dim>::forest *forest)
2147 "load() only works if the Triangulation already contains "
2151 "Coarse mesh of the Triangulation does not match the one "
2152 "of the provided forest!"));
2168 typename ::internal::p4est::types<dim>::forest *temp =
2169 const_cast<typename ::internal::p4est::types<dim>::forest *
>(
2180 catch (
const typename Triangulation<dim>::DistortedCellList &)
2193 template <
int dim,
int spacedim>
2199 "Can't produce a check sum when no forest is created yet."));
2204# if !DEAL_II_P4EST_VERSION_GTE(2, 8, 6, 0)
2220 template <
int dim,
int spacedim>
2222 const typename ::internal::p4est::types<dim>::forest
2226 ExcMessage(
"The forest has not been allocated yet."));
2232 template <
int dim,
int spacedim>
2234 typename ::internal::p4est::types<dim>::tree
2236 const int dealii_coarse_cell_index)
const
2238 const unsigned int tree_index =
2240 typename ::internal::p4est::types<dim>::tree *tree =
2241 static_cast<typename ::internal::p4est::types<dim>::tree *
>(
2256 std::integral_constant<int, 2>)
2258 const unsigned int dim = 2, spacedim = 2;
2266 std::vector<unsigned int> vertex_touch_count;
2268 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2271 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2272 const ::internal::p4est::types<2>::locidx num_vtt =
2273 std::accumulate(vertex_touch_count.begin(),
2274 vertex_touch_count.end(),
2280 const bool set_vertex_info = this->are_vertices_communicated_to_p4est();
2283 (set_vertex_info ==
true ? this->n_vertices() : 0),
2288 set_vertex_and_cell_info(*
this,
2291 coarse_cell_to_p4est_tree_permutation,
2295 Assert(p4est_connectivity_is_valid(connectivity) == 1,
2300 this->mpi_communicator,
2317 std::integral_constant<int, 2>)
2319 const unsigned int dim = 2, spacedim = 3;
2327 std::vector<unsigned int> vertex_touch_count;
2329 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2332 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2333 const ::internal::p4est::types<2>::locidx num_vtt =
2334 std::accumulate(vertex_touch_count.begin(),
2335 vertex_touch_count.end(),
2341 const bool set_vertex_info = this->are_vertices_communicated_to_p4est();
2344 (set_vertex_info ==
true ? this->n_vertices() : 0),
2349 set_vertex_and_cell_info(*
this,
2352 coarse_cell_to_p4est_tree_permutation,
2356 Assert(p4est_connectivity_is_valid(connectivity) == 1,
2361 this->mpi_communicator,
2376 std::integral_constant<int, 3>)
2378 const int dim = 3, spacedim = 3;
2386 std::vector<unsigned int> vertex_touch_count;
2387 std::vector<std::list<
2388 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
2390 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2391 const ::internal::p4est::types<2>::locidx num_vtt =
2392 std::accumulate(vertex_touch_count.begin(),
2393 vertex_touch_count.end(),
2396 std::vector<unsigned int> edge_touch_count;
2397 std::vector<std::list<
2398 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
2400 get_edge_to_cell_mappings(*
this, edge_touch_count, edge_to_cell);
2401 const ::internal::p4est::types<2>::locidx num_ett =
2402 std::accumulate(edge_touch_count.begin(), edge_touch_count.end(), 0u);
2405 const bool set_vertex_info = this->are_vertices_communicated_to_p4est();
2408 (set_vertex_info ==
true ? this->n_vertices() : 0),
2410 this->n_active_lines(),
2415 set_vertex_and_cell_info(*
this,
2418 coarse_cell_to_p4est_tree_permutation,
2447 const unsigned int deal_to_p4est_line_index[12] = {
2448 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11};
2451 this->begin_active();
2452 cell != this->
end();
2455 const unsigned int index =
2456 coarse_cell_to_p4est_tree_permutation[cell->
index()];
2457 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_cell; ++
e)
2459 deal_to_p4est_line_index[e]] =
2460 cell->
line(e)->index();
2465 connectivity->ett_offset[0] = 0;
2466 std::partial_sum(edge_touch_count.begin(),
2467 edge_touch_count.end(),
2468 &connectivity->ett_offset[1]);
2470 Assert(connectivity->ett_offset[this->n_active_lines()] == num_ett,
2473 for (
unsigned int v = 0; v < this->n_active_lines(); ++v)
2475 Assert(edge_to_cell[v].size() == edge_touch_count[v],
2479 std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2480 unsigned int>>::const_iterator p =
2481 edge_to_cell[v].begin();
2482 for (
unsigned int c = 0; c < edge_touch_count[v]; ++c, ++p)
2484 connectivity->edge_to_tree[connectivity->ett_offset[v] + c] =
2485 coarse_cell_to_p4est_tree_permutation[p->first->index()];
2486 connectivity->edge_to_edge[connectivity->ett_offset[v] + c] =
2487 deal_to_p4est_line_index[p->second];
2491 Assert(p8est_connectivity_is_valid(connectivity) == 1,
2496 this->mpi_communicator,
2513 template <
int dim,
int spacedim>
2515 enforce_mesh_balance_over_periodic_boundaries(
2521 std::vector<bool> flags_before[2];
2525 std::vector<unsigned int> topological_vertex_numbering(
2527 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
2528 topological_vertex_numbering[i] = i;
2546 using cell_iterator =
2550 const cell_iterator &cell_1 = it.first.first;
2551 const unsigned int face_no_1 = it.first.second;
2552 const cell_iterator &cell_2 = it.second.first.first;
2553 const unsigned int face_no_2 = it.second.first.second;
2554 const auto combined_orientation = it.second.second;
2556 if (cell_1->level() == cell_2->level())
2558 for (
const unsigned int v :
2559 cell_1->face(face_no_1)->vertex_indices())
2563 const unsigned int vface1 =
2564 cell_1->reference_cell().standard_to_real_face_vertex(
2565 v, face_no_1, combined_orientation);
2566 const unsigned int vi1 =
2567 topological_vertex_numbering[cell_1->face(face_no_1)
2568 ->vertex_index(vface1)];
2569 const unsigned int vi2 =
2570 topological_vertex_numbering[cell_2->face(face_no_2)
2572 const unsigned int min_index =
std::min(vi1, vi2);
2573 topological_vertex_numbering[cell_1->face(face_no_1)
2574 ->vertex_index(vface1)] =
2575 topological_vertex_numbering[cell_2->face(face_no_2)
2576 ->vertex_index(v)] =
2585 for (
unsigned int i = 0; i < topological_vertex_numbering.size();
2588 const unsigned int j = topological_vertex_numbering[i];
2589 Assert(j == i || topological_vertex_numbering[j] == j,
2591 "Got inconclusive constraints with chain: " +
2592 std::to_string(i) +
" vs " + std::to_string(j) +
2593 " which should be equal to " +
2594 std::to_string(topological_vertex_numbering[j])));
2601 bool continue_iterating =
true;
2602 std::vector<int> vertex_level(tria.
n_vertices());
2603 while (continue_iterating)
2607 std::fill(vertex_level.begin(), vertex_level.end(), 0);
2611 for (; cell != endc; ++cell)
2613 if (cell->refine_flag_set())
2614 for (
const unsigned int vertex :
2616 vertex_level[topological_vertex_numbering
2617 [cell->vertex_index(vertex)]] =
2618 std::max(vertex_level[topological_vertex_numbering
2619 [cell->vertex_index(vertex)]],
2621 else if (!cell->coarsen_flag_set())
2622 for (
const unsigned int vertex :
2624 vertex_level[topological_vertex_numbering
2625 [cell->vertex_index(vertex)]] =
2626 std::max(vertex_level[topological_vertex_numbering
2627 [cell->vertex_index(vertex)]],
2638 for (
const unsigned int vertex :
2640 vertex_level[topological_vertex_numbering
2641 [cell->vertex_index(vertex)]] =
2642 std::max(vertex_level[topological_vertex_numbering
2643 [cell->vertex_index(vertex)]],
2648 continue_iterating =
false;
2659 for (cell = tria.
last_active(); cell != endc; --cell)
2660 if (cell->refine_flag_set() ==
false)
2662 for (
const unsigned int vertex :
2664 if (vertex_level[topological_vertex_numbering
2665 [cell->vertex_index(vertex)]] >=
2669 cell->clear_coarsen_flag();
2674 if (vertex_level[topological_vertex_numbering
2675 [cell->vertex_index(vertex)]] >
2678 cell->set_refine_flag();
2679 continue_iterating =
true;
2681 for (
const unsigned int v :
2683 vertex_level[topological_vertex_numbering
2684 [cell->vertex_index(v)]] =
2686 vertex_level[topological_vertex_numbering
2687 [cell->vertex_index(v)]],
2701 if (cell->is_active())
2704 const unsigned int n_children = cell->n_children();
2705 unsigned int flagged_children = 0;
2706 for (
unsigned int child = 0; child < n_children; ++child)
2707 if (cell->child(child)->is_active() &&
2708 cell->child(child)->coarsen_flag_set())
2713 if (flagged_children < n_children)
2714 for (
unsigned int child = 0; child < n_children; ++child)
2715 if (cell->child(child)->is_active())
2716 cell->child(child)->clear_coarsen_flag();
2719 std::vector<bool> flags_after[2];
2722 return ((flags_before[0] != flags_after[0]) ||
2723 (flags_before[1] != flags_after[1]));
2729 template <
int dim,
int spacedim>
2748 template <
int dim,
int spacedim>
2776 bool mesh_changed =
false;
2792 for (
const auto &cell :
2795 cell->set_coarsen_flag();
2803 const typename Triangulation<dim, spacedim>::DistortedCellList &)
2821 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
2822 P4EST_CONNECT_CORNER) :
2823 typename ::internal::p4est::types<dim>::balance_type(
2824 P8EST_CONNECT_CORNER)));
2841 if (tree_exists_locally<dim, spacedim>(
2846 delete_all_children<dim, spacedim>(cell);
2847 if (cell->is_active())
2856 typename ::internal::p4est::types<dim>::quadrant
2858 typename ::internal::p4est::types<dim>::tree *tree =
2864 match_tree_recursively<dim, spacedim>(*tree,
2868 this->my_subdomain);
2875 typename ::internal::p4est::types<dim>::quadrant *quadr;
2877 typename ::internal::p4est::types<dim>::topidx ghost_tree = 0;
2879 for (
unsigned int g_idx = 0;
2883 while (g_idx >=
static_cast<unsigned int>(
2886 while (g_idx >=
static_cast<unsigned int>(
2890 quadr =
static_cast<
2891 typename ::internal::p4est::types<dim>::quadrant *
>(
2894 unsigned int coarse_cell_index =
2897 match_quadrant<dim, spacedim>(
this,
2912 bool mesh_changed =
true;
2913 unsigned int loop_counter = 0;
2923 enforce_mesh_balance_over_periodic_boundaries(*
this);
2935 "parallel::distributed::Triangulation::copy_local_forest_to_triangulation() "
2936 "for periodic boundaries detected. Aborting."));
2938 while (mesh_changed);
2946 return cell.refine_flag_set() ||
2947 cell.coarsen_flag_set();
2958 const typename Triangulation<dim, spacedim>::DistortedCellList &)
2965 while (mesh_changed);
2970 unsigned int num_ghosts = 0;
2974 if (cell->subdomain_id() != this->my_subdomain &&
2996 for (
unsigned int lvl = this->
n_levels(); lvl > 0;)
3001 if ((cell->is_active() &&
3002 cell->subdomain_id() ==
3003 this->locally_owned_subdomain()) ||
3004 (cell->has_children() &&
3005 cell->child(0)->level_subdomain_id() ==
3006 this->locally_owned_subdomain()))
3007 cell->set_level_subdomain_id(
3012 cell->set_level_subdomain_id(
3020 std::vector<std::vector<bool>> marked_vertices(this->
n_levels());
3021 for (
unsigned int lvl = 0; lvl < this->
n_levels(); ++lvl)
3026 typename ::internal::p4est::types<dim>::quadrant
3028 const unsigned int tree_index =
3030 typename ::internal::p4est::types<dim>::tree *tree =
3036 determine_level_subdomain_id_recursively<dim, spacedim>(
3047 for (
unsigned int lvl = this->n_levels(); lvl > 0;)
3052 if (cell->has_children())
3053 for (
unsigned int c = 0;
3054 c < GeometryInfo<dim>::max_children_per_cell;
3057 if (cell->child(c)->level_subdomain_id() ==
3058 this->locally_owned_subdomain())
3063 cell->child(0)->level_subdomain_id();
3067 cell->set_level_subdomain_id(mark);
3091 Assert(
static_cast<unsigned int>(
3098 Assert(
static_cast<unsigned int>(
3105 unsigned int n_owned = 0;
3108 if (cell->subdomain_id() == this->my_subdomain)
3112 Assert(
static_cast<unsigned int>(
3129 template <
int dim,
int spacedim>
3135 std::vector<Point<dim>> point{p};
3143 template <
int dim,
int spacedim>
3151 "Vertices need to be communicated to p4est to use this "
3152 "function. This must explicitly be turned on in the "
3153 "settings of the triangulation's constructor."));
3161 "This function can only be used if the triangulation "
3162 "has no other manifold than a Cartesian (flat) manifold attached."));
3166 PartitionSearch<dim> partition_search;
3178 sc_array_t *point_sc_array;
3182 sc_array_new_count(
sizeof(
double[dim + 1]), points.size());
3185 for (
size_t i = 0; i < points.size(); ++i)
3190 double *this_sc_point =
3191 static_cast<double *
>(sc_array_index_ssize_t(point_sc_array, i));
3193 for (
unsigned int d = 0; d < dim; ++d)
3195 this_sc_point[d] = p(d);
3197 this_sc_point[dim] = -1.0;
3203 static_cast<int>(
false),
3204 &PartitionSearch<dim>::local_quadrant_fn,
3205 &PartitionSearch<dim>::local_point_fn,
3209 std::vector<types::subdomain_id> owner_rank(
3213 for (
size_t i = 0; i < points.size(); ++i)
3216 double *this_sc_point =
3217 static_cast<double *
>(sc_array_index_ssize_t(point_sc_array, i));
3218 Assert(this_sc_point[dim] >= 0. || this_sc_point[dim] == -1.,
3220 if (this_sc_point[dim] < 0.)
3231 sc_array_destroy_null(&point_sc_array);
3238 template <
int dim,
int spacedim>
3246 if (cell->is_locally_owned() && cell->refine_flag_set())
3247 Assert(cell->refine_flag_set() ==
3250 "This class does not support anisotropic refinement"));
3267 !(cell->refine_flag_set()),
3269 "Fatal Error: maximum refinement level of p4est reached."));
3276 this->
signals.pre_distributed_refinement();
3282 if (cell->is_ghost() || cell->is_artificial())
3284 cell->clear_refine_flag();
3285 cell->clear_coarsen_flag();
3291 RefineAndCoarsenList<dim, spacedim> refine_and_coarsen_list(
3310 &RefineAndCoarsenList<dim, spacedim>::refine_callback,
3315 &RefineAndCoarsenList<dim, spacedim>::coarsen_callback,
3328 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
3329 P4EST_CONNECT_FULL) :
3330 typename ::internal::p4est::types<dim>::balance_type(
3331 P8EST_CONNECT_FULL)),
3340 this->
signals.post_p4est_refinement();
3344 std::vector<typename ::internal::p4est::types<dim>::gloidx>
3345 previous_global_first_quadrant;
3350 std::memcpy(previous_global_first_quadrant.data(),
3353 typename ::internal::p4est::types<dim>::gloidx) *
3361 if (this->
signals.weight.empty())
3375 this->mpi_communicator) > 0,
3377 "The global sum of weights over all active cells "
3378 "is zero. Please verify how you generate weights."));
3380 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
3391 &PartitionWeights<dim, spacedim>::cell_weight);
3407 this->cell_attached_data.pack_callbacks_variable,
3408 this->get_mpi_communicator());
3416 cell->clear_refine_flag();
3417 cell->clear_coarsen_flag();
3424 catch (
const typename Triangulation<dim>::DistortedCellList &)
3435 previous_global_first_quadrant.data());
3464 std::vector<bool> active_verts =
3467 const unsigned int maybe_coarser_lvl =
3468 (lvl > 0) ? (lvl - 1) : lvl;
3470 cell = this->
begin(maybe_coarser_lvl),
3471 endc = this->
end(lvl);
3472 for (; cell != endc; ++cell)
3473 if (cell->level() ==
static_cast<int>(lvl) ||
3476 const bool is_level_artificial =
3477 (cell->level_subdomain_id() ==
3479 bool need_to_know =
false;
3480 for (
const unsigned int vertex :
3482 if (active_verts[cell->vertex_index(vertex)])
3484 need_to_know =
true;
3489 !need_to_know || !is_level_artificial,
3491 "Internal error: the owner of cell" +
3492 cell->id().to_string() +
3493 " is unknown even though it is needed for geometric multigrid."));
3503 this->
signals.post_distributed_refinement();
3508 template <
int dim,
int spacedim>
3515 if (cell->is_locally_owned())
3517 !cell->refine_flag_set() && !cell->coarsen_flag_set(),
3519 "Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition()."));
3523 this->
signals.pre_distributed_repartition();
3527 std::vector<typename ::internal::p4est::types<dim>::gloidx>
3528 previous_global_first_quadrant;
3532 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
3533 std::memcpy(previous_global_first_quadrant.data(),
3534 parallel_forest->global_first_quadrant,
3536 typename ::internal::p4est::types<dim>::gloidx) *
3537 (parallel_forest->mpisize + 1));
3540 if (this->
signals.weight.empty())
3544 ::internal::p4est::functions<dim>::partition(
3552 const std::vector<unsigned int> cell_weights = get_cell_weights();
3555 Assert(Utilities::MPI::sum(std::accumulate(cell_weights.begin(),
3558 this->mpi_communicator) > 0,
3560 "The global sum of weights over all active cells "
3561 "is zero. Please verify how you generate weights."));
3563 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
3567 Assert(parallel_forest->user_pointer == this, ExcInternalError());
3568 parallel_forest->user_pointer = &partition_weights;
3570 ::internal::p4est::functions<dim>::partition(
3574 &PartitionWeights<dim, spacedim>::cell_weight);
3577 parallel_forest->user_pointer = this;
3583 this->data_serializer.pack_data(
3584 this->local_cell_relations,
3585 this->cell_attached_data.pack_callbacks_fixed,
3586 this->cell_attached_data.pack_callbacks_variable,
3587 this->get_mpi_communicator());
3592 copy_local_forest_to_triangulation();
3594 catch (
const typename Triangulation<dim>::DistortedCellList &)
3604 this->execute_transfer(parallel_forest,
3605 previous_global_first_quadrant.data());
3608 this->update_periodic_face_map();
3611 this->update_number_cache();
3614 this->signals.post_distributed_repartition();
3619 template <
int dim,
int spacedim>
3621 const std::vector<types::global_dof_index>
3630 template <
int dim,
int spacedim>
3632 const std::vector<types::global_dof_index>
3641 template <
int dim,
int spacedim>
3648 std::vector<bool> marked_vertices(this->
n_vertices(),
false);
3650 if (cell->level_subdomain_id() == this->locally_owned_subdomain())
3652 marked_vertices[cell->vertex_index(v)] =
true;
3669 for (
unsigned int repetition = 0; repetition < dim; ++repetition)
3673 const unsigned int face_no_1 = it.first.second;
3675 const unsigned int face_no_2 = it.second.first.second;
3676 const auto combined_orientation = it.second.second;
3677 const auto [orientation, rotation, flip] =
3680 if (cell_1->level() == level && cell_2->level() == level)
3682 for (
unsigned int v = 0;
3688 const unsigned int vface0 =
3690 v, orientation, flip, rotation);
3691 if (marked_vertices[cell_1->face(face_no_1)->vertex_index(
3693 marked_vertices[cell_2->face(face_no_2)->vertex_index(
3695 marked_vertices[cell_1->face(face_no_1)->vertex_index(
3697 marked_vertices[cell_2->face(face_no_2)->vertex_index(
3703 return marked_vertices;
3708 template <
int dim,
int spacedim>
3712 const
types::coarse_cell_id coarse_cell_id)
const
3719 template <
int dim,
int spacedim>
3723 const unsigned int coarse_cell_index)
const