907 for (
unsigned int alpha = 0;
908 alpha < GeometryInfo<dim>::vertices_per_cell;
912 point_matrix(0, alpha) = 1;
913 point_matrix(1, alpha) = cell_vertices[alpha](0);
914 point_matrix(2, alpha) = cell_vertices[alpha](1);
915 point_matrix(3, alpha) = cell_vertices[alpha](2);
916 point_matrix(4, alpha) =
917 cell_vertices[alpha](0) * cell_vertices[alpha](1);
918 point_matrix(5, alpha) =
919 cell_vertices[alpha](1) * cell_vertices[alpha](2);
920 point_matrix(6, alpha) =
921 cell_vertices[alpha](0) * cell_vertices[alpha](2);
922 point_matrix(7, alpha) = cell_vertices[alpha](0) *
923 cell_vertices[alpha](1) *
924 cell_vertices[alpha](2);
931 quadrant_mapping_matrix.invert(point_matrix);
934 is_reference_mapping_initialized =
true;
941 PartitionSearch<2>::QuadrantData::set_cell_vertices(
946 quad_length_on_level)
948 constexpr unsigned int dim = 2;
952 double corner_point[dim + 1] = {0};
955 const auto copy_vertex = [&](
unsigned int vertex_index) ->
void {
957 for (
unsigned int d = 0;
d < dim; ++
d)
959 cell_vertices[vertex_index](
d) = corner_point[d];
969 unsigned int vertex_index = 0;
970 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
971 forest->connectivity, which_tree, quadrant->x, quadrant->y, corner_point);
974 copy_vertex(vertex_index);
980 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
981 forest->connectivity,
983 quadrant->x + quad_length_on_level,
988 copy_vertex(vertex_index);
994 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
995 forest->connectivity,
998 quadrant->y + quad_length_on_level,
1002 copy_vertex(vertex_index);
1008 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1009 forest->connectivity,
1011 quadrant->x + quad_length_on_level,
1012 quadrant->y + quad_length_on_level,
1016 copy_vertex(vertex_index);
1018 are_vertices_initialized =
true;
1025 PartitionSearch<3>::QuadrantData::set_cell_vertices(
1030 quad_length_on_level)
1032 constexpr unsigned int dim = 3;
1034 double corner_point[dim] = {0};
1037 auto copy_vertex = [&](
unsigned int vertex_index) ->
void {
1039 for (
unsigned int d = 0;
d < dim; ++
d)
1041 cell_vertices[vertex_index](
d) = corner_point[d];
1043 corner_point[
d] = 0;
1051 unsigned int vertex_index = 0;
1052 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1053 forest->connectivity,
1061 copy_vertex(vertex_index);
1068 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1069 forest->connectivity,
1071 quadrant->x + quad_length_on_level,
1077 copy_vertex(vertex_index);
1083 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1084 forest->connectivity,
1087 quadrant->y + quad_length_on_level,
1092 copy_vertex(vertex_index);
1098 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1099 forest->connectivity,
1101 quadrant->x + quad_length_on_level,
1102 quadrant->y + quad_length_on_level,
1107 copy_vertex(vertex_index);
1113 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1114 forest->connectivity,
1118 quadrant->z + quad_length_on_level,
1122 copy_vertex(vertex_index);
1128 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1129 forest->connectivity,
1131 quadrant->x + quad_length_on_level,
1133 quadrant->z + quad_length_on_level,
1137 copy_vertex(vertex_index);
1143 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1144 forest->connectivity,
1147 quadrant->y + quad_length_on_level,
1148 quadrant->z + quad_length_on_level,
1152 copy_vertex(vertex_index);
1158 internal::p4est::functions<dim>::quadrant_coord_to_vertex(
1159 forest->connectivity,
1161 quadrant->x + quad_length_on_level,
1162 quadrant->y + quad_length_on_level,
1163 quadrant->z + quad_length_on_level,
1167 copy_vertex(vertex_index);
1170 are_vertices_initialized =
true;
1180 template <
int dim,
int spacedim>
1181 class RefineAndCoarsenList
1184 RefineAndCoarsenList(
const Triangulation<dim, spacedim> &triangulation,
1185 const std::vector<types::global_dof_index>
1186 &p4est_tree_to_coarse_cell_permutation,
1199 typename internal::p4est::types<dim>::forest *forest,
1200 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1201 typename internal::p4est::types<dim>::quadrant *quadrant);
1209 typename internal::p4est::types<dim>::forest *forest,
1210 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1211 typename internal::p4est::types<dim>::quadrant *children[]);
1214 pointers_are_at_end()
const;
1217 std::vector<typename internal::p4est::types<dim>::quadrant> refine_list;
1218 typename std::vector<typename internal::p4est::types<dim>::quadrant>::
1219 const_iterator current_refine_pointer;
1221 std::vector<typename internal::p4est::types<dim>::quadrant> coarsen_list;
1222 typename std::vector<typename internal::p4est::types<dim>::quadrant>::
1223 const_iterator current_coarsen_pointer;
1228 const typename internal::p4est::types<dim>::quadrant &p4est_cell,
1234 template <
int dim,
int spacedim>
1236 RefineAndCoarsenList<dim, spacedim>::pointers_are_at_end()
const
1238 return ((current_refine_pointer == refine_list.end()) &&
1239 (current_coarsen_pointer == coarsen_list.end()));
1244 template <
int dim,
int spacedim>
1245 RefineAndCoarsenList<dim, spacedim>::RefineAndCoarsenList(
1247 const std::vector<types::global_dof_index>
1248 &p4est_tree_to_coarse_cell_permutation,
1252 unsigned int n_refine_flags = 0, n_coarsen_flags = 0;
1265 refine_list.reserve(n_refine_flags);
1266 coarsen_list.reserve(n_coarsen_flags);
1276 for (
unsigned int c = 0; c < triangulation.
n_cells(0); ++c)
1278 unsigned int coarse_cell_index =
1279 p4est_tree_to_coarse_cell_permutation[c];
1282 &triangulation, 0, coarse_cell_index);
1284 typename internal::p4est::types<dim>::quadrant p4est_cell;
1285 internal::p4est::functions<dim>::quadrant_set_morton(&p4est_cell,
1288 p4est_cell.p.which_tree = c;
1289 build_lists(cell, p4est_cell, my_subdomain);
1297 for (
unsigned int i = 1; i < refine_list.size(); ++i)
1298 Assert(refine_list[i].p.which_tree >= refine_list[i - 1].p.which_tree,
1300 for (
unsigned int i = 1; i < coarsen_list.size(); ++i)
1301 Assert(coarsen_list[i].p.which_tree >= coarsen_list[i - 1].p.which_tree,
1304 current_refine_pointer = refine_list.begin();
1305 current_coarsen_pointer = coarsen_list.begin();
1310 template <
int dim,
int spacedim>
1312 RefineAndCoarsenList<dim, spacedim>::build_lists(
1314 const typename internal::p4est::types<dim>::quadrant &p4est_cell,
1322 refine_list.push_back(p4est_cell);
1324 coarsen_list.push_back(p4est_cell);
1329 typename internal::p4est::types<dim>::quadrant
1331 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1333 internal::p4est::functions<dim>::quadrant_init(p4est_child[c]);
1334 internal::p4est::functions<dim>::quadrant_childrenv(&p4est_cell,
1336 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1339 p4est_child[c].p.which_tree = p4est_cell.p.which_tree;
1340 build_lists(cell->
child(c), p4est_child[c], my_subdomain);
1346 template <
int dim,
int spacedim>
1348 RefineAndCoarsenList<dim, spacedim>::refine_callback(
1349 typename internal::p4est::types<dim>::forest *forest,
1350 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1351 typename internal::p4est::types<dim>::quadrant *quadrant)
1353 RefineAndCoarsenList<dim, spacedim> *this_object =
1354 reinterpret_cast<RefineAndCoarsenList<dim, spacedim> *
>(
1355 forest->user_pointer);
1359 if (this_object->current_refine_pointer == this_object->refine_list.end())
1362 Assert(coarse_cell_index <=
1363 this_object->current_refine_pointer->p.which_tree,
1368 if (coarse_cell_index < this_object->current_refine_pointer->p.which_tree)
1372 Assert(coarse_cell_index <=
1373 this_object->current_refine_pointer->p.which_tree,
1378 Assert(internal::p4est::functions<dim>::quadrant_compare(
1379 quadrant, &*this_object->current_refine_pointer) <= 0,
1383 if (internal::p4est::functions<dim>::quadrant_is_equal(
1384 quadrant, &*this_object->current_refine_pointer))
1386 ++this_object->current_refine_pointer;
1396 template <
int dim,
int spacedim>
1398 RefineAndCoarsenList<dim, spacedim>::coarsen_callback(
1399 typename internal::p4est::types<dim>::forest *forest,
1400 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1401 typename internal::p4est::types<dim>::quadrant *children[])
1403 RefineAndCoarsenList<dim, spacedim> *this_object =
1404 reinterpret_cast<RefineAndCoarsenList<dim, spacedim> *
>(
1405 forest->user_pointer);
1409 if (this_object->current_coarsen_pointer == this_object->coarsen_list.end())
1412 Assert(coarse_cell_index <=
1413 this_object->current_coarsen_pointer->p.which_tree,
1418 if (coarse_cell_index < this_object->current_coarsen_pointer->p.which_tree)
1422 Assert(coarse_cell_index <=
1423 this_object->current_coarsen_pointer->p.which_tree,
1428 Assert(internal::p4est::functions<dim>::quadrant_compare(
1429 children[0], &*this_object->current_coarsen_pointer) <= 0,
1434 if (internal::p4est::functions<dim>::quadrant_is_equal(
1435 children[0], &*this_object->current_coarsen_pointer))
1438 ++this_object->current_coarsen_pointer;
1442 for (
unsigned int c = 1; c < GeometryInfo<dim>::max_children_per_cell;
1445 Assert(internal::p4est::functions<dim>::quadrant_is_equal(
1446 children[c], &*this_object->current_coarsen_pointer),
1448 ++this_object->current_coarsen_pointer;
1466 template <
int dim,
int spacedim>
1467 class PartitionWeights
1475 explicit PartitionWeights(
const std::vector<unsigned int> &cell_weights);
1485 cell_weight(
typename internal::p4est::types<dim>::forest *forest,
1486 typename internal::p4est::types<dim>::topidx coarse_cell_index,
1487 typename internal::p4est::types<dim>::quadrant *quadrant);
1490 std::vector<unsigned int> cell_weights_list;
1491 std::vector<unsigned int>::const_iterator current_pointer;
1495 template <
int dim,
int spacedim>
1496 PartitionWeights<dim, spacedim>::PartitionWeights(
1497 const std::vector<unsigned int> &cell_weights)
1498 : cell_weights_list(cell_weights)
1502 current_pointer = cell_weights_list.begin();
1506 template <
int dim,
int spacedim>
1508 PartitionWeights<dim, spacedim>::cell_weight(
1509 typename internal::p4est::types<dim>::forest *forest,
1510 typename internal::p4est::types<dim>::topidx,
1511 typename internal::p4est::types<dim>::quadrant *)
1517 PartitionWeights<dim, spacedim> *this_object =
1518 reinterpret_cast<PartitionWeights<dim, spacedim> *
>(forest->user_pointer);
1520 Assert(this_object->current_pointer >=
1521 this_object->cell_weights_list.begin(),
1523 Assert(this_object->current_pointer < this_object->cell_weights_list.end(),
1529 const unsigned int weight = *this_object->current_pointer;
1530 ++this_object->current_pointer;
1532 Assert(weight <
static_cast<unsigned int>(std::numeric_limits<int>::max()),
1533 ExcMessage(
"p4est uses 'signed int' to represent the partition "
1534 "weights for cells. The weight provided here exceeds "
1535 "the maximum value represented as a 'signed int'."));
1536 return static_cast<int>(weight);
1539 template <
int dim,
int spacedim>
1540 using cell_relation_t =
typename std::pair<
1541 typename ::Triangulation<dim, spacedim>::cell_iterator,
1553 template <
int dim,
int spacedim>
1555 add_single_cell_relation(
1556 std::vector<cell_relation_t<dim, spacedim>> &cell_rel,
1557 const typename ::internal::p4est::types<dim>::tree &tree,
1558 const unsigned int idx,
1562 const unsigned int local_quadrant_index = tree.quadrants_offset + idx;
1568 cell_rel[local_quadrant_index] = std::make_pair(dealii_cell, status);
1582 template <
int dim,
int spacedim>
1584 update_cell_relations_recursively(
1585 std::vector<cell_relation_t<dim, spacedim>> &cell_rel,
1586 const typename ::internal::p4est::types<dim>::tree &tree,
1588 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell)
1591 const int idx = sc_array_bsearch(
1592 const_cast<sc_array_t *
>(&tree.quadrants),
1594 ::internal::p4est::functions<dim>::quadrant_compare);
1596 (::internal::p4est::functions<dim>::quadrant_overlaps_tree(
1597 const_cast<typename ::internal::p4est::types<dim>::tree *
>(
1599 &p4est_cell) ==
false))
1604 const bool p4est_has_children = (idx == -1);
1608 typename ::internal::p4est::types<dim>::quadrant
1611 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1613 internal::p4est::functions<dim>::quadrant_init(p4est_child[c]);
1615 ::internal::p4est::functions<dim>::quadrant_childrenv(
1616 &p4est_cell, p4est_child);
1618 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1621 update_cell_relations_recursively<dim, spacedim>(
1622 cell_rel, tree, dealii_cell->
child(c), p4est_child[c]);
1625 else if (!p4est_has_children && !dealii_cell->
has_children())
1629 add_single_cell_relation<dim, spacedim>(
1632 else if (p4est_has_children)
1640 typename ::internal::p4est::types<dim>::quadrant
1642 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1644 internal::p4est::functions<dim>::quadrant_init(p4est_child[c]);
1646 ::internal::p4est::functions<dim>::quadrant_childrenv(
1647 &p4est_cell, p4est_child);
1655 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
1658 child_idx = sc_array_bsearch(
1659 const_cast<sc_array_t *
>(&tree.quadrants),
1661 ::internal::p4est::functions<dim>::quadrant_compare);
1666 add_single_cell_relation<dim, spacedim>(
1667 cell_rel, tree, child_idx, dealii_cell, cell_status);
1675 add_single_cell_relation<dim, spacedim>(
1692 template <
int dim,
int spacedim>
1721 template <
int dim,
int spacedim>
1743 template <
int dim,
int spacedim>
1756 const typename ::Triangulation<dim, spacedim>::DistortedCellList
1767 "The class parallel::distributed::Triangulation only supports meshes "
1768 "consisting only of hypercube-like cells."));
1783 catch (
const typename Triangulation<dim>::DistortedCellList &)
1796 template <
int dim,
int spacedim>
1807 template <
int dim,
int spacedim>
1843 template <
int dim,
int spacedim>
1854 template <
int dim,
int spacedim>
1865 template <
int dim,
int spacedim>
1871 *previous_global_first_quadrant)
1879 this->data_serializer.sizes_fixed_cumulative.back());
1882 typename ::internal::p4est::types<dim>::transfer_context
1887 previous_global_first_quadrant,
1890 this->data_serializer.dest_data_fixed.data(),
1891 this->data_serializer.src_data_fixed.data(),
1892 this->data_serializer.sizes_fixed_cumulative.back());
1904 previous_global_first_quadrant,
1907 this->data_serializer.dest_sizes_variable.data(),
1908 this->data_serializer.src_sizes_variable.data(),
1909 sizeof(
unsigned int));
1923 this->data_serializer.dest_sizes_variable.end(),
1924 std::vector<int>::size_type(0)));
1929 previous_global_first_quadrant,
1932 this->data_serializer.dest_data_variable.data(),
1933 this->data_serializer.dest_sizes_variable.data(),
1934 this->data_serializer.src_data_variable.data(),
1935 this->data_serializer.src_sizes_variable.data());
1947 template <
int dim,
int spacedim>
1965 template <
int dim,
int spacedim>
1968 const
std::
string &file_basename)
const
1971 ExcMessage(
"Can't produce output when no forest is created yet."));
1975 "To use this function the triangulation's flag "
1976 "Settings::communicate_vertices_to_p4est must be set."));
1984 template <
int dim,
int spacedim>
1987 const
std::
string &file_basename)
const
1992 "Not all SolutionTransfer objects have been deserialized after the last call to load()."));
1994 ExcMessage(
"Can not save() an empty Triangulation."));
2000 this->
signals.pre_distributed_save();
2002 if (this->my_subdomain == 0)
2004 std::string fname = file_basename +
".info";
2005 std::ofstream f(fname);
2006 f <<
"version nproc n_attached_fixed_size_objs n_attached_variable_size_objs n_coarse_cells"
2012 << this->
n_cells(0) << std::endl;
2018 Assert((cell_rel.second ==
2033 this->
signals.post_distributed_save();
2038 template <
int dim,
int spacedim>
2045 "load() only works if the Triangulation already contains a coarse mesh!"));
2049 "Triangulation may only contain coarse cells when calling load()."));
2055 this->
signals.pre_distributed_load();
2069 unsigned int version, numcpus, attached_count_fixed,
2070 attached_count_variable, n_coarse_cells;
2072 std::string fname = std::string(file_basename) +
".info";
2073 std::ifstream f(fname);
2075 std::string firstline;
2076 getline(f, firstline);
2077 f >> version >> numcpus >> attached_count_fixed >>
2078 attached_count_variable >> n_coarse_cells;
2082 ExcMessage(
"Incompatible version found in .info file."));
2084 ExcMessage(
"Number of coarse cells differ!"));
2090 attached_count_fixed + attached_count_variable;
2093 file_basename.c_str(),
2094 this->mpi_communicator,
2114 catch (
const typename Triangulation<dim>::DistortedCellList &)
2126 attached_count_fixed,
2127 attached_count_variable);
2130 this->
signals.post_distributed_load();
2138 template <
int dim,
int spacedim>
2141 const typename ::
internal::p4est::
types<dim>::forest *forest)
2145 "load() only works if the Triangulation already contains "
2149 "Coarse mesh of the Triangulation does not match the one "
2150 "of the provided forest!"));
2166 typename ::internal::p4est::types<dim>::forest *temp =
2167 const_cast<typename ::internal::p4est::types<dim>::forest *
>(
2178 catch (
const typename Triangulation<dim>::DistortedCellList &)
2191 template <
int dim,
int spacedim>
2197 "Can't produce a check sum when no forest is created yet."));
2202# if !DEAL_II_P4EST_VERSION_GTE(2, 8, 6, 0)
2218 template <
int dim,
int spacedim>
2220 const typename ::internal::p4est::types<dim>::forest
2224 ExcMessage(
"The forest has not been allocated yet."));
2230 template <
int dim,
int spacedim>
2232 typename ::internal::p4est::types<dim>::tree
2234 const int dealii_coarse_cell_index)
const
2236 const unsigned int tree_index =
2238 typename ::internal::p4est::types<dim>::tree *tree =
2239 static_cast<typename ::internal::p4est::types<dim>::tree *
>(
2254 std::integral_constant<int, 2>)
2256 const unsigned int dim = 2, spacedim = 2;
2264 std::vector<unsigned int> vertex_touch_count;
2266 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2269 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2270 const ::internal::p4est::types<2>::locidx num_vtt =
2271 std::accumulate(vertex_touch_count.begin(),
2272 vertex_touch_count.end(),
2278 const bool set_vertex_info = this->are_vertices_communicated_to_p4est();
2281 (set_vertex_info ==
true ? this->n_vertices() : 0),
2286 set_vertex_and_cell_info(*
this,
2289 coarse_cell_to_p4est_tree_permutation,
2293 Assert(p4est_connectivity_is_valid(connectivity) == 1,
2298 this->mpi_communicator,
2315 std::integral_constant<int, 2>)
2317 const unsigned int dim = 2, spacedim = 3;
2325 std::vector<unsigned int> vertex_touch_count;
2327 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2330 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2331 const ::internal::p4est::types<2>::locidx num_vtt =
2332 std::accumulate(vertex_touch_count.begin(),
2333 vertex_touch_count.end(),
2339 const bool set_vertex_info = this->are_vertices_communicated_to_p4est();
2342 (set_vertex_info ==
true ? this->n_vertices() : 0),
2347 set_vertex_and_cell_info(*
this,
2350 coarse_cell_to_p4est_tree_permutation,
2354 Assert(p4est_connectivity_is_valid(connectivity) == 1,
2359 this->mpi_communicator,
2374 std::integral_constant<int, 3>)
2376 const int dim = 3, spacedim = 3;
2384 std::vector<unsigned int> vertex_touch_count;
2385 std::vector<std::list<
2386 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
2388 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2389 const ::internal::p4est::types<2>::locidx num_vtt =
2390 std::accumulate(vertex_touch_count.begin(),
2391 vertex_touch_count.end(),
2394 std::vector<unsigned int> edge_touch_count;
2395 std::vector<std::list<
2396 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
2398 get_edge_to_cell_mappings(*
this, edge_touch_count, edge_to_cell);
2399 const ::internal::p4est::types<2>::locidx num_ett =
2400 std::accumulate(edge_touch_count.begin(), edge_touch_count.end(), 0u);
2403 const bool set_vertex_info = this->are_vertices_communicated_to_p4est();
2406 (set_vertex_info ==
true ? this->n_vertices() : 0),
2408 this->n_active_lines(),
2413 set_vertex_and_cell_info(*
this,
2416 coarse_cell_to_p4est_tree_permutation,
2445 const unsigned int deal_to_p4est_line_index[12] = {
2446 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11};
2448 for (
const auto &cell : this->active_cell_iterators())
2450 const unsigned int index =
2451 coarse_cell_to_p4est_tree_permutation[cell->
index()];
2452 for (
unsigned int e = 0;
e < cell->
n_lines(); ++
e)
2454 deal_to_p4est_line_index[e]] =
2455 cell->
line(e)->index();
2460 connectivity->ett_offset[0] = 0;
2461 std::partial_sum(edge_touch_count.begin(),
2462 edge_touch_count.end(),
2463 &connectivity->ett_offset[1]);
2465 Assert(connectivity->ett_offset[this->n_active_lines()] == num_ett,
2468 for (
unsigned int v = 0; v < this->n_active_lines(); ++v)
2470 Assert(edge_to_cell[v].size() == edge_touch_count[v],
2474 std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2476 edge_to_cell[v].begin();
2477 for (
unsigned int c = 0; c < edge_touch_count[v]; ++c, ++p)
2479 connectivity->edge_to_tree[connectivity->ett_offset[v] + c] =
2480 coarse_cell_to_p4est_tree_permutation[p->first->index()];
2481 connectivity->edge_to_edge[connectivity->ett_offset[v] + c] =
2482 deal_to_p4est_line_index[p->second];
2486 Assert(p8est_connectivity_is_valid(connectivity) == 1,
2491 this->mpi_communicator,
2508 template <
int dim,
int spacedim>
2510 enforce_mesh_balance_over_periodic_boundaries(
2516 std::vector<bool> flags_before[2];
2520 std::vector<unsigned int> topological_vertex_numbering(
2522 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
2523 topological_vertex_numbering[i] = i;
2541 using cell_iterator =
2545 const cell_iterator &cell_1 = it.first.first;
2546 const unsigned int face_no_1 = it.first.second;
2547 const cell_iterator &cell_2 = it.second.first.first;
2548 const unsigned int face_no_2 = it.second.first.second;
2549 const auto combined_orientation = it.second.second;
2551 if (cell_1->level() == cell_2->level())
2553 for (
const unsigned int v :
2554 cell_1->face(face_no_1)->vertex_indices())
2558 const unsigned int vface1 =
2559 cell_1->reference_cell().standard_to_real_face_vertex(
2560 v, face_no_1, combined_orientation);
2561 const unsigned int vi1 =
2562 topological_vertex_numbering[cell_1->face(face_no_1)
2563 ->vertex_index(vface1)];
2564 const unsigned int vi2 =
2565 topological_vertex_numbering[cell_2->face(face_no_2)
2567 const unsigned int min_index =
std::min(vi1, vi2);
2568 topological_vertex_numbering[cell_1->face(face_no_1)
2569 ->vertex_index(vface1)] =
2570 topological_vertex_numbering[cell_2->face(face_no_2)
2571 ->vertex_index(v)] =
2580 for (
unsigned int i = 0; i < topological_vertex_numbering.size();
2583 const unsigned int j = topological_vertex_numbering[i];
2584 Assert(j == i || topological_vertex_numbering[j] == j,
2586 "Got inconclusive constraints with chain: " +
2587 std::to_string(i) +
" vs " + std::to_string(j) +
2588 " which should be equal to " +
2589 std::to_string(topological_vertex_numbering[j])));
2596 bool continue_iterating =
true;
2597 std::vector<int> vertex_level(tria.
n_vertices());
2598 while (continue_iterating)
2602 std::fill(vertex_level.begin(), vertex_level.end(), 0);
2606 for (; cell != endc; ++cell)
2608 if (cell->refine_flag_set())
2609 for (
const unsigned int vertex :
2611 vertex_level[topological_vertex_numbering
2612 [cell->vertex_index(vertex)]] =
2613 std::max(vertex_level[topological_vertex_numbering
2614 [cell->vertex_index(vertex)]],
2616 else if (!cell->coarsen_flag_set())
2617 for (
const unsigned int vertex :
2619 vertex_level[topological_vertex_numbering
2620 [cell->vertex_index(vertex)]] =
2621 std::max(vertex_level[topological_vertex_numbering
2622 [cell->vertex_index(vertex)]],
2633 for (
const unsigned int vertex :
2635 vertex_level[topological_vertex_numbering
2636 [cell->vertex_index(vertex)]] =
2637 std::max(vertex_level[topological_vertex_numbering
2638 [cell->vertex_index(vertex)]],
2643 continue_iterating =
false;
2654 for (cell = tria.
last_active(); cell != endc; --cell)
2655 if (cell->refine_flag_set() ==
false)
2657 for (
const unsigned int vertex :
2659 if (vertex_level[topological_vertex_numbering
2660 [cell->vertex_index(vertex)]] >=
2664 cell->clear_coarsen_flag();
2669 if (vertex_level[topological_vertex_numbering
2670 [cell->vertex_index(vertex)]] >
2673 cell->set_refine_flag();
2674 continue_iterating =
true;
2676 for (
const unsigned int v :
2678 vertex_level[topological_vertex_numbering
2679 [cell->vertex_index(v)]] =
2681 vertex_level[topological_vertex_numbering
2682 [cell->vertex_index(v)]],
2696 if (cell->is_active())
2699 const unsigned int n_children = cell->n_children();
2700 unsigned int flagged_children = 0;
2701 for (
unsigned int child = 0; child < n_children; ++child)
2702 if (cell->child(child)->is_active() &&
2703 cell->child(child)->coarsen_flag_set())
2708 if (flagged_children < n_children)
2709 for (
unsigned int child = 0; child < n_children; ++child)
2710 if (cell->child(child)->is_active())
2711 cell->child(child)->clear_coarsen_flag();
2714 std::vector<bool> flags_after[2];
2717 return ((flags_before[0] != flags_after[0]) ||
2718 (flags_before[1] != flags_after[1]));
2724 template <
int dim,
int spacedim>
2743 template <
int dim,
int spacedim>
2771 bool mesh_changed =
false;
2787 for (
const auto &cell :
2790 cell->set_coarsen_flag();
2798 const typename Triangulation<dim, spacedim>::DistortedCellList &)
2816 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
2817 P4EST_CONNECT_CORNER) :
2818 typename ::internal::p4est::types<dim>::balance_type(
2819 P8EST_CONNECT_CORNER)));
2836 if (tree_exists_locally<dim, spacedim>(
2841 delete_all_children<dim, spacedim>(cell);
2842 if (cell->is_active())
2851 typename ::internal::p4est::types<dim>::quadrant
2853 typename ::internal::p4est::types<dim>::tree *tree =
2859 match_tree_recursively<dim, spacedim>(*tree,
2863 this->my_subdomain);
2870 typename ::internal::p4est::types<dim>::quadrant *quadr;
2872 typename ::internal::p4est::types<dim>::topidx ghost_tree = 0;
2874 for (
unsigned int g_idx = 0;
2878 while (g_idx >=
static_cast<unsigned int>(
2881 while (g_idx >=
static_cast<unsigned int>(
2885 quadr =
static_cast<
2886 typename ::internal::p4est::types<dim>::quadrant *
>(
2889 unsigned int coarse_cell_index =
2892 match_quadrant<dim, spacedim>(
this,
2907 bool mesh_changed =
true;
2908 unsigned int loop_counter = 0;
2918 enforce_mesh_balance_over_periodic_boundaries(*
this);
2930 "parallel::distributed::Triangulation::copy_local_forest_to_triangulation() "
2931 "for periodic boundaries detected. Aborting."));
2933 while (mesh_changed);
2941 return cell.refine_flag_set() ||
2942 cell.coarsen_flag_set();
2953 const typename Triangulation<dim, spacedim>::DistortedCellList &)
2960 while (mesh_changed);
2965 unsigned int num_ghosts = 0;
2969 if (cell->subdomain_id() != this->my_subdomain &&
2991 for (
unsigned int lvl = this->
n_levels(); lvl > 0;)
2996 if ((cell->is_active() &&
2997 cell->subdomain_id() ==
2998 this->locally_owned_subdomain()) ||
2999 (cell->has_children() &&
3000 cell->child(0)->level_subdomain_id() ==
3001 this->locally_owned_subdomain()))
3002 cell->set_level_subdomain_id(
3007 cell->set_level_subdomain_id(
3015 std::vector<std::vector<bool>> marked_vertices(this->
n_levels());
3016 for (
unsigned int lvl = 0; lvl < this->
n_levels(); ++lvl)
3021 typename ::internal::p4est::types<dim>::quadrant
3023 const unsigned int tree_index =
3025 typename ::internal::p4est::types<dim>::tree *tree =
3031 determine_level_subdomain_id_recursively<dim, spacedim>(
3042 for (
unsigned int lvl = this->n_levels(); lvl > 0;)
3047 if (cell->has_children())
3048 for (
unsigned int c = 0;
3049 c < GeometryInfo<dim>::max_children_per_cell;
3052 if (cell->child(c)->level_subdomain_id() ==
3053 this->locally_owned_subdomain())
3058 cell->child(0)->level_subdomain_id();
3062 cell->set_level_subdomain_id(mark);
3086 Assert(
static_cast<unsigned int>(
3093 Assert(
static_cast<unsigned int>(
3100 unsigned int n_owned = 0;
3103 if (cell->subdomain_id() == this->my_subdomain)
3107 Assert(
static_cast<unsigned int>(
3124 template <
int dim,
int spacedim>
3130 std::vector<Point<dim>> point{p};
3138 template <
int dim,
int spacedim>
3146 "Vertices need to be communicated to p4est to use this "
3147 "function. This must explicitly be turned on in the "
3148 "settings of the triangulation's constructor."));
3156 "This function can only be used if the triangulation "
3157 "has no other manifold than a Cartesian (flat) manifold attached."));
3161 PartitionSearch<dim> partition_search;
3173 sc_array_t *point_sc_array;
3177 sc_array_new_count(
sizeof(
double[dim + 1]), points.size());
3180 for (
size_t i = 0; i < points.size(); ++i)
3185 double *this_sc_point =
3186 static_cast<double *
>(sc_array_index_ssize_t(point_sc_array, i));
3188 for (
unsigned int d = 0; d < dim; ++d)
3190 this_sc_point[d] = p(d);
3192 this_sc_point[dim] = -1.0;
3198 static_cast<int>(
false),
3199 &PartitionSearch<dim>::local_quadrant_fn,
3200 &PartitionSearch<dim>::local_point_fn,
3204 std::vector<types::subdomain_id> owner_rank(
3208 for (
size_t i = 0; i < points.size(); ++i)
3211 double *this_sc_point =
3212 static_cast<double *
>(sc_array_index_ssize_t(point_sc_array, i));
3213 Assert(this_sc_point[dim] >= 0. || this_sc_point[dim] == -1.,
3215 if (this_sc_point[dim] < 0.)
3226 sc_array_destroy_null(&point_sc_array);
3233 template <
int dim,
int spacedim>
3241 if (cell->is_locally_owned() && cell->refine_flag_set())
3242 Assert(cell->refine_flag_set() ==
3245 "This class does not support anisotropic refinement"));
3262 !(cell->refine_flag_set()),
3264 "Fatal Error: maximum refinement level of p4est reached."));
3271 this->
signals.pre_distributed_refinement();
3277 if (cell->is_ghost() || cell->is_artificial())
3279 cell->clear_refine_flag();
3280 cell->clear_coarsen_flag();
3286 RefineAndCoarsenList<dim, spacedim> refine_and_coarsen_list(
3305 &RefineAndCoarsenList<dim, spacedim>::refine_callback,
3310 &RefineAndCoarsenList<dim, spacedim>::coarsen_callback,
3323 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
3324 P4EST_CONNECT_FULL) :
3325 typename ::internal::p4est::types<dim>::balance_type(
3326 P8EST_CONNECT_FULL)),
3335 this->
signals.post_p4est_refinement();
3339 std::vector<typename ::internal::p4est::types<dim>::gloidx>
3340 previous_global_first_quadrant;
3345 std::memcpy(previous_global_first_quadrant.data(),
3348 typename ::internal::p4est::types<dim>::gloidx) *
3356 if (this->
signals.weight.empty())
3370 this->mpi_communicator) > 0,
3372 "The global sum of weights over all active cells "
3373 "is zero. Please verify how you generate weights."));
3375 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
3386 &PartitionWeights<dim, spacedim>::cell_weight);
3402 this->cell_attached_data.pack_callbacks_variable,
3403 this->get_mpi_communicator());
3411 cell->clear_refine_flag();
3412 cell->clear_coarsen_flag();
3419 catch (
const typename Triangulation<dim>::DistortedCellList &)
3430 previous_global_first_quadrant.data());
3459 std::vector<bool> active_verts =
3462 const unsigned int maybe_coarser_lvl =
3463 (lvl > 0) ? (lvl - 1) : lvl;
3465 cell = this->
begin(maybe_coarser_lvl),
3466 endc = this->
end(lvl);
3467 for (; cell != endc; ++cell)
3468 if (cell->level() ==
static_cast<int>(lvl) ||
3471 const bool is_level_artificial =
3472 (cell->level_subdomain_id() ==
3474 bool need_to_know =
false;
3475 for (
const unsigned int vertex :
3477 if (active_verts[cell->vertex_index(vertex)])
3479 need_to_know =
true;
3484 !need_to_know || !is_level_artificial,
3486 "Internal error: the owner of cell" +
3487 cell->id().to_string() +
3488 " is unknown even though it is needed for geometric multigrid."));
3498 this->
signals.post_distributed_refinement();
3503 template <
int dim,
int spacedim>
3510 if (cell->is_locally_owned())
3512 !cell->refine_flag_set() && !cell->coarsen_flag_set(),
3514 "Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition()."));
3518 this->
signals.pre_distributed_repartition();
3522 std::vector<typename ::internal::p4est::types<dim>::gloidx>
3523 previous_global_first_quadrant;
3527 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
3528 std::memcpy(previous_global_first_quadrant.data(),
3529 parallel_forest->global_first_quadrant,
3531 typename ::internal::p4est::types<dim>::gloidx) *
3532 (parallel_forest->mpisize + 1));
3535 if (this->
signals.weight.empty())
3539 ::internal::p4est::functions<dim>::partition(
3547 const std::vector<unsigned int> cell_weights = get_cell_weights();
3550 Assert(Utilities::MPI::sum(std::accumulate(cell_weights.begin(),
3553 this->mpi_communicator) > 0,
3555 "The global sum of weights over all active cells "
3556 "is zero. Please verify how you generate weights."));
3558 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
3562 Assert(parallel_forest->user_pointer == this, ExcInternalError());
3563 parallel_forest->user_pointer = &partition_weights;
3565 ::internal::p4est::functions<dim>::partition(
3569 &PartitionWeights<dim, spacedim>::cell_weight);
3572 parallel_forest->user_pointer = this;
3578 this->data_serializer.pack_data(
3579 this->local_cell_relations,
3580 this->cell_attached_data.pack_callbacks_fixed,
3581 this->cell_attached_data.pack_callbacks_variable,
3582 this->get_mpi_communicator());
3587 copy_local_forest_to_triangulation();
3589 catch (
const typename Triangulation<dim>::DistortedCellList &)
3599 this->execute_transfer(parallel_forest,
3600 previous_global_first_quadrant.data());
3603 this->update_periodic_face_map();
3606 this->update_number_cache();
3609 this->signals.post_distributed_repartition();
3614 template <
int dim,
int spacedim>
3616 const std::vector<types::global_dof_index>
3625 template <
int dim,
int spacedim>
3627 const std::vector<types::global_dof_index>
3636 template <
int dim,
int spacedim>
3643 std::vector<bool> marked_vertices(this->
n_vertices(),
false);
3645 if (cell->level_subdomain_id() == this->locally_owned_subdomain())
3647 marked_vertices[cell->vertex_index(v)] =
true;
3664 for (
unsigned int repetition = 0; repetition < dim; ++repetition)
3668 const unsigned int face_no_1 = it.first.second;
3670 const unsigned int face_no_2 = it.second.first.second;
3671 const auto combined_orientation = it.second.second;
3672 const auto [orientation, rotation, flip] =
3675 if (cell_1->level() == level && cell_2->level() == level)
3677 for (
unsigned int v = 0;
3683 const unsigned int vface0 =
3685 v, orientation, flip, rotation);
3686 if (marked_vertices[cell_1->face(face_no_1)->vertex_index(
3688 marked_vertices[cell_2->face(face_no_2)->vertex_index(
3690 marked_vertices[cell_1->face(face_no_1)->vertex_index(
3692 marked_vertices[cell_2->face(face_no_2)->vertex_index(
3698 return marked_vertices;
3703 template <
int dim,
int spacedim>
3707 const
types::coarse_cell_id coarse_cell_id)
const
3714 template <
int dim,
int spacedim>
3718 const unsigned int coarse_cell_index)
const