diff --git a/opm/simulators/flow/EclWriter.hpp b/opm/simulators/flow/EclWriter.hpp index b3bd59200..f9f4224ca 100644 --- a/opm/simulators/flow/EclWriter.hpp +++ b/opm/simulators/flow/EclWriter.hpp @@ -435,6 +435,8 @@ public: this->outputModule_->assignToSolution(localCellData); } + // Collect RFT data on rank 0 + this->outputModule_->accumulateRftDataParallel(simulator_.gridView().comm()); // Add cell data to perforations for RFT output this->outputModule_->addRftDataToWells(localWellData, reportStepNum); } diff --git a/opm/simulators/flow/GenericCpGridVanguard.cpp b/opm/simulators/flow/GenericCpGridVanguard.cpp index 0e017ecff..7000c9a14 100644 --- a/opm/simulators/flow/GenericCpGridVanguard.cpp +++ b/opm/simulators/flow/GenericCpGridVanguard.cpp @@ -209,7 +209,6 @@ doLoadBalance_(const Dune::EdgeWeightMethod edgeWeightsMethod, } // Add inactive wells to all ranks with connections (not solved, so OK even without distributed wells) - // @NOTE: Approach below is just for testing, there has to be a better way... std::unordered_set cellOnRank; const auto& global_cells = this->grid_->globalCell(); for (const auto cell : global_cells) cellOnRank.insert(cell); @@ -229,7 +228,7 @@ doLoadBalance_(const Dune::EdgeWeightMethod edgeWeightsMethod, std::vector well_on_rank_global(nranks, 0); comm.max(&well_on_rank[0], nranks); for (int i=0; i +void GenericOutputBlackoilModule:: +accumulateRftDataParallel(const Parallel::Communication& comm) { + if (comm.size() > 1) { + collectRftMapOnRoot(oilConnectionPressures_, comm); + collectRftMapOnRoot(waterConnectionSaturations_, comm); + collectRftMapOnRoot(gasConnectionSaturations_, comm); + } +} + +template +void GenericOutputBlackoilModule:: +collectRftMapOnRoot(std::map& local_map, const Parallel::Communication& comm) { + + const auto mapsize = local_map.size(); + std::vector keys; + std::vector values; + keys.reserve(mapsize); + values.reserve(mapsize); + for (const auto& [key, value] : local_map) { + keys.push_back(key); + values.push_back(value); + } + + std::vector all_keys; + std::vector all_values; + std::vector offsets; + + std::tie(all_keys, offsets) = Opm::gatherv(keys, comm, 0); + std::tie(all_values, std::ignore) = Opm::gatherv(values, comm, 0); + assert(all_keys.size() == all_values.size()); + + // Insert/update map values on root + if (comm.rank() == 0) { + for (auto i=static_cast(offsets[1]); i0) { + const Scalar prev_value = local_map[index]; + local_map[index] = std::max(prev_value, all_values[i]); + } else { + local_map[index] = all_values[i]; + } + } + } +} + + + template void GenericOutputBlackoilModule:: addRftDataToWells(data::Wells& wellDatas, std::size_t reportStepNum) diff --git a/opm/simulators/flow/GenericOutputBlackoilModule.hpp b/opm/simulators/flow/GenericOutputBlackoilModule.hpp index add9a3635..b7d8c2769 100644 --- a/opm/simulators/flow/GenericOutputBlackoilModule.hpp +++ b/opm/simulators/flow/GenericOutputBlackoilModule.hpp @@ -109,6 +109,8 @@ public: void outputErrorLog(const Parallel::Communication& comm) const; + void accumulateRftDataParallel(const Parallel::Communication& comm); + void addRftDataToWells(data::Wells& wellDatas, std::size_t reportStepNum); @@ -381,6 +383,8 @@ protected: virtual bool isDefunctParallelWell(std::string wname) const = 0; + void collectRftMapOnRoot(std::map& local_map, const Parallel::Communication& comm); + const EclipseState& eclState_; const Schedule& schedule_; const SummaryState& summaryState_;