20#ifndef OPM_BLACKOILWELLMODEL_RESCOUP_IMPL_HEADER_INCLUDED
21#define OPM_BLACKOILWELLMODEL_RESCOUP_IMPL_HEADER_INCLUDED
24#ifndef OPM_BLACKOILWELLMODEL_RESCOUP_HEADER_INCLUDED
29#ifdef RESERVOIR_COUPLING_ENABLED
31#include <opm/common/TimingMacros.hpp>
45template<
typename TypeTag>
46BlackoilWellModelRescoup<TypeTag>::
47BlackoilWellModelRescoup(BlackoilWellModel<TypeTag>& well_model)
48 : well_model_{well_model}
49 , network_{well_model.network()}
50 , simulator_{well_model.simulator()}
51 , param_{well_model.param()}
57template<
typename TypeTag>
59BlackoilWellModelRescoup<TypeTag>::
60masterIsInCoupledNetworkIteration()
const
62 return this->isReservoirCouplingMaster()
63 && this->reservoirCouplingMaster().isFirstSubstepOfSyncTimestep()
64 && this->masterNetworkHasMasterGroupLeaves()
65 && !this->lastSentMasterGroupNodePressuresIsFinal();
69template<
typename TypeTag>
71BlackoilWellModelRescoup<TypeTag>::
72masterNetworkHasMasterGroupLeaves()
const
77 if (!this->isReservoirCouplingMaster())
return false;
78 const auto& rcm = this->reservoirCouplingMaster();
79 const auto num_slaves = rcm.numSlaves();
80 for (std::size_t s = 0; s < num_slaves; ++s) {
81 if (!rcm.slaveIsActivated(s))
continue;
82 if (this->masterNetworkHasMasterGroupLeavesForSlave_(s)) {
89template<
typename TypeTag>
91BlackoilWellModelRescoup<TypeTag>::
92maybeExchangeNetworkOuterIterationWithSlaves(
bool more_network_update)
94 if (!this->masterIsInCoupledNetworkIteration()) {
97 const bool is_final = !more_network_update;
106 if (is_final || !this->well_model_.useTightRcNetworkCoupling()) {
108 this->sendMasterGroupNodePressuresToSlaves(is_final);
111 this->receiveSlaveGroupData();
116template<
typename TypeTag>
118BlackoilWellModelRescoup<TypeTag>::
119maybeExchangeNetworkSubIterationWithSlaves()
139 if (!this->well_model_.useTightRcNetworkCoupling()) {
142 if (!this->masterIsInCoupledNetworkIteration()) {
145 this->sendMasterGroupNodePressuresToSlaves(
false);
146 this->receiveSlaveGroupData();
149template<
typename TypeTag>
151BlackoilWellModelRescoup<TypeTag>::
152receiveCoupledNetworkActiveStatus()
155 assert(this->isReservoirCouplingSlave());
156 this->reservoirCouplingSlave().receiveCoupledNetworkActiveStatusFromMaster();
159template<
typename TypeTag>
161BlackoilWellModelRescoup<TypeTag>::
162receiveGroupConstraintsFromMaster()
165 RescoupReceiveGroupConstraints<Scalar, IndexTraits> constraint_receiver{
166 this->well_model_.guideRateHandler(),
167 this->groupStateHelper()
169 constraint_receiver.receiveGroupConstraintsFromMaster();
172template<
typename TypeTag>
174BlackoilWellModelRescoup<TypeTag>::
175receiveMasterGroupNodePressuresFromMaster()
178 assert(this->isReservoirCouplingSlave());
179 auto& rescoup_slave = this->reservoirCouplingSlave();
180 const auto [num_pressures, _is_final] =
181 rescoup_slave.receiveNumMasterGroupNodePressuresFromMaster();
182 if (num_pressures > 0) {
183 rescoup_slave.receiveMasterGroupNodePressuresFromMaster(num_pressures);
209 const auto& pressures = rescoup_slave.masterGroupNodePressures();
210 if (pressures.empty())
return;
211 const auto& summary_state = this->well_model_.summaryState();
212 auto& well_state = this->wellState();
213 for (
auto& well : this->wellContainer()) {
214 if (!well->isProducer() || !well->wellEcl().predictionMode())
continue;
215 const auto it = pressures.find(well->wellEcl().groupName());
216 if (it == pressures.end())
continue;
217 well->setDynamicThpLimit(it->second);
218 auto& ws = well_state[well->indexOfWell()];
219 if (ws.production_cmode == Well::ProducerCMode::THP) {
220 ws.thp = well->getTHPConstraint(summary_state);
225template<
typename TypeTag>
227BlackoilWellModelRescoup<TypeTag>::
228receiveSlaveGroupData()
231 assert(this->isReservoirCouplingMaster());
232 RescoupReceiveSlaveGroupData<Scalar, IndexTraits> slave_group_data_receiver{
233 this->groupStateHelper(),
235 slave_group_data_receiver.receiveSlaveGroupData();
238template<
typename TypeTag>
240BlackoilWellModelRescoup<TypeTag>::
241rescoupSyncSummaryData()
253 if (this->isReservoirCouplingMaster()) {
254 if (this->reservoirCouplingMaster().needsSlaveDataReceive()) {
255 this->receiveSlaveGroupData();
256 this->reservoirCouplingMaster().setNeedsSlaveDataReceive(
false);
259 if (this->isReservoirCouplingSlave()) {
260 if (this->reservoirCouplingSlave().isLastSubstepOfSyncTimestep()) {
261 this->sendSlaveGroupDataToMaster();
266template<
typename TypeTag>
268BlackoilWellModelRescoup<TypeTag>::
269sendCoupledNetworkActiveStatus()
272 assert(this->isReservoirCouplingMaster());
281 auto& rescoup_master = this->reservoirCouplingMaster();
282 const auto num_slaves = rescoup_master.numSlaves();
283 bool any_connected =
false;
284 for (std::size_t slave_idx = 0; slave_idx < num_slaves; ++slave_idx) {
285 if (rescoup_master.slaveIsActivated(slave_idx)) {
286 const bool connected =
287 this->masterNetworkHasMasterGroupLeavesForSlave_(slave_idx);
288 any_connected = any_connected || connected;
289 rescoup_master.sendCoupledNetworkActiveStatusToSlave(slave_idx, connected);
296 this->last_sent_master_group_node_pressures_is_final_ = !any_connected;
299template<
typename TypeTag>
301BlackoilWellModelRescoup<TypeTag>::
302sendMasterGroupConstraintsToSlaves()
308 RescoupConstraintsCalculator<Scalar, IndexTraits> constraints_calculator{
309 this->well_model_.guideRateHandler(),
310 this->groupStateHelper()
312 constraints_calculator.calculateMasterGroupConstraintsAndSendToSlaves();
315template<
typename TypeTag>
317BlackoilWellModelRescoup<TypeTag>::
318sendMasterGroupNodePressuresToSlaves(
bool is_final)
321 assert(this->isReservoirCouplingMaster());
322 auto& rescoup_master = this->reservoirCouplingMaster();
323 const auto& node_pressures = this->network_.nodePressures();
324 const auto num_slaves = rescoup_master.numSlaves();
325 for (std::size_t slave_idx = 0; slave_idx < num_slaves; ++slave_idx) {
326 if (!rescoup_master.slaveIsActivated(slave_idx))
continue;
327 std::vector<typename ReservoirCoupling::MasterGroupNodePressure<Scalar>> pressures;
328 const auto& master_groups = rescoup_master.getMasterGroupNamesForSlave(slave_idx);
329 for (std::size_t i = 0; i < master_groups.size(); ++i) {
330 const auto it = node_pressures.find(master_groups[i]);
331 if (it != node_pressures.end()) {
332 pressures.push_back({i, it->second});
335 rescoup_master.sendNumMasterGroupNodePressuresToSlave(
336 slave_idx, pressures.size(), is_final);
337 if (!pressures.empty()) {
338 rescoup_master.sendMasterGroupNodePressuresToSlave(slave_idx, pressures);
341 this->last_sent_master_group_node_pressures_is_final_ = is_final;
344template<
typename TypeTag>
346BlackoilWellModelRescoup<TypeTag>::
347sendSlaveGroupDataToMaster()
350 assert(this->isReservoirCouplingSlave());
351 RescoupSendSlaveGroupData<Scalar, IndexTraits> slave_group_data_sender{
352 this->groupStateHelper()};
353 slave_group_data_sender.sendSlaveGroupDataToMaster();
365template<
typename TypeTag>
366std::optional<ReservoirCoupling::ScopedLoggerGuard>
367BlackoilWellModelRescoup<TypeTag>::
368setupScopedLogger(DeferredLogger& local_logger)
370 if (this->isReservoirCouplingMaster()) {
371 return ReservoirCoupling::ScopedLoggerGuard{
372 this->reservoirCouplingMaster().logger(),
375 }
else if (this->isReservoirCouplingSlave()) {
376 return ReservoirCoupling::ScopedLoggerGuard{
377 this->reservoirCouplingSlave().logger(),
387template<
typename TypeTag>
389BlackoilWellModelRescoup<TypeTag>::
390masterNetworkHasMasterGroupLeavesForSlave_(std::size_t slave_idx)
const
394 if (!this->isReservoirCouplingMaster())
return false;
395 const int episodeIdx = this->simulator_.episodeIndex();
396 const auto& network = this->schedule()[episodeIdx].network();
397 if (!network.active())
return false;
398 const auto& rcm = this->reservoirCouplingMaster();
399 for (
const auto& mg : rcm.getMasterGroupNamesForSlave(slave_idx)) {
400 if (network.has_node(mg)) {
Definition: blackoilbioeffectsmodules.hh:45