From 7573ce2e4128d5a866ed3a0adb71b5115428359a Mon Sep 17 00:00:00 2001 From: Lisa Julia Nebel Date: Wed, 28 Aug 2024 15:03:02 +0200 Subject: [PATCH] Add globalToLocal and localToGlobal functions to the ParallelWellInfo class --- opm/simulators/wells/ParallelWellInfo.cpp | 61 +++++++++++++++++++++++ opm/simulators/wells/ParallelWellInfo.hpp | 10 ++++ 2 files changed, 71 insertions(+) diff --git a/opm/simulators/wells/ParallelWellInfo.cpp b/opm/simulators/wells/ParallelWellInfo.cpp index 97640292e..d77963448 100644 --- a/opm/simulators/wells/ParallelWellInfo.cpp +++ b/opm/simulators/wells/ParallelWellInfo.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -119,6 +120,50 @@ GlobalPerfContainerFactory(const IndexSet& local_indices, } } +template +void GlobalPerfContainerFactory::buildLocalToGlobalMap() const { + local_to_global_map_.clear(); + for (const auto& index : local_indices_) { + local_to_global_map_[index.local()] = index.global(); + } + l2g_map_built_ = true; +} + + +template +int GlobalPerfContainerFactory::localToGlobal(std::size_t localIndex) const { + if (local_indices_.size() == 0) + return localIndex; + if (!l2g_map_built_) + buildLocalToGlobalMap(); + auto it = local_to_global_map_.find(localIndex); + if (it == local_to_global_map_.end()) + OPM_THROW(std::logic_error, fmt::format("There is no global index for the localIndex {}.", localIndex)); + return it->second; +} + +template +void GlobalPerfContainerFactory::buildGlobalToLocalMap() const { + global_to_local_map_.clear(); + for (const auto& index : local_indices_) { + global_to_local_map_[index.global()] = index.local().local(); + } + g2l_map_built_ = true; +} + +template +int GlobalPerfContainerFactory::globalToLocal(const int globalIndex) const { + if (local_indices_.size() == 0) + return globalIndex; + if (!g2l_map_built_) { + buildGlobalToLocalMap(); + } + auto it = global_to_local_map_.find(globalIndex); + if (it == global_to_local_map_.end()) + return -1; // Global index not found + return it->second; +} + template std::vector GlobalPerfContainerFactory:: createGlobal(const std::vector& local_perf_container, @@ -477,6 +522,22 @@ ParallelWellInfo::ParallelWellInfo(const std::pair& w isOwner_ = (comm_->rank() == 0); } +template +int ParallelWellInfo::localToGlobal(std::size_t localIndex) const { + if(globalPerfCont_) + return globalPerfCont_->localToGlobal(localIndex); + else // If globalPerfCont_ is not set up, then this is a sequential run and local and global indices are the same. + return localIndex; +} + +template +int ParallelWellInfo::globalToLocal(const int globalIndex) const { + if(globalPerfCont_) + return globalPerfCont_->globalToLocal(globalIndex); + else // If globalPerfCont_ is not set up, then this is a sequential run and local and global indices are the same. + return globalIndex; +} + template void ParallelWellInfo::communicateFirstPerforation(bool hasFirst) { diff --git a/opm/simulators/wells/ParallelWellInfo.hpp b/opm/simulators/wells/ParallelWellInfo.hpp index 4439ff9bb..3eeac1b9e 100644 --- a/opm/simulators/wells/ParallelWellInfo.hpp +++ b/opm/simulators/wells/ParallelWellInfo.hpp @@ -161,8 +161,16 @@ public: std::size_t num_components) const; int numGlobalPerfs() const; + int globalToLocal(const int globalIndex) const; + int localToGlobal(std::size_t localIndex) const; private: + void buildLocalToGlobalMap() const; + void buildGlobalToLocalMap() const; + mutable std::unordered_map local_to_global_map_; // Cache for L2G mapping + mutable std::unordered_map global_to_local_map_; // Cache for G2L mapping + mutable bool l2g_map_built_ = false; + mutable bool g2l_map_built_ = false; const IndexSet& local_indices_; Parallel::Communication comm_; int num_global_perfs_; @@ -208,6 +216,8 @@ public: /// \brief Collectively decide which rank has first perforation. void communicateFirstPerforation(bool hasFirst); + int globalToLocal(const int globalIndex) const; + int localToGlobal(std::size_t localIndex) const; /// If the well does not have any open connections the member rankWithFirstPerf /// is not initialized, and no broadcast is performed. In this case the argument