34 template <
int structdim>
43 template <
int structdim>
50 for (
unsigned int i = 0; i <
vertices.size(); ++i)
90 template <
int dim,
int spacedim>
91 struct DescriptionTemp
97 template <
class Archive>
99 serialize(Archive &ar,
const unsigned int )
112 const std::vector<unsigned int> &relevant_processes,
113 const std::vector<DescriptionTemp<dim, spacedim>> &description_temp,
115 const bool vertices_have_unique_ids)
117 const auto create_request = [&](
const unsigned int other_rank) {
118 const auto ptr = std::find(relevant_processes.begin(),
119 relevant_processes.end(),
124 const auto other_rank_index =
125 std::distance(relevant_processes.begin(), ptr);
127 return description_temp[other_rank_index];
130 const auto process_request =
131 [&](
const unsigned int,
132 const DescriptionTemp<dim, spacedim> &request) {
133 this->
merge(request, vertices_have_unique_ids);
137 DescriptionTemp<dim, spacedim>>(relevant_processes,
149 merge(
const DescriptionTemp<dim, spacedim> &other,
150 const bool vertices_have_unique_ids)
153 std::max(other.cell_infos.size(), this->cell_infos.size()));
155 if (vertices_have_unique_ids ==
false)
158 std::map<Point<spacedim>,
161 map_point_to_local_vertex_index(
171 std::map<unsigned int, unsigned int>
172 map_old_to_new_local_vertex_index;
176 for (
const auto &p : other.coarse_cell_vertices)
177 if (map_point_to_local_vertex_index.find(p.second) ==
178 map_point_to_local_vertex_index.end())
181 map_point_to_local_vertex_index[p.second] =
182 map_old_to_new_local_vertex_index[p.first] = counter++;
185 map_old_to_new_local_vertex_index[p.first] =
186 map_point_to_local_vertex_index[p.second];
189 auto other_coarse_cells_copy = other.coarse_cells;
191 for (
auto &cell : other_coarse_cells_copy)
192 for (
auto &v : cell.vertices)
193 v = map_old_to_new_local_vertex_index[v];
196 other_coarse_cells_copy.begin(),
197 other_coarse_cells_copy.end());
202 other.coarse_cells.begin(),
203 other.coarse_cells.end());
206 other.coarse_cell_vertices.begin(),
207 other.coarse_cell_vertices.end());
212 other.coarse_cell_index_to_coarse_cell_id.begin(),
213 other.coarse_cell_index_to_coarse_cell_id.end());
215 for (
unsigned int i = 0; i < this->
cell_infos.size(); ++i)
217 other.cell_infos[i].begin(),
218 other.cell_infos[i].end());
234 for (
unsigned int i = 0; i < this->
coarse_cells.size(); ++i)
235 temp.emplace_back(this->coarse_cell_index_to_coarse_cell_id[i],
236 this->coarse_cells[i],
239 std::sort(temp.begin(),
241 [](
const auto &a,
const auto &
b) {
242 return std::get<0>(a) < std::get<0>(b);
244 temp.erase(std::unique(temp.begin(),
246 [](
const auto &a,
const auto &
b) {
247 return std::get<0>(a) == std::get<0>(b);
250 std::sort(temp.begin(),
252 [](
const auto &a,
const auto &
b) {
253 return std::get<2>(a) < std::get<2>(b);
259 for (
unsigned int i = 0; i < temp.size(); ++i)
262 std::get<0>(temp[i]);
270 this->coarse_cell_vertices.end(),
273 return a.first < b.first;
278 this->coarse_cell_vertices.end(),
281 if (a.first == b.first)
283 Assert(a.second.distance(b.second) <=
285 std::max(a.second.norm(), b.second.norm()),
295 for (
unsigned int i = 0; i < this->
cell_infos.size(); ++i)
302 [](
const auto &a,
const auto &
b) {
306 std::vector<CellData<dim>> temp;
309 for (
unsigned int j = 1; j < this->
cell_infos[i].size(); ++j)
312 temp.back().subdomain_id =
314 this->cell_infos[i][j].subdomain_id);
315 temp.back().level_subdomain_id =
316 std::min(temp.back().level_subdomain_id,
317 this->cell_infos[i][j].level_subdomain_id);
333 Description<dim, spacedim>
334 convert(
const MPI_Comm
comm,
339 Description<dim, spacedim> description;
342 description.comm =
comm;
347 description.smoothing = mesh_smoothing;
349 std::map<unsigned int, unsigned int> map;
353 description.coarse_cell_vertices.push_back(
360 for (
auto &cell : description.coarse_cells)
361 for (
unsigned int v = 0; v < cell.vertices.size(); ++v)
362 cell.vertices[v] = map[cell.vertices[v]];
364 description.coarse_cell_index_to_coarse_cell_id =
365 this->coarse_cell_index_to_coarse_cell_id;
366 description.cell_infos = this->cell_infos;
373 std::vector<std::pair<unsigned int, Point<spacedim>>>
384 template <
int dim,
int spacedim>
386 mark_cell_and_its_parents(
388 std::vector<std::vector<bool>> &cell_marked)
390 cell_marked[cell->level()][cell->index()] =
true;
391 if (cell->level() != 0)
392 mark_cell_and_its_parents(cell->parent(), cell_marked);
400 template <
int dim,
int spacedim>
401 class CreateDescriptionFromTriangulationHelper
404 CreateDescriptionFromTriangulationHelper(
405 const ::Triangulation<dim, spacedim> &
tria,
407 const typename ::Triangulation<dim, spacedim>::cell_iterator
410 const typename ::Triangulation<dim, spacedim>::cell_iterator
428 spacedim>::limit_level_difference_at_vertices),
430 "Source triangulation has to be set up with "
431 "limit_level_difference_at_vertices if the construction of the "
432 "multigrid hierarchy is requested!"));
438 template <
typename T>
440 create_description_for_rank(
const unsigned int my_rank)
const
444 set_additional_data(construction_data);
449 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells =
450 [
this](
const auto &cell,
451 std::vector<bool> &vertices_owned_by_locally_owned_cells) {
453 for (
const auto v : cell->vertex_indices())
455 vertices_owned_by_locally_owned_cells[cell->vertex_index(
457 const auto coinciding_vertex_group =
459 cell->vertex_index(v));
460 if (coinciding_vertex_group !=
463 coinciding_vertex_group->second))
464 vertices_owned_by_locally_owned_cells[co_vertex] =
true;
470 std::vector<std::vector<bool>> cell_marked(
tria.
n_levels());
480 std::vector<bool> vertices_owned_by_locally_owned_cells_on_level(
485 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
486 cell, vertices_owned_by_locally_owned_cells_on_level);
490 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
491 cell, vertices_owned_by_locally_owned_cells_on_level);
496 const auto is_locally_relevant_on_level = [&](
const auto &cell) {
497 for (
const auto v : cell->vertex_indices())
498 if (vertices_owned_by_locally_owned_cells_on_level
499 [cell->vertex_index(v)])
506 if (is_locally_relevant_on_level(cell))
507 mark_cell_and_its_parents(cell, cell_marked);
518 if (!cell_marked[cell->level()][cell->index()])
523 cell_data.material_id = cell->material_id();
524 cell_data.manifold_id = cell->manifold_id();
525 for (
const auto v : cell->vertex_indices())
526 cell_data.vertices[v] = cell->vertex_index(v);
527 construction_data.coarse_cells.push_back(cell_data);
530 for (
const auto v : cell->vertex_indices())
531 vertices_locally_relevant[cell->vertex_index(v)] =
true;
534 construction_data.coarse_cell_index_to_coarse_cell_id.push_back(
535 cell->id().get_coarse_cell_id());
538 add_vertices(construction_data, vertices_locally_relevant);
543 construction_data.cell_infos.resize(
547 std::vector<bool> vertices_owned_by_locally_owned_active_cells(
551 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
552 cell, vertices_owned_by_locally_owned_active_cells);
556 const auto is_locally_relevant_on_active_level =
557 [&](
const auto &cell) {
558 if (cell->is_active())
559 for (
const auto v : cell->vertex_indices())
560 if (vertices_owned_by_locally_owned_active_cells
561 [cell->vertex_index(v)])
566 for (
unsigned int level = 0;
571 std::vector<bool> vertices_owned_by_locally_owned_cells_on_level(
576 (cell->is_active() &&
578 add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
579 cell, vertices_owned_by_locally_owned_cells_on_level);
583 const auto is_locally_relevant_on_level = [&](
const auto &cell) {
584 for (
const auto v : cell->vertex_indices())
585 if (vertices_owned_by_locally_owned_cells_on_level
586 [cell->vertex_index(v)])
591 auto &level_cell_infos = construction_data.cell_infos[
level];
595 if (!cell_marked[cell->level()][cell->index()])
601 cell_info.id = cell->id().template to_binary<dim>();
604 for (
const auto f : cell->face_indices())
607 cell->face(f)->boundary_id();
609 cell_info.boundary_ids.emplace_back(f, boundary_ind);
619 for (
const auto line : cell->line_indices())
620 cell_info.manifold_line_ids[line] =
625 for (
const auto f : cell->face_indices())
626 cell_info.manifold_quad_ids[f] =
632 cell_info.level_subdomain_id =
635 if (is_locally_relevant_on_active_level(cell))
639 cell_info.level_subdomain_id =
642 else if (is_locally_relevant_on_level(cell))
644 cell_info.level_subdomain_id =
652 level_cell_infos.emplace_back(cell_info);
656 return construction_data;
661 set_additional_data(Description<dim, spacedim> &construction_data)
const
663 construction_data.comm =
comm;
665 construction_data.settings =
settings;
669 set_additional_data(DescriptionTemp<dim, spacedim> &)
const
675 add_vertices(Description<dim, spacedim> &construction_data,
676 const std::vector<bool> &vertices_locally_relevant)
const
678 std::vector<unsigned int> vertices_locally_relevant_indices(
679 vertices_locally_relevant.size());
682 unsigned int vertex_counter = 0;
683 for (
unsigned int i = 0; i < vertices_locally_relevant.size(); ++i)
684 if (vertices_locally_relevant[i])
686 construction_data.coarse_cell_vertices.push_back(
688 vertices_locally_relevant_indices[i] = vertex_counter++;
692 for (
auto &cell : construction_data.coarse_cells)
693 for (
unsigned int v = 0; v < cell.vertices.size(); ++v)
695 vertices_locally_relevant_indices[cell.vertices[v]];
699 add_vertices(DescriptionTemp<dim, spacedim> &construction_data,
700 const std::vector<bool> &vertices_locally_relevant)
const
702 for (
unsigned int i = 0; i < vertices_locally_relevant.size(); ++i)
703 if (vertices_locally_relevant[i])
704 construction_data.coarse_cell_vertices.emplace_back(
709 const ::Triangulation<dim, spacedim> &
tria;
711 const typename ::Triangulation<dim, spacedim>::cell_iterator &)>
714 const typename ::Triangulation<dim, spacedim>::cell_iterator &)>
721 std::map<unsigned int, std::vector<unsigned int>>
729 template <
int dim,
int spacedim>
730 Description<dim, spacedim>
732 const ::Triangulation<dim, spacedim> &
tria,
735 const unsigned int my_rank_in)
737 if (
const auto tria_pdt =
dynamic_cast<
740 ExcMessage(
"MPI communicators do not match."));
744 unsigned int my_rank = my_rank_in;
747 ExcMessage(
"Rank has to be smaller than available processes."));
749 if (
auto tria_pdt =
dynamic_cast<
755 "For creation from a parallel::distributed::Triangulation, "
756 "my_rank has to equal global rank."));
760 else if (
auto tria_serial =
761 dynamic_cast<const ::Triangulation<dim, spacedim> *
>(
770 ExcMessage(
"This type of triangulation is not supported!"));
774 return cell->subdomain_id();
778 return cell->level_subdomain_id();
781 return CreateDescriptionFromTriangulationHelper<dim, spacedim>(
787 .template create_description_for_rank<Description<dim, spacedim>>(
793 template <
int dim,
int spacedim>
797 &serial_grid_generator,
800 const unsigned int)> &serial_grid_partitioner,
802 const int group_size,
806 #ifndef DEAL_II_WITH_MPI
807 (void)serial_grid_generator;
808 (void)serial_grid_partitioner;
816 const unsigned int my_rank =
818 const unsigned int group_root = (my_rank / group_size) * group_size;
824 if (my_rank == group_root)
831 typename ::Triangulation<dim, spacedim>::MeshSmoothing
>(
834 spacedim>::limit_level_difference_at_vertices) :
836 serial_grid_generator(
tria);
839 serial_grid_partitioner(
tria,
comm, group_size);
846 const unsigned int end_group =
854 for (
unsigned int other_rank = group_root + 1; other_rank < end_group;
858 const auto construction_data =
864 std::vector<char> buffer;
868 const auto ierr = MPI_Send(buffer.data(),
890 auto ierr = MPI_Probe(group_root, mpi_tag,
comm, &status);
894 MPI_Get_count(&status, MPI_CHAR, &len);
896 std::vector<char> buf(len);
897 ierr = MPI_Recv(buf.data(),
908 auto construction_data =
909 ::Utilities::template unpack<Description<dim, spacedim>>(
914 construction_data.comm =
comm;
916 return construction_data;
923 template <
int dim,
int spacedim>
940 "Source triangulation has to be set up with "
941 "limit_level_difference_at_vertices if the construction of the "
942 "multigrid hierarchy is requested!"));
944 std::vector<LinearAlgebra::distributed::Vector<double>> partitions_mg;
948 const auto tria_parallel =
960 tria_parallel->global_level_cell_index_partitioner(
l).lock());
966 if (cell->is_locally_owned_on_level() ==
false)
969 if (cell->is_active())
970 partitions_mg[
level][cell->global_level_cell_index()] =
971 partition[cell->global_active_cell_index()];
973 partitions_mg[
level][cell->global_level_cell_index()] =
974 partitions_mg[
level + 1]
975 [cell->child(0)->global_level_cell_index()];
978 partitions_mg[
level].update_ghost_values();
990 template <
int dim,
int spacedim>
999 #ifdef DEAL_II_WITH_MPI
1014 for (
const auto &
partition : partitions_mg)
1018 const std::vector<unsigned int> relevant_processes = [&]() {
1019 std::set<unsigned int> relevant_processes;
1021 for (
unsigned int i = 0; i <
partition.locally_owned_size(); ++i)
1022 relevant_processes.insert(
1023 static_cast<unsigned int>(
partition.local_element(i)));
1025 for (
const auto &
partition : partitions_mg)
1026 for (
unsigned int i = 0; i <
partition.locally_owned_size(); ++i)
1027 relevant_processes.insert(
1028 static_cast<unsigned int>(
partition.local_element(i)));
1030 return std::vector<unsigned int>(relevant_processes.begin(),
1031 relevant_processes.end());
1044 if ((cell->is_active() && (cell->is_artificial() ==
false)))
1045 return static_cast<unsigned int>(
1046 partition[cell->global_active_cell_index()]);
1054 return static_cast<unsigned int>(
1055 partitions_mg[cell->level()][cell->global_level_cell_index()]);
1060 CreateDescriptionFromTriangulationHelper<dim, spacedim> helper(
1069 std::vector<DescriptionTemp<dim, spacedim>> descriptions_per_rank;
1070 descriptions_per_rank.reserve(relevant_processes.size());
1072 for (
const auto rank : relevant_processes)
1073 descriptions_per_rank.emplace_back(
1074 helper.template create_description_for_rank<
1075 DescriptionTemp<dim, spacedim>>(rank));
1079 DescriptionTemp<dim, spacedim> description_merged;
1080 description_merged.collect(
1082 descriptions_per_rank,
1089 description_merged.reduce();
1092 return description_merged.convert(
partition.get_mpi_communicator(),
1103 #include "tria_description.inst"
virtual const MeshSmoothing & get_mesh_smoothing() const
virtual MPI_Comm get_communicator() const
unsigned int n_levels() const
unsigned int n_raw_cells(const unsigned int level) const
virtual unsigned int n_global_levels() const
Triangulation< dim, spacedim > & get_triangulation()
unsigned int n_vertices() const
const std::vector< Point< spacedim > > & get_vertices() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcInternalError()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
static ::ExceptionBase & ExcMessage(std::string arg1)
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)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
Description< dim, spacedim > create_description_from_triangulation(const Triangulation< dim, spacedim > &tria, const LinearAlgebra::distributed::Vector< double > &partition, const std::vector< LinearAlgebra::distributed::Vector< double >> &partitions_mg, const TriangulationDescription::Settings settings_in)
Description< dim, spacedim > create_description_from_triangulation_in_groups(const std::function< void(::Triangulation< dim, spacedim > &)> &serial_grid_generator, const std::function< void(::Triangulation< dim, spacedim > &, const MPI_Comm, const unsigned int)> &serial_grid_partitioner, const MPI_Comm comm, const int group_size=1, const typename Triangulation< dim, spacedim >::MeshSmoothing smoothing=::Triangulation< dim, spacedim >::none, const TriangulationDescription::Settings setting=TriangulationDescription::Settings::default_setting)
@ construct_multigrid_hierarchy
VectorType::value_type * begin(VectorType &V)
VectorType::value_type * end(VectorType &V)
std::vector< unsigned int > selector(const std::vector< unsigned int > &targets, const std::function< RequestType(const unsigned int)> &create_request, const std::function< AnswerType(const unsigned int, const RequestType &)> &answer_request, const std::function< void(const unsigned int, const AnswerType &)> &process_answer, const MPI_Comm comm)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
T reduce(const T &local_value, const MPI_Comm comm, const std::function< T(const T &, const T &)> &combiner, const unsigned int root_process=0)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
constexpr DEAL_II_HOST TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
const types::boundary_id internal_face_boundary_id
const types::subdomain_id artificial_subdomain_id
static const unsigned int invalid_unsigned_int
const types::manifold_id flat_manifold_id
global_cell_index coarse_cell_id
unsigned int subdomain_id
std::vector< unsigned int > vertices
bool operator==(const CellData< structdim > &other) const
types::manifold_id manifold_id
types::material_id material_id
types::boundary_id boundary_id
CellData(const unsigned int n_vertices=ReferenceCells::get_hypercube< structdim >().n_vertices())
std::vector< CellData< 2 > > boundary_quads
bool check_consistency(const unsigned int dim) const
std::vector< CellData< 1 > > boundary_lines
std::vector< std::pair< unsigned int, Point< spacedim > > > coarse_cell_vertices
const TriangulationDescription::Settings settings
const bool construct_multigrid
std::map< unsigned int, unsigned int > vertex_to_coinciding_vertex_group
const std::function< types::subdomain_id(const typename ::Triangulation< dim, spacedim >::cell_iterator &)> subdomain_id_function
const std::function< types::subdomain_id(const typename ::Triangulation< dim, spacedim >::cell_iterator &)> level_subdomain_id_function
std::vector< types::coarse_cell_id > coarse_cell_index_to_coarse_cell_id
std::vector< std::vector< CellData< dim > > > cell_infos
std::map< unsigned int, std::vector< unsigned int > > coinciding_vertex_groups
const ::Triangulation< dim, spacedim > & tria
std::vector<::CellData< dim > > coarse_cells