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++;
936 template <
int dim,
int spacedim>
937 using cell_relation_t =
typename std::pair<
938 typename ::Triangulation<dim, spacedim>::cell_iterator,
939 typename ::Triangulation<dim, spacedim>::CellStatus>;
950 template <
int dim,
int spacedim>
952 add_single_cell_relation(
953 std::vector<cell_relation_t<dim, spacedim>> & cell_rel,
954 const typename ::internal::p4est::types<dim>::tree & tree,
955 const unsigned int idx,
959 const unsigned int local_quadrant_index = tree.quadrants_offset + idx;
965 cell_rel[local_quadrant_index] = std::make_pair(dealii_cell, status);
979 template <
int dim,
int spacedim>
981 update_cell_relations_recursively(
982 std::vector<cell_relation_t<dim, spacedim>> & cell_rel,
983 const typename ::internal::p4est::types<dim>::tree & tree,
985 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell)
988 const int idx = sc_array_bsearch(
989 const_cast<sc_array_t *
>(&tree.quadrants),
994 const_cast<typename ::internal::p4est::types<dim>::tree *
>(
996 &p4est_cell) ==
false))
1001 const bool p4est_has_children = (idx == -1);
1002 if (p4est_has_children && dealii_cell->has_children())
1005 typename ::internal::p4est::types<dim>::quadrant
1008 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1013 P4EST_QUADRANT_INIT(&p4est_child[c]);
1016 P8EST_QUADRANT_INIT(&p4est_child[c]);
1023 &p4est_cell, p4est_child);
1025 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1028 update_cell_relations_recursively<dim, spacedim>(
1029 cell_rel, tree, dealii_cell->child(c), p4est_child[c]);
1032 else if (!p4est_has_children && !dealii_cell->has_children())
1036 add_single_cell_relation<dim, spacedim>(
1043 else if (p4est_has_children)
1051 typename ::internal::p4est::types<dim>::quadrant
1053 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
1058 P4EST_QUADRANT_INIT(&p4est_child[c]);
1061 P8EST_QUADRANT_INIT(&p4est_child[c]);
1068 &p4est_cell, p4est_child);
1075 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_cell;
1078 child_idx = sc_array_bsearch(
1079 const_cast<sc_array_t *
>(&tree.quadrants),
1086 add_single_cell_relation<dim, spacedim>(
1087 cell_rel, tree, child_idx, dealii_cell, cell_status);
1095 add_single_cell_relation<dim, spacedim>(
1109 namespace distributed
1112 template <
int dim,
int spacedim>
1115 const typename ::Triangulation<dim, spacedim>::MeshSmoothing
1127 Triangulation<dim, spacedim>::limit_level_difference_at_vertices) :
1130 , settings(settings)
1131 , triangulation_has_content(false)
1132 , connectivity(nullptr)
1133 , parallel_forest(nullptr)
1140 template <
int dim,
int spacedim>
1160 template <
int dim,
int spacedim>
1173 const typename ::Triangulation<dim, spacedim>::DistortedCellList
1182 this->all_reference_cells_are_hyper_cube(),
1184 "The class parallel::distributed::Triangulation only supports meshes "
1185 "consisting only of hypercube-like cells."));
1190 triangulation_has_content =
true;
1192 setup_coarse_cell_to_p4est_tree_permutation();
1194 copy_new_triangulation_to_p4est(std::integral_constant<int, dim>());
1198 copy_local_forest_to_triangulation();
1207 this->update_periodic_face_map();
1208 this->update_number_cache();
1213 template <
int dim,
int spacedim>
1219 (void)construction_data;
1226 template <
int dim,
int spacedim>
1230 triangulation_has_content =
false;
1232 if (parallel_ghost !=
nullptr)
1236 parallel_ghost =
nullptr;
1239 if (parallel_forest !=
nullptr)
1242 parallel_forest =
nullptr;
1245 if (connectivity !=
nullptr)
1249 connectivity =
nullptr;
1252 coarse_cell_to_p4est_tree_permutation.resize(0);
1253 p4est_tree_to_coarse_cell_permutation.resize(0);
1257 this->update_number_cache();
1262 template <
int dim,
int spacedim>
1272 template <
int dim,
int spacedim>
1275 const typename ::internal::p4est::types<dim>::forest
1277 const typename ::internal::p4est::types<dim>::gloidx
1278 *previous_global_first_quadrant)
1280 Assert(this->data_transfer.sizes_fixed_cumulative.size() > 0,
1284 this->data_transfer.dest_data_fixed.resize(
1285 parallel_forest->local_num_quadrants *
1286 this->data_transfer.sizes_fixed_cumulative.back());
1289 typename ::internal::p4est::types<dim>::transfer_context
1293 parallel_forest->global_first_quadrant,
1294 previous_global_first_quadrant,
1295 parallel_forest->mpicomm,
1297 this->data_transfer.dest_data_fixed.data(),
1298 this->data_transfer.src_data_fixed.data(),
1299 this->data_transfer.sizes_fixed_cumulative.back());
1301 if (this->data_transfer.variable_size_data_stored)
1304 this->data_transfer.dest_sizes_variable.resize(
1305 parallel_forest->local_num_quadrants);
1310 parallel_forest->global_first_quadrant,
1311 previous_global_first_quadrant,
1312 parallel_forest->mpicomm,
1314 this->data_transfer.dest_sizes_variable.data(),
1315 this->data_transfer.src_sizes_variable.data(),
1316 sizeof(
unsigned int));
1322 this->data_transfer.src_data_fixed.clear();
1323 this->data_transfer.src_data_fixed.shrink_to_fit();
1325 if (this->data_transfer.variable_size_data_stored)
1328 this->data_transfer.dest_data_variable.resize(
1329 std::accumulate(this->data_transfer.dest_sizes_variable.begin(),
1330 this->data_transfer.dest_sizes_variable.end(),
1333# if DEAL_II_P4EST_VERSION_GTE(2, 0, 65, 0)
1340 if (this->data_transfer.src_sizes_variable.size() == 0)
1341 this->data_transfer.src_sizes_variable.resize(1);
1342 if (this->data_transfer.dest_sizes_variable.size() == 0)
1343 this->data_transfer.dest_sizes_variable.resize(1);
1348 parallel_forest->global_first_quadrant,
1349 previous_global_first_quadrant,
1350 parallel_forest->mpicomm,
1352 this->data_transfer.dest_data_variable.data(),
1353 this->data_transfer.dest_sizes_variable.data(),
1354 this->data_transfer.src_data_variable.data(),
1355 this->data_transfer.src_sizes_variable.data());
1358 this->data_transfer.src_sizes_variable.clear();
1359 this->data_transfer.src_sizes_variable.shrink_to_fit();
1360 this->data_transfer.src_data_variable.clear();
1361 this->data_transfer.src_data_variable.shrink_to_fit();
1366 template <
int dim,
int spacedim>
1370 if (this->n_global_levels() <= 1)
1379 const bool have_coarser_cell =
1380 std::any_of(this->begin_active(this->n_global_levels() - 2),
1381 this->end_active(this->n_global_levels() - 2),
1388 this->mpi_communicator);
1393 template <
int dim,
int spacedim>
1400 coarse_cell_to_p4est_tree_permutation.resize(this->
n_cells(0));
1402 cell_connectivity, coarse_cell_to_p4est_tree_permutation);
1404 p4est_tree_to_coarse_cell_permutation =
1410 template <
int dim,
int spacedim>
1413 const std::string &file_basename)
const
1415 Assert(parallel_forest !=
nullptr,
1416 ExcMessage(
"Can't produce output when no forest is created yet."));
1418 parallel_forest,
nullptr, file_basename.c_str());
1423 template <
int dim,
int spacedim>
1428 this->cell_attached_data.n_attached_deserialize == 0,
1430 "Not all SolutionTransfer objects have been deserialized after the last call to load()."));
1432 ExcMessage(
"Can not save() an empty Triangulation."));
1438 this->signals.pre_distributed_save();
1440 if (this->my_subdomain == 0)
1442 std::string fname = std::string(filename) +
".info";
1443 std::ofstream f(fname.c_str());
1444 f <<
"version nproc n_attached_fixed_size_objs n_attached_variable_size_objs n_coarse_cells"
1448 << this->cell_attached_data.pack_callbacks_fixed.size() <<
" "
1449 << this->cell_attached_data.pack_callbacks_variable.size() <<
" "
1450 << this->
n_cells(0) << std::endl;
1454 for (
const auto &cell_rel : this->local_cell_relations)
1464 this->save_attached_data(parallel_forest->global_first_quadrant[myrank],
1465 parallel_forest->global_num_quadrants,
1473 this->signals.post_distributed_save();
1478 template <
int dim,
int spacedim>
1481 const bool autopartition)
1486 "load() only works if the Triangulation already contains a coarse mesh!"));
1488 this->n_levels() == 1,
1490 "Triangulation may only contain coarse cells when calling load()."));
1496 this->signals.pre_distributed_load();
1498 if (parallel_ghost !=
nullptr)
1502 parallel_ghost =
nullptr;
1505 parallel_forest =
nullptr;
1508 connectivity =
nullptr;
1510 unsigned int version, numcpus, attached_count_fixed,
1511 attached_count_variable, n_coarse_cells;
1513 std::string fname = std::string(filename) +
".info";
1514 std::ifstream f(fname.c_str());
1516 std::string firstline;
1517 getline(f, firstline);
1518 f >> version >> numcpus >> attached_count_fixed >>
1519 attached_count_variable >> n_coarse_cells;
1523 ExcMessage(
"Incompatible version found in .info file."));
1525 ExcMessage(
"Number of coarse cells differ!"));
1529 this->cell_attached_data.n_attached_data_sets = 0;
1530 this->cell_attached_data.n_attached_deserialize =
1531 attached_count_fixed + attached_count_variable;
1535 this->mpi_communicator,
1550 if (this->signals.cell_weight.num_slots() == 0)
1562 const std::vector<unsigned int> cell_weights = get_cell_weights();
1564 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
1569 parallel_forest->user_pointer = &partition_weights;
1575 &PartitionWeights<dim, spacedim>::cell_weight);
1578 parallel_forest->user_pointer =
this;
1584 copy_local_forest_to_triangulation();
1596 this->load_attached_data(parallel_forest->global_first_quadrant[myrank],
1597 parallel_forest->global_num_quadrants,
1598 parallel_forest->local_num_quadrants,
1600 attached_count_fixed,
1601 attached_count_variable);
1604 this->signals.post_distributed_load();
1606 this->update_periodic_face_map();
1607 this->update_number_cache();
1612 template <
int dim,
int spacedim>
1615 const typename ::internal::p4est::types<dim>::forest *forest)
1619 "load() only works if the Triangulation already contains "
1623 "Coarse mesh of the Triangulation does not match the one "
1624 "of the provided forest!"));
1627 if (parallel_ghost !=
nullptr)
1631 parallel_ghost =
nullptr;
1634 parallel_forest =
nullptr;
1640 typename ::internal::p4est::types<dim>::forest *temp =
1641 const_cast<typename ::internal::p4est::types<dim>::forest *
>(
1645 parallel_forest->connectivity = connectivity;
1646 parallel_forest->user_pointer =
this;
1650 copy_local_forest_to_triangulation();
1659 this->update_periodic_face_map();
1660 this->update_number_cache();
1665 template <
int dim,
int spacedim>
1669 Assert(parallel_forest !=
nullptr,
1671 "Can't produce a check sum when no forest is created yet."));
1672 return ::internal::p4est::functions<dim>::checksum(parallel_forest);
1677 template <
int dim,
int spacedim>
1678 const typename ::internal::p4est::types<dim>::forest *
1681 Assert(parallel_forest !=
nullptr,
1682 ExcMessage(
"The forest has not been allocated yet."));
1683 return parallel_forest;
1688 template <
int dim,
int spacedim>
1689 typename ::internal::p4est::types<dim>::tree *
1691 const int dealii_coarse_cell_index)
const
1693 const unsigned int tree_index =
1694 coarse_cell_to_p4est_tree_permutation[dealii_coarse_cell_index];
1695 typename ::internal::p4est::types<dim>::tree *tree =
1696 static_cast<typename ::internal::p4est::types<dim>::tree *
>(
1697 sc_array_index(parallel_forest->trees, tree_index));
1711 std::integral_constant<int, 2>)
1713 const unsigned int dim = 2, spacedim = 2;
1721 std::vector<unsigned int> vertex_touch_count;
1723 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
1726 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
1727 const ::internal::p4est::types<2>::locidx num_vtt =
1728 std::accumulate(vertex_touch_count.begin(),
1729 vertex_touch_count.end(),
1735 const bool set_vertex_info
1744 (set_vertex_info ==
true ? this->n_vertices() : 0),
1749 set_vertex_and_cell_info(*
this,
1752 coarse_cell_to_p4est_tree_permutation,
1756 Assert(p4est_connectivity_is_valid(connectivity) == 1,
1761 this->mpi_communicator,
1778 std::integral_constant<int, 2>)
1780 const unsigned int dim = 2, spacedim = 3;
1788 std::vector<unsigned int> vertex_touch_count;
1790 std::list<std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
1793 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
1794 const ::internal::p4est::types<2>::locidx num_vtt =
1795 std::accumulate(vertex_touch_count.begin(),
1796 vertex_touch_count.end(),
1802 const bool set_vertex_info
1811 (set_vertex_info ==
true ? this->n_vertices() : 0),
1816 set_vertex_and_cell_info(*
this,
1819 coarse_cell_to_p4est_tree_permutation,
1823 Assert(p4est_connectivity_is_valid(connectivity) == 1,
1828 this->mpi_communicator,
1843 std::integral_constant<int, 3>)
1845 const int dim = 3, spacedim = 3;
1853 std::vector<unsigned int> vertex_touch_count;
1854 std::vector<std::list<
1855 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
1857 get_vertex_to_cell_mappings(*
this, vertex_touch_count, vertex_to_cell);
1858 const ::internal::p4est::types<2>::locidx num_vtt =
1859 std::accumulate(vertex_touch_count.begin(),
1860 vertex_touch_count.end(),
1863 std::vector<unsigned int> edge_touch_count;
1864 std::vector<std::list<
1865 std::pair<Triangulation<3>::active_cell_iterator,
unsigned int>>>
1867 get_edge_to_cell_mappings(*
this, edge_touch_count, edge_to_cell);
1868 const ::internal::p4est::types<2>::locidx num_ett =
1869 std::accumulate(edge_touch_count.begin(), edge_touch_count.end(), 0u);
1872 const bool set_vertex_info
1881 (set_vertex_info ==
true ? this->n_vertices() : 0),
1883 this->n_active_lines(),
1888 set_vertex_and_cell_info(*
this,
1891 coarse_cell_to_p4est_tree_permutation,
1920 const unsigned int deal_to_p4est_line_index[12] = {
1921 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11};
1924 this->begin_active();
1925 cell != this->
end();
1928 const unsigned int index =
1929 coarse_cell_to_p4est_tree_permutation[cell->index()];
1930 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_cell; ++
e)
1932 deal_to_p4est_line_index[
e]] =
1933 cell->line(
e)->index();
1938 connectivity->ett_offset[0] = 0;
1939 std::partial_sum(edge_touch_count.begin(),
1940 edge_touch_count.end(),
1941 &connectivity->ett_offset[1]);
1943 Assert(connectivity->ett_offset[this->n_active_lines()] == num_ett,
1946 for (
unsigned int v = 0; v < this->n_active_lines(); ++v)
1948 Assert(edge_to_cell[v].size() == edge_touch_count[v],
1952 std::pair<Triangulation<dim, spacedim>::active_cell_iterator,
1953 unsigned int>>::const_iterator p =
1954 edge_to_cell[v].begin();
1955 for (
unsigned int c = 0; c < edge_touch_count[v]; ++c, ++p)
1957 connectivity->edge_to_tree[connectivity->ett_offset[v] + c] =
1958 coarse_cell_to_p4est_tree_permutation[p->first->index()];
1959 connectivity->edge_to_edge[connectivity->ett_offset[v] + c] =
1960 deal_to_p4est_line_index[p->second];
1964 Assert(p8est_connectivity_is_valid(connectivity) == 1,
1969 this->mpi_communicator,
1986 template <
int dim,
int spacedim>
1988 enforce_mesh_balance_over_periodic_boundaries(
1994 std::vector<bool> flags_before[2];
1998 std::vector<unsigned int> topological_vertex_numbering(
2000 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
2001 topological_vertex_numbering[i] = i;
2017 using cell_iterator =
2019 typename std::map<std::pair<cell_iterator, unsigned int>,
2020 std::pair<std::pair<cell_iterator, unsigned int>,
2021 std::bitset<3>>>::const_iterator it;
2026 const cell_iterator &cell_1 = it->first.first;
2027 const unsigned int face_no_1 = it->first.second;
2028 const cell_iterator &cell_2 = it->second.first.first;
2029 const unsigned int face_no_2 = it->second.first.second;
2030 const std::bitset<3> face_orientation = it->second.second;
2032 if (cell_1->level() == cell_2->level())
2034 for (
unsigned int v = 0;
2040 const unsigned int vface0 =
2043 face_orientation[0],
2044 face_orientation[1],
2045 face_orientation[2]);
2046 const unsigned int vi0 =
2047 topological_vertex_numbering[cell_1->face(face_no_1)
2048 ->vertex_index(vface0)];
2049 const unsigned int vi1 =
2050 topological_vertex_numbering[cell_2->face(face_no_2)
2052 const unsigned int min_index =
std::min(vi0, vi1);
2053 topological_vertex_numbering[cell_1->face(face_no_1)
2054 ->vertex_index(vface0)] =
2055 topological_vertex_numbering[cell_2->face(face_no_2)
2056 ->vertex_index(v)] =
2063 for (
unsigned int i = 0; i < topological_vertex_numbering.size(); ++i)
2065 const unsigned int j = topological_vertex_numbering[i];
2073 bool continue_iterating =
true;
2074 std::vector<int> vertex_level(tria.
n_vertices());
2075 while (continue_iterating)
2079 std::fill(vertex_level.begin(), vertex_level.end(), 0);
2083 for (; cell != endc; ++cell)
2085 if (cell->refine_flag_set())
2086 for (
const unsigned int vertex :
2088 vertex_level[topological_vertex_numbering
2089 [cell->vertex_index(vertex)]] =
2090 std::max(vertex_level[topological_vertex_numbering
2091 [cell->vertex_index(vertex)]],
2093 else if (!cell->coarsen_flag_set())
2094 for (
const unsigned int vertex :
2096 vertex_level[topological_vertex_numbering
2097 [cell->vertex_index(vertex)]] =
2098 std::max(vertex_level[topological_vertex_numbering
2099 [cell->vertex_index(vertex)]],
2110 for (
const unsigned int vertex :
2112 vertex_level[topological_vertex_numbering
2113 [cell->vertex_index(vertex)]] =
2114 std::max(vertex_level[topological_vertex_numbering
2115 [cell->vertex_index(vertex)]],
2120 continue_iterating =
false;
2131 for (cell = tria.
last_active(); cell != endc; --cell)
2132 if (cell->refine_flag_set() ==
false)
2134 for (
const unsigned int vertex :
2136 if (vertex_level[topological_vertex_numbering
2137 [cell->vertex_index(vertex)]] >=
2141 cell->clear_coarsen_flag();
2146 if (vertex_level[topological_vertex_numbering
2147 [cell->vertex_index(vertex)]] >
2150 cell->set_refine_flag();
2151 continue_iterating =
true;
2153 for (
const unsigned int v :
2155 vertex_level[topological_vertex_numbering
2156 [cell->vertex_index(v)]] =
2158 vertex_level[topological_vertex_numbering
2159 [cell->vertex_index(v)]],
2173 if (cell->is_active())
2176 const unsigned int n_children = cell->n_children();
2177 unsigned int flagged_children = 0;
2178 for (
unsigned int child = 0; child < n_children; ++child)
2179 if (cell->child(child)->is_active() &&
2180 cell->child(child)->coarsen_flag_set())
2185 if (flagged_children < n_children)
2186 for (
unsigned int child = 0; child < n_children; ++child)
2187 if (cell->child(child)->is_active())
2188 cell->child(child)->clear_coarsen_flag();
2191 std::vector<bool> flags_after[2];
2194 return ((flags_before[0] != flags_after[0]) ||
2195 (flags_before[1] != flags_after[1]));
2201 template <
int dim,
int spacedim>
2205 std::vector<bool> flags_before[2];
2206 this->save_coarsen_flags(flags_before[0]);
2207 this->save_refine_flags(flags_before[1]);
2209 bool mesh_changed =
false;
2210 unsigned int loop_counter = 0;
2215 this->update_periodic_face_map();
2217 mesh_changed = enforce_mesh_balance_over_periodic_boundaries(*
this);
2227 "parallel::distributed::Triangulation::prepare_coarsening_and_refinement() "
2228 "for periodic boundaries detected. Aborting."));
2230 while (mesh_changed);
2234 std::vector<bool> flags_after[2];
2235 this->save_coarsen_flags(flags_after[0]);
2236 this->save_refine_flags(flags_after[1]);
2237 return ((flags_before[0] != flags_after[0]) ||
2238 (flags_before[1] != flags_after[1]));
2243 template <
int dim,
int spacedim>
2267 spacedim>::limit_level_difference_at_vertices;
2271 bool mesh_changed =
false;
2279 if (settings & mesh_reconstruction_after_repartitioning)
2280 while (this->n_levels() > 1)
2287 for (
const auto &cell :
2288 this->active_cell_iterators_on_level(this->n_levels() - 1))
2290 cell->set_coarsen_flag();
2308 if (parallel_ghost !=
nullptr)
2312 parallel_ghost =
nullptr;
2316 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
2317 P4EST_CONNECT_CORNER) :
2318 typename ::internal::p4est::types<dim>::balance_type(
2319 P8EST_CONNECT_CORNER)));
2326 for (
const auto &cell : this->cell_iterators_on_level(0))
2331 for (
const auto &cell : this->cell_iterators_on_level(0))
2336 if (tree_exists_locally<dim, spacedim>(
2338 coarse_cell_to_p4est_tree_permutation[cell->index()]) ==
2341 delete_all_children<dim, spacedim>(cell);
2342 if (cell->is_active())
2351 typename ::internal::p4est::types<dim>::quadrant
2353 typename ::internal::p4est::types<dim>::tree *tree =
2354 init_tree(cell->index());
2356 ::internal::p4est::init_coarse_quadrant<dim>(
2359 match_tree_recursively<dim, spacedim>(*tree,
2363 this->my_subdomain);
2370 typename ::internal::p4est::types<dim>::quadrant *quadr;
2372 typename ::internal::p4est::types<dim>::topidx ghost_tree = 0;
2374 for (
unsigned int g_idx = 0;
2375 g_idx < parallel_ghost->ghosts.elem_count;
2378 while (g_idx >=
static_cast<unsigned int>(
2379 parallel_ghost->proc_offsets[ghost_owner + 1]))
2381 while (g_idx >=
static_cast<unsigned int>(
2382 parallel_ghost->tree_offsets[ghost_tree + 1]))
2385 quadr =
static_cast<
2386 typename ::internal::p4est::types<dim>::quadrant *
>(
2387 sc_array_index(¶llel_ghost->ghosts, g_idx));
2389 unsigned int coarse_cell_index =
2390 p4est_tree_to_coarse_cell_permutation[ghost_tree];
2392 match_quadrant<dim, spacedim>(
this,
2399 this->prepare_coarsening_and_refinement();
2403 std::any_of(this->begin_active(),
2406 return cell.refine_flag_set() ||
2407 cell.coarsen_flag_set();
2425 while (mesh_changed);
2429 unsigned int num_ghosts = 0;
2431 for (
const auto &cell : this->active_cell_iterators())
2433 if (cell->subdomain_id() != this->my_subdomain &&
2438 Assert(num_ghosts == parallel_ghost->ghosts.elem_count,
2454 for (
unsigned int lvl = this->n_levels(); lvl > 0;)
2457 for (
const auto &cell : this->cell_iterators_on_level(lvl))
2459 if ((cell->is_active() &&
2460 cell->subdomain_id() ==
2462 (cell->has_children() &&
2463 cell->child(0)->level_subdomain_id() ==
2465 cell->set_level_subdomain_id(
2466 this->locally_owned_subdomain());
2470 cell->set_level_subdomain_id(
2478 std::vector<std::vector<bool>> marked_vertices(this->n_levels());
2479 for (
unsigned int lvl = 0; lvl < this->n_levels(); ++lvl)
2480 marked_vertices[lvl] = mark_locally_active_vertices_on_level(lvl);
2482 for (
const auto &cell : this->cell_iterators_on_level(0))
2484 typename ::internal::p4est::types<dim>::quadrant
2486 const unsigned int tree_index =
2487 coarse_cell_to_p4est_tree_permutation[cell->index()];
2488 typename ::internal::p4est::types<dim>::tree *tree =
2489 init_tree(cell->index());
2491 ::internal::p4est::init_coarse_quadrant<dim>(
2494 determine_level_subdomain_id_recursively<dim, spacedim>(
2505 for (
unsigned int lvl = this->n_levels(); lvl > 0;)
2508 for (
const auto &cell : this->cell_iterators_on_level(lvl))
2510 if (cell->has_children())
2511 for (
unsigned int c = 0;
2512 c < GeometryInfo<dim>::max_children_per_cell;
2515 if (cell->child(c)->level_subdomain_id() ==
2521 cell->child(0)->level_subdomain_id();
2525 cell->set_level_subdomain_id(mark);
2542 (void)total_local_cells;
2546 Assert(
static_cast<unsigned int>(
2547 parallel_forest->local_num_quadrants) == total_local_cells,
2552 Assert(
static_cast<unsigned int>(
2553 parallel_forest->local_num_quadrants) <= total_local_cells,
2558 unsigned int n_owned = 0;
2559 for (
const auto &cell : this->active_cell_iterators())
2561 if (cell->subdomain_id() == this->my_subdomain)
2565 Assert(
static_cast<unsigned int>(
2566 parallel_forest->local_num_quadrants) == n_owned,
2570 this->smooth_grid = save_smooth;
2576 update_cell_relations();
2581 template <
int dim,
int spacedim>
2587 for (
const auto &cell : this->active_cell_iterators())
2588 if (cell->is_locally_owned() && cell->refine_flag_set())
2589 Assert(cell->refine_flag_set() ==
2592 "This class does not support anisotropic refinement"));
2597 if (this->n_levels() ==
2601 cell = this->begin_active(
2609 !(cell->refine_flag_set()),
2611 "Fatal Error: maximum refinement level of p4est reached."));
2615 this->prepare_coarsening_and_refinement();
2618 this->signals.pre_distributed_refinement();
2623 for (
const auto &cell : this->active_cell_iterators())
2624 if (cell->is_ghost() || cell->is_artificial())
2626 cell->clear_refine_flag();
2627 cell->clear_coarsen_flag();
2633 RefineAndCoarsenList<dim, spacedim> refine_and_coarsen_list(
2634 *
this, p4est_tree_to_coarse_cell_permutation, this->my_subdomain);
2641 parallel_forest->user_pointer = &refine_and_coarsen_list;
2643 if (parallel_ghost !=
nullptr)
2647 parallel_ghost =
nullptr;
2652 &RefineAndCoarsenList<dim, spacedim>::refine_callback,
2657 &RefineAndCoarsenList<dim, spacedim>::coarsen_callback,
2664 parallel_forest->user_pointer =
this;
2670 (dim == 2 ? typename ::internal::p4est::types<dim>::balance_type(
2671 P4EST_CONNECT_FULL) :
2672 typename ::internal::p4est::types<dim>::balance_type(
2673 P8EST_CONNECT_FULL)),
2678 update_cell_relations();
2682 this->signals.post_p4est_refinement();
2687 std::vector<typename ::internal::p4est::types<dim>::gloidx>
2688 previous_global_first_quadrant;
2690 if (this->cell_attached_data.n_attached_data_sets > 0)
2692 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
2693 std::memcpy(previous_global_first_quadrant.data(),
2694 parallel_forest->global_first_quadrant,
2696 typename ::internal::p4est::types<dim>::gloidx) *
2697 (parallel_forest->mpisize + 1));
2700 if (!(settings & no_automatic_repartitioning))
2704 if (this->signals.cell_weight.num_slots() == 0)
2712 const std::vector<unsigned int> cell_weights = get_cell_weights();
2714 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
2719 parallel_forest->user_pointer = &partition_weights;
2725 &PartitionWeights<dim, spacedim>::cell_weight);
2729 parallel_forest, 0,
nullptr,
nullptr);
2731 parallel_forest->user_pointer =
this;
2736 if (this->cell_attached_data.n_attached_data_sets > 0)
2738 this->data_transfer.pack_data(
2739 this->local_cell_relations,
2740 this->cell_attached_data.pack_callbacks_fixed,
2741 this->cell_attached_data.pack_callbacks_variable);
2747 for (
const auto &cell : this->active_cell_iterators())
2749 cell->clear_refine_flag();
2750 cell->clear_coarsen_flag();
2755 copy_local_forest_to_triangulation();
2765 if (this->cell_attached_data.n_attached_data_sets > 0)
2767 this->execute_transfer(parallel_forest,
2768 previous_global_first_quadrant.data());
2771 this->data_transfer.unpack_cell_status(this->local_cell_relations);
2792 for (
unsigned int lvl = 0; lvl < this->n_global_levels(); ++lvl)
2794 std::vector<bool> active_verts =
2795 this->mark_locally_active_vertices_on_level(lvl);
2797 const unsigned int maybe_coarser_lvl =
2798 (lvl > 0) ? (lvl - 1) : lvl;
2800 cell = this->
begin(maybe_coarser_lvl),
2801 endc = this->
end(lvl);
2802 for (; cell != endc; ++cell)
2803 if (cell->level() ==
static_cast<int>(lvl) || cell->is_active())
2805 const bool is_level_artificial =
2806 (cell->level_subdomain_id() ==
2808 bool need_to_know =
false;
2809 for (
const unsigned int vertex :
2811 if (active_verts[cell->vertex_index(vertex)])
2813 need_to_know =
true;
2818 !need_to_know || !is_level_artificial,
2820 "Internal error: the owner of cell" +
2821 cell->id().to_string() +
2822 " is unknown even though it is needed for geometric multigrid."));
2828 this->update_periodic_face_map();
2829 this->update_number_cache();
2832 this->signals.post_distributed_refinement();
2837 template <
int dim,
int spacedim>
2842 for (
const auto &cell : this->active_cell_iterators())
2843 if (cell->is_locally_owned())
2845 !cell->refine_flag_set() && !cell->coarsen_flag_set(),
2847 "Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition()."));
2851 this->signals.pre_distributed_repartition();
2856 std::vector<typename ::internal::p4est::types<dim>::gloidx>
2857 previous_global_first_quadrant;
2859 if (this->cell_attached_data.n_attached_data_sets > 0)
2861 previous_global_first_quadrant.resize(parallel_forest->mpisize + 1);
2862 std::memcpy(previous_global_first_quadrant.data(),
2863 parallel_forest->global_first_quadrant,
2865 typename ::internal::p4est::types<dim>::gloidx) *
2866 (parallel_forest->mpisize + 1));
2869 if (this->signals.cell_weight.num_slots() == 0)
2881 const std::vector<unsigned int> cell_weights = get_cell_weights();
2883 PartitionWeights<dim, spacedim> partition_weights(cell_weights);
2888 parallel_forest->user_pointer = &partition_weights;
2894 &PartitionWeights<dim, spacedim>::cell_weight);
2897 parallel_forest->user_pointer =
this;
2901 if (this->cell_attached_data.n_attached_data_sets > 0)
2903 this->data_transfer.pack_data(
2904 this->local_cell_relations,
2905 this->cell_attached_data.pack_callbacks_fixed,
2906 this->cell_attached_data.pack_callbacks_variable);
2911 copy_local_forest_to_triangulation();
2921 if (this->cell_attached_data.n_attached_data_sets > 0)
2923 this->execute_transfer(parallel_forest,
2924 previous_global_first_quadrant.data());
2927 this->update_periodic_face_map();
2930 this->update_number_cache();
2933 this->signals.post_distributed_repartition();
2938 template <
int dim,
int spacedim>
2939 const std::vector<types::global_dof_index> &
2943 return p4est_tree_to_coarse_cell_permutation;
2948 template <
int dim,
int spacedim>
2949 const std::vector<types::global_dof_index> &
2953 return coarse_cell_to_p4est_tree_permutation;
2958 template <
int dim,
int spacedim>
2961 const int level)
const
2965 std::vector<bool> marked_vertices(this->n_vertices(),
false);
2966 for (
const auto &cell : this->cell_iterators_on_level(
level))
2969 marked_vertices[cell->vertex_index(v)] =
true;
2986 for (
unsigned int repetition = 0; repetition < dim; ++repetition)
2987 for (
const auto &it : this->get_periodic_face_map())
2990 const unsigned int face_no_1 = it.first.second;
2992 const unsigned int face_no_2 = it.second.first.second;
2993 const std::bitset<3> &face_orientation = it.second.second;
2995 if (cell_1->level() ==
level && cell_2->level() ==
level)
2997 for (
unsigned int v = 0;
3003 const unsigned int vface0 =
3006 face_orientation[0],
3007 face_orientation[1],
3008 face_orientation[2]);
3009 if (marked_vertices[cell_1->face(face_no_1)->vertex_index(
3011 marked_vertices[cell_2->face(face_no_2)->vertex_index(
3013 marked_vertices[cell_1->face(face_no_1)->vertex_index(
3015 marked_vertices[cell_2->face(face_no_2)->vertex_index(
3021 return marked_vertices;
3026 template <
int dim,
int spacedim>
3036 template <
int dim,
int spacedim>
3039 const unsigned int coarse_cell_index)
const
3041 return coarse_cell_to_p4est_tree_permutation[coarse_cell_index];
3046 template <
int dim,
int spacedim>
3050 &periodicity_vector)
3052 Assert(triangulation_has_content ==
true,
3054 Assert(this->n_levels() == 1,
3055 ExcMessage(
"The triangulation is refined!"));
3062 for (
const auto &face_pair : periodicity_vector)
3066 const unsigned int face_left = face_pair.face_idx[0];
3067 const unsigned int face_right = face_pair.face_idx[1];
3070 const unsigned int tree_left =
3071 coarse_cell_to_p4est_tree_permutation[first_cell->index()];
3072 const unsigned int tree_right =
3073 coarse_cell_to_p4est_tree_permutation[second_cell->index()];
3082 unsigned int p4est_orientation = 0;
3084 p4est_orientation = face_pair.orientation[1];
3087 const unsigned int face_idx_list[] = {face_left, face_right};
3088 const cell_iterator cell_list[] = {first_cell, second_cell};
3089 unsigned int lower_idx, higher_idx;
3090 if (face_left <= face_right)
3103 unsigned int first_p4est_idx_on_cell =
3104 p8est_face_corners[face_idx_list[lower_idx]][0];
3105 unsigned int first_dealii_idx_on_face =
3107 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face;
3110 const unsigned int first_dealii_idx_on_cell =
3112 face_idx_list[lower_idx],
3114 cell_list[lower_idx]->face_orientation(
3115 face_idx_list[lower_idx]),
3116 cell_list[lower_idx]->face_flip(face_idx_list[lower_idx]),
3117 cell_list[lower_idx]->face_rotation(
3118 face_idx_list[lower_idx]));
3119 if (first_p4est_idx_on_cell == first_dealii_idx_on_cell)
3121 first_dealii_idx_on_face = i;
3128 constexpr unsigned int left_to_right[8][4] = {{0, 2, 1, 3},
3136 constexpr unsigned int right_to_left[8][4] = {{0, 2, 1, 3},
3144 const unsigned int second_dealii_idx_on_face =
3145 lower_idx == 0 ? left_to_right[face_pair.orientation.to_ulong()]
3146 [first_dealii_idx_on_face] :
3147 right_to_left[face_pair.orientation.to_ulong()]
3148 [first_dealii_idx_on_face];
3149 const unsigned int second_dealii_idx_on_cell =
3151 face_idx_list[higher_idx],
3152 second_dealii_idx_on_face,
3153 cell_list[higher_idx]->face_orientation(
3154 face_idx_list[higher_idx]),
3155 cell_list[higher_idx]->face_flip(face_idx_list[higher_idx]),
3156 cell_list[higher_idx]->face_rotation(
3157 face_idx_list[higher_idx]));
3159 const unsigned int second_p4est_idx_on_face =
3160 p8est_corner_face_corners[second_dealii_idx_on_cell]
3161 [face_idx_list[higher_idx]];
3162 p4est_orientation = second_p4est_idx_on_face;
3182 this->mpi_communicator,
3193 copy_local_forest_to_triangulation();
3203 this->update_number_cache();
3208 template <
int dim,
int spacedim>
3219 this->cell_attached_data.n_attached_data_sets) +
3226 coarse_cell_to_p4est_tree_permutation) +
3228 p4est_tree_to_coarse_cell_permutation) +
3229 memory_consumption_p4est();
3236 template <
int dim,
int spacedim>
3240 return ::internal::p4est::functions<dim>::forest_memory_used(
3248 template <
int dim,
int spacedim>
3251 const ::Triangulation<dim, spacedim> &other_tria)
3255 const ::parallel::distributed::Triangulation<dim, spacedim> *
>(
3257 (other_tria.n_global_levels() == 1),
3268 const typename ::Triangulation<dim, spacedim>::DistortedCellList
3276 if (const ::parallel::distributed::Triangulation<dim, spacedim>
3277 *other_distributed =
3278 dynamic_cast<const ::parallel::distributed::
3279 Triangulation<dim, spacedim> *
>(&other_tria))
3282 settings = other_distributed->settings;
3283 triangulation_has_content =
3284 other_distributed->triangulation_has_content;
3285 coarse_cell_to_p4est_tree_permutation =
3286 other_distributed->coarse_cell_to_p4est_tree_permutation;
3287 p4est_tree_to_coarse_cell_permutation =
3288 other_distributed->p4est_tree_to_coarse_cell_permutation;
3289 this->cell_attached_data = other_distributed->cell_attached_data;
3290 this->data_transfer = other_distributed->data_transfer;
3293 typename ::internal::p4est::types<dim>::connectivity
3294 *temp_connectivity =
const_cast<
3295 typename ::internal::p4est::types<dim>::connectivity *
>(
3296 other_distributed->connectivity);
3298 ::internal::p4est::copy_connectivity<dim>(temp_connectivity);
3301 typename ::internal::p4est::types<dim>::forest *temp_forest =
3302 const_cast<typename ::internal::p4est::types<dim>::forest *
>(
3303 other_distributed->parallel_forest);
3307 parallel_forest->connectivity = connectivity;
3308 parallel_forest->user_pointer =
this;
3312 triangulation_has_content =
true;
3313 setup_coarse_cell_to_p4est_tree_permutation();
3314 copy_new_triangulation_to_p4est(std::integral_constant<int, dim>());
3319 copy_local_forest_to_triangulation();
3328 this->update_periodic_face_map();
3329 this->update_number_cache();
3334 template <
int dim,
int spacedim>
3339 this->local_cell_relations.resize(parallel_forest->local_num_quadrants);
3340 this->local_cell_relations.shrink_to_fit();
3343 for (
const auto &cell : this->cell_iterators_on_level(0))
3346 if (tree_exists_locally<dim, spacedim>(
3348 coarse_cell_to_p4est_tree_permutation[cell->index()]) ==
false)
3352 typename ::internal::p4est::types<dim>::quadrant
3354 ::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3357 typename ::internal::p4est::types<dim>::tree *tree =
3358 init_tree(cell->index());
3360 update_cell_relations_recursively<dim, spacedim>(
3361 this->local_cell_relations, *tree, cell, p4est_coarse_cell);
3367 template <
int dim,
int spacedim>
3368 std::vector<unsigned int>
3373 Assert(this->local_cell_relations.size() ==
3374 static_cast<unsigned int>(parallel_forest->local_num_quadrants),
3382 std::vector<unsigned int> weights;
3391 for (
const auto &cell_rel : this->local_cell_relations)
3393 const auto &cell_it = cell_rel.first;
3394 const auto &cell_status = cell_rel.second;
3396 switch (cell_status)
3399 spacedim>::CELL_PERSIST:
3400 weights.push_back(1000);
3401 weights.back() += this->signals.cell_weight(
3404 spacedim>::CELL_PERSIST);
3408 spacedim>::CELL_REFINE:
3410 spacedim>::CELL_INVALID:
3413 unsigned int parent_weight = 1000;
3414 parent_weight += this->signals.cell_weight(
3420 weights.push_back(parent_weight);
3425 spacedim>::CELL_COARSEN:
3426 weights.push_back(1000);
3427 weights.back() += this->signals.cell_weight(
3430 spacedim>::CELL_COARSEN);
3444 template <
int spacedim>
3447 const typename ::Triangulation<1, spacedim>::MeshSmoothing
3459 template <
int spacedim>
3467 template <
int spacedim>
3468 const std::vector<types::global_dof_index> &
3472 static std::vector<types::global_dof_index> a;
3478 template <
int spacedim>
3479 std::map<unsigned int, std::set<::types::subdomain_id>>
3481 const unsigned int )
const
3485 return std::map<unsigned int, std::set<::types::subdomain_id>>();
3490 template <
int spacedim>
3493 const unsigned int)
const
3496 return std::vector<bool>();
3501 template <
int spacedim>
3512 template <
int spacedim>
3515 const unsigned int)
const
3523 template <
int spacedim>
3532 template <
int spacedim>
3541 template <
int spacedim>
3551 template <
int spacedim>
3568 namespace distributed
3570 template <
int dim,
int spacedim>
3578#ifdef DEAL_II_WITH_P4EST
3588 const auto &cell = pair.first;
3589 const auto &status = pair.second;
3593 case ::Triangulation<dim, spacedim>::CELL_PERSIST:
3595 cell->clear_refine_flag();
3596 cell->clear_coarsen_flag();
3599 case ::Triangulation<dim, spacedim>::CELL_REFINE:
3601 cell->clear_coarsen_flag();
3602 cell->set_refine_flag();
3605 case ::Triangulation<dim, spacedim>::CELL_COARSEN:
3607 for (
const auto &child : cell->child_iterators())
3609 child->clear_refine_flag();
3610 child->set_coarsen_flag();
3614 case ::Triangulation<dim, spacedim>::CELL_INVALID:
3629 template <
int dim,
int spacedim>
3632#ifdef DEAL_II_WITH_P4EST
3633 if (distributed_tria)
3636 distributed_tria->load_coarsen_flags(saved_coarsen_flags);
3637 distributed_tria->load_refine_flags(saved_refine_flags);
3641 (void)distributed_tria;
bool is_locally_owned() const
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator > > &)
active_cell_iterator last_active() const
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
virtual types::subdomain_id locally_owned_subdomain() const
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
cell_iterator end() const
virtual void execute_coarsening_and_refinement()
virtual bool prepare_coarsening_and_refinement()
void save_refine_flags(std::ostream &out) const
unsigned int n_vertices() const
void save_coarsen_flags(std::ostream &out) const
active_cell_iterator begin_active(const unsigned int level=0) const
virtual void clear() override
virtual std::size_t memory_consumption() const override
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria) override
TemporarilyMatchRefineFlags(::Triangulation< dim, spacedim > &tria)
~TemporarilyMatchRefineFlags()
const SmartPointer< ::parallel::distributed::Triangulation< dim, spacedim > > distributed_tria
std::vector< bool > saved_refine_flags
std::vector< bool > saved_coarsen_flags
virtual void execute_coarsening_and_refinement() override
void setup_coarse_cell_to_p4est_tree_permutation()
virtual bool has_hanging_nodes() const override
virtual void add_periodicity(const std::vector<::GridTools::PeriodicFacePair< cell_iterator > > &) override
virtual types::coarse_cell_id coarse_cell_index_to_coarse_cell_id(const unsigned int coarse_cell_index) const override
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &other_tria) override
const std::vector< types::global_dof_index > & get_p4est_tree_to_coarse_cell_permutation() const
Triangulation(const MPI_Comm &mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const Settings settings=default_setting)
std::vector< unsigned int > get_cell_weights() const
unsigned int get_checksum() const
virtual ~Triangulation() override
virtual void update_cell_relations() override
void execute_transfer(const typename ::internal::p4est::types< dim >::forest *parallel_forest, const typename ::internal::p4est::types< dim >::gloidx *previous_global_first_quadrant)
typename::internal::p4est::types< dim >::tree * init_tree(const int dealii_coarse_cell_index) const
virtual void load(const std::string &filename, const bool autopartition=true) override
virtual bool prepare_coarsening_and_refinement() override
std::vector< bool > mark_locally_active_vertices_on_level(const int level) const
const ::internal::p4est::types< dim >::forest * get_p4est() const
const std::vector< types::global_dof_index > & get_coarse_cell_to_p4est_tree_permutation() const
void write_mesh_vtk(const std::string &file_basename) const
void copy_local_forest_to_triangulation()
virtual unsigned int coarse_cell_id_to_coarse_cell_index(const types::coarse_cell_id coarse_cell_id) const override
void copy_new_triangulation_to_p4est(std::integral_constant< int, 2 >)
virtual void save(const std::string &filename) const override
virtual std::size_t memory_consumption_p4est() const
virtual void clear() override
bool is_multilevel_hierarchy_constructed() const override
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata) override
virtual std::size_t memory_consumption() const override
typename::internal::p4est::types< dim >::ghost * parallel_ghost
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< cell_iterator > cell_iterators() const
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertNothrow(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ::Triangulation< dim, spacedim >::cell_iterator cell_iterator
typename ::Triangulation< dim, spacedim >::active_cell_iterator active_cell_iterator
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
void coarsen(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold)
types::global_dof_index size_type
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
@ construct_multigrid_hierarchy
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
T max(const T &t, const MPI_Comm &mpi_communicator)
std::vector< Integer > invert_permutation(const std::vector< Integer > &permutation)
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 3 > &c)
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 3 > &c)
bool tree_exists_locally(const typename types< dim >::forest *parallel_forest, const typename types< dim >::topidx coarse_grid_cell)
const types::subdomain_id artificial_subdomain_id
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
global_cell_index coarse_cell_id
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
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)
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)