From 4a87dcf5f34dfef76905aa8fa4964ca423768b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 19 Mar 2024 09:16:23 +0100 Subject: [PATCH 1/2] Use In-place Construction of PerforationData Objects This is (slightly) faster than construct + copy. --- opm/simulators/wells/BlackoilWellModelGeneric.cpp | 5 ++--- opm/simulators/wells/PerforationData.hpp | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index 86be56640..8858d3d6a 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -350,14 +350,13 @@ initializeWellPerfData() hasFirstConnection = true; } - auto pd = PerforationData{}; + auto& pd = well_perf_data_[well_index].emplace_back(); + pd.cell_index = active_index; pd.connection_transmissibility_factor = connection.CF(); pd.satnum_id = connection.satTableId(); pd.ecl_index = connection_index; - well_perf_data_[well_index].push_back(pd); - parallelWellInfo.pushBackEclIndex(connection_index_above, connection_index); } diff --git a/opm/simulators/wells/PerforationData.hpp b/opm/simulators/wells/PerforationData.hpp index a9ddeab9d..f195746cf 100644 --- a/opm/simulators/wells/PerforationData.hpp +++ b/opm/simulators/wells/PerforationData.hpp @@ -28,12 +28,12 @@ namespace Opm /// Static data associated with a well perforation. struct PerforationData { - int cell_index; - double connection_transmissibility_factor; - double connection_d_factor; - int satnum_id; + int cell_index{}; + double connection_transmissibility_factor{}; + double connection_d_factor{}; + int satnum_id{}; /// \brief The original index of the perforation in ECL Schedule - std::size_t ecl_index; + std::size_t ecl_index{}; }; struct PerforationRates From 7056c81a7b6be1cd6c7714e5a575e175e7f638a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 19 Mar 2024 09:17:48 +0100 Subject: [PATCH 2/2] Allow for Sparse Source-Location Subsets If a well is nominally connected in inactive cells, i.e., if its connections have not been filtered down to the active connections only, then 'allIndices' may not be a permutation of 0 .. allIndices.size()-1 Handle this case by sizing 'storageIndex_' according to the maximum index value insted of 'allIndices.size()'. --- .../wells/ParallelPAvgDynamicSourceData.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/opm/simulators/wells/ParallelPAvgDynamicSourceData.cpp b/opm/simulators/wells/ParallelPAvgDynamicSourceData.cpp index 1edf6da91..50da7086b 100644 --- a/opm/simulators/wells/ParallelPAvgDynamicSourceData.cpp +++ b/opm/simulators/wells/ParallelPAvgDynamicSourceData.cpp @@ -148,7 +148,19 @@ void Opm::ParallelPAvgDynamicSourceData::defineCommunication() // 4) Build translation mapping from source term element indices to // storage indices. - this->storageIndex_.resize(allIndices.size()); + // + // Note that if the source terms aren't all active--e.g., if a well + // is connected in deactivated cells--then allIndices is not a + // permutation of 0..allIndices.size()-1 and the maximum source + // location may exceed size()-1. Resize the storageIndex_ according + // to the largest source location ID. + if (auto maxIxPos = std::max_element(allIndices.begin(), allIndices.end()); + maxIxPos != allIndices.end()) + { + // +1 for zero-based indices. + this->storageIndex_.resize(*maxIxPos + 1); + } + auto storageIx = std::vector::size_type{0}; for (const auto& elemIndex : allIndices) { this->storageIndex_[elemIndex] = storageIx++;