From: Peter Munch Date: Fri, 15 Jan 2021 09:51:24 +0000 (+0100) Subject: Generalize communicate_locally_moved_vertices() for arbitrary distributed meshes X-Git-Tag: v9.3.0-rc1~589^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5123e05e1aef33e77ce31b13ed003d59285410b1;p=dealii.git Generalize communicate_locally_moved_vertices() for arbitrary distributed meshes --- diff --git a/doc/news/changes/minor/20210115Munch b/doc/news/changes/minor/20210115Munch new file mode 100644 index 0000000000..52b495f08f --- /dev/null +++ b/doc/news/changes/minor/20210115Munch @@ -0,0 +1,6 @@ +New: The method parallel::distributed::Triagnulation::communicate_locally_moved_vertices() +has been refactored and moved to parallel::DistributedTriangulationBase so that it can now also be +used for parallel::fullydistributed::Triangulation. +
+(Daniel Arndt, Ivan Fumagalli, Peter Munch, 2021/01/15) + diff --git a/include/deal.II/base/template_constraints.h b/include/deal.II/base/template_constraints.h index 092d37592a..429c4cb211 100644 --- a/include/deal.II/base/template_constraints.h +++ b/include/deal.II/base/template_constraints.h @@ -183,6 +183,24 @@ struct identity +/** + * A class that always returns a given value. + * This is needed as a workaround for lambdas used as default parameters + * some compilers struggle to deal with. + */ +template +struct always_return +{ + ValueType value; + ValueType + operator()(const ArgType &) + { + return value; + } +}; + + + /** * A class to perform comparisons of arbitrary pointers for equality. In some * circumstances, one would like to make sure that two arguments to a function diff --git a/include/deal.II/distributed/tria.h b/include/deal.II/distributed/tria.h index 161e936608..272ed414a6 100644 --- a/include/deal.II/distributed/tria.h +++ b/include/deal.II/distributed/tria.h @@ -519,62 +519,6 @@ namespace parallel void repartition(); - /** - * When vertices have been moved locally, for example using code like - * @code - * cell->vertex(0) = new_location; - * @endcode - * then this function can be used to update the location of vertices - * between MPI processes. - * - * All the vertices that have been moved and might be in the ghost layer - * of a process have to be reported in the @p vertex_locally_moved - * argument. This ensures that that part of the information that has to - * be send between processes is actually sent. Additionally, it is quite - * important that vertices on the boundary between processes are - * reported on exactly one process (e.g. the one with the highest id). - * Otherwise we could expect undesirable results if multiple processes - * move a vertex differently. A typical strategy is to let processor $i$ - * move those vertices that are adjacent to cells whose owners include - * processor $i$ but no other processor $j$ with $j &vertex_locally_moved); - /** * Return true if the triangulation has hanging nodes. @@ -889,43 +833,6 @@ namespace parallel const std::vector & get_p4est_tree_to_coarse_cell_permutation() const; - /** - * When vertices have been moved locally, for example using code like - * @code - * cell->vertex(0) = new_location; - * @endcode - * then this function can be used to update the location of vertices - * between MPI processes. - * - * All the vertices that have been moved and might be in the ghost layer - * of a process have to be reported in the @p vertex_locally_moved - * argument. This ensures that that part of the information that has to - * be send between processes is actually sent. Additionally, it is quite - * important that vertices on the boundary between processes are - * reported on exactly one process (e.g. the one with the highest id). - * Otherwise we could expect undesirable results if multiple processes - * move a vertex differently. A typical strategy is to let processor $i$ - * move those vertices that are adjacent to cells whose owners include - * processor $i$ but no other processor $j$ with $j &vertex_locally_moved); - /** * This function is not implemented, but needs to be present for the * compiler. diff --git a/include/deal.II/distributed/tria_base.h b/include/deal.II/distributed/tria_base.h index cf2586a7b4..5a65c72308 100644 --- a/include/deal.II/distributed/tria_base.h +++ b/include/deal.II/distributed/tria_base.h @@ -246,6 +246,62 @@ namespace parallel virtual std::vector get_manifold_ids() const override; + /** + * When vertices have been moved locally, for example using code like + * @code + * cell->vertex(0) = new_location; + * @endcode + * then this function can be used to update the location of vertices + * between MPI processes. + * + * All the vertices that have been moved and might be in the ghost layer + * of a process have to be reported in the @p vertex_locally_moved + * argument. This ensures that that part of the information that has to + * be send between processes is actually sent. Additionally, it is quite + * important that vertices on the boundary between processes are + * reported on exactly one process (e.g. the one with the highest id). + * Otherwise we could expect undesirable results if multiple processes + * move a vertex differently. A typical strategy is to let processor $i$ + * move those vertices that are adjacent to cells whose owners include + * processor $i$ but no other processor $j$ with $j &vertex_locally_moved); + protected: /** * MPI communicator to be used for the triangulation. We create a unique diff --git a/include/deal.II/grid/grid_tools.h b/include/deal.II/grid/grid_tools.h index c464e21576..6ac979c160 100644 --- a/include/deal.II/grid/grid_tools.h +++ b/include/deal.II/grid/grid_tools.h @@ -2939,7 +2939,7 @@ namespace GridTools const DataType &)> & unpack, const std::function &cell_filter = - [](const typename MeshType::active_cell_iterator &) { return true; }); + always_return{true}); /** * Exchange arbitrary data of type @p DataType provided by the function @@ -2959,9 +2959,9 @@ namespace GridTools const typename MeshType::level_cell_iterator &)> &pack, const std::function & unpack, - const std::function - &cell_filter = - [](const typename MeshType::level_cell_iterator &) { return true; }); + const std::function & + cell_filter = always_return{ + true}); /* Exchange with all processors of the MPI communicator @p mpi_communicator the vector of bounding * boxes @p local_bboxes. @@ -3980,7 +3980,7 @@ namespace GridTools template - void + inline void exchange_cell_data( const MeshType &mesh, const std::function< @@ -4218,7 +4218,7 @@ namespace GridTools } // namespace internal template - void + inline void exchange_cell_data_to_ghosts( const MeshType & mesh, const std::function( @@ -4256,7 +4256,7 @@ namespace GridTools template - void + inline void exchange_cell_data_to_level_ghosts( const MeshType & mesh, const std::function( diff --git a/source/distributed/tria.cc b/source/distributed/tria.cc index 350ff8ec70..c8b4e24eee 100644 --- a/source/distributed/tria.cc +++ b/source/distributed/tria.cc @@ -1223,348 +1223,6 @@ namespace parallel - // This anonymous namespace contains utility for - // the function Triangulation::communicate_locally_moved_vertices - namespace CommunicateLocallyMovedVertices - { - namespace - { - /** - * A list of tree+quadrant and their vertex indices. - * The bool vector describes which vertices are of interest - * and should be set on the receiving processes. - */ - template - struct CellInfo - { - // store all the tree_indices we send/receive consecutively (n_cells - // entries) - std::vector tree_index; - // store all the quadrants we send/receive consecutively (n_cells - // entries) - std::vector::quadrant> - quadrants; - // store for each cell the number of vertices we send/receive - // and then the vertex indices (for each cell: n_vertices+1 entries) - std::vector vertex_indices; - // store for each cell the vertices we send/receive - // (for each cell n_vertices entries) - std::vector> vertices; - // for receiving and unpacking data we need to store pointers to the - // first vertex and vertex_index on each cell additionally - // both vectors have as many entries as there are cells - std::vector first_vertex_indices; - std::vector *> first_vertices; - - unsigned int - bytes_for_buffer() const - { - return sizeof(unsigned int) + - tree_index.size() * sizeof(unsigned int) + - quadrants.size() * - sizeof( - typename dealii::internal::p4est::types::quadrant) + - vertex_indices.size() * sizeof(unsigned int) + - vertices.size() * sizeof(dealii::Point); - } - - void - pack_data(std::vector &buffer) const - { - buffer.resize(bytes_for_buffer()); - - char *ptr = buffer.data(); - - const unsigned int num_cells = tree_index.size(); - std::memcpy(ptr, &num_cells, sizeof(unsigned int)); - ptr += sizeof(unsigned int); - - std::memcpy(ptr, - tree_index.data(), - num_cells * sizeof(unsigned int)); - ptr += num_cells * sizeof(unsigned int); - - std::memcpy( - ptr, - quadrants.data(), - num_cells * - sizeof(typename dealii::internal::p4est::types::quadrant)); - ptr += - num_cells * - sizeof(typename dealii::internal::p4est::types::quadrant); - - std::memcpy(ptr, - vertex_indices.data(), - vertex_indices.size() * sizeof(unsigned int)); - ptr += vertex_indices.size() * sizeof(unsigned int); - std::memcpy(ptr, - vertices.data(), - vertices.size() * sizeof(dealii::Point)); - ptr += vertices.size() * sizeof(dealii::Point); - - Assert(ptr == buffer.data() + buffer.size(), ExcInternalError()); - } - - void - unpack_data(const std::vector &buffer) - { - const char * ptr = buffer.data(); - unsigned int cells; - memcpy(&cells, ptr, sizeof(unsigned int)); - ptr += sizeof(unsigned int); - - tree_index.resize(cells); - memcpy(tree_index.data(), ptr, sizeof(unsigned int) * cells); - ptr += sizeof(unsigned int) * cells; - - quadrants.resize(cells); - memcpy(quadrants.data(), - ptr, - sizeof( - typename dealii::internal::p4est::types::quadrant) * - cells); - ptr += - sizeof(typename dealii::internal::p4est::types::quadrant) * - cells; - - vertex_indices.clear(); - first_vertex_indices.resize(cells); - std::vector n_vertices_on_cell(cells); - std::vector first_indices(cells); - for (unsigned int c = 0; c < cells; ++c) - { - // The first 'vertex index' is the number of vertices. - // Additionally, we need to store the pointer to this - // vertex index with respect to the std::vector - const unsigned int *const vertex_index = - reinterpret_cast(ptr); - first_indices[c] = vertex_indices.size(); - vertex_indices.push_back(*vertex_index); - n_vertices_on_cell[c] = *vertex_index; - ptr += sizeof(unsigned int); - // Now copy all the 'real' vertex_indices - vertex_indices.resize(vertex_indices.size() + - n_vertices_on_cell[c]); - memcpy(&vertex_indices[vertex_indices.size() - - n_vertices_on_cell[c]], - ptr, - n_vertices_on_cell[c] * sizeof(unsigned int)); - ptr += n_vertices_on_cell[c] * sizeof(unsigned int); - } - for (unsigned int c = 0; c < cells; ++c) - first_vertex_indices[c] = &vertex_indices[first_indices[c]]; - - vertices.clear(); - first_vertices.resize(cells); - for (unsigned int c = 0; c < cells; ++c) - { - first_indices[c] = vertices.size(); - vertices.resize(vertices.size() + n_vertices_on_cell[c]); - memcpy(&vertices[vertices.size() - n_vertices_on_cell[c]], - ptr, - n_vertices_on_cell[c] * sizeof(dealii::Point)); - ptr += n_vertices_on_cell[c] * sizeof(dealii::Point); - } - for (unsigned int c = 0; c < cells; ++c) - first_vertices[c] = &vertices[first_indices[c]]; - - Assert(ptr == buffer.data() + buffer.size(), ExcInternalError()); - } - }; - - - - // This function is responsible for gathering the information - // we want to send to each process. - // For each dealii cell on the coarsest level the corresponding - // p4est_cell has to be provided when calling this function. - // By recursing through all children we consider each active cell. - // vertices_with_ghost_neighbors tells us which vertices - // are in the ghost layer and for which processes they might - // be interesting. - // Whether a vertex has actually been updated locally is - // stored in vertex_locally_moved. Only those are considered - // for sending. - // The gathered information is saved into needs_to_get_cell. - template - void - fill_vertices_recursively( - const typename parallel::distributed::Triangulation - & tria, - const unsigned int tree_index, - const typename Triangulation::cell_iterator - &dealii_cell, - const typename dealii::internal::p4est::types::quadrant - &p4est_cell, - const std::map> - & vertices_with_ghost_neighbors, - const std::vector &vertex_locally_moved, - std::map> - &needs_to_get_cell) - { - // see if we have to - // recurse... - if (dealii_cell->has_children()) - { - typename dealii::internal::p4est::types::quadrant - p4est_child[GeometryInfo::max_children_per_cell]; - dealii::internal::p4est::init_quadrant_children(p4est_cell, - p4est_child); - - - for (unsigned int c = 0; - c < GeometryInfo::max_children_per_cell; - ++c) - fill_vertices_recursively( - tria, - tree_index, - dealii_cell->child(c), - p4est_child[c], - vertices_with_ghost_neighbors, - vertex_locally_moved, - needs_to_get_cell); - return; - } - - // We're at a leaf cell. If the cell is locally owned, we may - // have to send its vertices to other processors if any of - // its vertices is adjacent to a ghost cell and has been moved - // - // If one of the vertices of the cell is interesting, - // send all moved vertices of the cell to all processors - // adjacent to all cells adjacent to this vertex - if (dealii_cell->is_locally_owned()) - { - std::set send_to; - for (const unsigned int v : GeometryInfo::vertex_indices()) - { - const std::map>:: - const_iterator neighbor_subdomains_of_vertex = - vertices_with_ghost_neighbors.find( - dealii_cell->vertex_index(v)); - - if (neighbor_subdomains_of_vertex != - vertices_with_ghost_neighbors.end()) - { - Assert(neighbor_subdomains_of_vertex->second.size() != 0, - ExcInternalError()); - send_to.insert( - neighbor_subdomains_of_vertex->second.begin(), - neighbor_subdomains_of_vertex->second.end()); - } - } - - if (send_to.size() > 0) - { - std::vector vertex_indices; - std::vector> local_vertices; - for (const unsigned int v : - GeometryInfo::vertex_indices()) - if (vertex_locally_moved[dealii_cell->vertex_index(v)]) - { - vertex_indices.push_back(v); - local_vertices.push_back(dealii_cell->vertex(v)); - } - - if (vertex_indices.size() > 0) - for (const auto subdomain : send_to) - { - // get an iterator to what needs to be sent to that - // subdomain (if already exists), or create such an - // object - const typename std::map< - dealii::types::subdomain_id, - CellInfo>::iterator p = - needs_to_get_cell - .insert(std::make_pair(subdomain, - CellInfo())) - .first; - - p->second.tree_index.push_back(tree_index); - p->second.quadrants.push_back(p4est_cell); - - p->second.vertex_indices.push_back( - vertex_indices.size()); - p->second.vertex_indices.insert( - p->second.vertex_indices.end(), - vertex_indices.begin(), - vertex_indices.end()); - - p->second.vertices.insert(p->second.vertices.end(), - local_vertices.begin(), - local_vertices.end()); - } - } - } - } - - - - // After the cell data has been received this function is responsible - // for moving the vertices in the corresponding ghost layer locally. - // As in fill_vertices_recursively for each dealii cell on the - // coarsest level the corresponding p4est_cell has to be provided - // when calling this function. By recursing through through all - // children we consider each active cell. - // Additionally, we need to give a pointer to the first vertex indices - // and vertices. Since the first information saved in vertex_indices - // is the number of vertices this all the information we need. - template - void - set_vertices_recursively( - const parallel::distributed::Triangulation &tria, - const typename dealii::internal::p4est::types::quadrant - &p4est_cell, - const typename Triangulation::cell_iterator - &dealii_cell, - const typename dealii::internal::p4est::types::quadrant - & quadrant, - const dealii::Point *const vertices, - const unsigned int *const vertex_indices) - { - if (dealii::internal::p4est::quadrant_is_equal(p4est_cell, - quadrant)) - { - Assert(!dealii_cell->is_artificial(), ExcInternalError()); - Assert(dealii_cell->is_active(), ExcInternalError()); - Assert(!dealii_cell->is_locally_owned(), ExcInternalError()); - - const unsigned int n_vertices = vertex_indices[0]; - - // update dof indices of cell - for (unsigned int i = 0; i < n_vertices; ++i) - dealii_cell->vertex(vertex_indices[i + 1]) = vertices[i]; - - return; - } - - if (dealii_cell->is_active()) - return; - - if (!dealii::internal::p4est::quadrant_is_ancestor(p4est_cell, - quadrant)) - return; - - typename dealii::internal::p4est::types::quadrant - p4est_child[GeometryInfo::max_children_per_cell]; - dealii::internal::p4est::init_quadrant_children(p4est_cell, - p4est_child); - - for (unsigned int c = 0; c < GeometryInfo::max_children_per_cell; - ++c) - set_vertices_recursively(tria, - p4est_child[c], - dealii_cell->child(c), - quadrant, - vertices, - vertex_indices); - } - } // namespace - } // namespace CommunicateLocallyMovedVertices - - - template void Triangulation::clear() @@ -3233,190 +2891,6 @@ namespace parallel - template - void - Triangulation::communicate_locally_moved_vertices( - const std::vector &vertex_locally_moved) - { - Assert(vertex_locally_moved.size() == this->n_vertices(), - ExcDimensionMismatch(vertex_locally_moved.size(), - this->n_vertices())); -# ifdef DEBUG - { - const std::vector locally_owned_vertices = - dealii::GridTools::get_locally_owned_vertices(*this); - for (unsigned int i = 0; i < locally_owned_vertices.size(); ++i) - Assert((vertex_locally_moved[i] == false) || - (locally_owned_vertices[i] == true), - ExcMessage("The vertex_locally_moved argument must not " - "contain vertices that are not locally owned")); - } -# endif - - // First find out which process should receive which vertices. - // These are specifically the ones that are located on cells at the - // boundary of the subdomain this process owns and the receiving - // process taking periodic faces into account. - // Here, it is sufficient to collect all vertices that are located - // at that boundary. - const std::map> - vertices_with_ghost_neighbors = - GridTools::compute_vertices_with_ghost_neighbors(*this); - - // now collect cells and their vertices - // for the interested neighbors - using cellmap_t = - std::map>; - cellmap_t needs_to_get_cells; - - for (typename Triangulation::cell_iterator cell = - this->begin(0); - cell != this->end(0); - ++cell) - { - typename dealii::internal::p4est::types::quadrant - p4est_coarse_cell; - dealii::internal::p4est::init_coarse_quadrant(p4est_coarse_cell); - - CommunicateLocallyMovedVertices::fill_vertices_recursively( - *this, - this->get_coarse_cell_to_p4est_tree_permutation()[cell->index()], - cell, - p4est_coarse_cell, - vertices_with_ghost_neighbors, - vertex_locally_moved, - needs_to_get_cells); - } - - // Send information - - // We need to protect this communication below using a mutex: - static Utilities::MPI::CollectiveMutex mutex; - Utilities::MPI::CollectiveMutex::ScopedLock lock( - mutex, this->get_communicator()); - - const int mpi_tag = Utilities::MPI::internal::Tags:: - triangulation_communicate_locally_moved_vertices; - - std::vector> sendbuffers(needs_to_get_cells.size()); - std::vector>::iterator buffer = sendbuffers.begin(); - std::vector requests(needs_to_get_cells.size()); - std::vector destinations; - - unsigned int idx = 0; - - for (typename cellmap_t::iterator it = needs_to_get_cells.begin(); - it != needs_to_get_cells.end(); - ++it, ++buffer, ++idx) - { - const unsigned int num_cells = it->second.tree_index.size(); - (void)num_cells; - destinations.push_back(it->first); - - Assert(num_cells == it->second.quadrants.size(), ExcInternalError()); - Assert(num_cells > 0, ExcInternalError()); - - // pack all the data into - // the buffer for this - // recipient and send - // it. keep data around - // till we can make sure - // that the packet has been - // received - it->second.pack_data(*buffer); - const int ierr = MPI_Isend(buffer->data(), - buffer->size(), - MPI_BYTE, - it->first, - mpi_tag, - this->get_communicator(), - &requests[idx]); - AssertThrowMPI(ierr); - } - - Assert(destinations.size() == needs_to_get_cells.size(), - ExcInternalError()); - - // collect the neighbors - // that are going to send stuff to us - const unsigned int n_senders = - Utilities::MPI::compute_n_point_to_point_communications( - this->get_communicator(), destinations); - - // receive ghostcelldata - std::vector receive; - CommunicateLocallyMovedVertices::CellInfo cellinfo; - for (unsigned int i = 0; i < n_senders; ++i) - { - MPI_Status status; - int ierr = MPI_Probe(MPI_ANY_SOURCE, - mpi_tag, - this->get_communicator(), - &status); - AssertThrowMPI(ierr); - - int len; - ierr = MPI_Get_count(&status, MPI_BYTE, &len); - AssertThrowMPI(ierr); - receive.resize(len); - - char *ptr = receive.data(); - ierr = MPI_Recv(ptr, - len, - MPI_BYTE, - status.MPI_SOURCE, - status.MPI_TAG, - this->get_communicator(), - &status); - AssertThrowMPI(ierr); - - cellinfo.unpack_data(receive); - const unsigned int cells = cellinfo.tree_index.size(); - for (unsigned int c = 0; c < cells; ++c) - { - typename dealii::parallel::distributed:: - Triangulation::cell_iterator cell( - this, - 0, - this->get_p4est_tree_to_coarse_cell_permutation() - [cellinfo.tree_index[c]]); - - typename dealii::internal::p4est::types::quadrant - p4est_coarse_cell; - dealii::internal::p4est::init_coarse_quadrant( - p4est_coarse_cell); - - CommunicateLocallyMovedVertices::set_vertices_recursively< - dim, - spacedim>(*this, - p4est_coarse_cell, - cell, - cellinfo.quadrants[c], - cellinfo.first_vertices[c], - cellinfo.first_vertex_indices[c]); - } - } - - // complete all sends, so that we can - // safely destroy the buffers. - if (requests.size() > 0) - { - const int ierr = - MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE); - AssertThrowMPI(ierr); - } - - // check all msgs got sent and received - Assert(Utilities::MPI::sum(needs_to_get_cells.size(), - this->get_communicator()) == - Utilities::MPI::sum(n_senders, this->get_communicator()), - ExcInternalError()); - } - - - template const std::vector & Triangulation::get_p4est_tree_to_coarse_cell_permutation() @@ -3937,16 +3411,6 @@ namespace parallel - template - void - Triangulation<1, spacedim>::communicate_locally_moved_vertices( - const std::vector & /*vertex_locally_moved*/) - { - Assert(false, ExcNotImplemented()); - } - - - template const std::vector & Triangulation<1, spacedim>::get_p4est_tree_to_coarse_cell_permutation() diff --git a/source/distributed/tria_base.cc b/source/distributed/tria_base.cc index 2153619526..c605c37f04 100644 --- a/source/distributed/tria_base.cc +++ b/source/distributed/tria_base.cc @@ -528,6 +528,56 @@ namespace parallel + template + void + TriangulationBase::communicate_locally_moved_vertices( + const std::vector &vertex_locally_moved) + { + AssertDimension(vertex_locally_moved.size(), this->n_vertices()); +#ifdef DEBUG + { + const std::vector locally_owned_vertices = + dealii::GridTools::get_locally_owned_vertices(*this); + for (unsigned int i = 0; i < locally_owned_vertices.size(); ++i) + Assert((vertex_locally_moved[i] == false) || + (locally_owned_vertices[i] == true), + ExcMessage("The vertex_locally_moved argument must not " + "contain vertices that are not locally owned")); + } +#endif + + Point invalid_point; + for (int d = 0; d < spacedim; ++d) + invalid_point[d] = std::numeric_limits::quiet_NaN(); + + const auto pack = [&](const auto &cell) { + std::vector> vertices(cell->n_vertices()); + + for (const auto v : cell->vertex_indices()) + if (vertex_locally_moved[cell->vertex_index(v)]) + vertices[v] = cell->vertex(v); + else + vertices[v] = invalid_point; + + return vertices; + }; + + const auto unpack = [&](const auto &cell, const auto &vertices) { + for (const auto v : cell->vertex_indices()) + if (std::isnan(vertices[v][0]) == false) + cell->vertex(v) = vertices[v]; + }; + + if (this->is_multilevel_hierarchy_constructed()) + GridTools::exchange_cell_data_to_level_ghosts< + std::vector>>(*this, pack, unpack); + else + GridTools::exchange_cell_data_to_ghosts>>( + *this, pack, unpack); + } + + + template const Utilities::MPI::Partitioner & TriangulationBase::global_active_cell_index_partitioner() const diff --git a/source/grid/grid_tools.cc b/source/grid/grid_tools.cc index 1d163e6589..5acf871166 100644 --- a/source/grid/grid_tools.cc +++ b/source/grid/grid_tools.cc @@ -1208,10 +1208,9 @@ namespace GridTools // If the triangulation is distributed, we need to // exchange the moved vertices across mpi processes - if (parallel::distributed::Triangulation - *distributed_triangulation = - dynamic_cast *>( - &triangulation)) + if (auto distributed_triangulation = + dynamic_cast *>( + &triangulation)) { const std::vector locally_owned_vertices = get_locally_owned_vertices(triangulation); @@ -1248,13 +1247,8 @@ namespace GridTools } } -#ifdef DEAL_II_WITH_P4EST distributed_triangulation->communicate_locally_moved_vertices( locally_owned_vertices); -#else - (void)distributed_triangulation; - Assert(false, ExcInternalError()); -#endif } else // if this is a sequential triangulation, we could in principle @@ -2247,20 +2241,20 @@ namespace GridTools vertex_to_cell_map(triangulation); // Create a local index for the locally "owned" vertices - types::global_vertex_index next_index = 0; - unsigned int max_cellid_size = 0; + types::global_vertex_index next_index = 0; + unsigned int max_cellid_size = 0; std::set> - vertices_added; + vertices_added; std::map> vertices_to_recv; std::map>> - vertices_to_send; + vertices_to_send; active_cell_iterator cell = triangulation.begin_active(), endc = triangulation.end(); std::set missing_vert_cells; - std::set used_vertex_index; + std::set used_vertex_index; for (; cell != endc; ++cell) { if (cell->is_locally_owned()) @@ -2270,7 +2264,7 @@ namespace GridTools types::subdomain_id lowest_subdomain_id = cell->subdomain_id(); typename std::set::iterator adjacent_cell = vertex_to_cell[cell->vertex_index(i)].begin(), - end_adj_cell = vertex_to_cell[cell->vertex_index(i)].end(); + end_adj_cell = vertex_to_cell[cell->vertex_index(i)].end(); for (; adjacent_cell != end_adj_cell; ++adjacent_cell) lowest_subdomain_id = std::min(lowest_subdomain_id, @@ -2369,7 +2363,7 @@ namespace GridTools // Make indices global by getting the number of vertices owned by each // processors and shifting the indices accordingly types::global_vertex_index shift = 0; - int ierr = MPI_Exscan(&next_index, + int ierr = MPI_Exscan(&next_index, &shift, 1, DEAL_II_VERTEX_INDEX_MPI_TYPE, @@ -2378,7 +2372,7 @@ namespace GridTools AssertThrowMPI(ierr); std::map::iterator - global_index_it = local_to_global_vertex_index.begin(), + global_index_it = local_to_global_vertex_index.begin(), global_index_end = local_to_global_vertex_index.end(); for (; global_index_it != global_index_end; ++global_index_it) global_index_it->second += shift; @@ -2402,14 +2396,14 @@ namespace GridTools std::vector>>::iterator - vert_to_send_it = vertices_to_send.begin(), + vert_to_send_it = vertices_to_send.begin(), vert_to_send_end = vertices_to_send.end(); for (unsigned int i = 0; vert_to_send_it != vert_to_send_end; ++vert_to_send_it, ++i) { - int destination = vert_to_send_it->first; - const unsigned int n_vertices = vert_to_send_it->second.size(); - const int buffer_size = 2 * n_vertices; + int destination = vert_to_send_it->first; + const unsigned int n_vertices = vert_to_send_it->second.size(); + const int buffer_size = 2 * n_vertices; vertices_send_buffers[i].resize(buffer_size); // fill the buffer @@ -2437,14 +2431,14 @@ namespace GridTools std::vector> vertices_recv_buffers( vertices_to_recv.size()); typename std::map>::iterator - vert_to_recv_it = vertices_to_recv.begin(), + vert_to_recv_it = vertices_to_recv.begin(), vert_to_recv_end = vertices_to_recv.end(); for (unsigned int i = 0; vert_to_recv_it != vert_to_recv_end; ++vert_to_recv_it, ++i) { - int source = vert_to_recv_it->first; - const unsigned int n_vertices = vert_to_recv_it->second.size(); - const int buffer_size = 2 * n_vertices; + int source = vert_to_recv_it->first; + const unsigned int n_vertices = vert_to_recv_it->second.size(); + const int buffer_size = 2 * n_vertices; vertices_recv_buffers[i].resize(buffer_size); // Receive the message @@ -2467,9 +2461,9 @@ namespace GridTools for (unsigned int i = 0; vert_to_send_it != vert_to_send_end; ++vert_to_send_it, ++i) { - int destination = vert_to_send_it->first; - const unsigned int n_vertices = vert_to_send_it->second.size(); - const int buffer_size = max_cellid_size * n_vertices; + int destination = vert_to_send_it->first; + const unsigned int n_vertices = vert_to_send_it->second.size(); + const int buffer_size = max_cellid_size * n_vertices; cellids_send_buffers[i].resize(buffer_size); // fill the buffer @@ -2506,9 +2500,9 @@ namespace GridTools for (unsigned int i = 0; vert_to_recv_it != vert_to_recv_end; ++vert_to_recv_it, ++i) { - int source = vert_to_recv_it->first; - const unsigned int n_vertices = vert_to_recv_it->second.size(); - const int buffer_size = max_cellid_size * n_vertices; + int source = vert_to_recv_it->first; + const unsigned int n_vertices = vert_to_recv_it->second.size(); + const int buffer_size = max_cellid_size * n_vertices; cellids_recv_buffers[i].resize(buffer_size); // Receive the message @@ -2538,7 +2532,7 @@ namespace GridTools &cellids_recv_buffers[i][max_cellid_size * j] + max_cellid_size); bool found = false; typename std::set::iterator - cell_set_it = missing_vert_cells.begin(), + cell_set_it = missing_vert_cells.begin(), end_cell_set = missing_vert_cells.end(); for (; (found == false) && (cell_set_it != end_cell_set); ++cell_set_it) @@ -3073,9 +3067,9 @@ namespace GridTools // are owned by other processors -- either because the vertex is // on an artificial cell, or because it is on a ghost cell with // a smaller subdomain - if (const parallel::distributed::Triangulation *tr = - dynamic_cast - *>(&triangulation)) + if (const auto *tr = dynamic_cast< + const parallel::DistributedTriangulationBase *>( + &triangulation)) for (const auto &cell : triangulation.active_cell_iterators()) if (cell->is_artificial() || (cell->is_ghost() && @@ -5098,7 +5092,7 @@ namespace GridTools guessed_points = GridTools::guess_point_owner(global_bboxes, local_points); // Preparing to call compute_point_locations on points which may be local - const auto &guess_loc_idx = std::get<0>(guessed_points)[my_rank]; + const auto & guess_loc_idx = std::get<0>(guessed_points)[my_rank]; const unsigned int n_local_guess = guess_loc_idx.size(); // Vector containing points which are probably local @@ -5187,7 +5181,7 @@ namespace GridTools for (const auto &probable_owners : points_to_probable_owners) { - const auto &point_idx = probable_owners.first; + const auto &point_idx = probable_owners.first; const auto &probable_owner_ranks = probable_owners.second; if (!std::binary_search(found_point_indices.begin(), found_point_indices.end(), @@ -5213,8 +5207,8 @@ namespace GridTools for (const auto &received_ghost_point : received_ghost_points) { // Transforming CellsIds into Tria iterators - const auto &cell_ids = std::get<0>(received_ghost_point.second); - const unsigned int n_cells = cell_ids.size(); + const auto & cell_ids = std::get<0>(received_ghost_point.second); + const unsigned int n_cells = cell_ids.size(); std::vector::active_cell_iterator> cell_iter(n_cells); for (unsigned int c = 0; c < n_cells; ++c) @@ -5238,11 +5232,11 @@ namespace GridTools // Copying data from the unordered map to the tuple // and returning output const unsigned int size_output = found_points.size(); - auto &out_cells = std::get<0>(output_tuple); - auto &out_qpoints = std::get<1>(output_tuple); - auto &out_maps = std::get<2>(output_tuple); - auto &out_points = std::get<3>(output_tuple); - auto &out_ranks = std::get<4>(output_tuple); + auto & out_cells = std::get<0>(output_tuple); + auto & out_qpoints = std::get<1>(output_tuple); + auto & out_maps = std::get<2>(output_tuple); + auto & out_points = std::get<3>(output_tuple); + auto & out_ranks = std::get<4>(output_tuple); out_cells.resize(size_output); out_qpoints.resize(size_output); @@ -5253,11 +5247,11 @@ namespace GridTools unsigned int c = 0; for (const auto &cell_and_data : found_points) { - out_cells[c] = cell_and_data.first; + out_cells[c] = cell_and_data.first; out_qpoints[c] = std::get<0>(cell_and_data.second); - out_maps[c] = std::get<1>(cell_and_data.second); - out_points[c] = std::get<2>(cell_and_data.second); - out_ranks[c] = std::get<3>(cell_and_data.second); + out_maps[c] = std::get<1>(cell_and_data.second); + out_points[c] = std::get<2>(cell_and_data.second); + out_ranks[c] = std::get<3>(cell_and_data.second); ++c; } @@ -5399,7 +5393,7 @@ namespace GridTools // Step 4: create the array of bboxes for output std::vector>> global_bboxes(n_procs); - unsigned int begin_idx = 0; + unsigned int begin_idx = 0; for (unsigned int i = 0; i < n_procs; ++i) { // Number of local bounding boxes