From 15116bf2a9ba83b95ad87c4a1c636b9e3acf3554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 12 May 2021 12:16:20 +0200 Subject: [PATCH] Reduce Aquifer Data Copying This commit switches to using 'map<>::insert_or_assign()' as the primary interface for collecting dynamic aquifer data. In turn, this activates move semantics for the substructures and reduces the number of times the data is copied. Insert_or_assign requires the key, so provide this value--i.e., the aquifer ID--as part of the AquiferInterface. --- .../aquifers/AquiferCarterTracy.hpp | 5 +- opm/simulators/aquifers/AquiferFetkovich.hpp | 20 ++++--- opm/simulators/aquifers/AquiferInterface.hpp | 60 +++++++++++-------- opm/simulators/aquifers/AquiferNumerical.hpp | 5 ++ .../aquifers/BlackoilAquiferModel_impl.hpp | 13 ++-- 5 files changed, 59 insertions(+), 44 deletions(-) diff --git a/opm/simulators/aquifers/AquiferCarterTracy.hpp b/opm/simulators/aquifers/AquiferCarterTracy.hpp index 71e63f7c9..8d6dc3773 100644 --- a/opm/simulators/aquifers/AquiferCarterTracy.hpp +++ b/opm/simulators/aquifers/AquiferCarterTracy.hpp @@ -57,8 +57,7 @@ public: const AquiferCT::AQUCT_data& aquct_data) : Base(aquct_data.aquiferID, connections, ebosSimulator) , aquct_data_(aquct_data) - { - } + {} void endTimeStep() override { @@ -73,7 +72,7 @@ public: data::AquiferData aquiferData() const { data::AquiferData data; - data.aquiferID = this->aquiferID; + data.aquiferID = this->aquiferID(); // TODO: not sure how to get this pressure value yet data.pressure = this->pa0_; data.fluxRate = 0.; diff --git a/opm/simulators/aquifers/AquiferFetkovich.hpp b/opm/simulators/aquifers/AquiferFetkovich.hpp index 381872de8..844d3aa6f 100644 --- a/opm/simulators/aquifers/AquiferFetkovich.hpp +++ b/opm/simulators/aquifers/AquiferFetkovich.hpp @@ -71,13 +71,15 @@ public: data::AquiferData aquiferData() const { // TODO: how to unify the two functions? - data::AquiferData data; - data.aquiferID = this->aquiferID; + auto data = data::AquiferData{}; + + data.aquiferID = this->aquiferID(); data.pressure = this->aquifer_pressure_; - data.fluxRate = 0.; - for (const auto& q : this->Qai_) { - data.fluxRate += q.value(); - } + data.fluxRate = std::accumulate(this->Qai_.begin(), this->Qai_.end(), 0.0, + [](const double flux, const auto& q) -> double + { + return flux + q.value(); + }); data.volume = this->W_flux_.value(); data.initPressure = this->pa0_; data.type = data::AquiferType::Fetkovich; @@ -95,8 +97,10 @@ protected: void assignRestartData(const data::AquiferData& xaq) override { if (xaq.type != data::AquiferType::Fetkovich) { - throw std::invalid_argument {"Analytic aquifer data for unexpected aquifer type " - "passed to Fetkovich aquifer"}; + throw std::invalid_argument { + "Analytic aquifer data for unexpected aquifer " + "type passed to Fetkovich aquifer" + }; } this->aquifer_pressure_ = xaq.pressure; diff --git a/opm/simulators/aquifers/AquiferInterface.hpp b/opm/simulators/aquifers/AquiferInterface.hpp index d292e1429..a26431079 100644 --- a/opm/simulators/aquifers/AquiferInterface.hpp +++ b/opm/simulators/aquifers/AquiferInterface.hpp @@ -77,13 +77,13 @@ public: AquiferInterface(int aqID, const std::vector& connections, const Simulator& ebosSimulator) - : aquiferID(aqID) + : aquiferID_(aqID) , connections_(connections) , ebos_simulator_(ebosSimulator) { } - // Deconstructor + // Destructor virtual ~AquiferInterface() { } @@ -92,7 +92,7 @@ public: { auto xaqPos = std::find_if(aquiferSoln.begin(), aquiferSoln.end(), [this](const data::AquiferData& xaq) -> bool { - return xaq.aquiferID == this->aquiferID; + return xaq.aquiferID == this->aquiferID(); }); if (xaqPos == aquiferSoln.end()) @@ -119,8 +119,8 @@ public: elemCtx.updatePrimaryStencil(elem); - int cellIdx = elemCtx.globalSpaceIndex(0, 0); - int idx = cellToConnectionIdx_[cellIdx]; + const int cellIdx = elemCtx.globalSpaceIndex(0, 0); + const int idx = cellToConnectionIdx_[cellIdx]; if (idx < 0) continue; @@ -131,30 +131,36 @@ public: } template - void addToSource(RateVector& rates, const Context& context, unsigned spaceIdx, unsigned timeIdx) + void addToSource(RateVector& rates, + const Context& context, + const unsigned spaceIdx, + const unsigned timeIdx) { - unsigned cellIdx = context.globalSpaceIndex(spaceIdx, timeIdx); + const unsigned cellIdx = context.globalSpaceIndex(spaceIdx, timeIdx); - int idx = cellToConnectionIdx_[cellIdx]; + const int idx = this->cellToConnectionIdx_[cellIdx]; if (idx < 0) return; - // We are dereferencing the value of IntensiveQuantities because cachedIntensiveQuantities return a const - // pointer to IntensiveQuantities of that particular cell_id - const IntensiveQuantities intQuants = context.intensiveQuantities(spaceIdx, timeIdx); - // This is the pressure at td + dt - updateCellPressure(pressure_current_, idx, intQuants); - updateCellDensity(idx, intQuants); - calculateInflowRate(idx, context.simulator()); - rates[BlackoilIndices::conti0EqIdx + FluidSystem::waterCompIdx] - += Qai_[idx] / context.dofVolume(spaceIdx, timeIdx); - } + // We are dereferencing the value of IntensiveQuantities because + // cachedIntensiveQuantities return a const pointer to + // IntensiveQuantities of that particular cell_id + const auto& intQuants = context.intensiveQuantities(spaceIdx, timeIdx); + // This is the pressure at td + dt + this->updateCellPressure(this->pressure_current_, idx, intQuants); + this->updateCellDensity(idx, intQuants); + this->calculateInflowRate(idx, context.simulator()); + + rates[BlackoilIndices::conti0EqIdx + FluidSystem::waterCompIdx] + += this->Qai_[idx] / context.dofVolume(spaceIdx, timeIdx); + } std::size_t size() const { return this->connections_.size(); } + int aquiferID() const { return this->aquiferID_; } protected: inline Scalar gravity_() const @@ -203,13 +209,14 @@ protected: virtual void endTimeStep() = 0; - const int aquiferID; + const int aquiferID_{}; const std::vector connections_; const Simulator& ebos_simulator_; // Grid variables std::vector faceArea_connected_; std::vector cellToConnectionIdx_; + // Quantities at each grid id std::vector cell_depth_; std::vector pressure_previous_; @@ -218,8 +225,8 @@ protected: std::vector rhow_; std::vector alphai_; - Scalar Tc_; // Time constant - Scalar pa0_; // initial aquifer pressure + Scalar Tc_{}; // Time constant + Scalar pa0_{}; // initial aquifer pressure Eval W_flux_; @@ -345,8 +352,8 @@ protected: const auto& elem = *elemIt; elemCtx.updatePrimaryStencil(elem); - size_t cellIdx = elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0); - int idx = this->cellToConnectionIdx_[cellIdx]; + const auto cellIdx = elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0); + const auto idx = this->cellToConnectionIdx_[cellIdx]; if (idx < 0) continue; @@ -364,10 +371,13 @@ protected: // We take the average of the calculated equilibrium pressures. const auto& comm = ebos_simulator_.vanguard().grid().comm(); + Scalar vals[2]; - vals[0] = std::accumulate(this->alphai_.begin(), this->alphai_.end(), 0.); - vals[1] = std::accumulate(pw_aquifer.begin(), pw_aquifer.end(), 0.); + vals[0] = std::accumulate(this->alphai_.begin(), this->alphai_.end(), 0.0); + vals[1] = std::accumulate(pw_aquifer.begin(), pw_aquifer.end(), 0.0); + comm.sum(vals, 2); + return vals[1] / vals[0]; } diff --git a/opm/simulators/aquifers/AquiferNumerical.hpp b/opm/simulators/aquifers/AquiferNumerical.hpp index 2387ff3f7..e52f11130 100644 --- a/opm/simulators/aquifers/AquiferNumerical.hpp +++ b/opm/simulators/aquifers/AquiferNumerical.hpp @@ -104,6 +104,11 @@ public: this->cumulative_flux_ = 0.; } + int aquiferID() const + { + return static_cast(this->id_); + } + private: const size_t id_; const Simulator& ebos_simulator_; diff --git a/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp b/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp index 2f8673320..0aea20558 100644 --- a/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp +++ b/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp @@ -237,23 +237,20 @@ template data::Aquifers BlackoilAquiferModel::aquiferData() const { data::Aquifers data; if (this->aquiferCarterTracyActive()) { - for (const auto& aqu : aquifers_CarterTracy) { - data::AquiferData aqu_data = aqu.aquiferData(); - data[aqu_data.aquiferID] = aqu_data; + for (const auto& aqu : this->aquifers_CarterTracy) { + data.insert_or_assign(aqu.aquiferID(), aqu.aquiferData()); } } if (this->aquiferFetkovichActive()) { - for (const auto& aqu : aquifers_Fetkovich) { - data::AquiferData aqu_data = aqu.aquiferData(); - data[aqu_data.aquiferID] = aqu_data; + for (const auto& aqu : this->aquifers_Fetkovich) { + data.insert_or_assign(aqu.aquiferID(), aqu.aquiferData()); } } if (this->aquiferNumericalActive()) { for (const auto& aqu : this->aquifers_numerical) { - data::AquiferData aqu_data = aqu.aquiferData(); - data[aqu_data.aquiferID] = aqu_data; + data.insert_or_assign(aqu.aquiferID(), aqu.aquiferData()); } }