BlackoilWellModelRescoup_impl.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_BLACKOILWELLMODEL_RESCOUP_IMPL_HEADER_INCLUDED
21#define OPM_BLACKOILWELLMODEL_RESCOUP_IMPL_HEADER_INCLUDED
22
23// Improve IDE experience
24#ifndef OPM_BLACKOILWELLMODEL_RESCOUP_HEADER_INCLUDED
25#include <config.h>
27#endif
28
29#ifdef RESERVOIR_COUPLING_ENABLED
30
31#include <opm/common/TimingMacros.hpp>
32
38
39#include <cassert>
40
41namespace Opm {
42
43// Constructor
44// -----------
45template<typename TypeTag>
46BlackoilWellModelRescoup<TypeTag>::
47BlackoilWellModelRescoup(BlackoilWellModel<TypeTag>& well_model)
48 : well_model_{well_model}
49{}
50
51// Public methods alphabetically
52// ------------------------------
53
54template<typename TypeTag>
55void
56BlackoilWellModelRescoup<TypeTag>::
57receiveGroupConstraintsFromMaster()
58{
59 OPM_TIMEFUNCTION();
60 RescoupReceiveGroupConstraints<Scalar, IndexTraits> constraint_receiver{
61 this->well_model_.guideRateHandler(),
62 this->well_model_.groupStateHelper()
63 };
64 constraint_receiver.receiveGroupConstraintsFromMaster();
65}
66
67template<typename TypeTag>
68void
69BlackoilWellModelRescoup<TypeTag>::
70receiveSlaveGroupData()
71{
72 OPM_TIMEFUNCTION();
73 assert(this->well_model_.isReservoirCouplingMaster());
74 RescoupReceiveSlaveGroupData<Scalar, IndexTraits> slave_group_data_receiver{
75 this->well_model_.groupStateHelper(),
76 };
77 slave_group_data_receiver.receiveSlaveGroupData();
78}
79
80template<typename TypeTag>
81void
82BlackoilWellModelRescoup<TypeTag>::
83rescoupSyncSummaryData()
84{
85 // Reservoir coupling: exchange production data between slaves and master.
86 //
87 // Master side: after its first substep, the master blocks here until all
88 // slaves have completed the sync step and sent their production data.
89 // This ensures evalSummaryState() (called next in endTimeStep) and all
90 // subsequent master substeps have correct slave production rates.
91 //
92 // Slave side: on the last substep of the sync step, the slave sends its
93 // production data to the master. The master is already waiting at this
94 // point (blocked on MPI_Recv from its first substep's timeStepSucceeded).
95 if (this->well_model_.isReservoirCouplingMaster()) {
96 if (this->well_model_.reservoirCouplingMaster().needsSlaveDataReceive()) {
97 this->receiveSlaveGroupData();
98 this->well_model_.reservoirCouplingMaster().setNeedsSlaveDataReceive(false);
99 }
100 }
101 if (this->well_model_.isReservoirCouplingSlave()) {
102 if (this->well_model_.reservoirCouplingSlave().isLastSubstepOfSyncTimestep()) {
103 this->sendSlaveGroupDataToMaster();
104 }
105 }
106}
107
108template<typename TypeTag>
109void
110BlackoilWellModelRescoup<TypeTag>::
111sendSlaveGroupDataToMaster()
112{
113 OPM_TIMEFUNCTION();
114 assert(this->well_model_.isReservoirCouplingSlave());
115 RescoupSendSlaveGroupData<Scalar, IndexTraits> slave_group_data_sender{
116 this->well_model_.groupStateHelper()};
117 slave_group_data_sender.sendSlaveGroupDataToMaster();
118}
119
120template<typename TypeTag>
121void
122BlackoilWellModelRescoup<TypeTag>::
123sendMasterGroupConstraintsToSlaves()
124{
125 OPM_TIMEFUNCTION();
126 // This function is called by the master process to send the group constraints to the slaves.
127 RescoupConstraintsCalculator<Scalar, IndexTraits> constraints_calculator{
128 this->well_model_.guideRateHandler(),
129 this->well_model_.groupStateHelper()
130 };
131 constraints_calculator.calculateMasterGroupConstraintsAndSendToSlaves();
132}
133
134// Automatically manages the lifecycle of the DeferredLogger pointer
135// in the reservoir coupling logger. Ensures the logger is properly
136// cleared when it goes out of scope, preventing dangling pointer issues:
137//
138// - The ScopedLoggerGuard constructor sets the logger pointer
139// - When the guard goes out of scope, the destructor clears the pointer
140// - Move semantics transfer ownership safely when returning from this function
141// - The moved-from guard is "nullified" and its destructor does nothing
142// - Only the final guard in the caller will clear the logger
143template<typename TypeTag>
144std::optional<ReservoirCoupling::ScopedLoggerGuard>
145BlackoilWellModelRescoup<TypeTag>::
146setupScopedLogger(DeferredLogger& local_logger)
147{
148 if (this->well_model_.isReservoirCouplingMaster()) {
149 return ReservoirCoupling::ScopedLoggerGuard{
150 this->well_model_.reservoirCouplingMaster().logger(),
151 &local_logger
152 };
153 } else if (this->well_model_.isReservoirCouplingSlave()) {
154 return ReservoirCoupling::ScopedLoggerGuard{
155 this->well_model_.reservoirCouplingSlave().logger(),
156 &local_logger
157 };
158 }
159 return std::nullopt;
160}
161
162} // namespace Opm
163
164#endif // RESERVOIR_COUPLING_ENABLED
165#endif // OPM_BLACKOILWELLMODEL_RESCOUP_IMPL_HEADER_INCLUDED
Definition: blackoilbioeffectsmodules.hh:45