41 #ifdef DEAL_II_WITH_P4EST 45 template <
int dim,
int spacedim>
47 get_vertex_to_cell_mappings(
49 std::vector<unsigned int> & vertex_touch_count,
50 std::vector<std::list<
52 unsigned int>>> & vertex_to_cell)
54 vertex_touch_count.resize(triangulation.
n_vertices());
55 vertex_to_cell.resize(triangulation.
n_vertices());
60 ++vertex_touch_count[cell->vertex_index(v)];
61 vertex_to_cell[cell->vertex_index(v)].emplace_back(cell, v);
67 template <
int dim,
int spacedim>
69 get_edge_to_cell_mappings(
71 std::vector<unsigned int> & edge_touch_count,
72 std::vector<std::list<
74 unsigned int>>> & edge_to_cell)
82 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
84 ++edge_touch_count[cell->line(
l)->index()];
85 edge_to_cell[cell->line(
l)->index()].emplace_back(cell,
l);
95 template <
int dim,
int spacedim>
97 set_vertex_and_cell_info(
99 const std::vector<unsigned int> & vertex_touch_count,
100 const std::vector<std::list<
102 unsigned int>>> & vertex_to_cell,
103 const std::vector<types::global_dof_index>
104 & coarse_cell_to_p4est_tree_permutation,
105 const bool set_vertex_info,
121 if (set_vertex_info ==
true)
122 for (
unsigned int v = 0; v < triangulation.
n_vertices(); ++v)
124 connectivity->vertices[3 * v] = triangulation.
get_vertices()[v][0];
125 connectivity->vertices[3 * v + 1] =
127 connectivity->vertices[3 * v + 2] =
128 (spacedim == 2 ? 0 : triangulation.
get_vertices()[v][2]);
138 endc = triangulation.
end();
139 for (; cell != endc; ++cell)
141 const unsigned int index =
142 coarse_cell_to_p4est_tree_permutation[cell->index()];
146 if (set_vertex_info ==
true)
149 v] = cell->vertex_index(v);
152 v] = cell->vertex_index(v);
158 if (cell->face(f)->at_boundary() ==
false)
161 coarse_cell_to_p4est_tree_permutation[cell->neighbor(f)->index()];
165 coarse_cell_to_p4est_tree_permutation[cell->index()];
170 if (cell->face(f)->at_boundary() ==
false)
176 connectivity->tree_to_face
178 cell->neighbor_of_neighbor(f);
197 connectivity->tree_to_face[index * 6 + f] =
198 cell->neighbor_of_neighbor(f);
200 unsigned int face_idx_list[2] = {
201 f, cell->neighbor_of_neighbor(f)};
203 cell_list[2] = {cell, cell->neighbor(f)};
204 unsigned int smaller_idx = 0;
206 if (f > cell->neighbor_of_neighbor(f))
209 unsigned int larger_idx = (smaller_idx + 1) % 2;
217 unsigned int g_idx = cell_list[smaller_idx]->vertex_index(
219 face_idx_list[smaller_idx],
221 cell_list[smaller_idx]->face_orientation(
222 face_idx_list[smaller_idx]),
223 cell_list[smaller_idx]->face_flip(
224 face_idx_list[smaller_idx]),
225 cell_list[smaller_idx]->face_rotation(
226 face_idx_list[smaller_idx])));
230 for (
unsigned int i = 0;
231 i < GeometryInfo<dim>::vertices_per_face;
235 cell_list[larger_idx]->vertex_index(
237 face_idx_list[larger_idx], i));
246 connectivity->tree_to_face[index * 6 + f] += 6 * v;
260 connectivity->ctt_offset[0] = 0;
261 std::partial_sum(vertex_touch_count.begin(),
262 vertex_touch_count.end(),
263 &connectivity->ctt_offset[1]);
266 std::accumulate(vertex_touch_count.begin(), vertex_touch_count.end(), 0u);
271 for (
unsigned int v = 0; v < triangulation.
n_vertices(); ++v)
273 Assert(vertex_to_cell[v].size() == vertex_touch_count[v],
277 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
278 unsigned int>>::const_iterator p =
279 vertex_to_cell[v].begin();
280 for (
unsigned int c = 0; c < vertex_touch_count[v]; ++c, ++p)
282 connectivity->corner_to_tree[connectivity->ctt_offset[v] + c] =
283 coarse_cell_to_p4est_tree_permutation[p->first->index()];
284 connectivity->corner_to_corner[connectivity->ctt_offset[v] + c] =
292 template <
int dim,
int spacedim>
298 Assert(coarse_grid_cell < parallel_forest->connectivity->num_trees,
300 return ((coarse_grid_cell >= parallel_forest->first_local_tree) &&
301 (coarse_grid_cell <= parallel_forest->last_local_tree));
305 template <
int dim,
int spacedim>
307 delete_all_children_and_self(
310 if (cell->has_children())
311 for (
unsigned int c = 0; c < cell->n_children(); ++c)
312 delete_all_children_and_self<dim, spacedim>(cell->child(c));
314 cell->set_coarsen_flag();
319 template <
int dim,
int spacedim>
324 if (cell->has_children())
325 for (
unsigned int c = 0; c < cell->n_children(); ++c)
326 delete_all_children_and_self<dim, spacedim>(cell->child(c));
330 template <
int dim,
int spacedim>
332 determine_level_subdomain_id_recursively(
339 const std::vector<std::vector<bool>> & marked_vertices)
348 if (marked_vertices[dealii_cell->level()]
349 [dealii_cell->vertex_index(v)])
368 if (!used && dealii_cell->is_active() &&
369 dealii_cell->is_artificial() ==
false &&
370 dealii_cell->level() + 1 <
static_cast<int>(marked_vertices.size()))
374 if (marked_vertices[dealii_cell->level() + 1]
375 [dealii_cell->vertex_index(v)])
384 if (!used && dealii_cell->is_active() &&
385 dealii_cell->is_artificial() ==
false && dealii_cell->level() > 0)
389 if (marked_vertices[dealii_cell->level() - 1]
390 [dealii_cell->vertex_index(v)])
401 &forest, tree_index, &p4est_cell, my_subdomain);
402 Assert((owner != -2) && (owner != -1),
404 dealii_cell->set_level_subdomain_id(owner);
408 if (dealii_cell->has_children())
412 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
417 P4EST_QUADRANT_INIT(&p4est_child[c]);
420 P8EST_QUADRANT_INIT(&p4est_child[c]);
430 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
433 determine_level_subdomain_id_recursively<dim, spacedim>(
436 dealii_cell->child(c),
446 template <
int dim,
int spacedim>
448 match_tree_recursively(
456 if (sc_array_bsearch(const_cast<sc_array_t *>(&tree.quadrants),
462 delete_all_children<dim, spacedim>(dealii_cell);
463 if (dealii_cell->is_active())
464 dealii_cell->set_subdomain_id(my_subdomain);
473 if (dealii_cell->is_active())
474 dealii_cell->set_refine_flag();
479 for (
unsigned int c = 0;
480 c < GeometryInfo<dim>::max_children_per_cell;
485 P4EST_QUADRANT_INIT(&p4est_child[c]);
488 P8EST_QUADRANT_INIT(&p4est_child[c]);
498 for (
unsigned int c = 0;
499 c < GeometryInfo<dim>::max_children_per_cell;
504 &p4est_child[c]) ==
false)
510 delete_all_children<dim, spacedim>(dealii_cell->child(c));
511 dealii_cell->child(c)->recursively_set_subdomain_id(
518 match_tree_recursively<dim, spacedim>(tree,
519 dealii_cell->child(c),
529 template <
int dim,
int spacedim>
532 const ::Triangulation<dim, spacedim> * tria,
533 unsigned int dealii_index,
537 const int l = ghost_quadrant.level;
539 for (
int i = 0; i <
l; ++i)
544 if (cell->is_active())
546 cell->clear_coarsen_flag();
547 cell->set_refine_flag();
554 dealii_index = cell->child_index(child_id);
560 if (cell->has_children())
561 delete_all_children<dim, spacedim>(cell);
564 cell->clear_coarsen_flag();
565 cell->set_subdomain_id(ghost_owner);
576 template <
int dim,
int spacedim>
577 class RefineAndCoarsenList
581 const std::vector<types::global_dof_index>
582 &p4est_tree_to_coarse_cell_permutation,
610 pointers_are_at_end()
const;
613 std::vector<typename internal::p4est::types<dim>::quadrant> refine_list;
614 typename std::vector<typename internal::p4est::types<dim>::quadrant>::
615 const_iterator current_refine_pointer;
617 std::vector<typename internal::p4est::types<dim>::quadrant> coarsen_list;
618 typename std::vector<typename internal::p4est::types<dim>::quadrant>::
619 const_iterator current_coarsen_pointer;
630 template <
int dim,
int spacedim>
632 RefineAndCoarsenList<dim, spacedim>::pointers_are_at_end()
const 634 return ((current_refine_pointer == refine_list.end()) &&
635 (current_coarsen_pointer == coarsen_list.end()));
640 template <
int dim,
int spacedim>
641 RefineAndCoarsenList<dim, spacedim>::RefineAndCoarsenList(
643 const std::vector<types::global_dof_index>
644 & p4est_tree_to_coarse_cell_permutation,
648 unsigned int n_refine_flags = 0, n_coarsen_flags = 0;
652 if (cell->subdomain_id() != my_subdomain)
655 if (cell->refine_flag_set())
657 else if (cell->coarsen_flag_set())
661 refine_list.reserve(n_refine_flags);
662 coarsen_list.reserve(n_coarsen_flags);
672 for (
unsigned int c = 0; c < triangulation.
n_cells(0); ++c)
674 unsigned int coarse_cell_index =
675 p4est_tree_to_coarse_cell_permutation[c];
678 &triangulation, 0, coarse_cell_index);
684 p4est_cell.p.which_tree = c;
685 build_lists(cell, p4est_cell, my_subdomain);
693 for (
unsigned int i = 1; i < refine_list.size(); ++i)
694 Assert(refine_list[i].p.which_tree >= refine_list[i - 1].p.which_tree,
696 for (
unsigned int i = 1; i < coarsen_list.size(); ++i)
697 Assert(coarsen_list[i].p.which_tree >= coarsen_list[i - 1].p.which_tree,
700 current_refine_pointer = refine_list.begin();
701 current_coarsen_pointer = coarsen_list.begin();
706 template <
int dim,
int spacedim>
708 RefineAndCoarsenList<dim, spacedim>::build_lists(
713 if (cell->is_active())
715 if (cell->subdomain_id() == my_subdomain)
717 if (cell->refine_flag_set())
718 refine_list.push_back(p4est_cell);
719 else if (cell->coarsen_flag_set())
720 coarsen_list.push_back(p4est_cell);
727 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
732 P4EST_QUADRANT_INIT(&p4est_child[c]);
735 P8EST_QUADRANT_INIT(&p4est_child[c]);
742 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
745 p4est_child[c].p.which_tree = p4est_cell.p.which_tree;
746 build_lists(cell->child(c), p4est_child[c], my_subdomain);
752 template <
int dim,
int spacedim>
754 RefineAndCoarsenList<dim, spacedim>::refine_callback(
759 RefineAndCoarsenList<dim, spacedim> *this_object =
760 reinterpret_cast<RefineAndCoarsenList<dim, spacedim> *
>(
761 forest->user_pointer);
765 if (this_object->current_refine_pointer == this_object->refine_list.end())
768 Assert(coarse_cell_index <=
769 this_object->current_refine_pointer->p.which_tree,
774 if (coarse_cell_index < this_object->current_refine_pointer->p.which_tree)
778 Assert(coarse_cell_index <=
779 this_object->current_refine_pointer->p.which_tree,
785 quadrant, &*this_object->current_refine_pointer) <= 0,
790 quadrant, &*this_object->current_refine_pointer))
792 ++this_object->current_refine_pointer;
802 template <
int dim,
int spacedim>
804 RefineAndCoarsenList<dim, spacedim>::coarsen_callback(
809 RefineAndCoarsenList<dim, spacedim> *this_object =
810 reinterpret_cast<RefineAndCoarsenList<dim, spacedim> *
>(
811 forest->user_pointer);
815 if (this_object->current_coarsen_pointer == this_object->coarsen_list.end())
818 Assert(coarse_cell_index <=
819 this_object->current_coarsen_pointer->p.which_tree,
824 if (coarse_cell_index < this_object->current_coarsen_pointer->p.which_tree)
828 Assert(coarse_cell_index <=
829 this_object->current_coarsen_pointer->p.which_tree,
835 children[0], &*this_object->current_coarsen_pointer) <= 0,
841 children[0], &*this_object->current_coarsen_pointer))
844 ++this_object->current_coarsen_pointer;
848 for (
unsigned int c = 1; c < GeometryInfo<dim>::max_children_per_cell;
852 children[c], &*this_object->current_coarsen_pointer),
854 ++this_object->current_coarsen_pointer;
872 template <
int dim,
int spacedim>
873 class PartitionWeights
881 explicit PartitionWeights(
const std::vector<unsigned int> &cell_weights);
896 std::vector<unsigned int> cell_weights_list;
897 std::vector<unsigned int>::const_iterator current_pointer;
901 template <
int dim,
int spacedim>
902 PartitionWeights<dim, spacedim>::PartitionWeights(
903 const std::vector<unsigned int> &cell_weights)
904 : cell_weights_list(cell_weights)
908 current_pointer = cell_weights_list.begin();
912 template <
int dim,
int spacedim>
914 PartitionWeights<dim, spacedim>::cell_weight(
923 PartitionWeights<dim, spacedim> *this_object =
924 reinterpret_cast<PartitionWeights<dim, spacedim> *
>(forest->user_pointer);
926 Assert(this_object->current_pointer >=
927 this_object->cell_weights_list.begin(),
929 Assert(this_object->current_pointer < this_object->cell_weights_list.end(),
933 return *this_object->current_pointer++;
938 template <
int dim,
int spacedim>
939 using quadrant_cell_relation_t =
typename std::tuple<
940 typename ::internal::p4est::types<dim>::quadrant *,
941 typename ::Triangulation<dim, spacedim>::CellStatus,
942 typename ::Triangulation<dim, spacedim>::cell_iterator>;
955 template <
int dim,
int spacedim>
957 add_single_quadrant_cell_relation(
958 std::vector<quadrant_cell_relation_t<dim, spacedim>> & quad_cell_rel,
959 const typename ::internal::p4est::types<dim>::tree & tree,
960 const unsigned int idx,
964 const unsigned int local_quadrant_index = tree.quadrants_offset + idx;
967 static_cast<typename ::internal::p4est::types<dim>::quadrant *
>(
968 sc_array_index(const_cast<sc_array_t *>(&tree.quadrants), idx));
974 quad_cell_rel[local_quadrant_index] =
975 std::make_tuple(q, status, dealii_cell);
989 template <
int dim,
int spacedim>
991 update_quadrant_cell_relations_recursively(
992 std::vector<quadrant_cell_relation_t<dim, spacedim>> & quad_cell_rel,
993 const typename ::internal::p4est::types<dim>::tree & tree,
995 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell)
998 const int idx = sc_array_bsearch(
999 const_cast<sc_array_t *>(&tree.quadrants),
1004 const_cast<typename ::internal::p4est::types<dim>::tree *
>(
1006 &p4est_cell) ==
false))
1011 const bool p4est_has_children = (idx == -1);
1012 if (p4est_has_children && dealii_cell->has_children())
1015 typename ::internal::p4est::types<dim>::quadrant
1018 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1023 P4EST_QUADRANT_INIT(&p4est_child[c]);
1026 P8EST_QUADRANT_INIT(&p4est_child[c]);
1033 &p4est_cell, p4est_child);
1035 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1038 update_quadrant_cell_relations_recursively<dim, spacedim>(
1039 quad_cell_rel, tree, dealii_cell->child(c), p4est_child[c]);
1042 else if (!p4est_has_children && !dealii_cell->has_children())
1046 add_single_quadrant_cell_relation<dim, spacedim>(
1053 else if (p4est_has_children)
1061 typename ::internal::p4est::types<dim>::quadrant
1063 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1068 P4EST_QUADRANT_INIT(&p4est_child[c]);
1071 P8EST_QUADRANT_INIT(&p4est_child[c]);
1078 &p4est_cell, p4est_child);
1085 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
1088 child_idx = sc_array_bsearch(
1089 const_cast<sc_array_t *>(&tree.quadrants),
1096 add_single_quadrant_cell_relation<dim, spacedim>(
1097 quad_cell_rel, tree, child_idx, dealii_cell, cell_status);
1105 add_single_quadrant_cell_relation<dim, spacedim>(
1119 namespace distributed
1124 template <
int dim,
int spacedim>
1127 : mpi_communicator(mpi_communicator)
1128 , variable_size_data_stored(false)
1133 template <
int dim,
int spacedim>
1136 const std::vector<quadrant_cell_relation_t> &quad_cell_relations,
1137 const std::vector<typename CellAttachedData::pack_callback_t>
1138 &pack_callbacks_fixed,
1139 const std::vector<typename CellAttachedData::pack_callback_t>
1140 &pack_callbacks_variable)
1143 ExcMessage(
"Previously packed data has not been released yet!"));
1146 const unsigned int n_callbacks_fixed = pack_callbacks_fixed.size();
1147 const unsigned int n_callbacks_variable = pack_callbacks_variable.size();
1157 std::vector<unsigned int> cell_sizes_variable_cumulative(
1158 n_callbacks_variable);
1172 std::vector<std::vector<std::vector<char>>> packed_fixed_size_data(
1173 quad_cell_relations.size());
1174 std::vector<std::vector<std::vector<char>>> packed_variable_size_data(
1183 auto quad_cell_rel_it = quad_cell_relations.cbegin();
1184 auto data_cell_fixed_it = packed_fixed_size_data.begin();
1185 auto data_cell_variable_it = packed_variable_size_data.begin();
1186 for (; quad_cell_rel_it != quad_cell_relations.cend();
1187 ++quad_cell_rel_it, ++data_cell_fixed_it)
1189 const auto &cell_status = std::get<1>(*quad_cell_rel_it);
1190 const auto &dealii_cell = std::get<2>(*quad_cell_rel_it);
1193 switch (cell_status)
1211 for (
unsigned int c = 0;
1212 c < GeometryInfo<dim>::max_children_per_cell;
1214 Assert(dealii_cell->child(c)->is_active(),
1236 const unsigned int n_fixed_size_data_sets_on_cell =
1243 data_cell_fixed_it->resize(n_fixed_size_data_sets_on_cell);
1246 auto data_fixed_it = data_cell_fixed_it->begin();
1262 for (
auto callback_it = pack_callbacks_fixed.cbegin();
1263 callback_it != pack_callbacks_fixed.cend();
1264 ++callback_it, ++data_fixed_it)
1266 *data_fixed_it = (*callback_it)(dealii_cell, cell_status);
1275 const unsigned int n_variable_size_data_sets_on_cell =
1280 n_callbacks_variable);
1281 data_cell_variable_it->resize(
1282 n_variable_size_data_sets_on_cell);
1284 auto callback_it = pack_callbacks_variable.cbegin();
1285 auto data_variable_it = data_cell_variable_it->begin();
1286 auto sizes_variable_it =
1287 cell_sizes_variable_cumulative.begin();
1288 for (; callback_it != pack_callbacks_variable.cend();
1289 ++callback_it, ++data_variable_it, ++sizes_variable_it)
1292 (*callback_it)(dealii_cell, cell_status);
1296 *sizes_variable_it = data_variable_it->size();
1300 std::partial_sum(cell_sizes_variable_cumulative.begin(),
1301 cell_sizes_variable_cumulative.end(),
1302 cell_sizes_variable_cumulative.begin());
1308 data_fixed_it->resize(n_callbacks_variable *
1309 sizeof(
unsigned int));
1310 for (
unsigned int i = 0; i < n_callbacks_variable; ++i)
1311 std::memcpy(&(data_fixed_it->at(i *
1312 sizeof(
unsigned int))),
1313 &(cell_sizes_variable_cumulative.at(i)),
1314 sizeof(
unsigned int));
1321 Assert(data_fixed_it == data_cell_fixed_it->end(),
1329 ++data_cell_variable_it;
1346 std::vector<unsigned int> local_sizes_fixed(
1348 for (
const auto &data_cell : packed_fixed_size_data)
1350 if (data_cell.size() == local_sizes_fixed.size())
1352 auto sizes_fixed_it = local_sizes_fixed.begin();
1353 auto data_fixed_it = data_cell.cbegin();
1354 for (; data_fixed_it != data_cell.cend();
1355 ++data_fixed_it, ++sizes_fixed_it)
1357 *sizes_fixed_it = data_fixed_it->size();
1365 for (
auto data_cell_fixed_it = packed_fixed_size_data.cbegin();
1366 data_cell_fixed_it != packed_fixed_size_data.cend();
1367 ++data_cell_fixed_it)
1369 Assert((data_cell_fixed_it->size() == 1) ||
1370 (data_cell_fixed_it->size() == local_sizes_fixed.size()),
1377 std::vector<unsigned int> global_sizes_fixed(local_sizes_fixed.size());
1380 global_sizes_fixed);
1385 std::partial_sum(global_sizes_fixed.begin(),
1386 global_sizes_fixed.end(),
1395 for (
const auto &data_cell : packed_variable_size_data)
1397 int variable_data_size_on_cell = 0;
1399 for (
const auto &data : data_cell)
1400 variable_data_size_on_cell += data.size();
1409 const unsigned int expected_size_fixed =
1411 const unsigned int expected_size_variable =
1418 for (
const auto &data_cell_fixed : packed_fixed_size_data)
1422 for (
const auto &data_fixed : data_cell_fixed)
1423 std::move(data_fixed.begin(),
1431 if ((data_cell_fixed.size() == 1) &&
1434 const std::size_t bytes_skipped =
1439 static_cast<char>(-1));
1448 for (
const auto &data_cell : packed_variable_size_data)
1452 for (
const auto &data : data_cell)
1453 std::move(data.begin(),
1467 template <
int dim,
int spacedim>
1470 const typename ::internal::p4est::types<dim>::forest
1472 const typename ::internal::p4est::types<dim>::gloidx
1473 *previous_global_first_quadrant)
1483 typename ::internal::p4est::types<dim>::transfer_context
1487 parallel_forest->global_first_quadrant,
1488 previous_global_first_quadrant,
1489 parallel_forest->mpicomm,
1503 parallel_forest->global_first_quadrant,
1504 previous_global_first_quadrant,
1505 parallel_forest->mpicomm,
1526 # if DEAL_II_P4EST_VERSION_GTE(2, 0, 65, 0) 1541 parallel_forest->global_first_quadrant,
1542 previous_global_first_quadrant,
1543 parallel_forest->mpicomm,
1560 template <
int dim,
int spacedim>
1563 std::vector<quadrant_cell_relation_t> &quad_cell_relations)
const 1567 if (quad_cell_relations.size() > 0)
1580 auto quad_cell_rel_it = quad_cell_relations.begin();
1582 for (; quad_cell_rel_it != quad_cell_relations.end();
1585 std::get<1>(*quad_cell_rel_it) =
1589 dest_fixed_it + size,
1596 template <
int dim,
int spacedim>
1599 const std::vector<quadrant_cell_relation_t> &quad_cell_relations,
1600 const unsigned int handle,
1601 const std::function<
void(
1602 const typename ::Triangulation<dim, spacedim>::cell_iterator &,
1603 const typename ::Triangulation<dim, spacedim>::CellStatus &,
1604 const boost::iterator_range<std::vector<char>::const_iterator> &)>
1605 &unpack_callback)
const 1611 const bool callback_variable_transfer = (handle % 2 == 0);
1612 const unsigned int callback_index = handle / 2;
1620 if (quad_cell_relations.size() > 0)
1626 std::vector<char>::const_iterator dest_data_it;
1627 std::vector<char>::const_iterator dest_sizes_cell_it;
1637 if (callback_variable_transfer)
1650 const unsigned int offset_variable_data_sizes =
1659 offset_variable_data_sizes +
1660 callback_index *
sizeof(
unsigned int);
1682 auto quad_cell_rel_it = quad_cell_relations.begin();
1684 for (; quad_cell_rel_it != quad_cell_relations.end();
1685 ++quad_cell_rel_it, dest_data_it += data_increment)
1687 const auto &cell_status = std::get<1>(*quad_cell_rel_it);
1688 const auto &dealii_cell = std::get<2>(*quad_cell_rel_it);
1690 if (callback_variable_transfer)
1694 data_increment = *dest_sizes_it;
1702 if (callback_index == 0)
1705 std::memcpy(&offset,
1706 &(*(dest_sizes_cell_it -
sizeof(
unsigned int))),
1707 sizeof(
unsigned int));
1710 &(*dest_sizes_cell_it),
1711 sizeof(
unsigned int));
1718 dest_data_it += offset;
1719 data_increment -= offset;
1727 switch (cell_status)
1733 unpack_callback(dealii_cell,
1742 unpack_callback(dealii_cell->parent(),
1763 template <
int dim,
int spacedim>
1766 const typename ::internal::p4est::types<dim>::forest
1768 const std::string &filename)
const 1783 const std::string fname_fixed = std::string(filename) +
"_fixed.data";
1786 int ierr = MPI_Info_create(&info);
1792 MPI_MODE_CREATE | MPI_MODE_WRONLY,
1797 ierr = MPI_File_set_size(fh, 0);
1803 ierr = MPI_Info_free(&info);
1817 ierr = MPI_File_write_at(fh,
1827 const unsigned int offset_fixed =
1832 ierr = MPI_File_write_at(
1835 parallel_forest->global_first_quadrant[myrank] *
1843 ierr = MPI_File_close(&fh);
1852 const std::string fname_variable =
1853 std::string(filename) +
"_variable.data";
1856 int ierr = MPI_Info_create(&info);
1862 MPI_MODE_CREATE | MPI_MODE_WRONLY,
1867 ierr = MPI_File_set_size(fh, 0);
1873 ierr = MPI_Info_free(&info);
1880 MPI_File_write_at(fh,
1881 parallel_forest->global_first_quadrant[myrank] *
1891 const unsigned int offset_variable =
1892 parallel_forest->global_num_quadrants *
sizeof(
int);
1898 unsigned int prefix_sum = 0;
1910 ierr = MPI_File_write_at(fh,
1919 ierr = MPI_File_close(&fh);
1926 template <
int dim,
int spacedim>
1929 const typename ::internal::p4est::types<dim>::forest
1931 const std::string &filename,
1932 const unsigned int n_attached_deserialize_fixed,
1933 const unsigned int n_attached_deserialize_variable)
1940 ExcMessage(
"Previously loaded data has not been released yet!"));
1950 const std::string fname_fixed = std::string(filename) +
"_fixed.data";
1953 int ierr = MPI_Info_create(&info);
1964 ierr = MPI_Info_free(&info);
1975 (variable_size_data_stored ? 1 : 0));
1976 ierr = MPI_File_read_at(fh,
1989 const unsigned int offset =
1992 ierr = MPI_File_read_at(
1994 offset + parallel_forest->global_first_quadrant[myrank] *
2002 ierr = MPI_File_close(&fh);
2009 if (variable_size_data_stored)
2011 const std::string fname_variable =
2012 std::string(filename) +
"_variable.data";
2015 int ierr = MPI_Info_create(&info);
2026 ierr = MPI_Info_free(&info);
2032 MPI_File_read_at(fh,
2033 parallel_forest->global_first_quadrant[myrank] *
2041 const unsigned int offset =
2042 parallel_forest->global_num_quadrants *
sizeof(
int);
2044 const unsigned int size_on_proc =
2050 unsigned int prefix_sum = 0;
2060 ierr = MPI_File_read_at(fh,
2061 offset + prefix_sum,
2068 ierr = MPI_File_close(&fh);
2075 template <
int dim,
int spacedim>
2111 template <
int dim,
int spacedim>
2114 const typename ::Triangulation<dim, spacedim>::MeshSmoothing
2129 , settings(settings)
2131 , connectivity(nullptr)
2132 , parallel_forest(nullptr)
2134 , data_transfer(mpi_communicator)
2136 parallel_ghost =
nullptr;
2141 template <
int dim,
int spacedim>
2161 template <
int dim,
int spacedim>
2174 const typename ::Triangulation<dim, spacedim>::DistortedCellList
2185 "The class parallel::distributed::Triangulation only supports meshes " 2186 "consisting only of hypercube-like cells."));
2191 triangulation_has_content =
true;
2193 setup_coarse_cell_to_p4est_tree_permutation();
2195 copy_new_triangulation_to_p4est(std::integral_constant<int, dim>());
2199 copy_local_forest_to_triangulation();
2209 this->update_number_cache();
2214 template <
int dim,
int spacedim>
2220 (void)construction_data;
2229 namespace CommunicateLocallyMovedVertices
2238 template <
int dim,
int spacedim>
2246 std::vector<typename ::internal::p4est::types<dim>::quadrant>
2261 bytes_for_buffer()
const 2263 return sizeof(
unsigned int) +
2264 tree_index.size() *
sizeof(
unsigned int) +
2267 typename ::internal::p4est::types<dim>::quadrant) +
2268 vertex_indices.size() *
sizeof(
unsigned int) +
2273 pack_data(std::vector<char> &buffer)
const 2275 buffer.resize(bytes_for_buffer());
2277 char *ptr = buffer.data();
2279 const unsigned int num_cells = tree_index.size();
2280 std::memcpy(ptr, &num_cells,
sizeof(
unsigned int));
2281 ptr +=
sizeof(
unsigned int);
2285 num_cells *
sizeof(
unsigned int));
2286 ptr += num_cells *
sizeof(
unsigned int);
2292 sizeof(typename ::internal::p4est::types<dim>::quadrant));
2295 sizeof(typename ::internal::p4est::types<dim>::quadrant);
2298 vertex_indices.data(),
2299 vertex_indices.size() *
sizeof(
unsigned int));
2300 ptr += vertex_indices.size() *
sizeof(
unsigned int);
2310 unpack_data(
const std::vector<char> &buffer)
2312 const char * ptr = buffer.data();
2314 memcpy(&cells, ptr,
sizeof(
unsigned int));
2315 ptr +=
sizeof(
unsigned int);
2317 tree_index.resize(cells);
2318 memcpy(tree_index.data(), ptr,
sizeof(
unsigned int) * cells);
2319 ptr +=
sizeof(
unsigned int) * cells;
2325 typename ::internal::p4est::types<dim>::quadrant) *
2328 sizeof(typename ::internal::p4est::types<dim>::quadrant) *
2331 vertex_indices.clear();
2332 first_vertex_indices.resize(cells);
2333 std::vector<unsigned int> n_vertices_on_cell(cells);
2334 std::vector<unsigned int> first_indices(cells);
2335 for (
unsigned int c = 0; c < cells; ++c)
2340 const unsigned int *
const vertex_index =
2341 reinterpret_cast<const unsigned int *
>(ptr);
2342 first_indices[c] = vertex_indices.size();
2343 vertex_indices.push_back(*vertex_index);
2344 n_vertices_on_cell[c] = *vertex_index;
2345 ptr +=
sizeof(
unsigned int);
2347 vertex_indices.resize(vertex_indices.size() +
2348 n_vertices_on_cell[c]);
2349 memcpy(&vertex_indices[vertex_indices.size() -
2350 n_vertices_on_cell[c]],
2352 n_vertices_on_cell[c] *
sizeof(
unsigned int));
2353 ptr += n_vertices_on_cell[c] *
sizeof(
unsigned int);
2355 for (
unsigned int c = 0; c < cells; ++c)
2356 first_vertex_indices[c] = &vertex_indices[first_indices[c]];
2359 first_vertices.resize(cells);
2360 for (
unsigned int c = 0; c < cells; ++c)
2362 first_indices[c] = vertices.size();
2363 vertices.resize(vertices.size() + n_vertices_on_cell[c]);
2364 memcpy(&vertices[vertices.size() - n_vertices_on_cell[c]],
2369 for (
unsigned int c = 0; c < cells; ++c)
2370 first_vertices[c] = &vertices[first_indices[c]];
2390 template <
int dim,
int spacedim>
2392 fill_vertices_recursively(
2395 const unsigned int tree_index,
2398 const typename ::internal::p4est::types<dim>::quadrant
2400 const std::map<
unsigned int, std::set<::types::subdomain_id>>
2402 const std::vector<bool> &vertex_locally_moved,
2408 if (dealii_cell->has_children())
2410 typename ::internal::p4est::types<dim>::quadrant
2412 ::internal::p4est::init_quadrant_children<dim>(p4est_cell,
2416 for (
unsigned int c = 0;
2417 c < GeometryInfo<dim>::max_children_per_cell;
2419 fill_vertices_recursively<dim, spacedim>(
2422 dealii_cell->child(c),
2425 vertex_locally_moved,
2437 if (dealii_cell->is_locally_owned())
2439 std::set<::types::subdomain_id> send_to;
2442 const std::map<
unsigned int,
2443 std::set<::types::subdomain_id>>::
2444 const_iterator neighbor_subdomains_of_vertex =
2446 dealii_cell->vertex_index(v));
2448 if (neighbor_subdomains_of_vertex !=
2451 Assert(neighbor_subdomains_of_vertex->second.size() != 0,
2454 neighbor_subdomains_of_vertex->second.begin(),
2455 neighbor_subdomains_of_vertex->second.end());
2459 if (send_to.size() > 0)
2462 std::vector<::Point<spacedim>> local_vertices;
2463 for (
const unsigned int v :
2465 if (vertex_locally_moved[dealii_cell->vertex_index(v)])
2467 vertex_indices.push_back(v);
2468 local_vertices.push_back(dealii_cell->vertex(v));
2471 if (vertex_indices.size() > 0)
2472 for (
const auto subdomain : send_to)
2477 const typename std::map<
2479 CellInfo<dim, spacedim>>::iterator p =
2481 .insert(std::make_pair(subdomain,
2482 CellInfo<dim, spacedim>()))
2485 p->second.tree_index.push_back(tree_index);
2486 p->second.quadrants.push_back(p4est_cell);
2488 p->second.vertex_indices.push_back(
2489 vertex_indices.size());
2490 p->second.vertex_indices.insert(
2491 p->second.vertex_indices.end(),
2492 vertex_indices.begin(),
2493 vertex_indices.end());
2495 p->second.vertices.insert(p->second.vertices.end(),
2496 local_vertices.begin(),
2497 local_vertices.end());
2514 template <
int dim,
int spacedim>
2516 set_vertices_recursively(
2518 const typename ::internal::p4est::types<dim>::quadrant
2522 const typename ::internal::p4est::types<dim>::quadrant
2524 const ::Point<spacedim> *
const vertices,
2527 if (::internal::p4est::quadrant_is_equal<dim>(p4est_cell,
2534 const unsigned int n_vertices = vertex_indices[0];
2537 for (
unsigned int i = 0; i <
n_vertices; ++i)
2538 dealii_cell->vertex(vertex_indices[i + 1]) = vertices[i];
2543 if (dealii_cell->is_active())
2546 if (!::internal::p4est::quadrant_is_ancestor<dim>(p4est_cell,
2550 typename ::internal::p4est::types<dim>::quadrant
2552 ::internal::p4est::init_quadrant_children<dim>(p4est_cell,
2555 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
2557 set_vertices_recursively<dim, spacedim>(tria,
2559 dealii_cell->child(c),
2569 template <
int dim,
int spacedim>
2573 triangulation_has_content =
false;
2575 cell_attached_data = {0, 0, {}, {}};
2576 data_transfer.clear();
2578 if (parallel_ghost !=
nullptr)
2582 parallel_ghost =
nullptr;
2585 if (parallel_forest !=
nullptr)
2588 parallel_forest =
nullptr;
2591 if (connectivity !=
nullptr)
2595 connectivity =
nullptr;
2598 coarse_cell_to_p4est_tree_permutation.resize(0);
2599 p4est_tree_to_coarse_cell_permutation.resize(0);
2603 this->update_number_cache();
2608 template <
int dim,
int spacedim>
2618 template <
int dim,
int spacedim>
2631 const bool have_coarser_cell =
2640 this->mpi_communicator);
2645 template <
int dim,
int spacedim>
2652 coarse_cell_to_p4est_tree_permutation.resize(this->
n_cells(0));
2654 cell_connectivity, coarse_cell_to_p4est_tree_permutation);
2656 p4est_tree_to_coarse_cell_permutation =
2662 template <
int dim,
int spacedim>
2665 const std::string &file_basename)
const 2667 Assert(parallel_forest !=
nullptr,
2668 ExcMessage(
"Can't produce output when no forest is created yet."));
2670 parallel_forest,
nullptr, file_basename.c_str());
2675 template <
int dim,
int spacedim>
2680 cell_attached_data.n_attached_deserialize == 0,
2682 "not all SolutionTransfer's got deserialized after the last load()"));
2684 ExcMessage(
"Can not save() an empty Triangulation."));
2689 if (this->my_subdomain == 0)
2691 std::string fname = std::string(filename) +
".info";
2692 std::ofstream f(fname.c_str());
2693 f <<
"version nproc n_attached_fixed_size_objs n_attached_variable_size_objs n_coarse_cells" 2697 << cell_attached_data.pack_callbacks_fixed.size() <<
" " 2698 << cell_attached_data.pack_callbacks_variable.size() <<
" " 2699 << this->
n_cells(0) << std::endl;
2703 for (
const auto &quad_cell_rel : local_quadrant_cell_relations)
2705 (void)quad_cell_rel;
2707 (std::get<1>(quad_cell_rel) ==
2712 if (cell_attached_data.n_attached_data_sets > 0)
2715 auto tria =
const_cast< 2721 local_quadrant_cell_relations,
2722 cell_attached_data.pack_callbacks_fixed,
2723 cell_attached_data.pack_callbacks_variable);
2726 tria->data_transfer.save(parallel_forest, filename);
2729 tria->data_transfer.clear();
2755 template <
int dim,
int spacedim>
2758 const bool autopartition)
2763 "load() only works if the Triangulation already contains a coarse mesh!"));
2767 "Triangulation may only contain coarse cells when calling load()."));
2772 if (parallel_ghost !=
nullptr)
2776 parallel_ghost =
nullptr;
2779 parallel_forest =
nullptr;
2782 connectivity =
nullptr;
2784 unsigned int version, numcpus, attached_count_fixed,
2785 attached_count_variable, n_coarse_cells;
2787 std::string fname = std::string(filename) +
".info";
2788 std::ifstream f(fname.c_str());
2790 std::string firstline;
2791 getline(f, firstline);
2792 f >> version >> numcpus >> attached_count_fixed >>
2793 attached_count_variable >> n_coarse_cells;
2797 ExcMessage(
"Incompatible version found in .info file."));
2799 ExcMessage(
"Number of coarse cells differ!"));
2803 cell_attached_data.n_attached_data_sets = 0;
2804 cell_attached_data.n_attached_deserialize =
2805 attached_count_fixed + attached_count_variable;
2809 this->mpi_communicator,
2836 const std::vector<unsigned int> cell_weights = get_cell_weights();
2838 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
2843 parallel_forest->user_pointer = &partition_weights;
2849 &PartitionWeights<dim, spacedim>::cell_weight);
2852 parallel_forest->user_pointer =
this;
2858 copy_local_forest_to_triangulation();
2870 if (cell_attached_data.n_attached_deserialize > 0)
2872 data_transfer.load(parallel_forest,
2874 attached_count_fixed,
2875 attached_count_variable);
2877 data_transfer.unpack_cell_status(local_quadrant_cell_relations);
2880 for (
const auto &quad_cell_rel : local_quadrant_cell_relations)
2882 (void)quad_cell_rel;
2884 (std::get<1>(quad_cell_rel) ==
2892 this->update_number_cache();
2900 template <
int dim,
int spacedim>
2904 Assert(parallel_forest !=
nullptr,
2906 "Can't produce a check sum when no forest is created yet."));
2907 return ::internal::p4est::functions<dim>::checksum(parallel_forest);
2912 template <
int dim,
int spacedim>
2913 const typename ::internal::p4est::types<dim>::forest *
2916 Assert(parallel_forest !=
nullptr,
2917 ExcMessage(
"The forest has not been allocated yet."));
2918 return parallel_forest;
2923 template <
int dim,
int spacedim>
2924 typename ::internal::p4est::types<dim>::tree *
2926 const int dealii_coarse_cell_index)
const 2928 const unsigned int tree_index =
2929 coarse_cell_to_p4est_tree_permutation[dealii_coarse_cell_index];
2930 typename ::internal::p4est::types<dim>::tree *tree =
2931 static_cast<typename ::internal::p4est::types<dim>::tree *
>(
2932 sc_array_index(parallel_forest->trees, tree_index));
2946 std::integral_constant<int, 2>)
2948 const unsigned int dim = 2, spacedim = 2;
2956 std::vector<unsigned int> vertex_touch_count;
2958 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2961 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2962 const ::internal::p4est::types<2>::locidx num_vtt =
2963 std::accumulate(vertex_touch_count.begin(),
2964 vertex_touch_count.end(),
2970 const bool set_vertex_info
2979 (set_vertex_info ==
true ? this->
n_vertices() : 0),
2984 set_vertex_and_cell_info(*
this,
2987 coarse_cell_to_p4est_tree_permutation,
2991 Assert(p4est_connectivity_is_valid(connectivity) == 1,
2996 this->mpi_communicator,
3013 std::integral_constant<int, 2>)
3015 const unsigned int dim = 2, spacedim = 3;
3023 std::vector<unsigned int> vertex_touch_count;
3025 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
3028 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
3029 const ::internal::p4est::types<2>::locidx num_vtt =
3030 std::accumulate(vertex_touch_count.begin(),
3031 vertex_touch_count.end(),
3037 const bool set_vertex_info
3046 (set_vertex_info ==
true ? this->
n_vertices() : 0),
3051 set_vertex_and_cell_info(*
this,
3054 coarse_cell_to_p4est_tree_permutation,
3058 Assert(p4est_connectivity_is_valid(connectivity) == 1,
3063 this->mpi_communicator,
3078 std::integral_constant<int, 3>)
3080 const int dim = 3, spacedim = 3;
3088 std::vector<unsigned int> vertex_touch_count;
3089 std::vector<std::list<
3090 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
3092 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
3093 const ::internal::p4est::types<2>::locidx num_vtt =
3094 std::accumulate(vertex_touch_count.begin(),
3095 vertex_touch_count.end(),
3098 std::vector<unsigned int> edge_touch_count;
3099 std::vector<std::list<
3100 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
3102 get_edge_to_cell_mappings(*
this, edge_touch_count, edge_to_cell);
3103 const ::internal::p4est::types<2>::locidx num_ett =
3104 std::accumulate(edge_touch_count.begin(), edge_touch_count.end(), 0u);
3107 const bool set_vertex_info
3116 (set_vertex_info ==
true ? this->
n_vertices() : 0),
3123 set_vertex_and_cell_info(*
this,
3126 coarse_cell_to_p4est_tree_permutation,
3155 const unsigned int deal_to_p4est_line_index[12] = {
3156 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11};
3160 cell != this->
end();
3163 const unsigned int index =
3164 coarse_cell_to_p4est_tree_permutation[cell->index()];
3165 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_cell; ++
e)
3167 deal_to_p4est_line_index[
e]] =
3168 cell->line(
e)->index();
3173 connectivity->ett_offset[0] = 0;
3174 std::partial_sum(edge_touch_count.begin(),
3175 edge_touch_count.end(),
3176 &connectivity->ett_offset[1]);
3178 Assert(connectivity->ett_offset[this->n_active_lines()] == num_ett,
3183 Assert(edge_to_cell[v].size() == edge_touch_count[v],
3187 std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
3188 unsigned int>>::const_iterator p =
3189 edge_to_cell[v].begin();
3190 for (
unsigned int c = 0; c < edge_touch_count[v]; ++c, ++p)
3192 connectivity->edge_to_tree[connectivity->ett_offset[v] + c] =
3193 coarse_cell_to_p4est_tree_permutation[p->first->index()];
3194 connectivity->edge_to_edge[connectivity->ett_offset[v] + c] =
3195 deal_to_p4est_line_index[p->second];
3199 Assert(p8est_connectivity_is_valid(connectivity) == 1,
3204 this->mpi_communicator,
3221 template <
int dim,
int spacedim>
3223 enforce_mesh_balance_over_periodic_boundaries(
3229 std::vector<bool> flags_before[2];
3233 std::vector<unsigned int> topological_vertex_numbering(
3235 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
3236 topological_vertex_numbering[i] = i;
3254 typename std::map<std::pair<cell_iterator, unsigned int>,
3255 std::pair<std::pair<cell_iterator, unsigned int>,
3256 std::bitset<3>>>::const_iterator it;
3262 const unsigned int face_no_1 = it->first.second;
3264 const unsigned int face_no_2 = it->second.first.second;
3265 const std::bitset<3> face_orientation = it->second.second;
3267 if (cell_1->level() == cell_2->level())
3269 for (
unsigned int v = 0;
3275 const unsigned int vface0 =
3278 face_orientation[0],
3279 face_orientation[1],
3280 face_orientation[2]);
3281 const unsigned int vi0 =
3282 topological_vertex_numbering[cell_1->face(face_no_1)
3283 ->vertex_index(vface0)];
3284 const unsigned int vi1 =
3285 topological_vertex_numbering[cell_2->face(face_no_2)
3287 const unsigned int min_index =
std::min(vi0, vi1);
3288 topological_vertex_numbering[cell_1->face(face_no_1)
3289 ->vertex_index(vface0)] =
3290 topological_vertex_numbering[cell_2->face(face_no_2)
3291 ->vertex_index(v)] =
3298 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
3300 const unsigned int j = topological_vertex_numbering[i];
3308 bool continue_iterating =
true;
3309 std::vector<int> vertex_level(tria.
n_vertices());
3310 while (continue_iterating)
3314 std::fill(vertex_level.begin(), vertex_level.end(), 0);
3318 for (; cell != endc; ++cell)
3320 if (cell->refine_flag_set())
3321 for (
const unsigned int vertex :
3323 vertex_level[topological_vertex_numbering
3324 [cell->vertex_index(vertex)]] =
3325 std::max(vertex_level[topological_vertex_numbering
3326 [cell->vertex_index(vertex)]],
3328 else if (!cell->coarsen_flag_set())
3329 for (
const unsigned int vertex :
3331 vertex_level[topological_vertex_numbering
3332 [cell->vertex_index(vertex)]] =
3333 std::max(vertex_level[topological_vertex_numbering
3334 [cell->vertex_index(vertex)]],
3345 for (
const unsigned int vertex :
3347 vertex_level[topological_vertex_numbering
3348 [cell->vertex_index(vertex)]] =
3349 std::max(vertex_level[topological_vertex_numbering
3350 [cell->vertex_index(vertex)]],
3355 continue_iterating =
false;
3366 for (cell = tria.
last_active(); cell != endc; --cell)
3367 if (cell->refine_flag_set() ==
false)
3369 for (
const unsigned int vertex :
3371 if (vertex_level[topological_vertex_numbering
3372 [cell->vertex_index(vertex)]] >=
3376 cell->clear_coarsen_flag();
3381 if (vertex_level[topological_vertex_numbering
3382 [cell->vertex_index(vertex)]] >
3385 cell->set_refine_flag();
3386 continue_iterating =
true;
3388 for (
const unsigned int v :
3390 vertex_level[topological_vertex_numbering
3391 [cell->vertex_index(v)]] =
3393 vertex_level[topological_vertex_numbering
3394 [cell->vertex_index(v)]],
3411 if (cell->is_active())
3414 const unsigned int n_children = cell->n_children();
3415 unsigned int flagged_children = 0;
3416 for (
unsigned int child = 0; child < n_children; ++child)
3417 if (cell->child(child)->is_active() &&
3418 cell->child(child)->coarsen_flag_set())
3423 if (flagged_children < n_children)
3424 for (
unsigned int child = 0; child < n_children; ++child)
3425 if (cell->child(child)->is_active())
3426 cell->child(child)->clear_coarsen_flag();
3429 std::vector<bool> flags_after[2];
3432 return ((flags_before[0] != flags_after[0]) ||
3433 (flags_before[1] != flags_after[1]));
3439 template <
int dim,
int spacedim>
3443 std::vector<bool> flags_before[2];
3447 bool mesh_changed =
false;
3448 unsigned int loop_counter = 0;
3455 mesh_changed = enforce_mesh_balance_over_periodic_boundaries(*
this);
3465 "parallel::distributed::Triangulation::prepare_coarsening_and_refinement() " 3466 "for periodic boundaries detected. Aborting."));
3468 while (mesh_changed);
3472 std::vector<bool> flags_after[2];
3475 return ((flags_before[0] != flags_after[0]) ||
3476 (flags_before[1] != flags_after[1]));
3481 template <
int dim,
int spacedim>
3509 bool mesh_changed =
false;
3517 if (settings & mesh_reconstruction_after_repartitioning)
3522 cell->set_coarsen_flag();
3542 if (parallel_ghost !=
nullptr)
3546 parallel_ghost =
nullptr;
3550 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
3551 P4EST_CONNECT_CORNER) :
3552 typename ::internal::p4est::types<dim>::balance_type(
3553 P8EST_CONNECT_CORNER)));
3562 cell != this->
end(0);
3570 cell != this->
end(0);
3576 if (tree_exists_locally<dim, spacedim>(
3578 coarse_cell_to_p4est_tree_permutation[cell->index()]) ==
3581 delete_all_children<dim, spacedim>(cell);
3582 if (cell->is_active())
3591 typename ::internal::p4est::types<dim>::quadrant
3593 typename ::internal::p4est::types<dim>::tree *tree =
3594 init_tree(cell->index());
3596 ::internal::p4est::init_coarse_quadrant<dim>(
3599 match_tree_recursively<dim, spacedim>(*tree,
3603 this->my_subdomain);
3610 typename ::internal::p4est::types<dim>::quadrant *quadr;
3612 typename ::internal::p4est::types<dim>::topidx ghost_tree = 0;
3614 for (
unsigned int g_idx = 0;
3615 g_idx < parallel_ghost->ghosts.elem_count;
3618 while (g_idx >= static_cast<unsigned int>(
3619 parallel_ghost->proc_offsets[ghost_owner + 1]))
3621 while (g_idx >= static_cast<unsigned int>(
3622 parallel_ghost->tree_offsets[ghost_tree + 1]))
3625 quadr =
static_cast< 3626 typename ::internal::p4est::types<dim>::quadrant *
>(
3627 sc_array_index(¶llel_ghost->ghosts, g_idx));
3629 unsigned int coarse_cell_index =
3630 p4est_tree_to_coarse_cell_permutation[ghost_tree];
3632 match_quadrant<dim, spacedim>(
this,
3646 return cell.refine_flag_set() ||
3647 cell.coarsen_flag_set();
3665 while (mesh_changed);
3669 unsigned int num_ghosts = 0;
3673 if (cell->subdomain_id() != this->my_subdomain &&
3678 Assert(num_ghosts == parallel_ghost->ghosts.elem_count,
3688 if (settings & construct_multigrid_hierarchy)
3694 for (
unsigned int lvl = this->
n_levels(); lvl > 0;)
3698 endc = this->
end(lvl);
3699 for (cell = this->
begin(lvl); cell != endc; ++cell)
3701 if ((cell->is_active() &&
3702 cell->subdomain_id() ==
3704 (cell->has_children() &&
3705 cell->child(0)->level_subdomain_id() ==
3707 cell->set_level_subdomain_id(
3712 cell->set_level_subdomain_id(
3720 std::vector<std::vector<bool>> marked_vertices(this->
n_levels());
3721 for (
unsigned int lvl = 0; lvl < this->
n_levels(); ++lvl)
3722 marked_vertices[lvl] = mark_locally_active_vertices_on_level(lvl);
3726 cell != this->
end(0);
3729 typename ::internal::p4est::types<dim>::quadrant
3731 const unsigned int tree_index =
3732 coarse_cell_to_p4est_tree_permutation[cell->index()];
3733 typename ::internal::p4est::types<dim>::tree *tree =
3734 init_tree(cell->index());
3736 ::internal::p4est::init_coarse_quadrant<dim>(
3739 determine_level_subdomain_id_recursively<dim, spacedim>(
3750 for (
unsigned int lvl = this->
n_levels(); lvl > 0;)
3754 endc = this->
end(lvl);
3755 for (cell = this->
begin(lvl); cell != endc; ++cell)
3757 if (cell->has_children())
3758 for (
unsigned int c = 0;
3759 c < GeometryInfo<dim>::max_children_per_cell;
3762 if (cell->child(c)->level_subdomain_id() ==
3768 cell->child(0)->level_subdomain_id();
3772 cell->set_level_subdomain_id(mark);
3789 (void)total_local_cells;
3793 Assert(static_cast<unsigned int>(
3794 parallel_forest->local_num_quadrants) == total_local_cells,
3799 Assert(static_cast<unsigned int>(
3800 parallel_forest->local_num_quadrants) <= total_local_cells,
3805 unsigned int n_owned = 0;
3808 if (cell->subdomain_id() == this->my_subdomain)
3812 Assert(static_cast<unsigned int>(
3813 parallel_forest->local_num_quadrants) == n_owned,
3823 update_quadrant_cell_relations();
3828 template <
int dim,
int spacedim>
3835 if (cell->is_locally_owned() && cell->refine_flag_set())
3836 Assert(cell->refine_flag_set() ==
3839 "This class does not support anisotropic refinement"));
3856 !(cell->refine_flag_set()),
3858 "Fatal Error: maximum refinement level of p4est reached."));
3871 if (cell->is_ghost() || cell->is_artificial())
3873 cell->clear_refine_flag();
3874 cell->clear_coarsen_flag();
3880 RefineAndCoarsenList<dim, spacedim> refine_and_coarsen_list(
3881 *
this, p4est_tree_to_coarse_cell_permutation, this->my_subdomain);
3888 parallel_forest->user_pointer = &refine_and_coarsen_list;
3890 if (parallel_ghost !=
nullptr)
3894 parallel_ghost =
nullptr;
3899 &RefineAndCoarsenList<dim, spacedim>::refine_callback,
3904 &RefineAndCoarsenList<dim, spacedim>::coarsen_callback,
3911 parallel_forest->user_pointer =
this;
3917 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
3918 P4EST_CONNECT_FULL) :
3919 typename ::internal::p4est::types<dim>::balance_type(
3920 P8EST_CONNECT_FULL)),
3925 update_quadrant_cell_relations();
3930 std::vector<typename ::internal::p4est::types<dim>::gloidx>
3931 previous_global_first_quadrant;
3934 if (cell_attached_data.n_attached_data_sets > 0)
3936 data_transfer.pack_data(local_quadrant_cell_relations,
3937 cell_attached_data.pack_callbacks_fixed,
3938 cell_attached_data.pack_callbacks_variable);
3942 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
3943 std::memcpy(previous_global_first_quadrant.data(),
3944 parallel_forest->global_first_quadrant,
3946 typename ::internal::p4est::types<dim>::gloidx) *
3947 (parallel_forest->mpisize + 1));
3950 if (!(settings & no_automatic_repartitioning))
3962 const std::vector<unsigned int> cell_weights = get_cell_weights();
3964 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
3969 parallel_forest->user_pointer = &partition_weights;
3975 &PartitionWeights<dim, spacedim>::cell_weight);
3979 parallel_forest, 0,
nullptr,
nullptr);
3981 parallel_forest->user_pointer =
this;
3990 cell->clear_refine_flag();
3991 cell->clear_coarsen_flag();
3996 copy_local_forest_to_triangulation();
4007 if (cell_attached_data.n_attached_data_sets > 0)
4010 data_transfer.execute_transfer(parallel_forest,
4011 previous_global_first_quadrant.data());
4014 data_transfer.unpack_cell_status(local_quadrant_cell_relations);
4037 std::vector<bool> active_verts =
4038 this->mark_locally_active_vertices_on_level(lvl);
4040 const unsigned int maybe_coarser_lvl =
4041 (lvl > 0) ? (lvl - 1) : lvl;
4043 cell = this->
begin(maybe_coarser_lvl),
4044 endc = this->
end(lvl);
4045 for (; cell != endc; ++cell)
4046 if (cell->level() ==
static_cast<int>(lvl) || cell->is_active())
4048 const bool is_level_artificial =
4049 (cell->level_subdomain_id() ==
4051 bool need_to_know =
false;
4052 for (
const unsigned int vertex :
4054 if (active_verts[cell->vertex_index(vertex)])
4056 need_to_know =
true;
4061 !need_to_know || !is_level_artificial,
4063 "Internal error: the owner of cell" +
4064 cell->id().to_string() +
4065 " is unknown even though it is needed for geometric multigrid."));
4072 this->update_number_cache();
4080 template <
int dim,
int spacedim>
4086 if (cell->is_locally_owned())
4088 !cell->refine_flag_set() && !cell->coarsen_flag_set(),
4090 "Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition()."));
4098 std::vector<typename ::internal::p4est::types<dim>::gloidx>
4099 previous_global_first_quadrant;
4102 if (cell_attached_data.n_attached_data_sets > 0)
4104 data_transfer.pack_data(local_quadrant_cell_relations,
4105 cell_attached_data.pack_callbacks_fixed,
4106 cell_attached_data.pack_callbacks_variable);
4110 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
4111 std::memcpy(previous_global_first_quadrant.data(),
4112 parallel_forest->global_first_quadrant,
4114 typename ::internal::p4est::types<dim>::gloidx) *
4115 (parallel_forest->mpisize + 1));
4130 const std::vector<unsigned int> cell_weights = get_cell_weights();
4132 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
4137 parallel_forest->user_pointer = &partition_weights;
4143 &PartitionWeights<dim, spacedim>::cell_weight);
4146 parallel_forest->user_pointer =
this;
4151 copy_local_forest_to_triangulation();
4162 if (cell_attached_data.n_attached_data_sets > 0)
4165 data_transfer.execute_transfer(parallel_forest,
4166 previous_global_first_quadrant.data());
4172 this->update_number_cache();
4180 template <
int dim,
int spacedim>
4183 const std::vector<bool> &vertex_locally_moved)
4190 const std::vector<bool> locally_owned_vertices =
4192 for (
unsigned int i = 0; i < locally_owned_vertices.size(); ++i)
4193 Assert((vertex_locally_moved[i] ==
false) ||
4194 (locally_owned_vertices[i] ==
true),
4195 ExcMessage(
"The vertex_locally_moved argument must not " 4196 "contain vertices that are not locally owned"));
4206 const std::map<unsigned int, std::set<::types::subdomain_id>>
4214 CommunicateLocallyMovedVertices::CellInfo<dim, spacedim>>;
4215 cellmap_t needs_to_get_cells;
4219 cell != this->
end(0);
4222 typename ::internal::p4est::types<dim>::quadrant
4224 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4226 CommunicateLocallyMovedVertices::fill_vertices_recursively<dim,
4229 this->get_coarse_cell_to_p4est_tree_permutation()[cell->index()],
4233 vertex_locally_moved,
4234 needs_to_get_cells);
4242 mutex, this->get_communicator());
4247 std::vector<std::vector<char>> sendbuffers(needs_to_get_cells.size());
4248 std::vector<std::vector<char>>::iterator buffer = sendbuffers.begin();
4249 std::vector<MPI_Request> requests(needs_to_get_cells.size());
4250 std::vector<unsigned int> destinations;
4252 unsigned int idx = 0;
4254 for (
typename cellmap_t::iterator it = needs_to_get_cells.begin();
4255 it != needs_to_get_cells.end();
4256 ++it, ++buffer, ++idx)
4258 const unsigned int num_cells = it->second.tree_index.size();
4260 destinations.push_back(it->first);
4272 it->second.pack_data(*buffer);
4273 const int ierr = MPI_Isend(buffer->data(),
4278 this->get_communicator(),
4283 Assert(destinations.size() == needs_to_get_cells.size(),
4288 const unsigned int n_senders =
4290 this->get_communicator(), destinations);
4293 std::vector<char> receive;
4294 CommunicateLocallyMovedVertices::CellInfo<dim, spacedim> cellinfo;
4295 for (
unsigned int i = 0; i < n_senders; ++i)
4298 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4300 this->get_communicator(),
4305 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
4307 receive.resize(len);
4309 char *ptr = receive.data();
4310 ierr = MPI_Recv(ptr,
4315 this->get_communicator(),
4319 cellinfo.unpack_data(receive);
4320 const unsigned int cells = cellinfo.tree_index.size();
4321 for (
unsigned int c = 0; c < cells; ++c)
4323 typename ::parallel::distributed::
4324 Triangulation<dim, spacedim>::cell_iterator cell(
4327 this->get_p4est_tree_to_coarse_cell_permutation()
4328 [cellinfo.tree_index[c]]);
4330 typename ::internal::p4est::types<dim>::quadrant
4332 ::internal::p4est::init_coarse_quadrant<dim>(
4335 CommunicateLocallyMovedVertices::set_vertices_recursively<
4340 cellinfo.quadrants[c],
4341 cellinfo.first_vertices[c],
4342 cellinfo.first_vertex_indices[c]);
4348 if (requests.size() > 0)
4351 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
4357 this->get_communicator()) ==
4364 template <
int dim,
int spacedim>
4367 const std::function<std::vector<char>(
const cell_iterator &,
4369 const bool returns_variable_size_data)
4375 if (returns_variable_size_data)
4377 handle = 2 * cell_attached_data.pack_callbacks_variable.size();
4378 cell_attached_data.pack_callbacks_variable.push_back(pack_callback);
4382 handle = 2 * cell_attached_data.pack_callbacks_fixed.size() + 1;
4383 cell_attached_data.pack_callbacks_fixed.push_back(pack_callback);
4387 ++cell_attached_data.n_attached_data_sets;
4394 template <
int dim,
int spacedim>
4397 const unsigned int handle,
4398 const std::function<
4401 const boost::iterator_range<std::vector<char>::const_iterator> &)>
4404 Assert(cell_attached_data.n_attached_data_sets > 0,
4405 ExcMessage(
"The notify_ready_to_unpack() has already been called " 4406 "once for each registered callback."));
4410 Assert(local_quadrant_cell_relations.size() ==
4411 static_cast<unsigned int>(parallel_forest->local_num_quadrants),
4418 const unsigned int callback_index = handle / 2;
4419 if (handle % 2 == 0)
4422 cell_attached_data.pack_callbacks_variable.size(),
4425 Assert(cell_attached_data.pack_callbacks_variable[callback_index] !=
4428 cell_attached_data.pack_callbacks_variable[callback_index] =
nullptr;
4433 cell_attached_data.pack_callbacks_fixed.size(),
4436 Assert(cell_attached_data.pack_callbacks_fixed[callback_index] !=
4439 cell_attached_data.pack_callbacks_fixed[callback_index] =
nullptr;
4444 data_transfer.unpack_data(local_quadrant_cell_relations,
4449 --cell_attached_data.n_attached_data_sets;
4450 if (cell_attached_data.n_attached_deserialize > 0)
4451 --cell_attached_data.n_attached_deserialize;
4459 if (cell_attached_data.n_attached_data_sets == 0 &&
4460 cell_attached_data.n_attached_deserialize == 0)
4463 cell_attached_data.pack_callbacks_fixed.clear();
4464 cell_attached_data.pack_callbacks_variable.clear();
4465 data_transfer.clear();
4468 for (
auto &quad_cell_rel : local_quadrant_cell_relations)
4469 std::get<1>(quad_cell_rel) =
4476 template <
int dim,
int spacedim>
4477 const std::vector<types::global_dof_index> &
4481 return p4est_tree_to_coarse_cell_permutation;
4486 template <
int dim,
int spacedim>
4487 const std::vector<types::global_dof_index> &
4491 return coarse_cell_to_p4est_tree_permutation;
4496 template <
int dim,
int spacedim>
4499 const int level)
const 4503 std::vector<bool> marked_vertices(this->
n_vertices(),
false);
4505 for (; cell != endc; ++cell)
4508 marked_vertices[cell->vertex_index(v)] =
true;
4515 typename std::map<std::pair<cell_iterator, unsigned int>,
4516 std::pair<std::pair<cell_iterator, unsigned int>,
4517 std::bitset<3>>>::const_iterator it;
4529 for (
unsigned int repetition = 0; repetition < dim; ++repetition)
4535 const unsigned int face_no_1 = it->first.second;
4537 const unsigned int face_no_2 = it->second.first.second;
4538 const std::bitset<3> &face_orientation = it->second.second;
4540 if (cell_1->level() == level && cell_2->level() ==
level)
4542 for (
unsigned int v = 0;
4548 const unsigned int vface0 =
4551 face_orientation[0],
4552 face_orientation[1],
4553 face_orientation[2]);
4554 if (marked_vertices[cell_1->face(face_no_1)->vertex_index(
4556 marked_vertices[cell_2->face(face_no_2)->vertex_index(
4558 marked_vertices[cell_1->face(face_no_1)->vertex_index(
4560 marked_vertices[cell_2->face(face_no_2)->vertex_index(
4566 return marked_vertices;
4571 template <
int dim,
int spacedim>
4581 template <
int dim,
int spacedim>
4584 const unsigned int coarse_cell_index)
const 4586 return coarse_cell_to_p4est_tree_permutation[coarse_cell_index];
4591 template <
int dim,
int spacedim>
4595 &periodicity_vector)
4597 Assert(triangulation_has_content ==
true,
4600 ExcMessage(
"The triangulation is refined!"));
4607 for (
const auto &face_pair : periodicity_vector)
4611 const unsigned int face_left = face_pair.face_idx[0];
4612 const unsigned int face_right = face_pair.face_idx[1];
4615 const unsigned int tree_left =
4616 coarse_cell_to_p4est_tree_permutation[first_cell->index()];
4617 const unsigned int tree_right =
4618 coarse_cell_to_p4est_tree_permutation[second_cell->index()];
4627 unsigned int p4est_orientation = 0;
4629 p4est_orientation = face_pair.orientation[1];
4632 const unsigned int face_idx_list[] = {face_left, face_right};
4633 const cell_iterator cell_list[] = {first_cell, second_cell};
4634 unsigned int lower_idx, higher_idx;
4635 if (face_left <= face_right)
4648 unsigned int first_p4est_idx_on_cell =
4649 p8est_face_corners[face_idx_list[lower_idx]][0];
4650 unsigned int first_dealii_idx_on_face =
4652 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face;
4655 const unsigned int first_dealii_idx_on_cell =
4657 face_idx_list[lower_idx],
4659 cell_list[lower_idx]->face_orientation(
4660 face_idx_list[lower_idx]),
4661 cell_list[lower_idx]->face_flip(face_idx_list[lower_idx]),
4662 cell_list[lower_idx]->face_rotation(
4663 face_idx_list[lower_idx]));
4664 if (first_p4est_idx_on_cell == first_dealii_idx_on_cell)
4666 first_dealii_idx_on_face = i;
4673 constexpr
unsigned int left_to_right[8][4] = {{0, 2, 1, 3},
4681 constexpr
unsigned int right_to_left[8][4] = {{0, 2, 1, 3},
4689 const unsigned int second_dealii_idx_on_face =
4690 lower_idx == 0 ? left_to_right[face_pair.orientation.to_ulong()]
4691 [first_dealii_idx_on_face] :
4692 right_to_left[face_pair.orientation.to_ulong()]
4693 [first_dealii_idx_on_face];
4694 const unsigned int second_dealii_idx_on_cell =
4696 face_idx_list[higher_idx],
4697 second_dealii_idx_on_face,
4698 cell_list[higher_idx]->face_orientation(
4699 face_idx_list[higher_idx]),
4700 cell_list[higher_idx]->face_flip(face_idx_list[higher_idx]),
4701 cell_list[higher_idx]->face_rotation(
4702 face_idx_list[higher_idx]));
4704 const unsigned int second_p4est_idx_on_face =
4705 p8est_corner_face_corners[second_dealii_idx_on_cell]
4706 [face_idx_list[higher_idx]];
4707 p4est_orientation = second_p4est_idx_on_face;
4727 this->mpi_communicator,
4738 copy_local_forest_to_triangulation();
4748 this->update_number_cache();
4753 template <
int dim,
int spacedim>
4764 cell_attached_data.n_attached_data_sets) +
4771 coarse_cell_to_p4est_tree_permutation) +
4773 p4est_tree_to_coarse_cell_permutation) +
4774 memory_consumption_p4est();
4781 template <
int dim,
int spacedim>
4785 return ::internal::p4est::functions<dim>::forest_memory_used(
4793 template <
int dim,
int spacedim>
4796 const ::Triangulation<dim, spacedim> &other_tria)
4804 const typename ::Triangulation<dim, spacedim>::DistortedCellList
4815 triangulation_has_content =
true;
4817 Assert(other_tria.n_levels() == 1,
4819 "Parallel distributed triangulations can only be copied, " 4820 "if they are not refined!"));
4822 if (const ::parallel::distributed::Triangulation<dim, spacedim>
4824 dynamic_cast<const ::parallel::distributed::
4825 Triangulation<dim, spacedim> *
>(&other_tria))
4827 coarse_cell_to_p4est_tree_permutation =
4828 other_tria_x->coarse_cell_to_p4est_tree_permutation;
4829 p4est_tree_to_coarse_cell_permutation =
4830 other_tria_x->p4est_tree_to_coarse_cell_permutation;
4831 cell_attached_data = other_tria_x->cell_attached_data;
4832 data_transfer = other_tria_x->data_transfer;
4834 settings = other_tria_x->settings;
4838 setup_coarse_cell_to_p4est_tree_permutation();
4841 copy_new_triangulation_to_p4est(std::integral_constant<int, dim>());
4845 copy_local_forest_to_triangulation();
4855 this->update_number_cache();
4860 template <
int dim,
int spacedim>
4865 local_quadrant_cell_relations.resize(
4866 parallel_forest->local_num_quadrants);
4867 local_quadrant_cell_relations.shrink_to_fit();
4872 cell != this->
end(0);
4876 if (tree_exists_locally<dim, spacedim>(
4878 coarse_cell_to_p4est_tree_permutation[cell->index()]) ==
false)
4882 typename ::internal::p4est::types<dim>::quadrant
4884 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4887 typename ::internal::p4est::types<dim>::tree *tree =
4888 init_tree(cell->index());
4890 update_quadrant_cell_relations_recursively<dim, spacedim>(
4891 local_quadrant_cell_relations, *tree, cell, p4est_coarse_cell);
4897 template <
int dim,
int spacedim>
4898 std::vector<unsigned int>
4903 Assert(local_quadrant_cell_relations.size() ==
4904 static_cast<unsigned int>(parallel_forest->local_num_quadrants),
4912 std::vector<unsigned int> weights;
4921 for (
const auto &quad_cell_rel : local_quadrant_cell_relations)
4923 const auto &cell_status = std::get<1>(quad_cell_rel);
4924 const auto &cell_it = std::get<2>(quad_cell_rel);
4926 switch (cell_status)
4930 weights.push_back(1000);
4943 unsigned int parent_weight = 1000;
4950 weights.push_back(parent_weight);
4956 weights.push_back(1000);
4974 template <
int spacedim>
4977 const typename ::Triangulation<1, spacedim>::MeshSmoothing
4989 template <
int spacedim>
4997 template <
int spacedim>
5000 const std::vector<bool> & )
5007 template <
int spacedim>
5010 const std::function<std::vector<char>(
5011 const typename ::Triangulation<1, spacedim>::cell_iterator &,
5012 const typename ::Triangulation<1, spacedim>::CellStatus)>
5022 template <
int spacedim>
5025 const unsigned int ,
5026 const std::function<
5027 void(
const typename ::Triangulation<1, spacedim>::cell_iterator &,
5028 const typename ::Triangulation<1, spacedim>::CellStatus,
5029 const boost::iterator_range<std::vector<char>::const_iterator> &)>
5037 template <
int spacedim>
5038 const std::vector<types::global_dof_index> &
5042 static std::vector<types::global_dof_index> a;
5048 template <
int spacedim>
5049 std::map<unsigned int, std::set<::types::subdomain_id>>
5051 const unsigned int )
const 5055 return std::map<unsigned int, std::set<::types::subdomain_id>>();
5060 template <
int spacedim>
5063 const unsigned int)
const 5066 return std::vector<bool>();
5071 template <
int spacedim>
5082 template <
int spacedim>
5085 const unsigned int)
const 5092 template <
int spacedim>
5101 template <
int spacedim>
5110 template <
int spacedim>
5122 #endif // DEAL_II_WITH_P4EST 5127 #include "tria.inst"
std::vector< char > dest_data_fixed
IteratorRange< BaseIterator > make_iterator_range(const BaseIterator &begin, const typename identity< BaseIterator >::type &end)
bool is_multilevel_hierarchy_constructed() const override
unsigned int n_active_cells() const
virtual unsigned int coarse_cell_id_to_coarse_cell_index(const types::coarse_cell_id coarse_cell_id) const
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
unsigned int n_vertices() const
unsigned int register_data_attach(const std::function< std::vector< char >(const cell_iterator &, const CellStatus)> &pack_callback, const bool returns_variable_size_data)
static const unsigned int invalid_unsigned_int
#define AssertNothrow(cond, exc)
bool tree_exists_locally(const typename types< dim >::forest *parallel_forest, const typename types< dim >::topidx coarse_grid_cell)
boost::signals2::signal< void()> post_distributed_repartition
virtual bool has_hanging_nodes() const
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)
void load(const std::string &filename, const bool autopartition=true)
void save(const typename ::internal::p4est::types< dim >::forest *parallel_forest, const std::string &filename) const
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria) override
unsigned int n_cells() const
types::global_dof_index size_type
void unpack_cell_status(std::vector< quadrant_cell_relation_t > &quad_cell_relations) const
static ::ExceptionBase & ExcIO()
MeshSmoothing smooth_grid
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
std::vector< unsigned int > vertex_indices
std::vector< Point< spacedim > > vertices
std::vector< char > dest_data_variable
IteratorRange< active_cell_iterator > active_cell_iterators() const
unsigned int compute_n_point_to_point_communications(const MPI_Comm &mpi_comm, const std::vector< unsigned int > &destinations)
boost::signals2::signal< void()> pre_distributed_refinement
bool triangulation_has_content
void pack_data(const std::vector< quadrant_cell_relation_t > &quad_cell_relations, const std::vector< typename CellAttachedData::pack_callback_t > &pack_callbacks_fixed, const std::vector< typename CellAttachedData::pack_callback_t > &pack_callbacks_variable)
active_cell_iterator begin_active(const unsigned int level=0) const
#define AssertThrow(cond, exc)
std::vector< unsigned int * > first_vertex_indices
void save(const std::string &filename) const
Triangulation(const MPI_Comm &mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const Settings settings=default_setting)
cell_iterator begin(const unsigned int level=0) const
const std::vector< types::global_dof_index > & get_p4est_tree_to_coarse_cell_permutation() const
std::vector< char > src_data_variable
unsigned int n_levels() const
bool is_locally_owned() const
std::vector<::Point< spacedim > * > first_vertices
cell_iterator end() const
virtual unsigned int coarse_cell_id_to_coarse_cell_index(const types::coarse_cell_id coarse_cell_id) const override
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator >> &)
virtual void execute_coarsening_and_refinement()
virtual std::size_t memory_consumption() const override
unsigned int n_active_lines() const
virtual bool prepare_coarsening_and_refinement()
static ::ExceptionBase & ExcMessage(std::string arg1)
DataTransfer(const MPI_Comm &mpi_communicator)
unsigned int subdomain_id
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
std::vector< char > src_data_fixed
virtual types::coarse_cell_id coarse_cell_index_to_coarse_cell_id(const unsigned int coarse_cell_index) const override
T sum(const T &t, const MPI_Comm &mpi_communicator)
typename ::Triangulation< dim, spacedim >::CellStatus CellStatus
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
#define Assert(cond, exc)
void load(const typename ::internal::p4est::types< dim >::forest *parallel_forest, const std::string &filename, const unsigned int n_attached_deserialize_fixed, const unsigned int n_attached_deserialize_variable)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void load(Archive &ar, const unsigned int version)
virtual types::coarse_cell_id coarse_cell_index_to_coarse_cell_id(const unsigned int coarse_cell_index) const
void save_coarsen_flags(std::ostream &out) const
const std::vector< Point< spacedim > > & get_vertices() const
#define DEAL_II_NAMESPACE_CLOSE
void notify_ready_to_unpack(const unsigned int handle, const std::function< void(const cell_iterator &, const CellStatus, const boost::iterator_range< std::vector< char >::const_iterator > &)> &unpack_callback)
void save_refine_flags(std::ostream &out) const
boost::signals2::signal< void()> pre_distributed_save
std::vector< Integer > invert_permutation(const std::vector< Integer > &permutation)
virtual std::size_t memory_consumption() const
void coarsen(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold)
void save(Archive &ar, const unsigned int version) const
static unsigned int standard_to_real_face_vertex(const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
std::vector< typename ::internal::p4est::types< dim >::quadrant > quadrants
std::vector< unsigned int > tree_index
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
#define DEAL_II_MPI_CONST_CAST(expr)
DataTransfer data_transfer
const types::subdomain_id artificial_subdomain_id
bool all_reference_cell_types_are_hyper_cube() const
boost::signals2::signal< void()> post_distributed_save
void communicate_locally_moved_vertices(const std::vector< bool > &vertex_locally_moved)
void unpack_data(const std::vector< quadrant_cell_relation_t > &quad_cell_relations, const unsigned int handle, const std::function< void(const typename ::Triangulation< dim, spacedim >::cell_iterator &, const typename ::Triangulation< dim, spacedim >::CellStatus &, const boost::iterator_range< std::vector< char >::const_iterator > &)> &unpack_callback) const
#define AssertThrowMPI(error_code)
active_cell_iterator end_active(const unsigned int level) const
const std::vector< bool > & get_used_vertices() const
bool variable_size_data_stored
#define DEAL_II_NAMESPACE_OPEN
virtual unsigned int n_global_levels() const
T min(const T &t, const MPI_Comm &mpi_communicator)
virtual ~Triangulation() override
std::vector< int > src_sizes_variable
void update_periodic_face_map()
virtual ~Triangulation() override
boost::signals2::signal< unsigned int(const cell_iterator &, const CellStatus), CellWeightSum< unsigned int > > cell_weight
boost::signals2::signal< void()> pre_distributed_load
void execute_transfer(const typename ::internal::p4est::types< dim >::forest *parallel_forest, const typename ::internal::p4est::types< dim >::gloidx *previous_global_first_quadrant)
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
std::vector< unsigned int > sizes_fixed_cumulative
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
static ::ExceptionBase & ExcNotImplemented()
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
active_cell_iterator last_active() const
std::map< unsigned int, std::set<::types::subdomain_id > > * vertices_with_ghost_neighbors
boost::signals2::signal< void()> post_distributed_load
std::vector< int > dest_sizes_variable
global_cell_index coarse_cell_id
MPI_Comm mpi_communicator
boost::signals2::signal< void()> pre_distributed_repartition
CellAttachedData cell_attached_data
std::vector< bool > mark_locally_active_vertices_on_level(const int level) const
T max(const T &t, const MPI_Comm &mpi_communicator)
virtual types::subdomain_id locally_owned_subdomain() const
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
const std::map< std::pair< cell_iterator, unsigned int >, std::pair< std::pair< cell_iterator, unsigned int >, std::bitset< 3 > > > & get_periodic_face_map() const
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcInternalError()
boost::signals2::signal< void()> post_distributed_refinement