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/GuideRate.hpp>
24
25#include <dune/common/parallel/mpitraits.hh>
26
27#include <mpi.h>
28#include <cmath>
29#include <iostream>
30#include <memory>
31#include <vector>
32
33namespace Opm {
34namespace ReservoirCoupling {
35
36class Logger {
37public:
38 Logger() = default;
39 void clearDeferredLogger() { deferred_logger_ = nullptr; }
40 bool haveDeferredLogger() const { return deferred_logger_ != nullptr; }
41 void info(const std::string &msg) const;
42 void setDeferredLogger(DeferredLogger *deferred_logger) { deferred_logger_ = deferred_logger; }
43
44private:
45 DeferredLogger *deferred_logger_ = nullptr;
46};
47
76public:
77 explicit ScopedLoggerGuard(Logger& logger, DeferredLogger* deferred_logger)
78 : logger_(&logger)
79 {
80 logger_->setDeferredLogger(deferred_logger);
81 }
82
84 // Only clear if we still own the logger (not moved-from)
85 if (logger_) {
86 logger_->clearDeferredLogger();
87 }
88 }
89
90 // Prevent copying to ensure single ownership
93
94 // Enable moving - required for returning from functions and std::optional
96 : logger_(other.logger_)
97 {
98 // Transfer ownership: moved-from object becomes inactive and won't clear the logger
99 other.logger_ = nullptr;
100 }
101
103 if (this != &other) {
104 // Clean up current logger before taking ownership of new one
105 if (logger_) {
106 logger_->clearDeferredLogger();
107 }
108 // Transfer ownership from other
109 logger_ = other.logger_;
110 other.logger_ = nullptr;
111 }
112 return *this;
113 }
114
115private:
116 // Use pointer instead of reference to enable move semantics
117 // (references cannot be reassigned, which is required for move operations)
118 Logger* logger_{nullptr};
119};
120
121enum class MessageTag : int {
130 SlaveName,
137};
138
141enum class Phase : std::size_t {
142 Oil = 0, // Matches Opm::Phase::OIL
143 Gas, // Matches Opm::Phase::GAS
144 Water, // Matches Opm::Phase::WATER
145 Count
146};
147
148template <class Scalar>
150 InjectionRates() = default;
151
152 std::array<Scalar, static_cast<std::size_t>(Phase::Count)> rate{};
153 [[nodiscard]] Scalar& operator[](Phase p) noexcept { return rate[static_cast<std::size_t>(p)]; }
154 [[nodiscard]] Scalar operator[](Phase p) const noexcept { return rate[static_cast<std::size_t>(p)]; }
155};
156
157
158// Used to communicate potentials for oil, gas, and water rates between slave and master processes
159template <class Scalar>
161 std::array<Scalar, static_cast<std::size_t>(Phase::Count)> rate{};
162
163 [[nodiscard]] Scalar& operator[](Phase p) noexcept { return rate[static_cast<std::size_t>(p)]; }
164 [[nodiscard]] Scalar operator[](Phase p) const noexcept { return rate[static_cast<std::size_t>(p)]; }
165};
166
167template <class Scalar>
169 ProductionRates() = default;
170
171 explicit ProductionRates(const GuideRate::RateVector& rate_vector)
172 : rate{static_cast<Scalar>(rate_vector.oil_rat),
173 static_cast<Scalar>(rate_vector.gas_rat),
174 static_cast<Scalar>(rate_vector.wat_rat)}
175 {}
176
177 std::array<Scalar, static_cast<std::size_t>(Phase::Count)> rate{};
178 [[nodiscard]] Scalar& operator[](Phase p) noexcept { return rate[static_cast<std::size_t>(p)]; }
179 [[nodiscard]] Scalar operator[](Phase p) const noexcept { return rate[static_cast<std::size_t>(p)]; }
180};
181
182// Slave group production data sent to the corresponding master group for target calculation.
183template <class Scalar>
185 // Group production potentials are used by the master group for guiderate calculations
187 // Production rates are used by the master group in guiderate calculations
188 // when converting the guide rate target to the phase of the master group.
189 ProductionRates<Scalar> surface_rates; // Surface production rates by phase
190 // NOTE: Currently, the master does not need the individual phase reservoir rates,
191 // we only send the total voidage replacement rate.
192 Scalar voidage_rate{0.0}; // Reservoir voidage replacement rate
193 Scalar gas_reinjection_rate{0.0}; // Reinjection (surface) rate for the gas phase
194};
195
196// Slave group injection data sent to the corresponding master group for target calculation.
197template <class Scalar>
199 InjectionRates<Scalar> surface_rates; // Surface injection rates by phase
200 InjectionRates<Scalar> reservoir_rates; // Reservoir injection rates by phase
201};
202
203
204// Helper functions
205void custom_error_handler_(MPI_Comm* comm, int* err, const std::string &msg);
206void setErrhandler(MPI_Comm comm, bool is_master);
207std::pair<std::vector<char>, std::size_t> serializeStrings(const std::vector<std::string>& data);
208
226struct Seconds {
228 static constexpr double abstol = 1e-15;
229
231 static constexpr double reltol = 1e-15;
232
251 static bool compare_eq(double a, double b);
252
258 static bool compare_gt(double a, double b);
259
265 static bool compare_gt_or_eq(double a, double b);
266
272 static bool compare_lt(double a, double b);
273
279 static bool compare_lt_or_eq(double a, double b);
280};
281
282} // namespace ReservoirCoupling
283} // namespace Opm
284
285#endif // OPM_RESERVOIR_COUPLING_HPP
Definition: DeferredLogger.hpp:57
Definition: ReservoirCoupling.hpp:36
void info(const std::string &msg) const
void setDeferredLogger(DeferredLogger *deferred_logger)
Definition: ReservoirCoupling.hpp:42
void clearDeferredLogger()
Definition: ReservoirCoupling.hpp:39
bool haveDeferredLogger() const
Definition: ReservoirCoupling.hpp:40
Guard for managing DeferredLogger lifecycle in ReservoirCoupling.
Definition: ReservoirCoupling.hpp:75
~ScopedLoggerGuard()
Definition: ReservoirCoupling.hpp:83
ScopedLoggerGuard & operator=(const ScopedLoggerGuard &)=delete
ScopedLoggerGuard(ScopedLoggerGuard &&other) noexcept
Definition: ReservoirCoupling.hpp:95
ScopedLoggerGuard(const ScopedLoggerGuard &)=delete
ScopedLoggerGuard & operator=(ScopedLoggerGuard &&other) noexcept
Definition: ReservoirCoupling.hpp:102
ScopedLoggerGuard(Logger &logger, DeferredLogger *deferred_logger)
Definition: ReservoirCoupling.hpp:77
std::pair< std::vector< char >, std::size_t > serializeStrings(const std::vector< std::string > &data)
MessageTag
Definition: ReservoirCoupling.hpp:121
void setErrhandler(MPI_Comm comm, bool is_master)
void custom_error_handler_(MPI_Comm *comm, int *err, const std::string &msg)
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:141
Definition: blackoilbioeffectsmodules.hh:43
Definition: ReservoirCoupling.hpp:149
Scalar operator[](Phase p) const noexcept
Definition: ReservoirCoupling.hpp:154
std::array< Scalar, static_cast< std::size_t >(Phase::Count)> rate
Definition: ReservoirCoupling.hpp:152
Scalar & operator[](Phase p) noexcept
Definition: ReservoirCoupling.hpp:153
Definition: ReservoirCoupling.hpp:160
std::array< Scalar, static_cast< std::size_t >(Phase::Count)> rate
Definition: ReservoirCoupling.hpp:161
Scalar & operator[](Phase p) noexcept
Definition: ReservoirCoupling.hpp:163
Scalar operator[](Phase p) const noexcept
Definition: ReservoirCoupling.hpp:164
Definition: ReservoirCoupling.hpp:168
Scalar operator[](Phase p) const noexcept
Definition: ReservoirCoupling.hpp:179
ProductionRates(const GuideRate::RateVector &rate_vector)
Definition: ReservoirCoupling.hpp:171
Scalar & operator[](Phase p) noexcept
Definition: ReservoirCoupling.hpp:178
std::array< Scalar, static_cast< std::size_t >(Phase::Count)> rate
Definition: ReservoirCoupling.hpp:177
Utility class for comparing double values representing epoch dates or elapsed time.
Definition: ReservoirCoupling.hpp:226
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:231
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:228
Definition: ReservoirCoupling.hpp:198
InjectionRates< Scalar > surface_rates
Definition: ReservoirCoupling.hpp:199
InjectionRates< Scalar > reservoir_rates
Definition: ReservoirCoupling.hpp:200
Definition: ReservoirCoupling.hpp:184
Scalar gas_reinjection_rate
Definition: ReservoirCoupling.hpp:193
Potentials< Scalar > potentials
Definition: ReservoirCoupling.hpp:186
Scalar voidage_rate
Definition: ReservoirCoupling.hpp:192
ProductionRates< Scalar > surface_rates
Definition: ReservoirCoupling.hpp:189