ReservoirCoupling.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_HPP
21#define OPM_RESERVOIR_COUPLING_HPP
23#include <opm/input/eclipse/Schedule/Group/Group.hpp>
24#include <opm/input/eclipse/Schedule/Group/GuideRate.hpp>
25
26#include <dune/common/parallel/mpitraits.hh>
27
28#include <mpi.h>
29#include <cmath>
30#include <iostream>
31#include <memory>
32#include <stdexcept>
33#include <vector>
34
35namespace Opm {
36namespace ReservoirCoupling {
37
38class Logger {
39public:
40 Logger() = default;
41 void clearDeferredLogger() { deferred_logger_ = nullptr; }
42 DeferredLogger& deferredLogger() { return *deferred_logger_; }
43 DeferredLogger& deferredLogger() const { return *deferred_logger_; }
44 bool haveDeferredLogger() const { return deferred_logger_ != nullptr; }
45 void info(const std::string &msg) const;
46 void warning(const std::string &msg) const;
47 void setDeferredLogger(DeferredLogger *deferred_logger) { deferred_logger_ = deferred_logger; }
48
49private:
50 DeferredLogger *deferred_logger_ = nullptr;
51};
52
81public:
82 explicit ScopedLoggerGuard(Logger& logger, DeferredLogger* deferred_logger)
83 : logger_(&logger)
84 {
85 logger_->setDeferredLogger(deferred_logger);
86 }
87
89 // Only clear if we still own the logger (not moved-from)
90 if (logger_) {
91 logger_->clearDeferredLogger();
92 }
93 }
94
95 // Prevent copying to ensure single ownership
98
99 // Enable moving - required for returning from functions and std::optional
101 : logger_(other.logger_)
102 {
103 // Transfer ownership: moved-from object becomes inactive and won't clear the logger
104 other.logger_ = nullptr;
105 }
106
108 if (this != &other) {
109 // Clean up current logger before taking ownership of new one
110 if (logger_) {
111 logger_->clearDeferredLogger();
112 }
113 // Transfer ownership from other
114 logger_ = other.logger_;
115 other.logger_ = nullptr;
116 }
117 return *this;
118 }
119
120private:
121 // Use pointer instead of reference to enable move semantics
122 // (references cannot be reassigned, which is required for move operations)
123 Logger* logger_{nullptr};
124};
125
126enum class MessageTag : int {
137 SlaveName,
144};
145
148enum class Phase : std::size_t {
149 Oil = 0, // Matches Opm::Phase::OIL
150 Gas, // Matches Opm::Phase::GAS
151 Water, // Matches Opm::Phase::WATER
152 Count
153};
154
155template <class Scalar>
157 InjectionRates() = default;
158
159 std::array<Scalar, static_cast<std::size_t>(Phase::Count)> rate{};
160 [[nodiscard]] Scalar& operator[](Phase p) noexcept { return rate[static_cast<std::size_t>(p)]; }
161 [[nodiscard]] Scalar operator[](Phase p) const noexcept { return rate[static_cast<std::size_t>(p)]; }
162};
163
164
165// Used to communicate potentials for oil, gas, and water rates between slave and master processes
166template <class Scalar>
168 std::array<Scalar, static_cast<std::size_t>(Phase::Count)> rate{};
169
170 [[nodiscard]] Scalar& operator[](Phase p) noexcept { return rate[static_cast<std::size_t>(p)]; }
171 [[nodiscard]] Scalar operator[](Phase p) const noexcept { return rate[static_cast<std::size_t>(p)]; }
172};
173
174template <class Scalar>
176 ProductionRates() = default;
177
178 explicit ProductionRates(const GuideRate::RateVector& rate_vector)
179 : rate{static_cast<Scalar>(rate_vector.oil_rat),
180 static_cast<Scalar>(rate_vector.gas_rat),
181 static_cast<Scalar>(rate_vector.wat_rat)}
182 {}
183
184 std::array<Scalar, static_cast<std::size_t>(Phase::Count)> rate{};
185 [[nodiscard]] Scalar& operator[](Phase p) noexcept { return rate[static_cast<std::size_t>(p)]; }
186 [[nodiscard]] Scalar operator[](Phase p) const noexcept { return rate[static_cast<std::size_t>(p)]; }
187};
188
189// Slave group production data sent to the corresponding master group for target calculation.
190template <class Scalar>
192 // Group production potentials are used by the master group for guiderate calculations
194 // Production rates are used by the master group in guiderate calculations
195 // when converting the guide rate target to the phase of the master group.
196 ProductionRates<Scalar> surface_rates; // Surface production rates by phase
197 // Individual phase reservoir production rates - needed when master's parent group
198 // has RESV control mode, so the conversion uses slave's PVT properties
199 ProductionRates<Scalar> reservoir_rates; // Reservoir production rates by phase
200 Scalar voidage_rate{0.0}; // Reservoir voidage replacement rate
201 Scalar gas_reinjection_rate{0.0}; // Reinjection (surface) rate for the gas phase
202};
203
204// Slave group injection data sent to the corresponding master group for target calculation.
205template <class Scalar>
207 InjectionRates<Scalar> surface_rates; // Surface injection rates by phase
208 InjectionRates<Scalar> reservoir_rates; // Reservoir injection rates by phase
209};
210
211template <class Scalar>
213 // To save memory and avoid varying size of the struct when serializing
214 // and deserializing the group name, we use an index instead of the full name.
215 std::size_t group_name_idx; // Index of group name in the master group names vector
216 Scalar target; // Target rate for the group
217 Group::InjectionCMode cmode; // Control mode for the group
218 Phase phase; // Phase the target applies to
219};
220
221template <class Scalar>
223 // To save memory and avoid varying size of the struct when serializing
224 // and deserializing the group name, we use an index instead of the full name.
225 std::size_t group_name_idx; // Index of group name in the master group names vector
226 Scalar target; // Target rate for the group
227 Group::ProductionCMode cmode; // Control mode for the group
228};
229
230// Helper functions
232void customErrorHandler_(MPI_Comm* comm, int* err, const std::string &msg);
233void customErrorHandlerSlave_(MPI_Comm* comm, int* err, ...);
234void customErrorHandlerMaster_(MPI_Comm* comm, int* err, ...);
235void setErrhandler(MPI_Comm comm, bool is_master);
236std::pair<std::vector<char>, std::size_t> serializeStrings(const std::vector<std::string>& data);
237
255struct Seconds {
257 static constexpr double abstol = 1e-15;
258
260 static constexpr double reltol = 1e-15;
261
280 static bool compare_eq(double a, double b);
281
287 static bool compare_gt(double a, double b);
288
294 static bool compare_gt_or_eq(double a, double b);
295
301 static bool compare_lt(double a, double b);
302
308 static bool compare_lt_or_eq(double a, double b);
309};
310
311} // namespace ReservoirCoupling
312} // namespace Opm
313
314#endif // OPM_RESERVOIR_COUPLING_HPP
Definition: DeferredLogger.hpp:57
Definition: ReservoirCoupling.hpp:38
void info(const std::string &msg) const
void warning(const std::string &msg) const
void setDeferredLogger(DeferredLogger *deferred_logger)
Definition: ReservoirCoupling.hpp:47
void clearDeferredLogger()
Definition: ReservoirCoupling.hpp:41
bool haveDeferredLogger() const
Definition: ReservoirCoupling.hpp:44
DeferredLogger & deferredLogger()
Definition: ReservoirCoupling.hpp:42
DeferredLogger & deferredLogger() const
Definition: ReservoirCoupling.hpp:43
Guard for managing DeferredLogger lifecycle in ReservoirCoupling.
Definition: ReservoirCoupling.hpp:80
~ScopedLoggerGuard()
Definition: ReservoirCoupling.hpp:88
ScopedLoggerGuard & operator=(const ScopedLoggerGuard &)=delete
ScopedLoggerGuard(ScopedLoggerGuard &&other) noexcept
Definition: ReservoirCoupling.hpp:100
ScopedLoggerGuard(const ScopedLoggerGuard &)=delete
ScopedLoggerGuard & operator=(ScopedLoggerGuard &&other) noexcept
Definition: ReservoirCoupling.hpp:107
ScopedLoggerGuard(Logger &logger, DeferredLogger *deferred_logger)
Definition: ReservoirCoupling.hpp:82
void customErrorHandler_(MPI_Comm *comm, int *err, const std::string &msg)
std::pair< std::vector< char >, std::size_t > serializeStrings(const std::vector< std::string > &data)
void customErrorHandlerSlave_(MPI_Comm *comm, int *err,...)
MessageTag
Definition: ReservoirCoupling.hpp:126
void setErrhandler(MPI_Comm comm, bool is_master)
void customErrorHandlerMaster_(MPI_Comm *comm, int *err,...)
Phase convertPhaseToReservoirCouplingPhase(::Opm::Phase phase)
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:148
Definition: blackoilbioeffectsmodules.hh:43
Definition: ReservoirCoupling.hpp:212
Scalar target
Definition: ReservoirCoupling.hpp:216
std::size_t group_name_idx
Definition: ReservoirCoupling.hpp:215
Group::InjectionCMode cmode
Definition: ReservoirCoupling.hpp:217
Phase phase
Definition: ReservoirCoupling.hpp:218
Definition: ReservoirCoupling.hpp:156
Scalar operator[](Phase p) const noexcept
Definition: ReservoirCoupling.hpp:161
std::array< Scalar, static_cast< std::size_t >(Phase::Count)> rate
Definition: ReservoirCoupling.hpp:159
Scalar & operator[](Phase p) noexcept
Definition: ReservoirCoupling.hpp:160
Definition: ReservoirCoupling.hpp:167
std::array< Scalar, static_cast< std::size_t >(Phase::Count)> rate
Definition: ReservoirCoupling.hpp:168
Scalar & operator[](Phase p) noexcept
Definition: ReservoirCoupling.hpp:170
Scalar operator[](Phase p) const noexcept
Definition: ReservoirCoupling.hpp:171
Definition: ReservoirCoupling.hpp:222
Scalar target
Definition: ReservoirCoupling.hpp:226
std::size_t group_name_idx
Definition: ReservoirCoupling.hpp:225
Group::ProductionCMode cmode
Definition: ReservoirCoupling.hpp:227
Definition: ReservoirCoupling.hpp:175
Scalar operator[](Phase p) const noexcept
Definition: ReservoirCoupling.hpp:186
ProductionRates(const GuideRate::RateVector &rate_vector)
Definition: ReservoirCoupling.hpp:178
Scalar & operator[](Phase p) noexcept
Definition: ReservoirCoupling.hpp:185
std::array< Scalar, static_cast< std::size_t >(Phase::Count)> rate
Definition: ReservoirCoupling.hpp:184
Utility class for comparing double values representing epoch dates or elapsed time.
Definition: ReservoirCoupling.hpp:255
static bool compare_gt_or_eq(double a, double b)
Determines if a is greater than b within the specified tolerance.
static bool compare_gt(double a, double b)
Determines if a is greater than b within the specified tolerance.
static bool compare_lt_or_eq(double a, double b)
Determines if a is less than or equal to b within the specified tolerance.
static bool compare_eq(double a, double b)
Determines if two double values are equal within a specified tolerance.
static constexpr double reltol
Relative tolerance used for comparisons.
Definition: ReservoirCoupling.hpp:260
static bool compare_lt(double a, double b)
Determines if a is less than b within the specified tolerance.
static constexpr double abstol
Absolute tolerance used for comparisons.
Definition: ReservoirCoupling.hpp:257
Definition: ReservoirCoupling.hpp:206
InjectionRates< Scalar > surface_rates
Definition: ReservoirCoupling.hpp:207
InjectionRates< Scalar > reservoir_rates
Definition: ReservoirCoupling.hpp:208
Definition: ReservoirCoupling.hpp:191
Scalar gas_reinjection_rate
Definition: ReservoirCoupling.hpp:201
Potentials< Scalar > potentials
Definition: ReservoirCoupling.hpp:193
ProductionRates< Scalar > reservoir_rates
Definition: ReservoirCoupling.hpp:199
Scalar voidage_rate
Definition: ReservoirCoupling.hpp:200
ProductionRates< Scalar > surface_rates
Definition: ReservoirCoupling.hpp:196