From 0d315253f3bb2f9c890738dc44affedaa856f15c Mon Sep 17 00:00:00 2001 From: Antonella Ritorto Date: Thu, 21 Nov 2024 13:03:01 +0100 Subject: [PATCH] Replace code calling selectWinnerPointIds and remove unnecesary if HAVE_MPI --- opm/grid/CpGrid.hpp | 4 ++ opm/grid/cpgrid/CpGrid.cpp | 81 +++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/opm/grid/CpGrid.hpp b/opm/grid/CpGrid.hpp index 0ed754d3c..7b3460c9b 100644 --- a/opm/grid/CpGrid.hpp +++ b/opm/grid/CpGrid.hpp @@ -480,6 +480,10 @@ namespace Dune int min_globalId_point_in_proc, const std::vector>& cells_per_dim_vec) const; + void selectWinnerPointIds(std::vector>& localToGlobal_points_per_level, + const std::vector>>& parent_to_children, + const std::vector>& cells_per_dim_vec) const; + /// --------------- Adaptivity (begin) --------------- /// @brief Mark entity for refinement (or coarsening). diff --git a/opm/grid/cpgrid/CpGrid.cpp b/opm/grid/cpgrid/CpGrid.cpp index e9d569275..e75f4eff2 100644 --- a/opm/grid/cpgrid/CpGrid.cpp +++ b/opm/grid/cpgrid/CpGrid.cpp @@ -1349,7 +1349,6 @@ void CpGrid::collectCellIdsAndCandidatePointIds( std::vector>& int min_globalId_point_in_proc, const std::vector>& cells_per_dim_vec ) const { -#if HAVE_MPI for (std::size_t level = 1; level < cells_per_dim_vec.size()+1; ++level) { localToGlobal_cells_per_level[level-1].resize((*current_data_)[level]-> size(0)); localToGlobal_points_per_level[level-1].resize((*current_data_)[level]-> size(3)); @@ -1380,6 +1379,43 @@ void CpGrid::collectCellIdsAndCandidatePointIds( std::vector>& } } } +} + +void CpGrid::selectWinnerPointIds(std::vector>& localToGlobal_points_per_level, + const std::vector>>& parent_to_children, + const std::vector>& cells_per_dim_vec) const +{ +#if HAVE_MPI + // To store cell_to_point_ information of all refined level grids. + std::vector>> level_cell_to_point(cells_per_dim_vec.size()); + // To decide which "candidate" point global id wins, the rank is stored. The smallest ranks wins, + // i.e., the other non-selected candidates get rewritten with the values from the smallest (winner) rank. + std::vector> level_winning_ranks(cells_per_dim_vec.size()); + + for (std::size_t level = 1; level < cells_per_dim_vec.size()+1; ++level) { + + level_cell_to_point[level -1] = currentData()[level]->cell_to_point_; + // Set std::numeric_limits::max() to make sure that, during communication, the rank of the interior cell + // wins (int between 0 and comm().size()). + level_winning_ranks[level-1].resize(currentData()[level]->size(3), std::numeric_limits::max()); + + for (const auto& element : elements(levelGridView(level))) { + // For interior cells, rewrite the rank value - later used in "point global id competition". + if (element.partitionType() == InteriorEntity) { + for (const auto& corner : currentData()[level]->cell_to_point_[element.index()]){ + int rank = comm().rank(); + level_winning_ranks[level -1][corner] = rank; + } + } + } + } + ParentToChildCellToPointGlobalIdHandle parentToChildCellToPointGlobalId_handle(parent_to_children, + level_cell_to_point, + level_winning_ranks, + localToGlobal_points_per_level); + currentData().front()->communicate(parentToChildCellToPointGlobalId_handle, + Dune::InteriorBorder_All_Interface, + Dune::ForwardCommunication ); #endif } @@ -2351,37 +2387,18 @@ void CpGrid::addLgrsUpdateLeafView(const std::vector>& cells_p // is always the same, accross all processes. // Even though the ordering of the corners in cell_to_point_ is the same accross all processes, // this may not be enough to correctly overwrite the "winner" point global ids for refined cells. - - // To store cell_to_point_ information of all refined level grids. - std::vector>> level_cell_to_point(cells_per_dim_vec.size()); - // To decide which "candidate" point global id wins, the rank is stored. The smallest ranks wins, - // i.e., the other non-selected candidates get rewritten with the values from the smallest (winner) rank. - std::vector> level_winning_ranks(cells_per_dim_vec.size()); - - for (std::size_t level = 1; level < cells_per_dim_vec.size()+1; ++level) { - - level_cell_to_point[level -1] = currentData()[level]->cell_to_point_; - // Set std::numeric_limits::max() to make sure that, during communication, the rank of the interior cell - // wins (int between 0 and comm().size()). - level_winning_ranks[level-1].resize(currentData()[level]->size(3), std::numeric_limits::max()); - - for (const auto& element : elements(levelGridView(level))) { - // For interior cells, rewrite the rank value - later used in "point global id competition". - if (element.partitionType() == InteriorEntity) { - for (const auto& corner : currentData()[level]->cell_to_point_[element.index()]){ - int rank = comm().rank(); - level_winning_ranks[level -1][corner] = rank; - } - } - } - } - ParentToChildCellToPointGlobalIdHandle parentToChildCellToPointGlobalId_handle(parent_to_children, - level_cell_to_point, - level_winning_ranks, - localToGlobal_points_per_level); - currentData().front()->communicate(parentToChildCellToPointGlobalId_handle, - Dune::InteriorBorder_All_Interface, - Dune::ForwardCommunication ); + // + /** Current approach avoids duplicated point ids when + // 1. the LGR is distributed in P_{i_0}, ..., P_{i_n}, with n+1 < comm().size(), + // AND + // 2. there is no coarse cell seen by a process P with P != P_{i_j}, j = 0, ..., n. + // Otherwise, there will be duplicated point ids. + // + // Reason: neighboring cells that only share corners (not faces) are NOT considered in the + // overlap layer of the process.*/ + selectWinnerPointIds(localToGlobal_points_per_level, + parent_to_children, + cells_per_dim_vec); for (std::size_t level = 1; level < cells_per_dim_vec.size()+1; ++level) { // For the general case where the LGRs might be also distributed, a communication step is needed to assign global ids