ConvergenceReport.hpp
Go to the documentation of this file.
1/*
2 Copyright 2018 SINTEF Digital, Mathematics and Cybernetics.
3 Copyright 2018, 2024 Equinor.
4
5 This file is part of the Open Porous Media project (OPM).
6
7 OPM is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 OPM is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with OPM. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#ifndef OPM_CONVERGENCEREPORT_HEADER_INCLUDED
22#define OPM_CONVERGENCEREPORT_HEADER_INCLUDED
23
24#include <algorithm>
25#include <cassert>
26#include <numeric>
27#include <string>
28#include <utility>
29#include <vector>
30
31namespace Opm
32{
33
38 {
39 public:
40
41 // ----------- Types -----------
42
43 enum Status {
46 WellFailed = 1 << 1,
47 };
48
49 enum struct Severity {
50 None = 0,
51 Normal = 1,
52 TooLarge = 2,
53 NotANumber = 3,
54 };
55
56 using CnvPvSplit = std::pair<
57 std::vector<double>,
58 std::vector<int>>;
59
61 {
62 public:
63 enum struct Type { Invalid, MassBalance, Cnv };
64
65 // Default constructor needed for object serialisation. Don't
66 // use this for anything else.
67 ReservoirFailure() = default;
68
70 : type_(t), severity_(s), phase_(phase)
71 {}
72
73 Type type() const { return type_; }
74 Severity severity() const { return severity_; }
75 int phase() const { return phase_; }
76
77 template <typename Serializer>
78 void serializeOp(Serializer& serializer)
79 {
80 serializer(this->type_);
81 serializer(this->severity_);
82 serializer(this->phase_);
83 }
84
85 private:
86 // Note to maintainers: If you change this list of data members,
87 // then please update serializeOp() accordingly.
88 Type type_ { Type::Invalid };
89 Severity severity_ { Severity::None };
90 int phase_ { -1 };
91 };
92
94 {
95 public:
96 // Default constructor needed for object serialisation. Don't
97 // use this for anything else.
99
101 : type_(t), phase_(phase), value_(value)
102 {}
103
104 ReservoirFailure::Type type() const { return type_; }
105 int phase() const { return phase_; }
106 double value() const { return value_; }
107
108 template <typename Serializer>
109 void serializeOp(Serializer& serializer)
110 {
111 serializer(this->type_);
112 serializer(this->phase_);
113 serializer(this->value_);
114 }
115
116 private:
117 // Note to maintainers: If you change this list of data members,
118 // then please update serializeOp() accordingly.
120 int phase_ { -1 };
121 double value_ { 0.0 };
122 };
123
125 {
126 public:
127 enum struct Type {
128 Invalid,
129 MassBalance,
130 Pressure,
131 ControlBHP,
132 ControlTHP,
133 ControlRate,
134 Unsolvable,
135 WrongFlowDirection,
136 };
137
138 // Default constructor needed for object serialisation. Don't
139 // use this for anything else.
140 WellFailure() = default;
141
142 WellFailure(Type t, Severity s, int phase, const std::string& well_name)
143 : type_(t), severity_(s), phase_(phase), well_name_(well_name)
144 {}
145
146 Type type() const { return type_; }
147 Severity severity() const { return severity_; }
148 int phase() const { return phase_; }
149 const std::string& wellName() const { return well_name_; }
150
151 template <typename Serializer>
152 void serializeOp(Serializer& serializer)
153 {
154 serializer(this->type_);
155 serializer(this->severity_);
156 serializer(this->phase_);
157 serializer(this->well_name_);
158 }
159
160 private:
161 // Note to maintainers: If you change this list of data members,
162 // then please update serializeOp() accordingly.
163 Type type_ { Type::Invalid };
164 Severity severity_ { Severity::None };
165 int phase_ { -1 };
166 std::string well_name_ {};
167 };
168
169 // ----------- Mutating member functions -----------
170
172 : ConvergenceReport{0.0}
173 {}
174
175 explicit ConvergenceReport(const double reportTime)
176 : reportTime_{reportTime}
177 , status_{AllGood}
178 , res_failures_{}
179 , well_failures_{}
180 , wellGroupTargetsViolated_(false)
181 {}
182
183 void clear()
184 {
185 status_ = AllGood;
186 res_failures_.clear();
187 well_failures_.clear();
188 wellGroupTargetsViolated_ = false;
189 }
190
192 {
193 status_ = static_cast<Status>(status_ | ReservoirFailed);
194 res_failures_.push_back(rf);
195 }
196
198 {
199 status_ = static_cast<Status>(status_ | WellFailed);
200 well_failures_.push_back(wf);
201 }
202
203 template <typename... Args>
204 void setReservoirConvergenceMetric(Args&&... args)
205 {
206 this->res_convergence_.emplace_back(std::forward<Args>(args)...);
207 }
208
209 void setWellGroupTargetsViolated(const bool wellGroupTargetsViolated)
210 {
211 wellGroupTargetsViolated_ = wellGroupTargetsViolated;
212 }
213
215 const double eligiblePoreVolume)
216 {
217 this->cnvPvSplit_ = cnvPvSplit;
218 this->eligiblePoreVolume_ = eligiblePoreVolume;
219 }
220
222 {
223 reportTime_ = std::max(reportTime_, other.reportTime_);
224 status_ = static_cast<Status>(status_ | other.status_);
225 res_failures_.insert(res_failures_.end(), other.res_failures_.begin(), other.res_failures_.end());
226 well_failures_.insert(well_failures_.end(), other.well_failures_.begin(), other.well_failures_.end());
227 res_convergence_.insert(res_convergence_.end(), other.res_convergence_.begin(), other.res_convergence_.end());
228 assert(reservoirFailed() != res_failures_.empty());
229 assert(wellFailed() != well_failures_.empty());
230 wellGroupTargetsViolated_ = (wellGroupTargetsViolated_ || other.wellGroupTargetsViolated_);
231
232 // Note regarding the CNV pore-volume split: We depend on the
233 // fact that the quantities have already been aggregated across
234 // all MPI ranks--see the implementation of member function
235 // BlackoilModel::getReservoirConvergence() for details--and are
236 // therefore equal on all ranks. Consequently, we simply assign
237 // 'other's values here, if it is non-empty. Empty splits
238 // typically come from well contributions.
239 if (! other.cnvPvSplit_.first.empty()) {
240 this->cnvPvSplit_ = other.cnvPvSplit_;
241 this->eligiblePoreVolume_ = other.eligiblePoreVolume_;
242 }
243
244 return *this;
245 }
246
247 // ----------- Const member functions (queries) -----------
248
249 double reportTime() const
250 {
251 return reportTime_;
252 }
253
254 double eligiblePoreVolume() const
255 {
256 return this->eligiblePoreVolume_;
257 }
258
259 const CnvPvSplit& cnvPvSplit() const
260 {
261 return this->cnvPvSplit_;
262 }
263
264 bool converged() const
265 {
266 return (status_ == AllGood) && !wellGroupTargetsViolated_;
267 }
268
269 bool reservoirFailed() const
270 {
271 return status_ & ReservoirFailed;
272 }
273
274 bool wellFailed() const
275 {
276 return status_ & WellFailed;
277 }
278
279 const std::vector<ReservoirFailure>& reservoirFailures() const
280 {
281 return res_failures_;
282 }
283
284 const std::vector<ReservoirConvergenceMetric>& reservoirConvergence() const
285 {
286 return res_convergence_;
287 }
288
289 const std::vector<WellFailure>& wellFailures() const
290 {
291 return well_failures_;
292 }
293
295 {
296 // A function to get the worst of two severities.
297 auto smax = [](Severity s1, Severity s2) {
298 return s1 < s2 ? s2 : s1;
299 };
300 auto s = Severity::None;
301 for (const auto& f : res_failures_) {
302 s = smax(s, f.severity());
303 }
304 for (const auto& f : well_failures_) {
305 s = smax(s, f.severity());
306 }
307 return s;
308 }
309
310 template <typename Serializer>
311 void serializeOp(Serializer& serializer)
312 {
313 serializer(this->reportTime_);
314 serializer(this->status_);
315 serializer(this->res_failures_);
316 serializer(this->well_failures_);
317 serializer(this->res_convergence_);
318 serializer(this->wellGroupTargetsViolated_);
319 serializer(this->cnvPvSplit_);
320 serializer(this->eligiblePoreVolume_);
321 }
322
323 private:
324 // ----------- Member variables -----------
325 // Note to maintainers: If you change this list of data members,
326 // then please update serializeOp() accordingly.
327 double reportTime_;
328 Status status_;
329 std::vector<ReservoirFailure> res_failures_;
330 std::vector<WellFailure> well_failures_;
331 std::vector<ReservoirConvergenceMetric> res_convergence_;
332 bool wellGroupTargetsViolated_;
333 CnvPvSplit cnvPvSplit_{};
334 double eligiblePoreVolume_{};
335 };
336
338 {
341 std::vector<ConvergenceReport> report;
342 };
343
345
347
349
351
352
353} // namespace Opm
354
355#endif // OPM_CONVERGENCEREPORT_HEADER_INCLUDED
Definition: ConvergenceReport.hpp:94
int phase() const
Definition: ConvergenceReport.hpp:105
double value() const
Definition: ConvergenceReport.hpp:106
ReservoirFailure::Type type() const
Definition: ConvergenceReport.hpp:104
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:109
ReservoirConvergenceMetric(ReservoirFailure::Type t, int phase, double value)
Definition: ConvergenceReport.hpp:100
Definition: ConvergenceReport.hpp:61
int phase() const
Definition: ConvergenceReport.hpp:75
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:78
Type
Definition: ConvergenceReport.hpp:63
ReservoirFailure(Type t, Severity s, int phase)
Definition: ConvergenceReport.hpp:69
Type type() const
Definition: ConvergenceReport.hpp:73
Severity severity() const
Definition: ConvergenceReport.hpp:74
Definition: ConvergenceReport.hpp:125
const std::string & wellName() const
Definition: ConvergenceReport.hpp:149
Type
Definition: ConvergenceReport.hpp:127
int phase() const
Definition: ConvergenceReport.hpp:148
Severity severity() const
Definition: ConvergenceReport.hpp:147
WellFailure(Type t, Severity s, int phase, const std::string &well_name)
Definition: ConvergenceReport.hpp:142
Type type() const
Definition: ConvergenceReport.hpp:146
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:152
Definition: ConvergenceReport.hpp:38
ConvergenceReport()
Definition: ConvergenceReport.hpp:171
Severity severityOfWorstFailure() const
Definition: ConvergenceReport.hpp:294
const std::vector< ReservoirConvergenceMetric > & reservoirConvergence() const
Definition: ConvergenceReport.hpp:284
void setWellFailed(const WellFailure &wf)
Definition: ConvergenceReport.hpp:197
void setWellGroupTargetsViolated(const bool wellGroupTargetsViolated)
Definition: ConvergenceReport.hpp:209
bool reservoirFailed() const
Definition: ConvergenceReport.hpp:269
const CnvPvSplit & cnvPvSplit() const
Definition: ConvergenceReport.hpp:259
void setReservoirConvergenceMetric(Args &&... args)
Definition: ConvergenceReport.hpp:204
Severity
Definition: ConvergenceReport.hpp:49
double reportTime() const
Definition: ConvergenceReport.hpp:249
void clear()
Definition: ConvergenceReport.hpp:183
ConvergenceReport(const double reportTime)
Definition: ConvergenceReport.hpp:175
bool converged() const
Definition: ConvergenceReport.hpp:264
Status
Definition: ConvergenceReport.hpp:43
@ ReservoirFailed
Definition: ConvergenceReport.hpp:45
@ AllGood
Definition: ConvergenceReport.hpp:44
@ WellFailed
Definition: ConvergenceReport.hpp:46
const std::vector< ReservoirFailure > & reservoirFailures() const
Definition: ConvergenceReport.hpp:279
const std::vector< WellFailure > & wellFailures() const
Definition: ConvergenceReport.hpp:289
void setReservoirFailed(const ReservoirFailure &rf)
Definition: ConvergenceReport.hpp:191
ConvergenceReport & operator+=(const ConvergenceReport &other)
Definition: ConvergenceReport.hpp:221
bool wellFailed() const
Definition: ConvergenceReport.hpp:274
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:311
void setCnvPoreVolSplit(const CnvPvSplit &cnvPvSplit, const double eligiblePoreVolume)
Definition: ConvergenceReport.hpp:214
std::pair< std::vector< double >, std::vector< int > > CnvPvSplit
Definition: ConvergenceReport.hpp:58
double eligiblePoreVolume() const
Definition: ConvergenceReport.hpp:254
Definition: blackoilboundaryratevector.hh:37
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
Definition: ConvergenceReport.hpp:338
std::vector< ConvergenceReport > report
Definition: ConvergenceReport.hpp:341
int report_step
Definition: ConvergenceReport.hpp:339
int current_step
Definition: ConvergenceReport.hpp:340