From 1cfe3e0aad58de8aff526f9cef416193d67fc97e Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Mon, 27 Sep 2021 11:28:27 +0200 Subject: [PATCH 1/3] remove cartesian to compressed vector --- opm/simulators/wells/BlackoilWellModel.hpp | 6 ++- .../wells/BlackoilWellModelGeneric.cpp | 5 +- .../wells/BlackoilWellModelGeneric.hpp | 8 ++-- .../wells/BlackoilWellModel_impl.hpp | 41 ++--------------- opm/simulators/wells/WellInterfaceGeneric.cpp | 46 ++++++++++--------- opm/simulators/wells/WellInterfaceGeneric.hpp | 2 +- 6 files changed, 39 insertions(+), 69 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel.hpp b/opm/simulators/wells/BlackoilWellModel.hpp index 727cf3774..a8248c0f8 100644 --- a/opm/simulators/wells/BlackoilWellModel.hpp +++ b/opm/simulators/wells/BlackoilWellModel.hpp @@ -370,8 +370,6 @@ namespace Opm { // setting the well_solutions_ based on well_state. void updatePrimaryVariables(DeferredLogger& deferred_logger); - void setupCartesianToCompressed_(const int* global_cell, int local_num__cells); - void updateAverageFormationFactor(); void computePotentials(const std::size_t widx, @@ -421,6 +419,10 @@ namespace Opm { void assignWellTracerRates(data::Wells& wsrpt) const; + int compressedIndex(int cartesian_cell_idx) const override { + return ebosSimulator_.vanguard().compressedIndex(cartesian_cell_idx); + } + private: BlackoilWellModel(Simulator& ebosSimulator, const PhaseUsage& pu); }; diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index 916675da8..5125cefc7 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -349,8 +349,7 @@ initializeWellPerfData() parallelWellInfo.beginReset(); for (const auto& completion : well.getConnections()) { - const int active_index = - cartesian_to_compressed_[completion.global_index()]; + const int active_index = compressedIndex(completion.global_index()); if (completion.state() == Connection::State::OPEN) { if (active_index >= 0) { if (firstOpenCompletion) @@ -1706,7 +1705,7 @@ BlackoilWellModelGeneric:: setRepRadiusPerfLength() { for (const auto& well : well_container_generic_) { - well->setRepRadiusPerfLength(cartesian_to_compressed_); + well->setRepRadiusPerfLength(); } } diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index c66508839..552df803e 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -374,6 +374,9 @@ protected: void runWellPIScaling(const int timeStepIdx, DeferredLogger& local_deferredLogger); + virtual int compressedIndex(int cartesian_cell_idx) const = 0; + + Schedule& schedule_; const SummaryState& summaryState_; const EclipseState& eclState_; @@ -401,11 +404,6 @@ protected: std::vector prod_index_calc_; - // Map from logically cartesian cell indices to compressed ones. - // Cells not in the interior are not mapped. This deactivates - // these for distributed wells and makes the distribution non-overlapping. - std::vector cartesian_to_compressed_; - std::vector pvt_region_idx_; mutable std::unordered_set closed_this_step_; diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index fb271f959..16bef9cdf 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -51,18 +51,11 @@ namespace Opm { // Number of cells the global grid view global_num_cells_ = ebosSimulator_.vanguard().globalNumCells(); - // Set up cartesian mapping. + // Set up parallel wells { - const auto& grid = this->ebosSimulator_.vanguard().grid(); - const auto& cartDims = UgGridHelpers::cartDims(grid); - setupCartesianToCompressed_(UgGridHelpers::globalCell(grid), - cartDims[0] * cartDims[1] * cartDims[2]); - auto& parallel_wells = ebosSimulator.vanguard().parallelWells(); - - for (const auto& wellinfo : parallel_wells) { - this->parallel_well_info_.emplace_back(wellinfo, grid.comm()); - } + this->parallel_well_info_.assign(parallel_wells.begin(), + parallel_wells.end()); } this->alternative_well_rate_init_ = @@ -129,8 +122,7 @@ namespace Opm { for ( size_t c=0; c < connectionSet.size(); c++ ) { const auto& connection = connectionSet.get(c); - int compressed_idx = cartesian_to_compressed_ - .at(connection.global_index()); + int compressed_idx = compressedIndex(connection.global_index()); if ( compressed_idx >= 0 ) { // Ignore connections in inactive/remote cells. wellCells.push_back(compressed_idx); @@ -1431,31 +1423,6 @@ namespace Opm { - template - void - BlackoilWellModel:: - setupCartesianToCompressed_(const int* global_cell, int number_of_cartesian_cells) - { - cartesian_to_compressed_.resize(number_of_cartesian_cells, -1); - if (global_cell) { - auto elemIt = ebosSimulator_.gridView().template begin(); - for (unsigned i = 0; i < local_num_cells_; ++i) { - // Skip perforations in the overlap/ghost for distributed wells. - if (elemIt->partitionType() == Dune::InteriorEntity) - { - assert(ebosSimulator_.gridView().indexSet().index(*elemIt) == static_cast(i)); - cartesian_to_compressed_[global_cell[i]] = i; - } - ++elemIt; - } - } - else { - for (unsigned i = 0; i < local_num_cells_; ++i) { - cartesian_to_compressed_[i] = i; - } - } - - } template void diff --git a/opm/simulators/wells/WellInterfaceGeneric.cpp b/opm/simulators/wells/WellInterfaceGeneric.cpp index a915b4dc6..6888bb661 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.cpp +++ b/opm/simulators/wells/WellInterfaceGeneric.cpp @@ -263,7 +263,7 @@ void WellInterfaceGeneric::setWellEfficiencyFactor(const double efficiency_facto well_efficiency_factor_ = efficiency_factor; } -void WellInterfaceGeneric::setRepRadiusPerfLength(const std::vector& cartesian_to_compressed) +void WellInterfaceGeneric::setRepRadiusPerfLength() { const int nperf = number_of_perforations_; @@ -275,31 +275,35 @@ void WellInterfaceGeneric::setRepRadiusPerfLength(const std::vector& cartes perf_length_.reserve(nperf); bore_diameters_.reserve(nperf); - // COMPDAT handling - const auto& connectionSet = well_ecl_.getConnections(); - CheckDistributedWellConnections checker(well_ecl_, parallel_well_info_); - for (size_t c=0; c= 0) + const WellConnections& connections = well_ecl_.getConnections(); + const std::size_t num_conns = connections.size(); + int num_active_connections = 0; + auto my_next_perf = perf_data_->begin(); + for (std::size_t c = 0; c < num_conns; ++c) { + if (my_next_perf == perf_data_->end()) { - checker.connectionFound(c); + break; } + if (my_next_perf->ecl_index > c) + { + continue; + } + assert(my_next_perf->ecl_index == c); + const auto& connection = connections[c]; if (connection.state() == Connection::State::OPEN) { - - if (cell >= 0) { - double radius = connection.rw(); - double re = connection.re(); // area equivalent radius of the grid block - double perf_length = connection.connectionLength(); // the length of the well perforation - const double repR = std::sqrt(re * radius); - perf_rep_radius_.push_back(repR); - perf_length_.push_back(perf_length); - bore_diameters_.push_back(2. * radius); - } + double radius = connection.rw(); + double re = connection.re(); // area equivalent radius of the grid block + double perf_length = connection.connectionLength(); // the length of the well perforation + const double repR = std::sqrt(re * radius); + perf_rep_radius_.push_back(repR); + perf_length_.push_back(perf_length); + bore_diameters_.push_back(2. * radius); + num_active_connections++; } + ++my_next_perf; } - checker.checkAllConnectionsFound(); + assert(my_next_perf == perf_data_->end()); + assert(num_active_connections == nperf); } void WellInterfaceGeneric::setWsolvent(const double wsolvent) diff --git a/opm/simulators/wells/WellInterfaceGeneric.hpp b/opm/simulators/wells/WellInterfaceGeneric.hpp index 96300e446..9da5157d5 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.hpp +++ b/opm/simulators/wells/WellInterfaceGeneric.hpp @@ -93,7 +93,7 @@ public: void setVFPProperties(const VFPProperties* vfp_properties_arg); void setGuideRate(const GuideRate* guide_rate_arg); void setWellEfficiencyFactor(const double efficiency_factor); - void setRepRadiusPerfLength(const std::vector& cartesian_to_compressed); + void setRepRadiusPerfLength(); void setWsolvent(const double wsolvent); void setDynamicThpLimit(const double thp_limit); void updatePerforatedCell(std::vector& is_cell_perforated); From 23e0b06387fd83e086fb5967666aa28db65bdc19 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Tue, 19 Oct 2021 12:24:04 +0200 Subject: [PATCH 2/3] Allow communicators other than MPI_COMM_WORLD. --- opm/simulators/wells/BlackoilWellModel_impl.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 16bef9cdf..21402e470 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -52,10 +52,13 @@ namespace Opm { global_num_cells_ = ebosSimulator_.vanguard().globalNumCells(); // Set up parallel wells + auto& parallel_wells = ebosSimulator.vanguard().parallelWells(); + + this->parallel_well_info_.reserve(parallel_wells.size()); + for( const auto& name_bool: parallel_wells) { - auto& parallel_wells = ebosSimulator.vanguard().parallelWells(); - this->parallel_well_info_.assign(parallel_wells.begin(), - parallel_wells.end()); + this->parallel_well_info_.emplace_back(name_bool, + ebosSimulator_.gridView().comm()); } this->alternative_well_rate_init_ = From fa9e93529bc2bc4a29375e0a12df3afd5809b248 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Tue, 19 Oct 2021 16:50:42 +0200 Subject: [PATCH 3/3] Only consider perforation in the interior of the local grid. This is needed for distributed wells to save most of the code from checking whether a perforation is in the interior. We add new methods compressedIndexForInterior that return -1 for non-interior cells and use that for the wells. This restores the old behaviour before 1cfe3e0aad58 --- ebos/eclbasevanguard.hh | 44 +++++++++++++++++-- opm/simulators/wells/BlackoilWellModel.hpp | 4 +- .../wells/BlackoilWellModelGeneric.cpp | 2 +- .../wells/BlackoilWellModelGeneric.hpp | 3 +- .../wells/BlackoilWellModel_impl.hpp | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/ebos/eclbasevanguard.hh b/ebos/eclbasevanguard.hh index fe2611446..1aac6ae29 100644 --- a/ebos/eclbasevanguard.hh +++ b/ebos/eclbasevanguard.hh @@ -296,6 +296,8 @@ public: /*! * \brief Return compressed index from cartesian index * + * \return compressed index of cell is in interior, -1 otherwise + * */ int compressedIndex(int cartesianCellIdx) const { @@ -306,6 +308,25 @@ public: return -1; } + /*! + * \brief Return compressed index from cartesian index only in interior + * + * \return compressed index of cell is in interior, -1 otherwise + * + */ + int compressedIndexForInterior(int cartesianCellIdx) const + { + auto index_pair = cartesianToCompressed_.find(cartesianCellIdx); + if (index_pair == cartesianToCompressed_.end() || + !is_interior_[index_pair->second]) + { + return -1; + } + else + { + return index_pair->second; + } + } /*! * \brief Extract Cartesian index triplet (i,j,k) of an active cell. * @@ -424,9 +445,22 @@ protected: void updateCartesianToCompressedMapping_() { size_t num_cells = asImp_().grid().leafGridView().size(0); - for (unsigned i = 0; i < num_cells; ++i) { - unsigned cartesianCellIdx = cartesianIndex(i); - cartesianToCompressed_[cartesianCellIdx] = i; + is_interior_.resize(num_cells); + + ElementMapper elemMapper(this->gridView(), Dune::mcmgElementLayout()); + for (const auto& element : elements(this->gridView())) + { + const auto elemIdx = elemMapper.index(element); + unsigned cartesianCellIdx = cartesianIndex(elemIdx); + cartesianToCompressed_[cartesianCellIdx] = elemIdx; + if (element.partitionType() == Dune::InteriorEntity) + { + is_interior_[elemIdx] = 1; + } + else + { + is_interior_[elemIdx] = 0; + } } } @@ -515,6 +549,10 @@ protected: /*! \brief Cell thickness */ std::vector cellThickness_; + + /*! \brief Whether a cells is in the interior. + */ + std::vector is_interior_; }; } // namespace Opm diff --git a/opm/simulators/wells/BlackoilWellModel.hpp b/opm/simulators/wells/BlackoilWellModel.hpp index a8248c0f8..27e239f4f 100644 --- a/opm/simulators/wells/BlackoilWellModel.hpp +++ b/opm/simulators/wells/BlackoilWellModel.hpp @@ -419,8 +419,8 @@ namespace Opm { void assignWellTracerRates(data::Wells& wsrpt) const; - int compressedIndex(int cartesian_cell_idx) const override { - return ebosSimulator_.vanguard().compressedIndex(cartesian_cell_idx); + int compressedIndexForInterior(int cartesian_cell_idx) const override { + return ebosSimulator_.vanguard().compressedIndexForInterior(cartesian_cell_idx); } private: diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index 5125cefc7..36c28d3f7 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -349,7 +349,7 @@ initializeWellPerfData() parallelWellInfo.beginReset(); for (const auto& completion : well.getConnections()) { - const int active_index = compressedIndex(completion.global_index()); + const int active_index = compressedIndexForInterior(completion.global_index()); if (completion.state() == Connection::State::OPEN) { if (active_index >= 0) { if (firstOpenCompletion) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index 552df803e..311283637 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -374,7 +374,8 @@ protected: void runWellPIScaling(const int timeStepIdx, DeferredLogger& local_deferredLogger); - virtual int compressedIndex(int cartesian_cell_idx) const = 0; + /// \brief get compressed index for interior cells (-1, otherwise + virtual int compressedIndexForInterior(int cartesian_cell_idx) const = 0; Schedule& schedule_; diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 21402e470..c9ef4e0b1 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -125,7 +125,7 @@ namespace Opm { for ( size_t c=0; c < connectionSet.size(); c++ ) { const auto& connection = connectionSet.get(c); - int compressed_idx = compressedIndex(connection.global_index()); + int compressed_idx = compressedIndexForInterior(connection.global_index()); if ( compressed_idx >= 0 ) { // Ignore connections in inactive/remote cells. wellCells.push_back(compressed_idx);