From 38ad832ed70ca6d714c976dcb37ee7f8f071cd85 Mon Sep 17 00:00:00 2001 From: Giovanni Alzetta Date: Mon, 30 Jul 2018 13:51:11 +0200 Subject: [PATCH] Adding global tree of bounding boxes --- .../changes/minor/20181217GiovanniAlzetta | 6 ++ include/deal.II/grid/grid_tools.h | 33 +++++++++++ source/grid/grid_tools.cc | 59 +++++++++++++++++++ source/grid/grid_tools.inst.in | 8 ++- 4 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 doc/news/changes/minor/20181217GiovanniAlzetta diff --git a/doc/news/changes/minor/20181217GiovanniAlzetta b/doc/news/changes/minor/20181217GiovanniAlzetta new file mode 100644 index 0000000000..9e40685ce2 --- /dev/null +++ b/doc/news/changes/minor/20181217GiovanniAlzetta @@ -0,0 +1,6 @@ +New: Function GridTools::build_global_description_tree which exchanges a given +vector of bounding boxes on all processes and uses the result to build an Rtree +with packing algorithm. +
+(Giovanni Alzetta, 2018/12/17) + diff --git a/include/deal.II/grid/grid_tools.h b/include/deal.II/grid/grid_tools.h index a9a1addc77..d6d87c9b75 100644 --- a/include/deal.II/grid/grid_tools.h +++ b/include/deal.II/grid/grid_tools.h @@ -22,6 +22,8 @@ # include # include +# include + # include # include @@ -40,6 +42,7 @@ # include # include +# include # include # include # include @@ -2690,6 +2693,36 @@ namespace GridTools const std::vector> &local_bboxes, MPI_Comm mpi_communicator); + /** + * In this collective operation each process provides a vector + * of bounding boxes and a communicator. + * All these vectors are gathered in each process + * and organized in a search tree which is then returned. + * + * The idea is that the vector of bounding boxes describes + * a relevant property which could be of use to other processes, + * e.g. for a distributed triangulation, the bounding + * boxes could describe the portion of the mesh which is + * locally owned by the current process. + * + * The search tree is an r-tree with packing algorithm, + * which is provided by boost library. + * + * In the returned tree, each node contains a pair of elements: + * the first being a bounding box, + * the second being the rank of the process whose local description + * contains the bounding box. + * + * Note: this function is a collective operation. + * + * @author Giovanni Alzetta, 2018. + */ + template + RTree, unsigned int>> + build_global_description_tree( + const std::vector> &local_description, + MPI_Comm mpi_communicator); + /** * A structure that allows the transfer of cell data of type @p T from one processor * to another. It corresponds to a packed buffer that stores a vector of diff --git a/source/grid/grid_tools.cc b/source/grid/grid_tools.cc index 14a856ec18..2da178fa23 100644 --- a/source/grid/grid_tools.cc +++ b/source/grid/grid_tools.cc @@ -5081,6 +5081,65 @@ namespace GridTools #endif // DEAL_II_WITH_MPI } + template + RTree, unsigned int>> + build_global_description_tree( + const std::vector> &local_description, + MPI_Comm mpi_communicator) + { +#ifndef DEAL_II_WITH_MPI + (void)local_description; + (void)mpi_communicator; + Assert(false, + ExcMessage( + "GridTools::build_global_description_tree() requires MPI.")); + return RTree, unsigned int>>{}; +#else + // Exchanging local bounding boxes + std::vector>> global_bboxes; + global_bboxes = + Utilities::MPI::all_gather(mpi_communicator, local_description); + + // Preparing to flatten the vector + unsigned int n_procs = Utilities::MPI::n_mpi_processes(mpi_communicator); + unsigned int tot_bboxes = 0; + // The i element of the following vector contains the index of the first + // local bounding box from the process of rank i + std::vector bboxes_position(n_procs); + + for (const auto &process_bboxes : global_bboxes) + tot_bboxes += process_bboxes.size(); + + // Now flattening the vector + std::vector, unsigned int>> + flat_global_bboxes; + flat_global_bboxes.reserve(tot_bboxes); + unsigned int process_index = 0; + for (const auto &process_bboxes : global_bboxes) + { + // Initializing a vector containing bounding boxes and rank of a process + std::vector, unsigned int>> + boxes_and_indices(process_bboxes.size()); + // Adding to each box the rank of the process owning it + for (unsigned int i = 0; i < process_bboxes.size(); ++i) + boxes_and_indices[i] = + std::make_pair(process_bboxes[i], process_index); + + flat_global_bboxes.insert(flat_global_bboxes.end(), + boxes_and_indices.begin(), + boxes_and_indices.end()); + ++process_index; + } + + // Building a tree out of the bounding boxes + // We avoid using the insert method so that boost uses the packing algorithm + RTree, unsigned int>> r_tree( + flat_global_bboxes.begin(), flat_global_bboxes.end()); + return r_tree; +#endif // DEAL_II_WITH_MPI + } + + } /* namespace GridTools */ diff --git a/source/grid/grid_tools.inst.in b/source/grid/grid_tools.inst.in index d8c1a41e5f..c8b0ce9120 100644 --- a/source/grid/grid_tools.inst.in +++ b/source/grid/grid_tools.inst.in @@ -149,6 +149,11 @@ for (deal_II_space_dimension : SPACE_DIMENSIONS) GridTools::guess_point_owner( const std::vector>> &, const std::vector> &); + + template RTree< + std::pair, unsigned int>> + GridTools::build_global_description_tree( + const std::vector> &, MPI_Comm); } @@ -157,7 +162,6 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS) #if deal_II_dimension <= deal_II_space_dimension namespace GridTools \{ - template double diameter( const Triangulation &); @@ -331,9 +335,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS) &distorted_cells, Triangulation &triangulation); - # endif - \} #endif } -- 2.39.5