39 template <
int dim,
int spacedim>
41 set_user_flag_and_of_its_parents(
44 cell->set_user_flag();
45 if (cell->level() != 0)
46 set_user_flag_and_of_its_parents(cell->parent());
56 convert_cell_id_binary_type_to_level_coarse_cell_id(
64 const unsigned int n_child_indices = binary_representation[1] >> 2;
66 const unsigned int children_per_value =
67 sizeof(CellId::binary_type::value_type) * 8 / dim;
68 unsigned int child_level = 0;
69 unsigned int binary_entry = 2;
72 std::vector<unsigned int> cell_indices;
73 while (child_level < n_child_indices)
75 Assert(binary_entry < binary_representation.size(),
78 for (
unsigned int j = 0; j < children_per_value; ++j)
80 unsigned int cell_index =
81 (((binary_representation[binary_entry] >> (j * dim))) &
83 cell_indices.push_back(cell_index);
85 if (child_level == n_child_indices)
93 for (
auto i : cell_indices)
94 level_coarse_cell_id =
97 return level_coarse_cell_id;
102 template <
int dim,
int spacedim>
103 Description<dim, spacedim>
105 const ::Triangulation<dim, spacedim> &tria,
108 const unsigned int my_rank_in)
110 if (
auto tria_pdt =
dynamic_cast<
112 Assert(comm == tria_pdt->get_communicator(),
113 ExcMessage(
"MPI communicators do not match."));
117 unsigned int my_rank = my_rank_in;
120 ExcMessage(
"Rank has to be smaller than available processes."));
122 if (
auto tria_pdt =
dynamic_cast<
129 "If parallel::distributed::Triangulation as source triangulation, my_rank has to equal global rank."));
133 else if (
auto tria_serial =
134 dynamic_cast<const ::Triangulation<dim, spacedim> *
>(
143 ExcMessage(
"This type of triangulation is not supported!"));
149 construction_data.
comm = comm;
152 std::map<unsigned int, std::vector<unsigned int>>
153 coinciding_vertex_groups;
154 std::map<unsigned int, unsigned int> vertex_to_coinciding_vertex_group;
157 coinciding_vertex_groups,
158 vertex_to_coinciding_vertex_group);
162 auto add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells =
163 [coinciding_vertex_groups, vertex_to_coinciding_vertex_group](
165 std::vector<bool> &vertices_owned_by_locally_owned_cells) {
169 vertices_owned_by_locally_owned_cells[cell->vertex_index(v)] =
171 const auto coinciding_vertex_group =
172 vertex_to_coinciding_vertex_group.find(cell->vertex_index(v));
173 if (coinciding_vertex_group !=
174 vertex_to_coinciding_vertex_group.end())
175 for (
const auto &co_vertex : coinciding_vertex_groups.at(
176 coinciding_vertex_group->second))
177 vertices_owned_by_locally_owned_cells[co_vertex] =
true;
181 construction_data.
smoothing = tria.get_mesh_smoothing();
182 construction_data.
settings = settings;
187 (tria.get_mesh_smoothing() &
190 "Source triangulation has to be setup with limit_level_difference_at_vertices if the construction of the multigrid hierarchy is requested!"));
193 std::vector<bool> old_user_flags;
194 tria.save_user_flags(old_user_flags);
202 for (
int level = tria.get_triangulation().n_global_levels() - 1;
208 std::vector<bool> vertices_owned_by_locally_owned_cells_on_level(
210 for (
auto cell : tria.cell_iterators_on_level(
level))
211 if (cell->level_subdomain_id() == my_rank ||
212 (cell->active() && cell->subdomain_id() == my_rank))
213 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
214 cell, vertices_owned_by_locally_owned_cells_on_level);
216 for (
auto cell : tria.active_cell_iterators())
217 if (cell->subdomain_id() == my_rank)
218 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
219 cell, vertices_owned_by_locally_owned_cells_on_level);
224 auto is_locally_relevant_on_level =
227 if (vertices_owned_by_locally_owned_cells_on_level
228 [cell->vertex_index(v)])
234 for (
auto cell : tria.cell_iterators_on_level(
level))
235 if (is_locally_relevant_on_level(cell))
236 set_user_flag_and_of_its_parents(cell);
241 std::map<unsigned int, unsigned int> vertices_locally_relevant;
244 for (
auto cell : tria.cell_iterators_on_level(0))
246 if (!cell->user_flag_set())
251 cell_data.material_id = cell->material_id();
254 cell_data.vertices[v] = cell->vertex_index(v);
259 vertices_locally_relevant[cell->vertex_index(v)] =
264 cell->id().get_coarse_cell_id());
268 unsigned int vertex_counter = 0;
269 for (
auto &vertex : vertices_locally_relevant)
272 tria.get_vertices()[vertex.first]);
273 vertex.second = vertex_counter++;
279 cell.vertices[v] = vertices_locally_relevant[cell.vertices[v]];
285 tria.get_triangulation().n_global_levels());
288 std::vector<bool> vertices_owned_by_locally_owned_active_cells(
290 for (
auto cell : tria.active_cell_iterators())
291 if (cell->subdomain_id() == my_rank)
292 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
293 cell, vertices_owned_by_locally_owned_active_cells);
297 auto is_locally_relevant_on_active_level =
301 if (vertices_owned_by_locally_owned_active_cells
302 [cell->vertex_index(v)])
307 for (
unsigned int level = 0;
308 level < tria.get_triangulation().n_global_levels();
312 std::vector<bool> vertices_owned_by_locally_owned_cells_on_level(
314 for (
auto cell : tria.cell_iterators_on_level(
level))
315 if (cell->level_subdomain_id() == my_rank ||
316 (cell->active() && cell->subdomain_id() == my_rank))
317 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
318 cell, vertices_owned_by_locally_owned_cells_on_level);
322 auto is_locally_relevant_on_level =
325 if (vertices_owned_by_locally_owned_cells_on_level
326 [cell->vertex_index(v)])
332 for (
auto cell : tria.cell_iterators_on_level(
level))
335 if (!(cell->user_flag_set()))
341 cell_info.
id = cell->id().template to_binary<dim>();
347 cell->face(f)->boundary_id();
359 for (
unsigned int line = 0;
360 line < GeometryInfo<dim>::lines_per_cell;
363 cell->line(line)->manifold_id();
367 for (
unsigned int quad = 0;
368 quad < GeometryInfo<dim>::quads_per_cell;
371 cell->quad(quad)->manifold_id();
378 if (is_locally_relevant_on_active_level(cell))
383 else if (is_locally_relevant_on_level(cell))
389 level_cell_infos.emplace_back(cell_info);
396 return construction_data;
401 template <
int dim,
int spacedim>
405 & serial_grid_generator,
408 const unsigned int)> &serial_grid_partitioner,
410 const int group_size,
414 #ifndef DEAL_II_WITH_MPI
415 (void)serial_grid_generator;
416 (void)serial_grid_partitioner;
424 const unsigned int my_rank =
426 const unsigned int group_root = (my_rank / group_size) * group_size;
432 if (my_rank == group_root)
439 typename ::Triangulation<dim, spacedim>::MeshSmoothing
>(
442 spacedim>::limit_level_difference_at_vertices) :
444 serial_grid_generator(tria);
447 serial_grid_partitioner(tria, comm, group_size);
454 const unsigned int end_group =
462 for (
unsigned int other_rank = group_root + 1; other_rank < end_group;
466 const auto construction_data =
472 std::vector<char> buffer;
476 const auto ierr = MPI_Send(buffer.data(),
498 auto ierr = MPI_Probe(group_root, mpi_tag, comm, &status);
502 MPI_Get_count(&status, MPI_CHAR, &len);
504 std::vector<char> buf(len);
505 ierr = MPI_Recv(buf.data(),
516 auto construction_data =
517 ::Utilities::template unpack<Description<dim, spacedim>>(
522 construction_data.comm = comm;
524 return construction_data;
535 #include "tria_description.inst"