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 // More severe problems should have higher numbers
49 enum struct Severity {
50 None = 0,
51 Normal = 1,
52 ConvergenceMonitorFailure = 2,
53 TooLarge = 3,
54 NotANumber = 4,
55 };
56
57 struct PenaltyCard {
61
62 int total() const {
64 }
65
66 void reset()
67 {
68 nonConverged = 0;
69 distanceDecay = 0;
71 }
72
77 return *this;
78 }
79
80 template <typename Serializer>
81 void serializeOp(Serializer& serializer)
82 {
83 serializer(nonConverged);
84 serializer(distanceDecay);
85 serializer(largeWellResiduals);
86 }
87 };
88
89 using CnvPvSplit = std::pair<
90 std::vector<double>,
91 std::vector<int>>;
92
94 {
95 public:
96 enum struct Type { Invalid, MassBalance, Cnv, ConvergenceMonitorFailure };
97
98 // Default constructor needed for object serialisation. Don't
99 // use this for anything else.
100 ReservoirFailure() = default;
101
103 : type_(t), severity_(s), phase_(phase)
104 {}
105
106 Type type() const { return type_; }
107 Severity severity() const { return severity_; }
108 int phase() const { return phase_; }
109
110 template <typename Serializer>
111 void serializeOp(Serializer& serializer)
112 {
113 serializer(this->type_);
114 serializer(this->severity_);
115 serializer(this->phase_);
116 }
117
118 private:
119 // Note to maintainers: If you change this list of data members,
120 // then please update serializeOp() accordingly.
121 Type type_ { Type::Invalid };
122 Severity severity_ { Severity::None };
123 int phase_ { -1 };
124 };
125
127 {
128 public:
129 // Default constructor needed for object serialisation. Don't
130 // use this for anything else.
132
134 : type_(t), phase_(phase), value_(value), tolerance_(tolerance)
135 {}
136
137 ReservoirFailure::Type type() const { return type_; }
138 int phase() const { return phase_; }
139 double value() const { return value_; }
140 double tolerance() const { return tolerance_; }
141
142 template <typename Serializer>
143 void serializeOp(Serializer& serializer)
144 {
145 serializer(this->type_);
146 serializer(this->phase_);
147 serializer(this->value_);
148 serializer(this->tolerance_);
149 }
150
151 private:
152 // Note to maintainers: If you change this list of data members,
153 // then please update serializeOp() accordingly.
155 int phase_ { -1 };
156 double value_ { 0.0 };
157 double tolerance_ { 0.0 };
158 };
159
161 {
162 public:
163 enum struct Type {
164 Invalid,
165 MassBalance,
166 Pressure,
167 ControlBHP,
168 ControlTHP,
169 ControlRate,
170 Unsolvable,
171 WrongFlowDirection,
172 };
173
174 // Default constructor needed for object serialisation. Don't
175 // use this for anything else.
176 WellFailure() = default;
177
178 WellFailure(Type t, Severity s, int phase, const std::string& well_name)
179 : type_(t), severity_(s), phase_(phase), well_name_(well_name)
180 {}
181
182 Type type() const { return type_; }
183 Severity severity() const { return severity_; }
184 int phase() const { return phase_; }
185 const std::string& wellName() const { return well_name_; }
186
187 template <typename Serializer>
188 void serializeOp(Serializer& serializer)
189 {
190 serializer(this->type_);
191 serializer(this->severity_);
192 serializer(this->phase_);
193 serializer(this->well_name_);
194 }
195
196 private:
197 // Note to maintainers: If you change this list of data members,
198 // then please update serializeOp() accordingly.
199 Type type_ { Type::Invalid };
200 Severity severity_ { Severity::None };
201 int phase_ { -1 };
202 std::string well_name_ {};
203 };
204
206 {
207 public:
208 // Default constructor needed for object serialisation. Don't
209 // use this for anything else.
211
212 WellConvergenceMetric(WellFailure::Type t, Severity s, int phase, double value, const std::string& well_name)
213 : type_(t), severity_(s), phase_(phase), value_(value), well_name_(well_name)
214 {}
215
216 WellFailure::Type type() const { return type_; }
217 Severity severity() const { return severity_; }
218 int phase() const { return phase_; }
219 double value() const { return value_; }
220 const std::string& wellName() const { return well_name_; }
221
222 template <typename Serializer>
223 void serializeOp(Serializer& serializer)
224 {
225 serializer(this->type_);
226 serializer(this->severity_);
227 serializer(this->phase_);
228 serializer(this->value_);
229 serializer(this->well_name_);
230 }
231
232 private:
233 // Note to maintainers: If you change this list of data members,
234 // then please update serializeOp() accordingly.
236 Severity severity_ { Severity::None };
237 int phase_ { -1 };
238 double value_ { 0.0 };
239 std::string well_name_ {};
240 };
241
242 // ----------- Mutating member functions -----------
243
245 : ConvergenceReport{0.0}
246 {}
247
248 explicit ConvergenceReport(const double reportTime)
249 : reportTime_{reportTime}
250 , status_{AllGood}
251 , res_failures_{}
252 , well_failures_{}
253 , wellGroupTargetsViolated_(false)
254 , network_needs_more_balancing_force_another_newton_iteration_(false)
255 {}
256
257 void clear()
258 {
259 status_ = AllGood;
260 res_failures_.clear();
261 well_failures_.clear();
262 wellGroupTargetsViolated_ = false;
263 network_needs_more_balancing_force_another_newton_iteration_ = false;
264 }
265
267 {
268 status_ = static_cast<Status>(status_ | ReservoirFailed);
269 res_failures_.push_back(rf);
270 }
271
273 {
274 status_ = static_cast<Status>(status_ | WellFailed);
275 well_failures_.push_back(wf);
276 }
277
278 template <typename... Args>
279 void setReservoirConvergenceMetric(Args&&... args)
280 {
281 this->res_convergence_.emplace_back(std::forward<Args>(args)...);
282 }
283
284 template <typename... Args>
285 void setWellConvergenceMetric(Args&&... args)
286 {
287 this->well_convergence_.emplace_back(std::forward<Args>(args)...);
288 }
289
290 void setWellGroupTargetsViolated(const bool wellGroupTargetsViolated)
291 {
292 wellGroupTargetsViolated_ = wellGroupTargetsViolated;
293 }
294
295 void setNetworkNotYetBalancedForceAnotherNewtonIteration(const bool network_needs_more_balancing_force_another_newton_iteration)
296 {
297 network_needs_more_balancing_force_another_newton_iteration_ = network_needs_more_balancing_force_another_newton_iteration;
298 }
299
301 const double eligiblePoreVolume)
302 {
303 this->cnvPvSplit_ = cnvPvSplit;
304 this->eligiblePoreVolume_ = eligiblePoreVolume;
305 }
306
308 {
309 reportTime_ = std::max(reportTime_, other.reportTime_);
310 status_ = static_cast<Status>(status_ | other.status_);
311 res_failures_.insert(res_failures_.end(), other.res_failures_.begin(), other.res_failures_.end());
312 well_failures_.insert(well_failures_.end(), other.well_failures_.begin(), other.well_failures_.end());
313 res_convergence_.insert(res_convergence_.end(), other.res_convergence_.begin(), other.res_convergence_.end());
314 well_convergence_.insert(well_convergence_.end(), other.well_convergence_.begin(), other.well_convergence_.end());
315 assert(reservoirFailed() != res_failures_.empty());
316 assert(wellFailed() != well_failures_.empty());
317 wellGroupTargetsViolated_ = (wellGroupTargetsViolated_ || other.wellGroupTargetsViolated_);
318 network_needs_more_balancing_force_another_newton_iteration_ = (network_needs_more_balancing_force_another_newton_iteration_
319 || other.network_needs_more_balancing_force_another_newton_iteration_);
320
321 // Note regarding the CNV pore-volume split: We depend on the
322 // fact that the quantities have already been aggregated across
323 // all MPI ranks--see the implementation of member function
324 // BlackoilModel::getReservoirConvergence() for details--and are
325 // therefore equal on all ranks. Consequently, we simply assign
326 // 'other's values here, if it is non-empty. Empty splits
327 // typically come from well contributions.
328 if (! other.cnvPvSplit_.first.empty()) {
329 this->cnvPvSplit_ = other.cnvPvSplit_;
330 this->eligiblePoreVolume_ = other.eligiblePoreVolume_;
331 }
332
333 return *this;
334 }
335
336 // ----------- Const member functions (queries) -----------
337
338 double reportTime() const
339 {
340 return reportTime_;
341 }
342
343 double eligiblePoreVolume() const
344 {
345 return this->eligiblePoreVolume_;
346 }
347
348 const CnvPvSplit& cnvPvSplit() const
349 {
350 return this->cnvPvSplit_;
351 }
352
353 bool converged() const
354 {
355 return (status_ == AllGood)
356 && !wellGroupTargetsViolated_
357 && !network_needs_more_balancing_force_another_newton_iteration_;
358 }
359
360 bool reservoirFailed() const
361 {
362 return status_ & ReservoirFailed;
363 }
364
365 bool wellFailed() const
366 {
367 return status_ & WellFailed;
368 }
369
370 const std::vector<ReservoirFailure>& reservoirFailures() const
371 {
372 return res_failures_;
373 }
374
375 const std::vector<ReservoirConvergenceMetric>& reservoirConvergence() const
376 {
377 return res_convergence_;
378 }
379
380 const std::vector<WellFailure>& wellFailures() const
381 {
382 return well_failures_;
383 }
384
385 const std::vector<WellConvergenceMetric>& wellConvergence() const
386 {
387 return well_convergence_;
388 }
389
391 {
392 return penaltyCard_;
393 }
394
396 {
397 penaltyCard_.nonConverged++;
398 }
399
401 {
402 penaltyCard_.distanceDecay++;
403 }
404
406 {
407 penaltyCard_.largeWellResiduals++;
408 }
409
411 {
412 // A function to get the worst of two severities.
413 auto smax = [](Severity s1, Severity s2) {
414 return s1 < s2 ? s2 : s1;
415 };
416 auto s = Severity::None;
417 for (const auto& f : res_failures_) {
418 s = smax(s, f.severity());
419 }
420 for (const auto& f : well_failures_) {
421 s = smax(s, f.severity());
422 }
423 return s;
424 }
425
426 template <typename Serializer>
427 void serializeOp(Serializer& serializer)
428 {
429 serializer(this->reportTime_);
430 serializer(this->status_);
431 serializer(this->res_failures_);
432 serializer(this->well_failures_);
433 serializer(this->res_convergence_);
434 serializer(this->well_convergence_);
435 serializer(this->wellGroupTargetsViolated_);
436 serializer(this->network_needs_more_balancing_force_another_newton_iteration_);
437 serializer(this->cnvPvSplit_);
438 serializer(this->eligiblePoreVolume_);
439 serializer(this->penaltyCard_);
440 }
441
442 private:
443 // ----------- Member variables -----------
444 // Note to maintainers: If you change this list of data members,
445 // then please update serializeOp() accordingly.
446 double reportTime_;
447 Status status_;
448 std::vector<ReservoirFailure> res_failures_;
449 std::vector<WellFailure> well_failures_;
450 std::vector<ReservoirConvergenceMetric> res_convergence_;
451 std::vector<WellConvergenceMetric> well_convergence_;
452 bool wellGroupTargetsViolated_;
453 bool network_needs_more_balancing_force_another_newton_iteration_;
454 CnvPvSplit cnvPvSplit_{};
455 double eligiblePoreVolume_{};
456 PenaltyCard penaltyCard_;
457 };
458
460 {
463 std::vector<ConvergenceReport> report;
464 };
465
467
469
471
473
475
476
477
478} // namespace Opm
479
480#endif // OPM_CONVERGENCEREPORT_HEADER_INCLUDED
Definition: ConvergenceReport.hpp:127
int phase() const
Definition: ConvergenceReport.hpp:138
double value() const
Definition: ConvergenceReport.hpp:139
ReservoirFailure::Type type() const
Definition: ConvergenceReport.hpp:137
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:143
double tolerance() const
Definition: ConvergenceReport.hpp:140
ReservoirConvergenceMetric(ReservoirFailure::Type t, int phase, double value, double tolerance)
Definition: ConvergenceReport.hpp:133
Definition: ConvergenceReport.hpp:94
int phase() const
Definition: ConvergenceReport.hpp:108
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:111
Type
Definition: ConvergenceReport.hpp:96
ReservoirFailure(Type t, Severity s, int phase)
Definition: ConvergenceReport.hpp:102
Type type() const
Definition: ConvergenceReport.hpp:106
Severity severity() const
Definition: ConvergenceReport.hpp:107
Definition: ConvergenceReport.hpp:206
WellConvergenceMetric(WellFailure::Type t, Severity s, int phase, double value, const std::string &well_name)
Definition: ConvergenceReport.hpp:212
int phase() const
Definition: ConvergenceReport.hpp:218
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:223
double value() const
Definition: ConvergenceReport.hpp:219
WellFailure::Type type() const
Definition: ConvergenceReport.hpp:216
const std::string & wellName() const
Definition: ConvergenceReport.hpp:220
Severity severity() const
Definition: ConvergenceReport.hpp:217
Definition: ConvergenceReport.hpp:161
const std::string & wellName() const
Definition: ConvergenceReport.hpp:185
Type
Definition: ConvergenceReport.hpp:163
int phase() const
Definition: ConvergenceReport.hpp:184
Severity severity() const
Definition: ConvergenceReport.hpp:183
WellFailure(Type t, Severity s, int phase, const std::string &well_name)
Definition: ConvergenceReport.hpp:178
Type type() const
Definition: ConvergenceReport.hpp:182
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:188
Definition: ConvergenceReport.hpp:38
ConvergenceReport()
Definition: ConvergenceReport.hpp:244
Severity severityOfWorstFailure() const
Definition: ConvergenceReport.hpp:410
const std::vector< ReservoirConvergenceMetric > & reservoirConvergence() const
Definition: ConvergenceReport.hpp:375
void addDistanceDecayPenalty()
Definition: ConvergenceReport.hpp:400
void setWellFailed(const WellFailure &wf)
Definition: ConvergenceReport.hpp:272
void setWellGroupTargetsViolated(const bool wellGroupTargetsViolated)
Definition: ConvergenceReport.hpp:290
bool reservoirFailed() const
Definition: ConvergenceReport.hpp:360
const PenaltyCard & getPenaltyCard() const
Definition: ConvergenceReport.hpp:390
const CnvPvSplit & cnvPvSplit() const
Definition: ConvergenceReport.hpp:348
const std::vector< WellConvergenceMetric > & wellConvergence() const
Definition: ConvergenceReport.hpp:385
void setReservoirConvergenceMetric(Args &&... args)
Definition: ConvergenceReport.hpp:279
Severity
Definition: ConvergenceReport.hpp:49
double reportTime() const
Definition: ConvergenceReport.hpp:338
void clear()
Definition: ConvergenceReport.hpp:257
ConvergenceReport(const double reportTime)
Definition: ConvergenceReport.hpp:248
void addNonConvergedPenalty()
Definition: ConvergenceReport.hpp:395
bool converged() const
Definition: ConvergenceReport.hpp:353
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:370
const std::vector< WellFailure > & wellFailures() const
Definition: ConvergenceReport.hpp:380
void addLargeWellResidualsPenalty()
Definition: ConvergenceReport.hpp:405
void setReservoirFailed(const ReservoirFailure &rf)
Definition: ConvergenceReport.hpp:266
ConvergenceReport & operator+=(const ConvergenceReport &other)
Definition: ConvergenceReport.hpp:307
void setNetworkNotYetBalancedForceAnotherNewtonIteration(const bool network_needs_more_balancing_force_another_newton_iteration)
Definition: ConvergenceReport.hpp:295
bool wellFailed() const
Definition: ConvergenceReport.hpp:365
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:427
void setCnvPoreVolSplit(const CnvPvSplit &cnvPvSplit, const double eligiblePoreVolume)
Definition: ConvergenceReport.hpp:300
std::pair< std::vector< double >, std::vector< int > > CnvPvSplit
Definition: ConvergenceReport.hpp:91
double eligiblePoreVolume() const
Definition: ConvergenceReport.hpp:343
void setWellConvergenceMetric(Args &&... args)
Definition: ConvergenceReport.hpp:285
Definition: blackoilbioeffectsmodules.hh:43
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
Definition: ConvergenceReport.hpp:57
void serializeOp(Serializer &serializer)
Definition: ConvergenceReport.hpp:81
int nonConverged
Definition: ConvergenceReport.hpp:58
int total() const
Definition: ConvergenceReport.hpp:62
int largeWellResiduals
Definition: ConvergenceReport.hpp:60
PenaltyCard & operator+=(const PenaltyCard &other)
Definition: ConvergenceReport.hpp:73
void reset()
Definition: ConvergenceReport.hpp:66
int distanceDecay
Definition: ConvergenceReport.hpp:59
Definition: ConvergenceReport.hpp:460
std::vector< ConvergenceReport > report
Definition: ConvergenceReport.hpp:463
int report_step
Definition: ConvergenceReport.hpp:461
int current_step
Definition: ConvergenceReport.hpp:462