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