From 6bd6c7a8727ccfae866819dd2e0dc6c0740064b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20H=C3=A6gland?= Date: Thu, 12 Jun 2025 10:08:51 +0200 Subject: [PATCH] Store group potentials in GroupState Store the group potentials in the GroupState object so we avoid recomputing them later when we need to send the slave group potentials to the master. --- .../wells/BlackoilWellModel_impl.hpp | 2 +- opm/simulators/wells/GroupState.cpp | 17 ++++++++++++++++ opm/simulators/wells/GroupState.hpp | 14 +++++++++++++ opm/simulators/wells/GuideRateHandler.cpp | 20 +++++++++++++------ opm/simulators/wells/GuideRateHandler.hpp | 6 +++--- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 06b38761bf..7a2142fd9b 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -475,7 +475,7 @@ namespace Opm { ); #ifdef RESERVOIR_COUPLING_ENABLED if (this->isReservoirCouplingSlave()) { - this->guide_rate_handler_.sendSlaveGroupPotentialsToMaster(); + this->guide_rate_handler_.sendSlaveGroupPotentialsToMaster(this->groupState()); } #endif std::string exc_msg; diff --git a/opm/simulators/wells/GroupState.cpp b/opm/simulators/wells/GroupState.cpp index 73643c69af..439da83e77 100644 --- a/opm/simulators/wells/GroupState.cpp +++ b/opm/simulators/wells/GroupState.cpp @@ -509,6 +509,23 @@ gconsump_rates(const std::string& gname) const { return zero_pair; } +template +void GroupState:: +update_group_production_potential(const std::string& gname, Scalar oil_rate, + Scalar gas_rate, Scalar water_rate) +{ + this->production_group_potentials.emplace( + gname, GroupPotential{oil_rate, gas_rate, water_rate} + ); +} + +template +const typename GroupState::GroupPotential& +GroupState:: +get_production_group_potential(const std::string& gname) const +{ + return this->production_group_potentials.at(gname); +} template class GroupState; diff --git a/opm/simulators/wells/GroupState.hpp b/opm/simulators/wells/GroupState.hpp index 2e5da37ee5..729379f99b 100644 --- a/opm/simulators/wells/GroupState.hpp +++ b/opm/simulators/wells/GroupState.hpp @@ -107,6 +107,19 @@ public: void update_gconsump(const Schedule& schedule, const int report_step, const SummaryState& summary_state); const std::pair& gconsump_rates(const std::string& gname) const; + struct GroupPotential { + Scalar oil_rate; + Scalar gas_rate; + Scalar water_rate; + + GroupPotential(Scalar oil = 0.0, Scalar gas = 0.0, Scalar water = 0.0) + : oil_rate(oil), gas_rate(gas), water_rate(water) {} + }; + + void update_group_production_potential( + const std::string& gname, Scalar oil_rate, Scalar gas_rate, Scalar water_rate + ); + const GroupPotential& get_production_group_potential(const std::string& gname) const; std::size_t data_size() const; std::size_t collect(Scalar* data) const; @@ -220,6 +233,7 @@ private: std::map m_grat_sales_target; std::map m_gpmaint_target; std::map group_thp; + std::map production_group_potentials; std::map, Group::InjectionCMode> injection_controls; WellContainer gpmaint_state; diff --git a/opm/simulators/wells/GuideRateHandler.cpp b/opm/simulators/wells/GuideRateHandler.cpp index 38153dc363..98b11e2308 100644 --- a/opm/simulators/wells/GuideRateHandler.cpp +++ b/opm/simulators/wells/GuideRateHandler.cpp @@ -108,7 +108,7 @@ receiveMasterGroupPotentialsFromSlaves() template void GuideRateHandler:: -sendSlaveGroupPotentialsToMaster() +sendSlaveGroupPotentialsToMaster(const GroupState& group_state) { assert(this->isReservoirCouplingSlave()); auto& rescoup_slave = this->reservoirCouplingSlave(); @@ -124,10 +124,10 @@ sendSlaveGroupPotentialsToMaster() // For injection groups, we do not have potentials. In that case, // we will send dummy values (0.0) for the potentials. if (this->guide_rate_.hasPotentials(slave_group_name)) { - const auto& gr_pot = this->guide_rate_.getPotentials(slave_group_name); - pot[Potentials::Phase::Oil] = gr_pot.oil_rat; - pot[Potentials::Phase::Gas] = gr_pot.gas_rat; - pot[Potentials::Phase::Water] = gr_pot.wat_rat; + const auto& gr_pot = group_state.get_production_group_potential(slave_group_name); + pot[Potentials::Phase::Oil] = gr_pot.oil_rate; + pot[Potentials::Phase::Gas] = gr_pot.gas_rate; + pot[Potentials::Phase::Water] = gr_pot.water_rate; } potentials.push_back(pot); } @@ -444,7 +444,7 @@ UpdateGuideRates( const int report_step_idx, const double sim_time, const WellState& well_state, - const GroupState& group_state, + GroupState& group_state, const int num_phases ) : parent_{parent} , report_step_idx_{report_step_idx} @@ -609,6 +609,14 @@ updateGuideRatesForProductionGroups_(const Group& group, std::vector& po this->guideRate().compute( group.name(), this->report_step_idx_, this->sim_time_, oil_pot, gas_pot, water_pot ); + // NOTE: For reservoir coupling: We will later need to send the slave group potentials + // to the master. The above call to GuideRate::compute() will as a side-effect store + // them in the GuideRate object. But those potentials are meant to be internal to the + // GuideRate object, so we choose to store the potentials in the GroupState object + // below for this reason. + this->group_state_.update_group_production_potential( + group.name(), oil_pot, gas_pot, water_pot + ); } template diff --git a/opm/simulators/wells/GuideRateHandler.hpp b/opm/simulators/wells/GuideRateHandler.hpp index 2813ca1ddc..0c81e17166 100644 --- a/opm/simulators/wells/GuideRateHandler.hpp +++ b/opm/simulators/wells/GuideRateHandler.hpp @@ -88,7 +88,7 @@ public: const int report_step_idx, const double sim_time, const WellState &well_state, - const GroupState &group_state, + GroupState &group_state, const int num_phases ); @@ -124,7 +124,7 @@ public: const int report_step_idx_; const double sim_time_; const WellState &well_state_; - const GroupState &group_state_; + GroupState &group_state_; const int num_phases_; const UnitSystem& unit_system_; }; @@ -146,7 +146,7 @@ public: void receiveMasterGroupPotentialsFromSlaves(); ReservoirCouplingMaster& reservoirCouplingMaster() { return *(this->reservoir_coupling_master_); } ReservoirCouplingSlave& reservoirCouplingSlave() { return *(this->reservoir_coupling_slave_); } - void sendSlaveGroupPotentialsToMaster(); + void sendSlaveGroupPotentialsToMaster(const GroupState& group_state); void setReservoirCouplingMaster(ReservoirCouplingMaster *reservoir_coupling_master) { this->reservoir_coupling_master_ = reservoir_coupling_master; }