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.slaveIsCoupled(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();
112 this->refreshAndSendInjectionTargets_();
117template<
typename TypeTag>
119BlackoilWellModelRescoup<TypeTag>::
120maybeExchangeNetworkSubIterationWithSlaves()
140 if (!this->well_model_.useTightRcNetworkCoupling()) {
143 if (!this->masterIsInCoupledNetworkIteration()) {
146 this->sendMasterGroupNodePressuresToSlaves(
false);
147 this->receiveSlaveGroupData();
148 this->refreshAndSendInjectionTargets_();
151template<
typename TypeTag>
153BlackoilWellModelRescoup<TypeTag>::
154receiveCoupledNetworkActiveStatus()
157 assert(this->isReservoirCouplingSlave());
158 this->reservoirCouplingSlave().receiveCoupledNetworkActiveStatusFromMaster();
161template<
typename TypeTag>
163BlackoilWellModelRescoup<TypeTag>::
164receiveGroupConstraintsFromMaster()
167 RescoupReceiveGroupConstraints<Scalar, IndexTraits> constraint_receiver{
168 this->well_model_.guideRateHandler(),
169 this->groupStateHelper()
171 constraint_receiver.receiveGroupConstraintsFromMaster();
174template<
typename TypeTag>
176BlackoilWellModelRescoup<TypeTag>::
177receiveMasterGroupNodePressuresFromMaster()
180 assert(this->isReservoirCouplingSlave());
181 auto& rescoup_slave = this->reservoirCouplingSlave();
182 const auto [num_pressures, _is_final] =
183 rescoup_slave.receiveNumMasterGroupNodePressuresFromMaster();
184 if (num_pressures > 0) {
185 rescoup_slave.receiveMasterGroupNodePressuresFromMaster(num_pressures);
218 const auto& pressures = rescoup_slave.masterGroupNodePressures();
219 if (pressures.empty())
return;
220 const auto& summary_state = this->well_model_.summaryState();
221 auto& well_state = this->wellState();
222 for (
auto& well : this->wellContainer()) {
223 if (!well->isProducer() || !well->wellEcl().predictionMode())
continue;
224 const auto& group_name = well->wellEcl().groupName();
225 const auto it = pressures.find(group_name);
226 if (it == pressures.end())
continue;
227 if (!this->slaveGroupIsFixedPressureNodeInOwnNetwork_(group_name))
continue;
228 well->setDynamicThpLimit(it->second);
229 auto& ws = well_state[well->indexOfWell()];
230 if (ws.production_cmode == Well::ProducerCMode::THP) {
231 ws.thp = well->getTHPConstraint(summary_state);
236template<
typename TypeTag>
238BlackoilWellModelRescoup<TypeTag>::
239receiveSlaveGroupData()
242 assert(this->isReservoirCouplingMaster());
243 RescoupReceiveSlaveGroupData<Scalar, IndexTraits> slave_group_data_receiver{
244 this->groupStateHelper(),
246 slave_group_data_receiver.receiveSlaveGroupData();
249template<
typename TypeTag>
251BlackoilWellModelRescoup<TypeTag>::
252rescoupSyncSummaryData()
264 if (this->isReservoirCouplingMaster()) {
265 if (this->reservoirCouplingMaster().needsSlaveDataReceive()) {
266 this->receiveSlaveGroupData();
267 this->reservoirCouplingMaster().setNeedsSlaveDataReceive(
false);
270 if (this->isReservoirCouplingSlave()) {
271 if (this->reservoirCouplingSlave().isLastSubstepOfSyncTimestep()) {
272 this->sendSlaveGroupDataToMaster();
277template<
typename TypeTag>
279BlackoilWellModelRescoup<TypeTag>::
280sendCoupledNetworkActiveStatus()
283 assert(this->isReservoirCouplingMaster());
292 auto& rescoup_master = this->reservoirCouplingMaster();
293 const auto num_slaves = rescoup_master.numSlaves();
294 bool any_connected =
false;
295 for (std::size_t slave_idx = 0; slave_idx < num_slaves; ++slave_idx) {
296 if (rescoup_master.slaveIsCoupled(slave_idx)) {
297 const bool connected =
298 this->masterNetworkHasMasterGroupLeavesForSlave_(slave_idx);
299 any_connected = any_connected || connected;
300 rescoup_master.sendCoupledNetworkActiveStatusToSlave(slave_idx, connected);
307 this->last_sent_master_group_node_pressures_is_final_ = !any_connected;
310template<
typename TypeTag>
312BlackoilWellModelRescoup<TypeTag>::
313sendMasterGroupConstraintsToSlaves()
319 RescoupConstraintsCalculator<Scalar, IndexTraits> constraints_calculator{
320 this->well_model_.guideRateHandler(),
321 this->groupStateHelper()
323 constraints_calculator.calculateMasterGroupConstraintsAndSendToSlaves();
326template<
typename TypeTag>
328BlackoilWellModelRescoup<TypeTag>::
329sendMasterGroupNodePressuresToSlaves(
bool is_final)
332 assert(this->isReservoirCouplingMaster());
333 auto& rescoup_master = this->reservoirCouplingMaster();
334 const auto& node_pressures = this->network_.nodePressures();
335 const auto num_slaves = rescoup_master.numSlaves();
336 for (std::size_t slave_idx = 0; slave_idx < num_slaves; ++slave_idx) {
337 if (!rescoup_master.slaveIsCoupled(slave_idx))
continue;
338 std::vector<typename ReservoirCoupling::MasterGroupNodePressure<Scalar>> pressures;
339 const auto& master_groups = rescoup_master.getMasterGroupNamesForSlave(slave_idx);
340 for (std::size_t i = 0; i < master_groups.size(); ++i) {
341 const auto it = node_pressures.find(master_groups[i]);
342 if (it != node_pressures.end()) {
343 pressures.push_back({i, it->second});
346 rescoup_master.sendNumMasterGroupNodePressuresToSlave(
347 slave_idx, pressures.size(), is_final);
348 if (!pressures.empty()) {
349 rescoup_master.sendMasterGroupNodePressuresToSlave(slave_idx, pressures);
352 this->last_sent_master_group_node_pressures_is_final_ = is_final;
355template<
typename TypeTag>
357BlackoilWellModelRescoup<TypeTag>::
358sendSlaveGroupDataToMaster()
361 assert(this->isReservoirCouplingSlave());
362 RescoupSendSlaveGroupData<Scalar, IndexTraits> slave_group_data_sender{
363 this->groupStateHelper()};
364 slave_group_data_sender.sendSlaveGroupDataToMaster();
376template<
typename TypeTag>
377std::optional<ReservoirCoupling::ScopedLoggerGuard>
378BlackoilWellModelRescoup<TypeTag>::
379setupScopedLogger(DeferredLogger& local_logger)
381 if (this->isReservoirCouplingMaster()) {
382 return ReservoirCoupling::ScopedLoggerGuard{
383 this->reservoirCouplingMaster().logger(),
386 }
else if (this->isReservoirCouplingSlave()) {
387 return ReservoirCoupling::ScopedLoggerGuard{
388 this->reservoirCouplingSlave().logger(),
398template<
typename TypeTag>
400BlackoilWellModelRescoup<TypeTag>::
401masterNetworkHasMasterGroupLeavesForSlave_(std::size_t slave_idx)
const
405 if (!this->isReservoirCouplingMaster())
return false;
406 const int episodeIdx = this->simulator_.episodeIndex();
407 const auto& network = this->schedule()[episodeIdx].network();
408 if (!network.active())
return false;
409 const auto& rcm = this->reservoirCouplingMaster();
410 for (
const auto& mg : rcm.getMasterGroupNamesForSlave(slave_idx)) {
411 if (network.has_node(mg)) {
418template<
typename TypeTag>
420BlackoilWellModelRescoup<TypeTag>::
421refreshAndSendInjectionTargets_()
430 const int report_step_idx = this->well_model_.simulator().episodeIndex();
431 this->well_model_.updateAndCommunicateGroupData(
432 report_step_idx,
false);
433 this->sendMasterGroupInjectionTargetsToSlaves_();
436template<
typename TypeTag>
438BlackoilWellModelRescoup<TypeTag>::
439sendMasterGroupInjectionTargetsToSlaves_()
442 RescoupConstraintsCalculator<Scalar, IndexTraits> constraints_calculator{
443 this->well_model_.guideRateHandler(),
444 this->groupStateHelper()
446 constraints_calculator.recalculateInjectionTargetsAndSendToSlaves();
449template<
typename TypeTag>
451BlackoilWellModelRescoup<TypeTag>::
452slaveGroupIsFixedPressureNodeInOwnNetwork_(
const std::string& group_name)
const
454 const int episodeIdx = this->simulator_.episodeIndex();
455 const auto& network = this->schedule()[episodeIdx].network();
456 if (!network.active())
return false;
457 if (!network.has_node(group_name))
return false;
458 return network.node(group_name).terminal_pressure().has_value();
Definition: blackoilbioeffectsmodules.hh:45