diff --git a/opm/simulators/wells/ParallelWellInfo.cpp b/opm/simulators/wells/ParallelWellInfo.cpp index 6a4efedfd..3acf5cb1a 100644 --- a/opm/simulators/wells/ParallelWellInfo.cpp +++ b/opm/simulators/wells/ParallelWellInfo.cpp @@ -45,7 +45,8 @@ void ParallelWellInfo::DestroyComm::operator()(Communication* comm) ParallelWellInfo::ParallelWellInfo(const std::string& name, bool hasLocalCells) : name_(name), hasLocalCells_ (hasLocalCells), - isOwner_(true), comm_(new Communication(Dune::MPIHelper::getLocalCommunicator())) + isOwner_(true), rankWithFirstPerf_(-1), + comm_(new Communication(Dune::MPIHelper::getLocalCommunicator())) {} ParallelWellInfo::ParallelWellInfo(const std::pair& well_info, @@ -63,6 +64,16 @@ ParallelWellInfo::ParallelWellInfo(const std::pair& well_info, isOwner_ = (comm_->rank() == 0); } +void ParallelWellInfo::communicateFirstPerforation(bool hasFirst) +{ + int first = hasFirst; + std::vector firstVec(comm_->size()); + comm_->allgather(&first, 1, firstVec.data()); + auto found = std::find_if(firstVec.begin(), firstVec.end(), + [](int i) -> bool{ return i;}); + rankWithFirstPerf_ = found - firstVec.begin(); +} + bool operator<(const ParallelWellInfo& well1, const ParallelWellInfo& well2) { return well1.name() < well2.name() || (! (well2.name() < well1.name()) && well1.hasLocalCells() < well2.hasLocalCells()); diff --git a/opm/simulators/wells/ParallelWellInfo.hpp b/opm/simulators/wells/ParallelWellInfo.hpp index a1f1fd361..497bb095c 100644 --- a/opm/simulators/wells/ParallelWellInfo.hpp +++ b/opm/simulators/wells/ParallelWellInfo.hpp @@ -61,6 +61,17 @@ public: return *comm_; } + /// \brief Collectively decide which ran has first perforation. + void communicateFirstPerforation(bool hasFirst); + + template + T broadcastFirstPerforationValue(const T& t) const + { + T res=t; + comm_->broadcast(&res, 1, rankWithFirstPerf_); + return res; + } + /// \brief Name of the well. const std::string& name() const { @@ -92,6 +103,8 @@ private: bool hasLocalCells_; /// \brief Whether we own the well and should do reports etc. bool isOwner_; + /// \brief Rank with the first perforation on it. + int rankWithFirstPerf_; /// \brief Communication object for the well /// /// Contains only ranks where this well will perforate local cells.