opm-simulators
RescoupProxy.hpp
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_RESCOUP_PROXY_HPP
21 #define OPM_RESCOUP_PROXY_HPP
22 
23 #include <opm/simulators/flow/rescoup/ReservoirCouplingEnabled.hpp>
24 #ifdef RESERVOIR_COUPLING_ENABLED
25 #include <opm/simulators/flow/rescoup/ReservoirCoupling.hpp>
26 #include <opm/simulators/flow/rescoup/ReservoirCouplingMaster.hpp>
27 #include <opm/simulators/flow/rescoup/ReservoirCouplingSlave.hpp>
28 #else
29 #include <stdexcept>
30 #include <string>
31 #endif
32 
33 namespace Opm {
34 
35 #ifndef RESERVOIR_COUPLING_ENABLED
36 // Forward declarations for non-MPI builds
37 template <class Scalar> class ReservoirCouplingMaster;
38 template <class Scalar> class ReservoirCouplingSlave;
39 #endif
40 
41 namespace ReservoirCoupling {
42 
53 template <class Scalar>
54 class Proxy {
55 public:
56  Proxy() = default;
57 
58  // Copyable and movable (just holds non-owning pointers)
59  Proxy(const Proxy&) = default;
60  Proxy& operator=(const Proxy&) = default;
61  Proxy(Proxy&&) noexcept = default;
62  Proxy& operator=(Proxy&&) noexcept = default;
63 
64 #ifdef RESERVOIR_COUPLING_ENABLED
65  // === Mode Queries ===
66 
68  bool isEnabled() const noexcept { return master_ || slave_; }
69 
71  bool isMaster() const noexcept { return master_ != nullptr; }
72 
74  bool isSlave() const noexcept { return slave_ != nullptr; }
75 
76  // === Setters (called during init, after construction) ===
77 
79  void setMaster(ReservoirCouplingMaster<Scalar>* master) {
80  master_ = master;
81  slave_ = nullptr;
82  }
83 
85  void setSlave(ReservoirCouplingSlave<Scalar>* slave) {
86  slave_ = slave;
87  master_ = nullptr;
88  }
89 
90  // === Pointer Access ===
91 
93  ReservoirCouplingMaster<Scalar>* masterPtr() noexcept { return master_; }
94  const ReservoirCouplingMaster<Scalar>* masterPtr() const noexcept { return master_; }
95 
97  ReservoirCouplingSlave<Scalar>* slavePtr() noexcept { return slave_; }
98  const ReservoirCouplingSlave<Scalar>* slavePtr() const noexcept { return slave_; }
99 
100  // === Reference Access (caller must ensure correct mode) ===
101 
103  ReservoirCouplingMaster<Scalar>& master() { return *master_; }
104  const ReservoirCouplingMaster<Scalar>& master() const { return *master_; }
105 
107  ReservoirCouplingSlave<Scalar>& slave() { return *slave_; }
108  const ReservoirCouplingSlave<Scalar>& slave() const { return *slave_; }
109 
110  // === Facade Methods (safe to call regardless of mode) ===
111 
115  bool isMasterGroup(const std::string& group_name) const {
116  return master_ && master_->isMasterGroup(group_name);
117  }
118 
122  bool isSlaveGroup(const std::string& group_name) const {
123  return slave_ && slave_->isSlaveGroup(group_name);
124  }
125 
126 private:
127  ReservoirCouplingMaster<Scalar>* master_ = nullptr;
128  ReservoirCouplingSlave<Scalar>* slave_ = nullptr;
129 
130 #else // !RESERVOIR_COUPLING_ENABLED
131 
132  // === Mode Queries (always false in non-MPI builds) ===
133 
134  bool isEnabled() const noexcept { return false; }
135  bool isMaster() const noexcept { return false; }
136  bool isSlave() const noexcept { return false; }
137 
138  // Stub implementations for non-MPI builds.
139  // These should never be called since isMaster()/isSlave() always return false.
140 
141  void setMaster(ReservoirCouplingMaster<Scalar>*) {
142  throw std::logic_error("ReservoirCoupling::Proxy::setMaster() called in non-MPI build");
143  }
144 
145  void setSlave(ReservoirCouplingSlave<Scalar>*) {
146  throw std::logic_error("ReservoirCoupling::Proxy::setSlave() called in non-MPI build");
147  }
148 
149  ReservoirCouplingMaster<Scalar>* masterPtr() noexcept { return nullptr; }
150  const ReservoirCouplingMaster<Scalar>* masterPtr() const noexcept { return nullptr; }
151 
152  ReservoirCouplingSlave<Scalar>* slavePtr() noexcept { return nullptr; }
153  const ReservoirCouplingSlave<Scalar>* slavePtr() const noexcept { return nullptr; }
154 
156  throw std::logic_error("ReservoirCoupling::Proxy::master() called in non-MPI build");
157  }
158  const ReservoirCouplingMaster<Scalar>& master() const {
159  throw std::logic_error("ReservoirCoupling::Proxy::master() called in non-MPI build");
160  }
161 
163  throw std::logic_error("ReservoirCoupling::Proxy::slave() called in non-MPI build");
164  }
165  const ReservoirCouplingSlave<Scalar>& slave() const {
166  throw std::logic_error("ReservoirCoupling::Proxy::slave() called in non-MPI build");
167  }
168 
169  // === Facade Methods (always return false/no-op in non-MPI builds) ===
170 
171  bool isMasterGroup(const std::string& /*group_name*/) const noexcept {
172  return false;
173  }
174 
175  bool isSlaveGroup(const std::string& /*group_name*/) const noexcept {
176  return false;
177  }
178 #endif // !RESERVOIR_COUPLING_ENABLED
179 };
180 
181 } // namespace ReservoirCoupling
182 } // namespace Opm
183 
184 #endif // OPM_RESCOUP_PROXY_HPP
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Definition: ReservoirCouplingMaster.hpp:38
Definition: ReservoirCouplingSlave.hpp:40
Thin proxy for reservoir coupling master/slave pointers.
Definition: RescoupProxy.hpp:54