ReservoirCouplingSlave.hpp
Go to the documentation of this file.
1/*
2 Copyright 2024 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_HPP
21#define OPM_RESERVOIR_COUPLING_SLAVE_HPP
22
25#include <opm/input/eclipse/Schedule/Schedule.hpp>
28#include <opm/common/OpmLog/OpmLog.hpp>
29
30#include <mpi.h>
31
32#include <vector>
33
34namespace Opm {
35
36template <class Scalar>
37class ReservoirCouplingSlaveReportStep;
38
39template <class Scalar>
41public:
50
52 const Parallel::Communication &comm, const Schedule &schedule, const SimulatorTimer &timer
53 );
54 bool activated() const { return activated_; }
60 const std::map<std::string, std::map<Phase, Scalar>>& effectiveInjectionTargets() const
61 { return effective_injection_targets_; }
62 std::map<std::string, std::map<Phase, Scalar>>& effectiveInjectionTargets()
63 { return effective_injection_targets_; }
69 const std::map<std::string, std::map<Group::ProductionCMode, Scalar>>& effectiveProductionTargets() const
70 { return effective_production_targets_; }
71 std::map<std::string, std::map<Group::ProductionCMode, Scalar>>& effectiveProductionTargets()
72 { return effective_production_targets_; }
73
74 const Parallel::Communication& getComm() const { return comm_; }
75 MPI_Comm getMasterComm() const { return slave_master_comm_; }
76 const std::string& getSlaveName() const { return slave_name_; }
77 const std::map<std::string, std::string>& getSlaveToMasterGroupNameMap() const {
78 return slave_to_master_group_map_; }
81 bool hasMasterGroupNodePressure(const std::string& gname) const;
82
85 bool hasMasterInjectionTarget(const std::string& gname, const Phase phase) const;
86
89 bool hasMasterProductionLimits(const std::string& gname) const;
90
93 bool hasMasterProductionTarget(const std::string& gname) const;
104 bool isSlaveGroup(const std::string& group_name) const;
105
110
115
116 ReservoirCoupling::Logger& logger() { return this->logger_; }
117 ReservoirCoupling::Logger& logger() const { return this->logger_; }
120 Scalar masterGroupNodePressure(const std::string& gname) const;
121
124 const std::map<std::string, Scalar>& masterGroupNodePressures() const;
125
128 std::pair<Scalar, Group::InjectionCMode> masterInjectionTarget(
129 const std::string& gname, const Phase phase) const;
130
133 const MasterProductionLimits& masterProductionLimits(const std::string& gname) const;
134
137 std::pair<Scalar, Group::ProductionCMode> masterProductionTarget(const std::string& gname) const;
138 void maybeActivate(int report_step);
139 std::size_t numSlaveGroups() const { return this->slave_group_order_.size(); }
147 std::pair<std::size_t, std::size_t> receiveNumGroupConstraintsFromMaster() const;
150 void receiveInjectionGroupTargetsFromMaster(std::size_t num_targets);
151
154 void receiveMasterGroupNodePressuresFromMaster(std::size_t num_pressures);
155
159 std::pair<std::size_t, bool> receiveNumMasterGroupNodePressuresFromMaster();
160
163 void receiveProductionGroupConstraintsFromMaster(std::size_t num_targets);
164
166 void sendInjectionDataToMaster(const std::vector<SlaveGroupInjectionData> &injection_data) const;
168 void sendProductionDataToMaster(const std::vector<SlaveGroupProductionData> &production_data) const;
169 void setDeferredLogger(DeferredLogger *deferred_logger) {
170 this->logger_.setDeferredLogger(deferred_logger);
171 }
177
180 void markSlaveGroupsInSchedule(Schedule& schedule, int report_step_idx);
181
185
186 const std::string& slaveGroupIdxToGroupName(std::size_t group_idx) const {
187 return this->slave_group_order_.at(group_idx);
188 }
189 bool terminated() const { return this->terminated_; }
190
200
221
225
226private:
227 void checkGrupSlavGroupNames_();
228 std::pair<double, bool> getGrupSlavActivationDateAndCheckHistoryMatchingMode_() const;
229 bool historyMatchingMode_() const { return this->history_matching_mode_; }
230
231 std::size_t numMasterGroups_() const { return this->slave_to_master_group_map_.size(); }
238 void receiveInitStatusFromMasterProcess_();
239 void receiveMasterGroupNamesFromMasterProcess_();
240 void receiveSlaveNameFromMasterProcess_();
241 void saveMasterGroupNamesAsMapAndEstablishOrder_(const std::vector<char>& group_names);
242 void sendActivationDateToMasterProcess_();
243 void sendActivationHandshakeToMasterProcess_() const;
244 void sendSimulationStartDateToMasterProcess_() const;
245 void sendStatusToMasterProcess_(bool ok);
246
247 const Parallel::Communication &comm_;
248 const Schedule& schedule_;
249 const SimulatorTimer &timer_;
250 // MPI parent communicator for a slave process
251 MPI_Comm slave_master_comm_{MPI_COMM_NULL};
252 std::map<std::string, std::string> slave_to_master_group_map_;
253 bool activated_{false};
254 // True if the slave was terminated by the master process
255 bool terminated_{false};
256 // True if no GRUPMAST keyword in the master schedule and no GRUPSLAV keyword in the slave schedule
257 bool history_matching_mode_{false};
258 std::string slave_name_; // This is the slave name as defined in the master process
259 mutable ReservoirCoupling::Logger logger_;
260 // Order of the slave groups. A mapping from slave group index to slave group name.
261 // The indices are determined by the order the master process sends us the group names, see
262 // receiveMasterGroupNamesFromMasterProcess_()
263 // Later, the master process will send us group name indices, and not the group names themselves,
264 // so we use this mapping to recover the slave group names from the indices.
265 std::map<std::size_t, std::string> slave_group_order_;
266 // See effectiveInjectionTargets().
267 std::map<std::string, std::map<Phase, Scalar>> effective_injection_targets_;
268 // See effectiveProductionTargets().
269 std::map<std::string, std::map<Group::ProductionCMode, Scalar>> effective_production_targets_;
270 // Stores data that changes for a single report step or for timesteps within a report step.
271 std::unique_ptr<ReservoirCouplingSlaveReportStep<Scalar>> report_step_data_{nullptr};
272};
273
274} // namespace Opm
275
276#endif // OPM_RESERVOIR_COUPLING_SLAVE_HPP
Definition: DeferredLogger.hpp:57
Definition: ReservoirCoupling.hpp:42
void setDeferredLogger(DeferredLogger *deferred_logger)
Definition: ReservoirCoupling.hpp:55
void clearDeferredLogger()
Definition: ReservoirCoupling.hpp:47
Definition: ReservoirCouplingSlave.hpp:40
const std::map< std::string, std::string > & getSlaveToMasterGroupNameMap() const
Definition: ReservoirCouplingSlave.hpp:77
ReservoirCouplingSlave(const Parallel::Communication &comm, const Schedule &schedule, const SimulatorTimer &timer)
void notifyEndOfRunAndDisconnect()
Wind up the coupling after the slave has run out of report steps of its own.
const std::string & getSlaveName() const
Definition: ReservoirCouplingSlave.hpp:76
void setFirstSubstepOfSyncTimestep(bool value)
bool lastReceivedMasterGroupNodePressuresIsFinal() const
Whether the most recent master-group-node-pressures receive carried the is_final flag.
Scalar masterGroupNodePressure(const std::string &gname) const
Get the master-computed network-leaf node pressure for a master group.
void sendProductionDataToMaster(const std::vector< SlaveGroupProductionData > &production_data) const
std::size_t numSlaveGroups() const
Definition: ReservoirCouplingSlave.hpp:139
bool isFirstSubstepOfSyncTimestep() const
std::pair< Scalar, Group::ProductionCMode > masterProductionTarget(const std::string &gname) const
Get the master-imposed production target and control mode for a group.
const Parallel::Communication & getComm() const
Definition: ReservoirCouplingSlave.hpp:74
bool isSlaveGroup(const std::string &group_name) const
std::pair< std::size_t, bool > receiveNumMasterGroupNodePressuresFromMaster()
Receive the master-group-node-pressures header from master.
void receiveCoupledNetworkActiveStatusFromMaster()
Receive the master's single-bool flag for the current sync timestep and mirror it into the slave's lo...
std::pair< std::size_t, std::size_t > receiveNumGroupConstraintsFromMaster() const
const MasterProductionLimits & masterProductionLimits(const std::string &gname) const
Get the master-imposed per-rate-type production limits for a group.
void receiveInjectionGroupTargetsFromMaster(std::size_t num_targets)
Receive injection group targets from master and store them locally.
void receiveProductionGroupConstraintsFromMaster(std::size_t num_targets)
Receive production group constraints from master and store them locally.
bool connectedToMasterCoupledNetwork() const
Whether this slave is connected to the master's cross-rescoup network this sync step.
bool isLastSubstepOfSyncTimestep() const
Check if this is the last substep within a "sync" timestep.
void setDeferredLogger(DeferredLogger *deferred_logger)
Definition: ReservoirCouplingSlave.hpp:169
MPI_Comm getMasterComm() const
Definition: ReservoirCouplingSlave.hpp:75
void clearDeferredLogger()
Definition: ReservoirCouplingSlave.hpp:55
bool hasMasterInjectionTarget(const std::string &gname, const Phase phase) const
Check if a master-imposed injection target exists for a group and phase.
const std::map< std::string, Scalar > & masterGroupNodePressures() const
Get the full map of master-computed network-leaf node pressures.
const std::map< std::string, std::map< Phase, Scalar > > & effectiveInjectionTargets() const
The surface injection rate target in force for each slave group and phase this sync step (SI): the ma...
Definition: ReservoirCouplingSlave.hpp:60
void sendNextReportDateToMasterProcess() const
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 wellsSolvedThisSyncStep() const
True once the initial well solve for this sync step has run.
ReservoirCoupling::Logger & logger()
Definition: ReservoirCouplingSlave.hpp:116
bool maybeReceiveTerminateSignalFromMaster()
Blocking receive for terminate/continue signal from master.
bool hasMasterGroupNodePressure(const std::string &gname) const
Check if a master-computed network-leaf node pressure exists for a master group.
const std::string & slaveGroupIdxToGroupName(std::size_t group_idx) const
Definition: ReservoirCouplingSlave.hpp:186
bool terminated() const
Definition: ReservoirCouplingSlave.hpp:189
void sendInjectionDataToMaster(const std::vector< SlaveGroupInjectionData > &injection_data) const
bool hasMasterProductionTarget(const std::string &gname) const
Check if a master-imposed production target exists for a group.
bool activated() const
Definition: ReservoirCouplingSlave.hpp:54
ReservoirCoupling::Logger & logger() const
Definition: ReservoirCouplingSlave.hpp:117
void setLastSubstepOfSyncTimestep(bool value)
Set whether this is the last substep within a "sync" timestep.
std::map< std::string, std::map< Phase, Scalar > > & effectiveInjectionTargets()
Definition: ReservoirCouplingSlave.hpp:62
void maybeActivate(int report_step)
bool hasMasterProductionLimits(const std::string &gname) const
Check if master-imposed per-rate-type production limits exist for a group.
void setWellsSolvedThisSyncStep(bool value)
Record whether the initial well solve for this sync step has run.
const std::map< std::string, std::map< Group::ProductionCMode, Scalar > > & effectiveProductionTargets() const
The production rate limit in force for each slave group and rate type (ORAT, WRAT,...
Definition: ReservoirCouplingSlave.hpp:69
std::map< std::string, std::map< Group::ProductionCMode, Scalar > > & effectiveProductionTargets()
Definition: ReservoirCouplingSlave.hpp:71
void receiveMasterGroupNodePressuresFromMaster(std::size_t num_pressures)
Receive master-computed network-leaf node pressures from master.
void markSlaveGroupsInSchedule(Schedule &schedule, int report_step_idx)
Mark slave groups in the Schedule as production/injection groups.
typename ReservoirCoupling::MasterProductionLimits< Scalar > MasterProductionLimits
Definition: ReservoirCouplingSlave.hpp:48
Definition: SimulatorTimer.hpp:38
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
MessageTag
Definition: ReservoirCoupling.hpp:138
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:183
Definition: blackoilbioeffectsmodules.hh:45
Definition: ReservoirCoupling.hpp:286
Master-computed network-leaf node pressure for a single master group.
Definition: ReservoirCoupling.hpp:329
Per-rate-type production limits received from master hierarchy. A value of -1 means no limit defined ...
Definition: ReservoirCoupling.hpp:314
Definition: ReservoirCoupling.hpp:214
Definition: ReservoirCoupling.hpp:296
Definition: ReservoirCoupling.hpp:271
Definition: ReservoirCoupling.hpp:238