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)
57 for (
const auto &cell :
triangulation.active_cell_iterators())
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)
81 for (
const auto &cell :
triangulation.active_cell_iterators())
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] =
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;
649 for (
const auto &cell :
triangulation.active_cell_iterators())
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);
674 unsigned int coarse_cell_index =
675 p4est_tree_to_coarse_cell_permutation[c];
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)
1142 Assert(src_data_fixed.size() == 0,
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();
1151 variable_size_data_stored = (n_callbacks_variable > 0);
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(
1175 variable_size_data_stored ? quad_cell_relations.size() : 0);
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 =
1242 ((variable_size_data_stored ? 1 : 0) + n_callbacks_fixed));
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);
1273 if (variable_size_data_stored)
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(),
1328 if (variable_size_data_stored)
1329 ++data_cell_variable_it;
1346 std::vector<unsigned int> local_sizes_fixed(
1347 1 + n_callbacks_fixed + (variable_size_data_stored ? 1 : 0));
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);
1384 sizes_fixed_cumulative.resize(global_sizes_fixed.size());
1385 std::partial_sum(global_sizes_fixed.begin(),
1386 global_sizes_fixed.end(),
1387 sizes_fixed_cumulative.begin());
1392 if (variable_size_data_stored)
1394 src_sizes_variable.reserve(packed_variable_size_data.size());
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();
1402 src_sizes_variable.push_back(variable_data_size_on_cell);
1409 const unsigned int expected_size_fixed =
1410 quad_cell_relations.size() * sizes_fixed_cumulative.back();
1411 const unsigned int expected_size_variable =
1412 std::accumulate(src_sizes_variable.begin(),
1413 src_sizes_variable.end(),
1417 src_data_fixed.reserve(expected_size_fixed);
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(),
1425 std::back_inserter(src_data_fixed));
1431 if ((data_cell_fixed.size() == 1) &&
1432 (sizes_fixed_cumulative.size() > 1))
1434 const std::size_t bytes_skipped =
1435 sizes_fixed_cumulative.back() - sizes_fixed_cumulative.front();
1437 src_data_fixed.insert(src_data_fixed.end(),
1439 static_cast<char>(-1));
1445 if (variable_size_data_stored)
1447 src_data_variable.reserve(expected_size_variable);
1448 for (
const auto &data_cell : packed_variable_size_data)
1452 for (
const auto &data : data_cell)
1453 std::move(data.begin(),
1455 std::back_inserter(src_data_variable));
1461 Assert(src_data_variable.size() == expected_size_variable,
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)
1475 Assert(sizes_fixed_cumulative.size() > 0,
1480 sizes_fixed_cumulative.back());
1483 typename ::internal::p4est::types<dim>::transfer_context
1488 previous_global_first_quadrant,
1491 dest_data_fixed.data(),
1492 src_data_fixed.data(),
1493 sizes_fixed_cumulative.back());
1495 if (variable_size_data_stored)
1504 previous_global_first_quadrant,
1507 dest_sizes_variable.data(),
1508 src_sizes_variable.data(),
1515 src_data_fixed.clear();
1516 src_data_fixed.shrink_to_fit();
1518 if (variable_size_data_stored)
1521 dest_data_variable.resize(
1522 std::accumulate(dest_sizes_variable.begin(),
1523 dest_sizes_variable.end(),
1526 # if DEAL_II_P4EST_VERSION_GTE(2, 0, 65, 0)
1533 if (src_sizes_variable.size() == 0)
1534 src_sizes_variable.resize(1);
1535 if (dest_sizes_variable.size() == 0)
1536 dest_sizes_variable.resize(1);
1542 previous_global_first_quadrant,
1545 dest_data_variable.data(),
1546 dest_sizes_variable.data(),
1547 src_data_variable.data(),
1548 src_sizes_variable.data());
1551 src_sizes_variable.clear();
1552 src_sizes_variable.shrink_to_fit();
1553 src_data_variable.clear();
1554 src_data_variable.shrink_to_fit();
1560 template <
int dim,
int spacedim>
1563 std::vector<quadrant_cell_relation_t> &quad_cell_relations)
const
1565 Assert(sizes_fixed_cumulative.size() > 0,
1567 if (quad_cell_relations.size() > 0)
1569 Assert(dest_data_fixed.size() > 0,
1574 const unsigned int size = sizes_fixed_cumulative.front();
1580 auto quad_cell_rel_it = quad_cell_relations.begin();
1581 auto dest_fixed_it = dest_data_fixed.cbegin();
1582 for (; quad_cell_rel_it != quad_cell_relations.end();
1583 ++quad_cell_rel_it, dest_fixed_it += sizes_fixed_cumulative.back())
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;
1618 Assert(sizes_fixed_cumulative.size() > 0,
1620 if (quad_cell_relations.size() > 0)
1622 Assert(dest_data_fixed.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 =
1651 sizes_fixed_cumulative[sizes_fixed_cumulative.size() - 2];
1658 dest_sizes_cell_it = dest_data_fixed.cbegin() +
1659 offset_variable_data_sizes +
1660 callback_index *
sizeof(
unsigned int);
1663 dest_data_it = dest_data_variable.cbegin();
1670 offset = sizes_fixed_cumulative[callback_index];
1671 size = sizes_fixed_cumulative[callback_index + 1] - offset;
1672 data_increment = sizes_fixed_cumulative.back();
1678 dest_data_it = dest_data_fixed.cbegin() + offset;
1682 auto quad_cell_rel_it = quad_cell_relations.begin();
1683 auto dest_sizes_it = dest_sizes_variable.cbegin();
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;
1723 dest_sizes_cell_it += sizes_fixed_cumulative.back();
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
1774 Assert(sizes_fixed_cumulative.size() > 0,
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);
1815 const unsigned int *data = sizes_fixed_cumulative.data();
1817 ierr = MPI_File_write_at(fh,
1820 sizes_fixed_cumulative.size(),
1827 const unsigned int offset_fixed =
1828 sizes_fixed_cumulative.size() *
sizeof(
unsigned int);
1830 const char *data = src_data_fixed.data();
1832 ierr = MPI_File_write_at(
1836 sizes_fixed_cumulative.back(),
1838 src_data_fixed.size(),
1843 ierr = MPI_File_close(&fh);
1850 if (variable_size_data_stored)
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);
1878 const int *data = src_sizes_variable.data();
1880 MPI_File_write_at(fh,
1884 src_sizes_variable.size(),
1891 const unsigned int offset_variable =
1895 const unsigned int size_on_proc = src_data_variable.size();
1898 unsigned int prefix_sum = 0;
1907 const char *data = src_data_variable.data();
1910 ierr = MPI_File_write_at(fh,
1914 src_data_variable.size(),
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)
1939 Assert(dest_data_fixed.size() == 0,
1940 ExcMessage(
"Previously loaded data has not been released yet!"));
1942 variable_size_data_stored = (n_attached_deserialize_variable > 0);
1950 const std::string fname_fixed = std::string(filename) +
"_fixed.data";
1953 int ierr = MPI_Info_create(&info);
1964 ierr = MPI_Info_free(&info);
1974 sizes_fixed_cumulative.resize(1 + n_attached_deserialize_fixed +
1975 (variable_size_data_stored ? 1 : 0));
1976 ierr = MPI_File_read_at(fh,
1978 sizes_fixed_cumulative.data(),
1979 sizes_fixed_cumulative.size(),
1986 sizes_fixed_cumulative.back());
1989 const unsigned int offset =
1990 sizes_fixed_cumulative.size() *
sizeof(
unsigned int);
1992 ierr = MPI_File_read_at(
1995 sizes_fixed_cumulative.back(),
1996 dest_data_fixed.data(),
1997 dest_data_fixed.size(),
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,
2035 dest_sizes_variable.data(),
2036 dest_sizes_variable.size(),
2041 const unsigned int offset =
2044 const unsigned int size_on_proc =
2045 std::accumulate(dest_sizes_variable.begin(),
2046 dest_sizes_variable.end(),
2050 unsigned int prefix_sum = 0;
2059 dest_data_variable.resize(size_on_proc);
2060 ierr = MPI_File_read_at(fh,
2061 offset + prefix_sum,
2062 dest_data_variable.data(),
2063 dest_data_variable.size(),
2068 ierr = MPI_File_close(&fh);
2075 template <
int dim,
int spacedim>
2079 variable_size_data_stored =
false;
2082 sizes_fixed_cumulative.clear();
2083 sizes_fixed_cumulative.shrink_to_fit();
2086 src_data_fixed.clear();
2087 src_data_fixed.shrink_to_fit();
2089 dest_data_fixed.clear();
2090 dest_data_fixed.shrink_to_fit();
2093 src_sizes_variable.clear();
2094 src_sizes_variable.shrink_to_fit();
2096 src_data_variable.clear();
2097 src_data_variable.shrink_to_fit();
2099 dest_sizes_variable.clear();
2100 dest_sizes_variable.shrink_to_fit();
2102 dest_data_variable.clear();
2103 dest_data_variable.shrink_to_fit();
2111 template <
int dim,
int spacedim>
2114 const typename ::Triangulation<dim, spacedim>::MeshSmoothing
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 triangulation_has_content =
true;
2187 setup_coarse_cell_to_p4est_tree_permutation();
2189 copy_new_triangulation_to_p4est(std::integral_constant<int, dim>());
2193 copy_local_forest_to_triangulation();
2202 this->update_periodic_face_map();
2203 this->update_number_cache();
2208 template <
int dim,
int spacedim>
2214 (void)construction_data;
2223 namespace CommunicateLocallyMovedVertices
2232 template <
int dim,
int spacedim>
2240 std::vector<typename ::internal::p4est::types<dim>::quadrant>
2255 bytes_for_buffer()
const
2257 return sizeof(
unsigned int) +
2261 typename ::internal::p4est::types<dim>::quadrant) +
2267 pack_data(std::vector<char> &buffer)
const
2269 buffer.resize(bytes_for_buffer());
2271 char *ptr = buffer.data();
2273 const unsigned int num_cells =
tree_index.size();
2274 std::memcpy(ptr, &num_cells,
sizeof(
unsigned int));
2275 ptr +=
sizeof(
unsigned int);
2279 num_cells *
sizeof(
unsigned int));
2280 ptr += num_cells *
sizeof(
unsigned int);
2286 sizeof(typename ::internal::p4est::types<dim>::quadrant));
2289 sizeof(typename ::internal::p4est::types<dim>::quadrant);
2304 unpack_data(
const std::vector<char> &buffer)
2306 const char * ptr = buffer.data();
2308 memcpy(&cells, ptr,
sizeof(
unsigned int));
2309 ptr +=
sizeof(
unsigned int);
2312 memcpy(
tree_index.data(), ptr,
sizeof(
unsigned int) * cells);
2313 ptr +=
sizeof(
unsigned int) * cells;
2319 typename ::internal::p4est::types<dim>::quadrant) *
2322 sizeof(typename ::internal::p4est::types<dim>::quadrant) *
2327 std::vector<unsigned int> n_vertices_on_cell(cells);
2328 std::vector<unsigned int> first_indices(cells);
2329 for (
unsigned int c = 0; c < cells; ++c)
2334 const unsigned int *
const vertex_index =
2335 reinterpret_cast<const unsigned int *
>(ptr);
2338 n_vertices_on_cell[c] = *vertex_index;
2339 ptr +=
sizeof(
unsigned int);
2342 n_vertices_on_cell[c]);
2344 n_vertices_on_cell[c]],
2346 n_vertices_on_cell[c] *
sizeof(
unsigned int));
2347 ptr += n_vertices_on_cell[c] *
sizeof(
unsigned int);
2349 for (
unsigned int c = 0; c < cells; ++c)
2354 for (
unsigned int c = 0; c < cells; ++c)
2356 first_indices[c] =
vertices.size();
2363 for (
unsigned int c = 0; c < cells; ++c)
2384 template <
int dim,
int spacedim>
2386 fill_vertices_recursively(
2392 const typename ::internal::p4est::types<dim>::quadrant
2394 const std::map<
unsigned int, std::set<::types::subdomain_id>>
2396 const std::vector<bool> &vertex_locally_moved,
2402 if (dealii_cell->has_children())
2404 typename ::internal::p4est::types<dim>::quadrant
2406 ::internal::p4est::init_quadrant_children<dim>(p4est_cell,
2410 for (
unsigned int c = 0;
2411 c < GeometryInfo<dim>::max_children_per_cell;
2413 fill_vertices_recursively<dim, spacedim>(
2416 dealii_cell->child(c),
2419 vertex_locally_moved,
2431 if (dealii_cell->is_locally_owned())
2433 std::set<::types::subdomain_id> send_to;
2436 const std::map<
unsigned int,
2437 std::set<::types::subdomain_id>>::
2438 const_iterator neighbor_subdomains_of_vertex =
2440 dealii_cell->vertex_index(v));
2442 if (neighbor_subdomains_of_vertex !=
2445 Assert(neighbor_subdomains_of_vertex->second.size() != 0,
2448 neighbor_subdomains_of_vertex->second.begin(),
2449 neighbor_subdomains_of_vertex->second.end());
2453 if (send_to.size() > 0)
2456 std::vector<::Point<spacedim>> local_vertices;
2457 for (
const unsigned int v :
2459 if (vertex_locally_moved[dealii_cell->vertex_index(v)])
2462 local_vertices.push_back(dealii_cell->vertex(v));
2466 for (
const auto subdomain : send_to)
2471 const typename std::map<
2473 CellInfo<dim, spacedim>>::iterator p =
2475 .insert(std::make_pair(subdomain,
2476 CellInfo<dim, spacedim>()))
2480 p->second.quadrants.push_back(p4est_cell);
2482 p->second.vertex_indices.push_back(
2484 p->second.vertex_indices.insert(
2485 p->second.vertex_indices.end(),
2489 p->second.vertices.insert(p->second.vertices.end(),
2490 local_vertices.begin(),
2491 local_vertices.end());
2508 template <
int dim,
int spacedim>
2510 set_vertices_recursively(
2512 const typename ::internal::p4est::types<dim>::quadrant
2516 const typename ::internal::p4est::types<dim>::quadrant
2518 const ::Point<spacedim> *
const vertices,
2521 if (::internal::p4est::quadrant_is_equal<dim>(p4est_cell,
2531 for (
unsigned int i = 0; i < n_vertices; ++i)
2537 if (dealii_cell->is_active())
2540 if (!::internal::p4est::quadrant_is_ancestor<dim>(p4est_cell,
2544 typename ::internal::p4est::types<dim>::quadrant
2546 ::internal::p4est::init_quadrant_children<dim>(p4est_cell,
2549 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
2551 set_vertices_recursively<dim, spacedim>(tria,
2553 dealii_cell->child(c),
2563 template <
int dim,
int spacedim>
2567 triangulation_has_content =
false;
2569 cell_attached_data = {0, 0, {}, {}};
2570 data_transfer.clear();
2572 if (parallel_ghost !=
nullptr)
2576 parallel_ghost =
nullptr;
2579 if (parallel_forest !=
nullptr)
2582 parallel_forest =
nullptr;
2585 if (connectivity !=
nullptr)
2589 connectivity =
nullptr;
2592 coarse_cell_to_p4est_tree_permutation.resize(0);
2593 p4est_tree_to_coarse_cell_permutation.resize(0);
2597 this->update_number_cache();
2602 template <
int dim,
int spacedim>
2612 template <
int dim,
int spacedim>
2616 if (this->n_global_levels() <= 1)
2625 const bool have_coarser_cell =
2626 std::any_of(this->begin_active(this->n_global_levels() - 2),
2627 this->end_active(this->n_global_levels() - 2),
2634 this->mpi_communicator);
2639 template <
int dim,
int spacedim>
2646 coarse_cell_to_p4est_tree_permutation.resize(this->
n_cells(0));
2648 cell_connectivity, coarse_cell_to_p4est_tree_permutation);
2650 p4est_tree_to_coarse_cell_permutation =
2656 template <
int dim,
int spacedim>
2659 const std::string &file_basename)
const
2661 Assert(parallel_forest !=
nullptr,
2662 ExcMessage(
"Can't produce output when no forest is created yet."));
2664 parallel_forest,
nullptr, file_basename.c_str());
2669 template <
int dim,
int spacedim>
2674 cell_attached_data.n_attached_deserialize == 0,
2676 "not all SolutionTransfer's got deserialized after the last load()"));
2678 ExcMessage(
"Can not save() an empty Triangulation."));
2681 this->signals.pre_distributed_save();
2683 if (this->my_subdomain == 0)
2685 std::string fname = std::string(filename) +
".info";
2686 std::ofstream f(fname.c_str());
2687 f <<
"version nproc n_attached_fixed_size_objs n_attached_variable_size_objs n_coarse_cells"
2691 << cell_attached_data.pack_callbacks_fixed.size() <<
" "
2692 << cell_attached_data.pack_callbacks_variable.size() <<
" "
2693 << this->
n_cells(0) << std::endl;
2697 for (
const auto &quad_cell_rel : local_quadrant_cell_relations)
2699 (void)quad_cell_rel;
2701 (std::get<1>(quad_cell_rel) ==
2706 if (cell_attached_data.n_attached_data_sets > 0)
2709 auto tria =
const_cast<
2715 local_quadrant_cell_relations,
2716 cell_attached_data.pack_callbacks_fixed,
2717 cell_attached_data.pack_callbacks_variable);
2744 this->signals.post_distributed_save();
2749 template <
int dim,
int spacedim>
2752 const bool autopartition)
2757 "load() only works if the Triangulation already contains a coarse mesh!"));
2759 this->n_levels() == 1,
2761 "Triangulation may only contain coarse cells when calling load()."));
2764 this->signals.pre_distributed_load();
2766 if (parallel_ghost !=
nullptr)
2770 parallel_ghost =
nullptr;
2773 parallel_forest =
nullptr;
2776 connectivity =
nullptr;
2778 unsigned int version, numcpus, attached_count_fixed,
2779 attached_count_variable, n_coarse_cells;
2781 std::string fname = std::string(filename) +
".info";
2782 std::ifstream f(fname.c_str());
2784 std::string firstline;
2785 getline(f, firstline);
2786 f >> version >> numcpus >> attached_count_fixed >>
2787 attached_count_variable >> n_coarse_cells;
2791 ExcMessage(
"Incompatible version found in .info file."));
2793 ExcMessage(
"Number of coarse cells differ!"));
2797 cell_attached_data.n_attached_data_sets = 0;
2798 cell_attached_data.n_attached_deserialize =
2799 attached_count_fixed + attached_count_variable;
2803 this->mpi_communicator,
2818 if (this->signals.cell_weight.num_slots() == 0)
2830 const std::vector<unsigned int> cell_weights = get_cell_weights();
2832 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
2837 parallel_forest->user_pointer = &partition_weights;
2843 &PartitionWeights<dim, spacedim>::cell_weight);
2846 parallel_forest->user_pointer =
this;
2852 copy_local_forest_to_triangulation();
2864 if (cell_attached_data.n_attached_deserialize > 0)
2866 data_transfer.load(parallel_forest,
2868 attached_count_fixed,
2869 attached_count_variable);
2871 data_transfer.unpack_cell_status(local_quadrant_cell_relations);
2874 for (
const auto &quad_cell_rel : local_quadrant_cell_relations)
2876 (void)quad_cell_rel;
2878 (std::get<1>(quad_cell_rel) ==
2880 spacedim>::CELL_PERSIST),
2885 this->update_periodic_face_map();
2886 this->update_number_cache();
2889 this->signals.post_distributed_load();
2894 template <
int dim,
int spacedim>
2898 Assert(parallel_forest !=
nullptr,
2900 "Can't produce a check sum when no forest is created yet."));
2901 return ::internal::p4est::functions<dim>::checksum(parallel_forest);
2906 template <
int dim,
int spacedim>
2907 const typename ::internal::p4est::types<dim>::forest *
2910 Assert(parallel_forest !=
nullptr,
2911 ExcMessage(
"The forest has not been allocated yet."));
2912 return parallel_forest;
2917 template <
int dim,
int spacedim>
2918 typename ::internal::p4est::types<dim>::tree *
2920 const int dealii_coarse_cell_index)
const
2923 coarse_cell_to_p4est_tree_permutation[dealii_coarse_cell_index];
2924 typename ::internal::p4est::types<dim>::tree *tree =
2925 static_cast<typename ::internal::p4est::types<dim>::tree *
>(
2926 sc_array_index(parallel_forest->trees,
tree_index));
2940 std::integral_constant<int, 2>)
2942 const unsigned int dim = 2, spacedim = 2;
2950 std::vector<unsigned int> vertex_touch_count;
2952 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
2955 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
2956 const ::internal::p4est::types<2>::locidx num_vtt =
2957 std::accumulate(vertex_touch_count.begin(),
2958 vertex_touch_count.end(),
2964 const bool set_vertex_info
2973 (set_vertex_info ==
true ? this->n_vertices() : 0),
2978 set_vertex_and_cell_info(*
this,
2981 coarse_cell_to_p4est_tree_permutation,
2985 Assert(p4est_connectivity_is_valid(connectivity) == 1,
2990 this->mpi_communicator,
3007 std::integral_constant<int, 2>)
3009 const unsigned int dim = 2, spacedim = 3;
3017 std::vector<unsigned int> vertex_touch_count;
3019 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
3022 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
3023 const ::internal::p4est::types<2>::locidx num_vtt =
3024 std::accumulate(vertex_touch_count.begin(),
3025 vertex_touch_count.end(),
3031 const bool set_vertex_info
3040 (set_vertex_info ==
true ? this->n_vertices() : 0),
3045 set_vertex_and_cell_info(*
this,
3048 coarse_cell_to_p4est_tree_permutation,
3052 Assert(p4est_connectivity_is_valid(connectivity) == 1,
3057 this->mpi_communicator,
3072 std::integral_constant<int, 3>)
3074 const int dim = 3, spacedim = 3;
3082 std::vector<unsigned int> vertex_touch_count;
3083 std::vector<std::list<
3084 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
3086 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
3087 const ::internal::p4est::types<2>::locidx num_vtt =
3088 std::accumulate(vertex_touch_count.begin(),
3089 vertex_touch_count.end(),
3092 std::vector<unsigned int> edge_touch_count;
3093 std::vector<std::list<
3094 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
3096 get_edge_to_cell_mappings(*
this, edge_touch_count, edge_to_cell);
3097 const ::internal::p4est::types<2>::locidx num_ett =
3098 std::accumulate(edge_touch_count.begin(), edge_touch_count.end(), 0u);
3101 const bool set_vertex_info
3110 (set_vertex_info ==
true ? this->n_vertices() : 0),
3112 this->n_active_lines(),
3117 set_vertex_and_cell_info(*
this,
3120 coarse_cell_to_p4est_tree_permutation,
3149 const unsigned int deal_to_p4est_line_index[12] = {
3150 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11};
3153 this->begin_active();
3154 cell != this->
end();
3157 const unsigned int index =
3158 coarse_cell_to_p4est_tree_permutation[cell->index()];
3159 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_cell; ++
e)
3161 deal_to_p4est_line_index[
e]] =
3162 cell->line(
e)->index();
3167 connectivity->ett_offset[0] = 0;
3168 std::partial_sum(edge_touch_count.begin(),
3169 edge_touch_count.end(),
3170 &connectivity->ett_offset[1]);
3172 Assert(connectivity->ett_offset[this->n_active_lines()] == num_ett,
3175 for (
unsigned int v = 0; v < this->n_active_lines(); ++v)
3177 Assert(edge_to_cell[v].size() == edge_touch_count[v],
3181 std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
3182 unsigned int>>::const_iterator p =
3183 edge_to_cell[v].begin();
3184 for (
unsigned int c = 0; c < edge_touch_count[v]; ++c, ++p)
3186 connectivity->edge_to_tree[connectivity->ett_offset[v] + c] =
3187 coarse_cell_to_p4est_tree_permutation[p->first->index()];
3188 connectivity->edge_to_edge[connectivity->ett_offset[v] + c] =
3189 deal_to_p4est_line_index[p->second];
3193 Assert(p8est_connectivity_is_valid(connectivity) == 1,
3198 this->mpi_communicator,
3215 template <
int dim,
int spacedim>
3217 enforce_mesh_balance_over_periodic_boundaries(
3223 std::vector<bool> flags_before[2];
3227 std::vector<unsigned int> topological_vertex_numbering(
3229 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
3230 topological_vertex_numbering[i] = i;
3246 using cell_iterator =
3248 typename std::map<std::pair<cell_iterator, unsigned int>,
3249 std::pair<std::pair<cell_iterator, unsigned int>,
3250 std::bitset<3>>>::const_iterator it;
3255 const cell_iterator &cell_1 = it->first.first;
3256 const unsigned int face_no_1 = it->first.second;
3257 const cell_iterator &cell_2 = it->second.first.first;
3258 const unsigned int face_no_2 = it->second.first.second;
3259 const std::bitset<3> face_orientation = it->second.second;
3261 if (cell_1->level() == cell_2->level())
3263 for (
unsigned int v = 0;
3269 const unsigned int vface0 =
3272 face_orientation[0],
3273 face_orientation[1],
3274 face_orientation[2]);
3275 const unsigned int vi0 =
3276 topological_vertex_numbering[cell_1->face(face_no_1)
3277 ->vertex_index(vface0)];
3278 const unsigned int vi1 =
3279 topological_vertex_numbering[cell_2->face(face_no_2)
3281 const unsigned int min_index =
std::min(vi0, vi1);
3282 topological_vertex_numbering[cell_1->face(face_no_1)
3283 ->vertex_index(vface0)] =
3284 topological_vertex_numbering[cell_2->face(face_no_2)
3285 ->vertex_index(v)] =
3292 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
3294 const unsigned int j = topological_vertex_numbering[i];
3302 bool continue_iterating =
true;
3303 std::vector<int> vertex_level(tria.
n_vertices());
3304 while (continue_iterating)
3308 std::fill(vertex_level.begin(), vertex_level.end(), 0);
3312 for (; cell != endc; ++cell)
3314 if (cell->refine_flag_set())
3315 for (
const unsigned int vertex :
3317 vertex_level[topological_vertex_numbering
3318 [cell->vertex_index(vertex)]] =
3319 std::max(vertex_level[topological_vertex_numbering
3320 [cell->vertex_index(vertex)]],
3322 else if (!cell->coarsen_flag_set())
3323 for (
const unsigned int vertex :
3325 vertex_level[topological_vertex_numbering
3326 [cell->vertex_index(vertex)]] =
3327 std::max(vertex_level[topological_vertex_numbering
3328 [cell->vertex_index(vertex)]],
3339 for (
const unsigned int vertex :
3341 vertex_level[topological_vertex_numbering
3342 [cell->vertex_index(vertex)]] =
3343 std::max(vertex_level[topological_vertex_numbering
3344 [cell->vertex_index(vertex)]],
3349 continue_iterating =
false;
3360 for (cell = tria.
last_active(); cell != endc; --cell)
3361 if (cell->refine_flag_set() ==
false)
3363 for (
const unsigned int vertex :
3365 if (vertex_level[topological_vertex_numbering
3366 [cell->vertex_index(vertex)]] >=
3370 cell->clear_coarsen_flag();
3375 if (vertex_level[topological_vertex_numbering
3376 [cell->vertex_index(vertex)]] >
3379 cell->set_refine_flag();
3380 continue_iterating =
true;
3382 for (
const unsigned int v :
3384 vertex_level[topological_vertex_numbering
3385 [cell->vertex_index(v)]] =
3387 vertex_level[topological_vertex_numbering
3388 [cell->vertex_index(v)]],
3405 if (cell->is_active())
3408 const unsigned int n_children = cell->n_children();
3409 unsigned int flagged_children = 0;
3410 for (
unsigned int child = 0; child < n_children; ++child)
3411 if (cell->child(child)->is_active() &&
3412 cell->child(child)->coarsen_flag_set())
3417 if (flagged_children < n_children)
3418 for (
unsigned int child = 0; child < n_children; ++child)
3419 if (cell->child(child)->is_active())
3420 cell->child(child)->clear_coarsen_flag();
3423 std::vector<bool> flags_after[2];
3426 return ((flags_before[0] != flags_after[0]) ||
3427 (flags_before[1] != flags_after[1]));
3433 template <
int dim,
int spacedim>
3437 std::vector<bool> flags_before[2];
3438 this->save_coarsen_flags(flags_before[0]);
3439 this->save_refine_flags(flags_before[1]);
3441 bool mesh_changed =
false;
3446 this->update_periodic_face_map();
3448 mesh_changed = enforce_mesh_balance_over_periodic_boundaries(*
this);
3450 while (mesh_changed);
3454 std::vector<bool> flags_after[2];
3455 this->save_coarsen_flags(flags_after[0]);
3456 this->save_refine_flags(flags_after[1]);
3457 return ((flags_before[0] != flags_after[0]) ||
3458 (flags_before[1] != flags_after[1]));
3463 template <
int dim,
int spacedim>
3487 spacedim>::limit_level_difference_at_vertices;
3491 bool mesh_changed =
false;
3499 if (settings & mesh_reconstruction_after_repartitioning)
3500 while (this->begin_active()->
level() > 0)
3502 for (
const auto &cell : this->active_cell_iterators())
3504 cell->set_coarsen_flag();
3507 this->prepare_coarsening_and_refinement();
3524 if (parallel_ghost !=
nullptr)
3528 parallel_ghost =
nullptr;
3532 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
3533 P4EST_CONNECT_CORNER) :
3534 typename ::internal::p4est::types<dim>::balance_type(
3535 P8EST_CONNECT_CORNER)));
3544 cell != this->
end(0);
3552 cell != this->
end(0);
3558 if (tree_exists_locally<dim, spacedim>(
3560 coarse_cell_to_p4est_tree_permutation[cell->index()]) ==
3563 delete_all_children<dim, spacedim>(cell);
3564 if (cell->is_active())
3573 typename ::internal::p4est::types<dim>::quadrant
3575 typename ::internal::p4est::types<dim>::tree *tree =
3576 init_tree(cell->index());
3578 ::internal::p4est::init_coarse_quadrant<dim>(
3581 match_tree_recursively<dim, spacedim>(*tree,
3585 this->my_subdomain);
3592 typename ::internal::p4est::types<dim>::quadrant *quadr;
3594 typename ::internal::p4est::types<dim>::topidx ghost_tree = 0;
3596 for (
unsigned int g_idx = 0;
3597 g_idx < parallel_ghost->ghosts.elem_count;
3600 while (g_idx >=
static_cast<unsigned int>(
3601 parallel_ghost->proc_offsets[ghost_owner + 1]))
3603 while (g_idx >=
static_cast<unsigned int>(
3604 parallel_ghost->tree_offsets[ghost_tree + 1]))
3607 quadr =
static_cast<
3608 typename ::internal::p4est::types<dim>::quadrant *
>(
3609 sc_array_index(¶llel_ghost->ghosts, g_idx));
3611 unsigned int coarse_cell_index =
3612 p4est_tree_to_coarse_cell_permutation[ghost_tree];
3614 match_quadrant<dim, spacedim>(
this,
3621 this->prepare_coarsening_and_refinement();
3625 std::any_of(this->begin_active(),
3628 return cell.refine_flag_set() ||
3629 cell.coarsen_flag_set();
3647 while (mesh_changed);
3651 unsigned int num_ghosts = 0;
3653 for (
const auto &cell : this->active_cell_iterators())
3655 if (cell->subdomain_id() != this->my_subdomain &&
3660 Assert(num_ghosts == parallel_ghost->ghosts.elem_count,
3676 for (
unsigned int lvl = this->n_levels(); lvl > 0;)
3680 endc = this->
end(lvl);
3681 for (cell = this->
begin(lvl); cell != endc; ++cell)
3683 if ((cell->is_active() &&
3684 cell->subdomain_id() ==
3685 this->locally_owned_subdomain()) ||
3686 (cell->has_children() &&
3687 cell->child(0)->level_subdomain_id() ==
3688 this->locally_owned_subdomain()))
3689 cell->set_level_subdomain_id(
3690 this->locally_owned_subdomain());
3694 cell->set_level_subdomain_id(
3702 std::vector<std::vector<bool>> marked_vertices(this->n_levels());
3703 for (
unsigned int lvl = 0; lvl < this->n_levels(); ++lvl)
3704 marked_vertices[lvl] = mark_locally_active_vertices_on_level(lvl);
3708 cell != this->
end(0);
3711 typename ::internal::p4est::types<dim>::quadrant
3714 coarse_cell_to_p4est_tree_permutation[cell->index()];
3715 typename ::internal::p4est::types<dim>::tree *tree =
3716 init_tree(cell->index());
3718 ::internal::p4est::init_coarse_quadrant<dim>(
3721 determine_level_subdomain_id_recursively<dim, spacedim>(
3732 for (
unsigned int lvl = this->n_levels(); lvl > 0;)
3736 endc = this->
end(lvl);
3737 for (cell = this->
begin(lvl); cell != endc; ++cell)
3739 if (cell->has_children())
3740 for (
unsigned int c = 0;
3741 c < GeometryInfo<dim>::max_children_per_cell;
3744 if (cell->child(c)->level_subdomain_id() ==
3745 this->locally_owned_subdomain())
3750 cell->child(0)->level_subdomain_id();
3754 cell->set_level_subdomain_id(mark);
3771 (void)total_local_cells;
3775 Assert(
static_cast<unsigned int>(
3776 parallel_forest->local_num_quadrants) == total_local_cells,
3781 Assert(
static_cast<unsigned int>(
3782 parallel_forest->local_num_quadrants) <= total_local_cells,
3787 unsigned int n_owned = 0;
3788 for (
const auto &cell : this->active_cell_iterators())
3790 if (cell->subdomain_id() == this->my_subdomain)
3794 Assert(
static_cast<unsigned int>(
3795 parallel_forest->local_num_quadrants) == n_owned,
3799 this->smooth_grid = save_smooth;
3805 update_quadrant_cell_relations();
3810 template <
int dim,
int spacedim>
3816 for (
const auto &cell : this->active_cell_iterators())
3817 if (cell->is_locally_owned() && cell->refine_flag_set())
3818 Assert(cell->refine_flag_set() ==
3821 "This class does not support anisotropic refinement"));
3826 if (this->n_levels() ==
3830 cell = this->begin_active(
3838 !(cell->refine_flag_set()),
3840 "Fatal Error: maximum refinement level of p4est reached."));
3844 this->prepare_coarsening_and_refinement();
3847 this->signals.pre_distributed_refinement();
3852 for (
const auto &cell : this->active_cell_iterators())
3853 if (cell->is_ghost() || cell->is_artificial())
3855 cell->clear_refine_flag();
3856 cell->clear_coarsen_flag();
3862 RefineAndCoarsenList<dim, spacedim> refine_and_coarsen_list(
3863 *
this, p4est_tree_to_coarse_cell_permutation, this->my_subdomain);
3870 parallel_forest->user_pointer = &refine_and_coarsen_list;
3872 if (parallel_ghost !=
nullptr)
3876 parallel_ghost =
nullptr;
3881 &RefineAndCoarsenList<dim, spacedim>::refine_callback,
3886 &RefineAndCoarsenList<dim, spacedim>::coarsen_callback,
3893 parallel_forest->user_pointer =
this;
3899 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
3900 P4EST_CONNECT_FULL) :
3901 typename ::internal::p4est::types<dim>::balance_type(
3902 P8EST_CONNECT_FULL)),
3907 update_quadrant_cell_relations();
3912 std::vector<typename ::internal::p4est::types<dim>::gloidx>
3913 previous_global_first_quadrant;
3916 if (cell_attached_data.n_attached_data_sets > 0)
3918 data_transfer.pack_data(local_quadrant_cell_relations,
3919 cell_attached_data.pack_callbacks_fixed,
3920 cell_attached_data.pack_callbacks_variable);
3924 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
3925 std::memcpy(previous_global_first_quadrant.data(),
3926 parallel_forest->global_first_quadrant,
3928 typename ::internal::p4est::types<dim>::gloidx) *
3929 (parallel_forest->mpisize + 1));
3932 if (!(settings & no_automatic_repartitioning))
3936 if (this->signals.cell_weight.num_slots() == 0)
3944 const std::vector<unsigned int> cell_weights = get_cell_weights();
3946 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
3951 parallel_forest->user_pointer = &partition_weights;
3957 &PartitionWeights<dim, spacedim>::cell_weight);
3961 parallel_forest, 0,
nullptr,
nullptr);
3963 parallel_forest->user_pointer =
this;
3970 for (
const auto &cell : this->active_cell_iterators())
3972 cell->clear_refine_flag();
3973 cell->clear_coarsen_flag();
3978 copy_local_forest_to_triangulation();
3989 if (cell_attached_data.n_attached_data_sets > 0)
3992 data_transfer.execute_transfer(parallel_forest,
3993 previous_global_first_quadrant.data());
3996 data_transfer.unpack_cell_status(local_quadrant_cell_relations);
4017 for (
unsigned int lvl = 0; lvl < this->n_global_levels(); ++lvl)
4019 std::vector<bool> active_verts =
4020 this->mark_locally_active_vertices_on_level(lvl);
4022 const unsigned int maybe_coarser_lvl =
4023 (lvl > 0) ? (lvl - 1) : lvl;
4025 cell = this->
begin(maybe_coarser_lvl),
4026 endc = this->
end(lvl);
4027 for (; cell != endc; ++cell)
4028 if (cell->level() ==
static_cast<int>(lvl) || cell->is_active())
4030 const bool is_level_artificial =
4031 (cell->level_subdomain_id() ==
4033 bool need_to_know =
false;
4034 for (
const unsigned int vertex :
4036 if (active_verts[cell->vertex_index(vertex)])
4038 need_to_know =
true;
4043 !need_to_know || !is_level_artificial,
4045 "Internal error: the owner of cell" +
4046 cell->id().to_string() +
4047 " is unknown even though it is needed for geometric multigrid."));
4053 this->update_periodic_face_map();
4054 this->update_number_cache();
4057 this->signals.post_distributed_refinement();
4062 template <
int dim,
int spacedim>
4067 for (
const auto &cell : this->active_cell_iterators())
4068 if (cell->is_locally_owned())
4070 !cell->refine_flag_set() && !cell->coarsen_flag_set(),
4072 "Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition()."));
4076 this->signals.pre_distributed_repartition();
4080 std::vector<typename ::internal::p4est::types<dim>::gloidx>
4081 previous_global_first_quadrant;
4084 if (cell_attached_data.n_attached_data_sets > 0)
4086 data_transfer.pack_data(local_quadrant_cell_relations,
4087 cell_attached_data.pack_callbacks_fixed,
4088 cell_attached_data.pack_callbacks_variable);
4092 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
4093 std::memcpy(previous_global_first_quadrant.data(),
4094 parallel_forest->global_first_quadrant,
4096 typename ::internal::p4est::types<dim>::gloidx) *
4097 (parallel_forest->mpisize + 1));
4100 if (this->signals.cell_weight.num_slots() == 0)
4112 const std::vector<unsigned int> cell_weights = get_cell_weights();
4114 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
4119 parallel_forest->user_pointer = &partition_weights;
4125 &PartitionWeights<dim, spacedim>::cell_weight);
4128 parallel_forest->user_pointer =
this;
4133 copy_local_forest_to_triangulation();
4144 if (cell_attached_data.n_attached_data_sets > 0)
4147 data_transfer.execute_transfer(parallel_forest,
4148 previous_global_first_quadrant.data());
4151 this->update_periodic_face_map();
4154 this->update_number_cache();
4157 this->signals.post_distributed_repartition();
4162 template <
int dim,
int spacedim>
4165 const std::vector<bool> &vertex_locally_moved)
4167 Assert(vertex_locally_moved.size() == this->n_vertices(),
4169 this->n_vertices()));
4172 const std::vector<bool> locally_owned_vertices =
4174 for (
unsigned int i = 0; i < locally_owned_vertices.size(); ++i)
4175 Assert((vertex_locally_moved[i] ==
false) ||
4176 (locally_owned_vertices[i] ==
true),
4177 ExcMessage(
"The vertex_locally_moved argument must not "
4178 "contain vertices that are not locally owned"));
4188 const std::map<unsigned int, std::set<::types::subdomain_id>>
4196 CommunicateLocallyMovedVertices::CellInfo<dim, spacedim>>;
4197 cellmap_t needs_to_get_cells;
4201 cell != this->
end(0);
4204 typename ::internal::p4est::types<dim>::quadrant
4206 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4208 CommunicateLocallyMovedVertices::fill_vertices_recursively<dim,
4211 this->get_coarse_cell_to_p4est_tree_permutation()[cell->index()],
4215 vertex_locally_moved,
4216 needs_to_get_cells);
4224 mutex, this->get_communicator());
4229 std::vector<std::vector<char>> sendbuffers(needs_to_get_cells.size());
4230 std::vector<std::vector<char>>::iterator buffer = sendbuffers.begin();
4231 std::vector<MPI_Request> requests(needs_to_get_cells.size());
4232 std::vector<unsigned int> destinations;
4234 unsigned int idx = 0;
4236 for (
typename cellmap_t::iterator it = needs_to_get_cells.begin();
4237 it != needs_to_get_cells.end();
4238 ++it, ++buffer, ++idx)
4240 const unsigned int num_cells = it->second.tree_index.size();
4242 destinations.push_back(it->first);
4254 it->second.pack_data(*buffer);
4255 const int ierr = MPI_Isend(buffer->data(),
4260 this->get_communicator(),
4265 Assert(destinations.size() == needs_to_get_cells.size(),
4270 const unsigned int n_senders =
4272 this->get_communicator(), destinations);
4275 std::vector<char> receive;
4276 CommunicateLocallyMovedVertices::CellInfo<dim, spacedim> cellinfo;
4277 for (
unsigned int i = 0; i < n_senders; ++i)
4280 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4282 this->get_communicator(),
4287 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
4289 receive.resize(len);
4291 char *ptr = receive.data();
4292 ierr = MPI_Recv(ptr,
4297 this->get_communicator(),
4301 cellinfo.unpack_data(receive);
4302 const unsigned int cells = cellinfo.tree_index.size();
4303 for (
unsigned int c = 0; c < cells; ++c)
4305 typename ::parallel::distributed::
4306 Triangulation<dim, spacedim>::cell_iterator cell(
4309 this->get_p4est_tree_to_coarse_cell_permutation()
4310 [cellinfo.tree_index[c]]);
4312 typename ::internal::p4est::types<dim>::quadrant
4314 ::internal::p4est::init_coarse_quadrant<dim>(
4317 CommunicateLocallyMovedVertices::set_vertices_recursively<
4322 cellinfo.quadrants[c],
4323 cellinfo.first_vertices[c],
4324 cellinfo.first_vertex_indices[c]);
4330 if (requests.size() > 0)
4333 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
4339 this->get_communicator()) ==
4346 template <
int dim,
int spacedim>
4349 const std::function<std::vector<char>(
const cell_iterator &,
4351 const bool returns_variable_size_data)
4357 if (returns_variable_size_data)
4359 handle = 2 * cell_attached_data.pack_callbacks_variable.size();
4360 cell_attached_data.pack_callbacks_variable.push_back(pack_callback);
4364 handle = 2 * cell_attached_data.pack_callbacks_fixed.size() + 1;
4365 cell_attached_data.pack_callbacks_fixed.push_back(pack_callback);
4369 ++cell_attached_data.n_attached_data_sets;
4376 template <
int dim,
int spacedim>
4379 const unsigned int handle,
4380 const std::function<
4383 const boost::iterator_range<std::vector<char>::const_iterator> &)>
4386 Assert(cell_attached_data.n_attached_data_sets > 0,
4387 ExcMessage(
"The notify_ready_to_unpack() has already been called "
4388 "once for each registered callback."));
4392 Assert(local_quadrant_cell_relations.size() ==
4393 static_cast<unsigned int>(parallel_forest->local_num_quadrants),
4400 const unsigned int callback_index = handle / 2;
4401 if (handle % 2 == 0)
4404 cell_attached_data.pack_callbacks_variable.size(),
4407 Assert(cell_attached_data.pack_callbacks_variable[callback_index] !=
4410 cell_attached_data.pack_callbacks_variable[callback_index] =
nullptr;
4415 cell_attached_data.pack_callbacks_fixed.size(),
4418 Assert(cell_attached_data.pack_callbacks_fixed[callback_index] !=
4421 cell_attached_data.pack_callbacks_fixed[callback_index] =
nullptr;
4426 data_transfer.unpack_data(local_quadrant_cell_relations,
4431 --cell_attached_data.n_attached_data_sets;
4432 if (cell_attached_data.n_attached_deserialize > 0)
4433 --cell_attached_data.n_attached_deserialize;
4441 if (cell_attached_data.n_attached_data_sets == 0 &&
4442 cell_attached_data.n_attached_deserialize == 0)
4445 cell_attached_data.pack_callbacks_fixed.clear();
4446 cell_attached_data.pack_callbacks_variable.clear();
4447 data_transfer.clear();
4450 for (
auto &quad_cell_rel : local_quadrant_cell_relations)
4451 std::get<1>(quad_cell_rel) =
4458 template <
int dim,
int spacedim>
4459 const std::vector<types::global_dof_index> &
4463 return p4est_tree_to_coarse_cell_permutation;
4468 template <
int dim,
int spacedim>
4469 const std::vector<types::global_dof_index> &
4473 return coarse_cell_to_p4est_tree_permutation;
4478 template <
int dim,
int spacedim>
4481 const int level)
const
4485 std::vector<bool> marked_vertices(this->n_vertices(),
false);
4487 for (; cell != endc; ++cell)
4488 if (cell->level_subdomain_id() == this->locally_owned_subdomain())
4490 marked_vertices[cell->vertex_index(v)] =
true;
4497 typename std::map<std::pair<cell_iterator, unsigned int>,
4498 std::pair<std::pair<cell_iterator, unsigned int>,
4499 std::bitset<3>>>::const_iterator it;
4511 for (
unsigned int repetition = 0; repetition < dim; ++repetition)
4512 for (it = this->get_periodic_face_map().
begin();
4513 it != this->get_periodic_face_map().end();
4517 const unsigned int face_no_1 = it->first.second;
4519 const unsigned int face_no_2 = it->second.first.second;
4520 const std::bitset<3> &face_orientation = it->second.second;
4522 if (cell_1->level() ==
level && cell_2->level() ==
level)
4524 for (
unsigned int v = 0;
4530 const unsigned int vface0 =
4533 face_orientation[0],
4534 face_orientation[1],
4535 face_orientation[2]);
4536 if (marked_vertices[cell_1->face(face_no_1)->vertex_index(
4538 marked_vertices[cell_2->face(face_no_2)->vertex_index(
4540 marked_vertices[cell_1->face(face_no_1)->vertex_index(
4542 marked_vertices[cell_2->face(face_no_2)->vertex_index(
4548 return marked_vertices;
4553 template <
int dim,
int spacedim>
4563 template <
int dim,
int spacedim>
4566 const unsigned int coarse_cell_index)
const
4568 return coarse_cell_to_p4est_tree_permutation[coarse_cell_index];
4573 template <
int dim,
int spacedim>
4577 &periodicity_vector)
4579 Assert(triangulation_has_content ==
true,
4581 Assert(this->n_levels() == 1,
4582 ExcMessage(
"The triangulation is refined!"));
4589 for (
const auto &face_pair : periodicity_vector)
4593 const unsigned int face_left = face_pair.face_idx[0];
4594 const unsigned int face_right = face_pair.face_idx[1];
4597 const unsigned int tree_left =
4598 coarse_cell_to_p4est_tree_permutation[first_cell->index()];
4599 const unsigned int tree_right =
4600 coarse_cell_to_p4est_tree_permutation[second_cell->index()];
4609 unsigned int p4est_orientation = 0;
4611 p4est_orientation = face_pair.orientation[1];
4614 const unsigned int face_idx_list[] = {face_left, face_right};
4615 const cell_iterator cell_list[] = {first_cell, second_cell};
4616 unsigned int lower_idx, higher_idx;
4617 if (face_left <= face_right)
4630 unsigned int first_p4est_idx_on_cell =
4631 p8est_face_corners[face_idx_list[lower_idx]][0];
4632 unsigned int first_dealii_idx_on_face =
4634 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face;
4637 const unsigned int first_dealii_idx_on_cell =
4639 face_idx_list[lower_idx],
4641 cell_list[lower_idx]->face_orientation(
4642 face_idx_list[lower_idx]),
4643 cell_list[lower_idx]->face_flip(face_idx_list[lower_idx]),
4644 cell_list[lower_idx]->face_rotation(
4645 face_idx_list[lower_idx]));
4646 if (first_p4est_idx_on_cell == first_dealii_idx_on_cell)
4648 first_dealii_idx_on_face = i;
4655 constexpr
unsigned int left_to_right[8][4] = {{0, 2, 1, 3},
4663 constexpr
unsigned int right_to_left[8][4] = {{0, 2, 1, 3},
4671 const unsigned int second_dealii_idx_on_face =
4672 lower_idx == 0 ? left_to_right[face_pair.orientation.to_ulong()]
4673 [first_dealii_idx_on_face] :
4674 right_to_left[face_pair.orientation.to_ulong()]
4675 [first_dealii_idx_on_face];
4676 const unsigned int second_dealii_idx_on_cell =
4678 face_idx_list[higher_idx],
4679 second_dealii_idx_on_face,
4680 cell_list[higher_idx]->face_orientation(
4681 face_idx_list[higher_idx]),
4682 cell_list[higher_idx]->face_flip(face_idx_list[higher_idx]),
4683 cell_list[higher_idx]->face_rotation(
4684 face_idx_list[higher_idx]));
4686 const unsigned int second_p4est_idx_on_face =
4687 p8est_corner_face_corners[second_dealii_idx_on_cell]
4688 [face_idx_list[higher_idx]];
4689 p4est_orientation = second_p4est_idx_on_face;
4709 this->mpi_communicator,
4720 copy_local_forest_to_triangulation();
4730 this->update_number_cache();
4735 template <
int dim,
int spacedim>
4746 cell_attached_data.n_attached_data_sets) +
4753 coarse_cell_to_p4est_tree_permutation) +
4755 p4est_tree_to_coarse_cell_permutation) +
4756 memory_consumption_p4est();
4763 template <
int dim,
int spacedim>
4767 return ::internal::p4est::functions<dim>::forest_memory_used(
4775 template <
int dim,
int spacedim>
4778 const ::Triangulation<dim, spacedim> &other_tria)
4786 const typename ::Triangulation<dim, spacedim>::DistortedCellList
4797 triangulation_has_content =
true;
4799 Assert(other_tria.n_levels() == 1,
4801 "Parallel distributed triangulations can only be copied, "
4802 "if they are not refined!"));
4804 if (const ::parallel::distributed::Triangulation<dim, spacedim>
4806 dynamic_cast<const ::parallel::distributed::
4807 Triangulation<dim, spacedim> *
>(&other_tria))
4809 coarse_cell_to_p4est_tree_permutation =
4810 other_tria_x->coarse_cell_to_p4est_tree_permutation;
4811 p4est_tree_to_coarse_cell_permutation =
4812 other_tria_x->p4est_tree_to_coarse_cell_permutation;
4813 cell_attached_data = other_tria_x->cell_attached_data;
4814 data_transfer = other_tria_x->data_transfer;
4816 settings = other_tria_x->settings;
4820 setup_coarse_cell_to_p4est_tree_permutation();
4823 copy_new_triangulation_to_p4est(std::integral_constant<int, dim>());
4827 copy_local_forest_to_triangulation();
4836 this->update_periodic_face_map();
4837 this->update_number_cache();
4842 template <
int dim,
int spacedim>
4847 local_quadrant_cell_relations.resize(
4848 parallel_forest->local_num_quadrants);
4849 local_quadrant_cell_relations.shrink_to_fit();
4854 cell != this->
end(0);
4858 if (tree_exists_locally<dim, spacedim>(
4860 coarse_cell_to_p4est_tree_permutation[cell->index()]) ==
false)
4864 typename ::internal::p4est::types<dim>::quadrant
4866 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4869 typename ::internal::p4est::types<dim>::tree *tree =
4870 init_tree(cell->index());
4872 update_quadrant_cell_relations_recursively<dim, spacedim>(
4873 local_quadrant_cell_relations, *tree, cell, p4est_coarse_cell);
4879 template <
int dim,
int spacedim>
4880 std::vector<unsigned int>
4885 Assert(local_quadrant_cell_relations.size() ==
4886 static_cast<unsigned int>(parallel_forest->local_num_quadrants),
4894 std::vector<unsigned int> weights;
4903 for (
const auto &quad_cell_rel : local_quadrant_cell_relations)
4905 const auto &cell_status = std::get<1>(quad_cell_rel);
4906 const auto &cell_it = std::get<2>(quad_cell_rel);
4908 switch (cell_status)
4911 spacedim>::CELL_PERSIST:
4912 weights.push_back(1000);
4913 weights.back() += this->signals.cell_weight(
4916 spacedim>::CELL_PERSIST);
4920 spacedim>::CELL_REFINE:
4922 spacedim>::CELL_INVALID:
4925 unsigned int parent_weight = 1000;
4926 parent_weight += this->signals.cell_weight(
4932 weights.push_back(parent_weight);
4937 spacedim>::CELL_COARSEN:
4938 weights.push_back(1000);
4939 weights.back() += this->signals.cell_weight(
4942 spacedim>::CELL_COARSEN);
4956 template <
int spacedim>
4959 const typename ::Triangulation<1, spacedim>::MeshSmoothing
4971 template <
int spacedim>
4979 template <
int spacedim>
4982 const std::vector<bool> & )
4989 template <
int spacedim>
4992 const std::function<std::vector<char>(
4993 const typename ::Triangulation<1, spacedim>::cell_iterator &,
4994 const typename ::Triangulation<1, spacedim>::CellStatus)>
5004 template <
int spacedim>
5007 const unsigned int ,
5008 const std::function<
5009 void(
const typename ::Triangulation<1, spacedim>::cell_iterator &,
5010 const typename ::Triangulation<1, spacedim>::CellStatus,
5011 const boost::iterator_range<std::vector<char>::const_iterator> &)>
5019 template <
int spacedim>
5020 const std::vector<types::global_dof_index> &
5024 static std::vector<types::global_dof_index> a;
5030 template <
int spacedim>
5031 std::map<unsigned int, std::set<::types::subdomain_id>>
5033 const unsigned int )
const
5037 return std::map<unsigned int, std::set<::types::subdomain_id>>();
5042 template <
int spacedim>
5045 const unsigned int)
const
5048 return std::vector<bool>();
5053 template <
int spacedim>
5064 template <
int spacedim>
5067 const unsigned int)
const
5074 template <
int spacedim>
5083 template <
int spacedim>
5092 template <
int spacedim>
5104 #endif // DEAL_II_WITH_P4EST
5109 #include "tria.inst"