ReservoirCouplingSlaveReportStep.hpp
Go to the documentation of this file.
1/*
2 Copyright 2025 Equinor ASA
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef OPM_RESERVOIR_COUPLING_SLAVE_REPORT_STEP_HPP
21#define OPM_RESERVOIR_COUPLING_SLAVE_REPORT_STEP_HPP
22
24#include <opm/input/eclipse/EclipseState/Phase.hpp>
25#include <opm/input/eclipse/Schedule/Group/Group.hpp>
26
27#include <map>
28#include <string>
29#include <utility>
30
31namespace Opm {
32
33// Avoid including the complete definition of ReservoirCouplingSlave here to avoid circular dependency.
34template <class Scalar> class ReservoirCouplingSlave;
35
54template <class Scalar>
56public:
64
69 );
70
73 const Parallel::Communication &comm() const { return this->slave_.getComm(); }
74
77 MPI_Comm getSlaveMasterComm() const { return this->slave_.getMasterComm(); }
78
83 bool hasMasterInjectionTarget(const std::string& gname, const Phase phase) const;
84
88 bool hasMasterGroupNodePressure(const std::string& gname) const;
89
93 bool hasMasterProductionLimits(const std::string& gname) const;
94
98 bool hasMasterProductionTarget(const std::string& gname) const;
99
105 bool isFirstSubstepOfSyncTimestep() const { return is_first_substep_of_sync_timestep_; }
106
114 bool isLastSubstepOfSyncTimestep() const { return is_last_substep_of_sync_timestep_; }
115
118 ReservoirCoupling::Logger& logger() const { return this->slave_.logger(); }
119
124 Scalar masterGroupNodePressure(const std::string& gname) const;
125
128 const std::map<std::string, Scalar>& masterGroupNodePressures() const
129 { return master_group_node_pressures_; }
130
136 std::pair<Scalar, Group::InjectionCMode> masterInjectionTarget(
137 const std::string& gname, const Phase phase) const;
138
143 const MasterProductionLimits& masterProductionLimits(const std::string& gname) const;
144
149 std::pair<Scalar, Group::ProductionCMode> masterProductionTarget(const std::string& gname) const;
150
155 void receiveMasterGroupNodePressuresFromMaster(std::size_t num_pressures);
156
160 std::pair<std::size_t, bool> receiveNumMasterGroupNodePressuresFromMaster();
161
169
177 { return last_received_master_group_node_pressures_is_final_; }
178
187 { return connected_to_master_coupled_network_; }
188
191 std::pair<std::size_t, std::size_t> receiveNumGroupConstraintsFromMaster() const;
192
195 void receiveInjectionGroupTargetsFromMaster(std::size_t num_targets);
196
199 void receiveProductionGroupConstraintsFromMaster(std::size_t num_targets);
200
211 void sendProductionDataToMaster(const std::vector<SlaveGroupProductionData> &production_data) const;
212
223 void sendInjectionDataToMaster(const std::vector<SlaveGroupInjectionData> &injection_data) const;
224
227 void setFirstSubstepOfSyncTimestep(bool value) { is_first_substep_of_sync_timestep_ = value; }
228
232 void setLastSubstepOfSyncTimestep(bool value) { is_last_substep_of_sync_timestep_ = value; }
233
240 void markSlaveGroupsInSchedule(Schedule& schedule, int report_step_idx);
241
244 const std::string& slaveName() const { return this->slave_.getSlaveName(); }
245
249 void setMasterGroupNodePressure(const std::string& gname, const Scalar pressure);
250
257 const std::string& gname, const Phase phase, const Scalar target, const Group::InjectionCMode cmode);
258
262 void setMasterProductionLimits(const std::string& gname, const MasterProductionLimits& limits);
263
268 void setMasterProductionTarget(const std::string& gname, const Scalar target, const Group::ProductionCMode cmode);
269
270
271private:
288 template <class DataType>
289 void sendDataToMaster_(
290 const std::vector<DataType>& data,
291 MessageTag tag,
292 const std::string& data_type_name
293 ) const;
294
297 // Flag to track if this is the first substep within a "sync" timestep.
298 // Used to control reservoir coupling synchronization.
299 bool is_first_substep_of_sync_timestep_{true};
300 // Flag to track if this is the last substep within a "sync" timestep.
301 // Used to control reservoir coupling synchronization of summary data sent from
302 // the slave to the master process.
303 bool is_last_substep_of_sync_timestep_{false};
304
305 // Master-imposed targets and corresponding control modes, received from the master
306 // process at the beginning of each sync timestep. Cleared and repopulated on every
307 // receive cycle. Used by GroupStateHelper to override slave group targets.
308 //
309 // Key: slave group name. Value: (target rate, production control mode).
310 std::map<std::string, std::pair<Scalar, Group::ProductionCMode>> master_production_targets_;
311 // Key: (injection phase, slave group name). Value: (target rate, injection control mode).
312 std::map<std::pair<Phase, std::string>, std::pair<Scalar, Group::InjectionCMode>> master_injection_targets_;
313 // Per-rate-type production limits from master hierarchy. Key: slave group name.
314 // A limit of -1 means no limit defined in the hierarchy for that rate type.
315 std::map<std::string, MasterProductionLimits> master_production_limits_;
316 // Master-computed network-leaf node pressures keyed by slave group name. Only
317 // populated for master groups that are leaf nodes in the master's extended
318 // network. Cleared and repopulated on every receive cycle.
319 std::map<std::string, Scalar> master_group_node_pressures_;
320 // Whether *this* slave is connected to the master's cross-rescoup network
321 // this sync step. Set once per sync step by
322 // receiveCoupledNetworkActiveStatusFromMaster() from the master's per-slave
323 // flag (BlackoilWellModelRescoup::masterNetworkHasMasterGroupLeavesForSlave_()).
324 // A slave that is not connected does not participate in the cross-rescoup
325 // exchange at all and balances only its own (local) network.
326 //
327 // This is deliberately separate from
328 // last_received_master_group_node_pressures_is_final_ below: connectivity is
329 // a per-sync-step property, whereas is_final is the per-iteration
330 // termination signal (only meaningful while connected).
331 bool connected_to_master_coupled_network_{false};
332 // The iteration-termination flag. Initialized for each sync step through:
333 // beginTimeStep() -> BlackoilWellModelRescoup::sendCoupledNetworkActiveStatus()
334 // to is_final = !connected (so an unconnected slave sees is_final = true and
335 // never enters the per-iteration receive). For a connected slave it then
336 // tracks the per-iteration is_final from the node-pressure header:
337 //
338 // In that case it is set to "true" in the course of the network iteration
339 // in BlackoilWellModel::assemble() -> BlackoilWellModel::updateWellControlsAndNetworkIteration()
340 // based on the "more_network_update" return value of BlackoilWellModelNetwork::update().
341 // If it returns "false" the flag is reset to "true" and stays true for the rest of the sync timestep.
342 //
343 // Connected slaves use this variable to determine when to exit the outer
344 // network loop such that the MPI master-slave communication protocol is kept in sync.
345 bool last_received_master_group_node_pressures_is_final_{true};
346};
347} // namespace Opm
348#endif // OPM_RESERVOIR_COUPLING_SLAVE_REPORT_STEP_HPP
Definition: ReservoirCoupling.hpp:42
Definition: ReservoirCouplingSlave.hpp:40
Manages slave-side reservoir coupling operations for a single report step.
Definition: ReservoirCouplingSlaveReportStep.hpp:55
MPI_Comm getSlaveMasterComm() const
Get the MPI communicator for slave-master communication.
Definition: ReservoirCouplingSlaveReportStep.hpp:77
const std::string & slaveName() const
Get the name of this slave process.
Definition: ReservoirCouplingSlaveReportStep.hpp:244
std::pair< Scalar, Group::ProductionCMode > masterProductionTarget(const std::string &gname) const
Get the master-imposed production target and control mode for a group.
void setMasterInjectionTarget(const std::string &gname, const Phase phase, const Scalar target, const Group::InjectionCMode cmode)
Store a master-imposed injection target for a group and phase.
void setMasterGroupNodePressure(const std::string &gname, const Scalar pressure)
Store a master-computed network-leaf node pressure for a master group.
bool hasMasterInjectionTarget(const std::string &gname, const Phase phase) const
Check if a master-imposed injection target exists for a group and phase.
void setFirstSubstepOfSyncTimestep(bool value)
Set whether this is the first substep within a "sync" timestep.
Definition: ReservoirCouplingSlaveReportStep.hpp:227
void receiveProductionGroupConstraintsFromMaster(std::size_t num_targets)
Receive production group constraints from master and store them locally.
const MasterProductionLimits & masterProductionLimits(const std::string &gname) const
Get the master-imposed per-rate-type production limits for a group.
void receiveMasterGroupNodePressuresFromMaster(std::size_t num_pressures)
Receive master-computed network-leaf node pressures from master and store them locally....
bool hasMasterProductionLimits(const std::string &gname) const
Check if master-imposed per-rate-type production limits exist for a group.
bool hasMasterGroupNodePressure(const std::string &gname) const
Check if a master-computed network-leaf node pressure exists for a master group.
const Parallel::Communication & comm() const
Get the MPI communicator for intra-slave communication.
Definition: ReservoirCouplingSlaveReportStep.hpp:73
std::pair< std::size_t, bool > receiveNumMasterGroupNodePressuresFromMaster()
Receive the master-group-node-pressures header from master.
bool lastReceivedMasterGroupNodePressuresIsFinal() const
Whether the most recent master-group-node-pressures receive carried the is_final flag....
Definition: ReservoirCouplingSlaveReportStep.hpp:176
void setLastSubstepOfSyncTimestep(bool value)
Set whether this is the last substep within a "sync" timestep.
Definition: ReservoirCouplingSlaveReportStep.hpp:232
void setMasterProductionTarget(const std::string &gname, const Scalar target, const Group::ProductionCMode cmode)
Store a master-imposed production target for a group.
const std::map< std::string, Scalar > & masterGroupNodePressures() const
Get the full map of master-computed network-leaf node pressures.
Definition: ReservoirCouplingSlaveReportStep.hpp:128
bool isLastSubstepOfSyncTimestep() const
Check if this is the last substep within a "sync" timestep.
Definition: ReservoirCouplingSlaveReportStep.hpp:114
Scalar masterGroupNodePressure(const std::string &gname) const
Get the master-computed network-leaf node pressure for a master group.
void receiveCoupledNetworkActiveStatusFromMaster()
Receive the master's single-bool flag for the current sync timestep and mirror it into last_received_...
ReservoirCoupling::Logger & logger() const
Get the logger for reservoir coupling operations.
Definition: ReservoirCouplingSlaveReportStep.hpp:118
void sendProductionDataToMaster(const std::vector< SlaveGroupProductionData > &production_data) const
Send production data to the master process.
std::pair< Scalar, Group::InjectionCMode > masterInjectionTarget(const std::string &gname, const Phase phase) const
Get the master-imposed injection target and control mode for a group and phase.
bool hasMasterProductionTarget(const std::string &gname) const
Check if a master-imposed production target exists for a group.
std::pair< std::size_t, std::size_t > receiveNumGroupConstraintsFromMaster() const
Receive the number of injection and production constraints from master.
bool connectedToMasterCoupledNetwork() const
Whether this slave is connected to the master's cross-rescoup network this sync step (i....
Definition: ReservoirCouplingSlaveReportStep.hpp:186
void sendInjectionDataToMaster(const std::vector< SlaveGroupInjectionData > &injection_data) const
Send injection data to the master process.
void receiveInjectionGroupTargetsFromMaster(std::size_t num_targets)
Receive injection group targets from master and store them locally.
ReservoirCouplingSlaveReportStep(ReservoirCouplingSlave< Scalar > &slave)
Construct a report step manager for the slave process.
bool isFirstSubstepOfSyncTimestep() const
Check if this is the first substep within a "sync" timestep.
Definition: ReservoirCouplingSlaveReportStep.hpp:105
void setMasterProductionLimits(const std::string &gname, const MasterProductionLimits &limits)
Store master-imposed per-rate-type production limits for a group.
void markSlaveGroupsInSchedule(Schedule &schedule, int report_step_idx)
Mark slave groups in the Schedule as production/injection groups.
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
MessageTag
Definition: ReservoirCoupling.hpp:134
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:159
Definition: blackoilbioeffectsmodules.hh:45
Definition: ReservoirCoupling.hpp:238
Master-computed network-leaf node pressure for a single master group.
Definition: ReservoirCoupling.hpp:281
Per-rate-type production limits received from master hierarchy. A value of -1 means no limit defined ...
Definition: ReservoirCoupling.hpp:266
Definition: ReservoirCoupling.hpp:248
Definition: ReservoirCoupling.hpp:232
Definition: ReservoirCoupling.hpp:214