From d4ab9ea4b1d0750f282c68d4415de826c1ead2f7 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Thu, 7 Oct 2021 21:09:25 +0200 Subject: [PATCH] [refactor] Use well_container and PerforationData for tracers This saves some (expensive?) lookups that already have been done in the well model. We had to make the well_container accessible from the well model for this. Using the perforation data will automatically make sure that the perforations are not shut and reside on this process in a parallel run. --- ebos/ecltracermodel.hh | 56 ++++--------------- opm/simulators/wells/BlackoilWellModel.hpp | 6 ++ opm/simulators/wells/WellInterfaceGeneric.cpp | 5 ++ opm/simulators/wells/WellInterfaceGeneric.hpp | 3 + 4 files changed, 25 insertions(+), 45 deletions(-) diff --git a/ebos/ecltracermodel.hh b/ebos/ecltracermodel.hh index e335c108a..10acccfbd 100644 --- a/ebos/ecltracermodel.hh +++ b/ebos/ecltracermodel.hh @@ -291,38 +291,21 @@ protected: } // Wells terms - const int episodeIdx = simulator_.episodeIndex(); - const auto& wells = simulator_.vanguard().schedule().getWells(episodeIdx); - for (const auto& well : wells) { + const auto& wellPtrs = simulator_.problem().wellModel().localNonshutWells(); + for (const auto& wellPtr : wellPtrs) { + const auto& well = wellPtr->wellEcl(); for (int tIdx =0; tIdx < tr.numTracer(); ++tIdx) { this->wellTracerRate_[std::make_pair(well.name(),this->tracerNames_[tr.idx_[tIdx]])] = 0.0; } - if (well.getStatus() == Well::Status::SHUT) - continue; - - if (!simulator_.problem().wellModel().hasWell(well.name())) - continue; - - const auto& wellPtr = simulator_.problem().wellModel().getWell(well.name()); - std::vector wtracer(tr.numTracer()); for (int tIdx =0; tIdx < tr.numTracer(); ++tIdx) { wtracer[tIdx] = well.getTracerProperties().getConcentration(this->tracerNames_[tr.idx_[tIdx]]); } - std::array cartesianCoordinate; - for (auto& connection : well.getConnections()) { - - if (connection.state() == Connection::State::SHUT) - continue; - - cartesianCoordinate[0] = connection.getI(); - cartesianCoordinate[1] = connection.getJ(); - cartesianCoordinate[2] = connection.getK(); - const size_t cartIdx = simulator_.vanguard().cartesianIndex(cartesianCoordinate); - const int I = this->cartToGlobal_[cartIdx]; + for (auto& perfData : wellPtr->perforationData()) { + auto I = perfData.cell_index; Scalar rate = wellPtr->volumetricSurfaceRateForConnection(I, tr.phaseIdx_); if (rate > 0) { for (int tIdx =0; tIdx < tr.numTracer(); ++tIdx) { @@ -388,34 +371,17 @@ protected: } // Store _producer_ tracer rate for reporting - const int episodeIdx = simulator_.episodeIndex(); - const auto& wells = simulator_.vanguard().schedule().getWells(episodeIdx); - for (const auto& well : wells) { - - if (well.getStatus() == Well::Status::SHUT) - continue; - - if (!simulator_.problem().wellModel().hasWell(well.name())) - continue; - - const auto& wellPtr = simulator_.problem().wellModel().getWell(well.name()); + const auto& wellPtrs = simulator_.problem().wellModel().localNonshutWells(); + for (const auto& wellPtr : wellPtrs) { + const auto& well = wellPtr->wellEcl(); if (!well.isProducer()) //Injection rates already reported during assembly continue; Scalar rateWellPos = 0.0; Scalar rateWellNeg = 0.0; - std::array cartesianCoordinate; - for (auto& connection : well.getConnections()) { - - if (connection.state() == Connection::State::SHUT) - continue; - - cartesianCoordinate[0] = connection.getI(); - cartesianCoordinate[1] = connection.getJ(); - cartesianCoordinate[2] = connection.getK(); - const size_t cartIdx = simulator_.vanguard().cartesianIndex(cartesianCoordinate); - const int I = this->cartToGlobal_[cartIdx]; + for (auto& perfData : wellPtr->perforationData()) { + const int I = perfData.cell_index; Scalar rate = wellPtr->volumetricSurfaceRateForConnection(I, tr.phaseIdx_); if (rate < 0) { rateWellNeg += rate; @@ -490,7 +456,7 @@ protected: // Since oil or gas tracers appears in dual compositions when VAPOIL respectively DISGAS // is active, the template argument is intended to support future extension to these // scenarios by supplying an extended vector type. - + template struct TracerBatch { std::vector idx_; diff --git a/opm/simulators/wells/BlackoilWellModel.hpp b/opm/simulators/wells/BlackoilWellModel.hpp index a54b4401a..e3ffd3322 100644 --- a/opm/simulators/wells/BlackoilWellModel.hpp +++ b/opm/simulators/wells/BlackoilWellModel.hpp @@ -292,6 +292,12 @@ namespace Opm { void initGliftEclWellMap(GLiftEclWells &ecl_well_map); + /// \brief Get list of local nonshut wells + const std::vector& localNonshutWells() + { + return well_container_; + } + protected: Simulator& ebosSimulator_; diff --git a/opm/simulators/wells/WellInterfaceGeneric.cpp b/opm/simulators/wells/WellInterfaceGeneric.cpp index 2e426696b..7536bb6f5 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.cpp +++ b/opm/simulators/wells/WellInterfaceGeneric.cpp @@ -98,6 +98,11 @@ WellInterfaceGeneric::WellInterfaceGeneric(const Well& well, wsolvent_ = 0.0; } +const std::vector& WellInterfaceGeneric::perforationData() const +{ + return *perf_data_; +} + const std::string& WellInterfaceGeneric::name() const { return well_ecl_.name(); diff --git a/opm/simulators/wells/WellInterfaceGeneric.hpp b/opm/simulators/wells/WellInterfaceGeneric.hpp index a78e00f66..4fbc5efbd 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.hpp +++ b/opm/simulators/wells/WellInterfaceGeneric.hpp @@ -60,6 +60,9 @@ public: const int index_of_well, const std::vector& perf_data); + /// \brief Get the perforations of the well + const std::vector& perforationData() const; + /// Well name. const std::string& name() const;