My Project
Loading...
Searching...
No Matches
ScheduleState.hpp
1/*
2 Copyright 2021 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 SCHEDULE_TSTEP_HPP
21#define SCHEDULE_TSTEP_HPP
22
23#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
24#include <opm/common/utility/TimeService.hpp>
25
26#include <opm/input/eclipse/EclipseState/Runspec.hpp>
27#include <opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp>
28#include <opm/input/eclipse/Schedule/Well/PAvg.hpp>
29#include <opm/input/eclipse/Schedule/Tuning.hpp>
30#include <opm/input/eclipse/Schedule/OilVaporizationProperties.hpp>
31#include <opm/input/eclipse/Schedule/Events.hpp>
32#include <opm/input/eclipse/Schedule/BCProp.hpp>
33#include <opm/input/eclipse/Schedule/Source.hpp>
34#include <opm/input/eclipse/Schedule/Group/Group.hpp>
35#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
36#include <opm/input/eclipse/Schedule/MessageLimits.hpp>
37#include <opm/input/eclipse/Schedule/VFPProdTable.hpp>
38#include <opm/input/eclipse/Schedule/VFPInjTable.hpp>
39#include <opm/input/eclipse/Schedule/RSTConfig.hpp>
40
41#include <cstddef>
42#include <memory>
43#include <optional>
44#include <type_traits>
45#include <unordered_map>
46#include <utility>
47
48namespace {
49
50[[maybe_unused]] std::string as_string(int value) {
51 return std::to_string(value);
52}
53
54[[maybe_unused]] std::string as_string(const std::string& value) {
55 return value;
56}
57
58}
59
60namespace Opm {
61
62 namespace Action {
63 class Actions;
64 }
65 class GasLiftOpt;
66 class GConSale;
67 class GConSump;
68 class GroupEconProductionLimits;
69 class GroupOrder;
70 class GuideRateConfig;
71 class NameOrder;
72 namespace Network {
73 class Balance;
74 class ExtNetwork;
75 }
76 namespace ReservoirCoupling {
77 class CouplingInfo;
78 }
79 class RFTConfig;
80 class RPTConfig;
81 class UDQActive;
82 class UDQConfig;
83 class Well;
84 class WellTestConfig;
85 class WListManager;
86
87 /*
88 The purpose of the ScheduleState class is to hold the entire Schedule
89 information, i.e. wells and groups and so on, at exactly one point in
90 time. The ScheduleState class itself has no dynamic behavior, the dynamics
91 is handled by the Schedule instance owning the ScheduleState instance.
92 */
93
95 public:
96 /*
97 In the SCHEDULE section typically all information is a function of
98 time, and the ScheduleState class is used to manage a snapshot of
99 state at one point in time. Typically a large part of the
100 configuration does not change between timesteps and consecutive
101 ScheduleState instances are very similar, to handle this many of the
102 ScheduleState members are implemented as std::shared_ptr<>s.
103
104 The ptr_member<T> class is a small wrapper around the
105 std::shared_ptr<T>. The ptr_member<T> class is meant to be internal to
106 the Schedule implementation and downstream should only access this
107 indirectly like e.g.
108
109 const auto& gconsum = sched_state.gconsump();
110
111 The remaining details of the ptr_member<T> class are heavily
112 influenced by the code used to serialize the Schedule information.
113 */
114
115
116
117 template <typename T>
119 public:
120 const T& get() const {
121 return *this->m_data;
122 }
123
124 /*
125 This will allocate new storage and assign @object to the new
126 storage.
127 */
128 void update(T object)
129 {
130 this->m_data = std::make_shared<T>( std::move(object) );
131 }
132
133 /*
134 Will reassign the pointer to point to existing shared instance
135 @other.
136 */
137 void update(const ptr_member<T>& other)
138 {
139 this->m_data = other.m_data;
140 }
141
142 const T& operator()() const {
143 return *this->m_data;
144 }
145
146 private:
147 std::shared_ptr<T> m_data;
148 };
149
150
151 /*
152 The map_member class is a quite specialized class used to internalize
153 the map variables managed in the ScheduleState. The actual value
154 objects will be stored as std::shared_ptr<T>, and only the unique
155 objects have dedicated storage. The class T must implement the method:
156
157 const K& T::name() const;
158
159 Which is used to get the storage key for the objects.
160 */
161
162 template <typename K, typename T>
164 public:
165 std::vector<K> keys() const {
166 std::vector<K> key_vector;
167 std::transform( this->m_data.begin(), this->m_data.end(), std::back_inserter(key_vector), [](const auto& pair) { return pair.first; });
168 return key_vector;
169 }
170
171
172 template <typename Predicate>
173 const T* find(Predicate&& predicate) const {
174 auto iter = std::find_if( this->m_data.begin(), this->m_data.end(), std::forward<Predicate>(predicate));
175 if (iter == this->m_data.end())
176 return nullptr;
177
178 return iter->second.get();
179 }
180
181
182 const std::shared_ptr<T> get_ptr(const K& key) const {
183 auto iter = this->m_data.find(key);
184 if (iter != this->m_data.end())
185 return iter->second;
186
187 return {};
188 }
189
190
191 bool has(const K& key) const {
192 auto ptr = this->get_ptr(key);
193 return (ptr != nullptr);
194 }
195
196
197 void update(T object) {
198 auto key = object.name();
199 this->m_data[key] = std::make_shared<T>( std::move(object) );
200 }
201
202 void update(const K& key, const map_member<K,T>& other) {
203 auto other_ptr = other.get_ptr(key);
204 if (other_ptr)
205 this->m_data[key] = other.get_ptr(key);
206 else
207 throw std::logic_error(std::string{"Tried to update member: "} + as_string(key) + std::string{"with uninitialized object"});
208 }
209
210 const T& operator()(const K& key) const {
211 return this->get(key);
212 }
213
214 const T& get(const K& key) const {
215 return *this->m_data.at(key);
216 }
217
218 T& get(const K& key) {
219 return *this->m_data.at(key);
220 }
221
222
223 std::vector<std::reference_wrapper<const T>> operator()() const {
224 std::vector<std::reference_wrapper<const T>> as_vector;
225 for (const auto& [_, elm_ptr] : this->m_data) {
226 (void)_;
227 as_vector.push_back( std::cref(*elm_ptr));
228 }
229 return as_vector;
230 }
231
232
233 std::vector<std::reference_wrapper<T>> operator()() {
234 std::vector<std::reference_wrapper<T>> as_vector;
235 for (const auto& [_, elm_ptr] : this->m_data) {
236 (void)_;
237 as_vector.push_back( std::ref(*elm_ptr));
238 }
239 return as_vector;
240 }
241
242
243 bool operator==(const map_member<K,T>& other) const {
244 if (this->m_data.size() != other.m_data.size())
245 return false;
246
247 for (const auto& [key1, ptr1] : this->m_data) {
248 const auto& ptr2 = other.get_ptr(key1);
249 if (!ptr2)
250 return false;
251
252 if (!(*ptr1 == *ptr2))
253 return false;
254 }
255 return true;
256 }
257
258
259 std::size_t size() const {
260 return this->m_data.size();
261 }
262
263 typename std::unordered_map<K, std::shared_ptr<T>>::const_iterator begin() const {
264 return this->m_data.begin();
265 }
266
267 typename std::unordered_map<K, std::shared_ptr<T>>::const_iterator end() const {
268 return this->m_data.end();
269 }
270
271
272 static map_member<K,T> serializationTestObject() {
273 map_member<K,T> map_object;
274 T value_object = T::serializationTestObject();
275 K key = value_object.name();
276 map_object.m_data.emplace( key, std::make_shared<T>( std::move(value_object) ));
277 return map_object;
278 }
279
280
281 private:
282 std::unordered_map<K, std::shared_ptr<T>> m_data;
283 };
284
285 struct BHPDefaults {
286 std::optional<double> prod_target;
287 std::optional<double> inj_limit;
288
289 static BHPDefaults serializationTestObject()
290 {
291 return BHPDefaults{1.0, 2.0};
292 }
293
294 bool operator==(const BHPDefaults& rhs) const
295 {
296 return this->prod_target == rhs.prod_target
297 && this->inj_limit == rhs.inj_limit;
298 }
299
300 template<class Serializer>
301 void serializeOp(Serializer& serializer)
302 {
303 serializer(prod_target);
304 serializer(inj_limit);
305 }
306 };
307
308 ScheduleState() = default;
309 explicit ScheduleState(const time_point& start_time);
310 ScheduleState(const time_point& start_time, const time_point& end_time);
311 ScheduleState(const ScheduleState& src, const time_point& start_time);
312 ScheduleState(const ScheduleState& src, const time_point& start_time, const time_point& end_time);
313
314
315 time_point start_time() const;
316 time_point end_time() const;
317 ScheduleState next(const time_point& next_start);
318
319 // The sim_step() is the report step we are currently simulating on. The
320 // results when we have completed sim_step=N are stored in report_step
321 // N+1.
322 std::size_t sim_step() const;
323
324 // The month_num and year_num() functions return the accumulated number
325 // of full months/years to the start of the current block.
326 std::size_t month_num() const;
327 std::size_t year_num() const;
328 bool first_in_month() const;
329 bool first_in_year() const;
330
331 bool operator==(const ScheduleState& other) const;
332 static ScheduleState serializationTestObject();
333
334 void update_tuning(Tuning tuning);
335 Tuning& tuning();
336 const Tuning& tuning() const;
337 double max_next_tstep(const bool enableTUNING = false) const;
338
339 void init_nupcol(Nupcol nupcol);
340 void update_nupcol(int nupcol);
341 int nupcol() const;
342
343 void update_oilvap(OilVaporizationProperties oilvap);
344 const OilVaporizationProperties& oilvap() const;
346
347 void update_events(Events events);
348 Events& events();
349 const Events& events() const;
350
351 void update_wellgroup_events(WellGroupEvents wgevents);
352 WellGroupEvents& wellgroup_events();
353 const WellGroupEvents& wellgroup_events() const;
354
355 void update_geo_keywords(std::vector<DeckKeyword> geo_keywords);
356 std::vector<DeckKeyword>& geo_keywords();
357 const std::vector<DeckKeyword>& geo_keywords() const;
358
359 void update_message_limits(MessageLimits message_limits);
360 MessageLimits& message_limits();
361 const MessageLimits& message_limits() const;
362
363 WellProducerCMode whistctl() const;
364 void update_whistctl(WellProducerCMode whistctl);
365
366 bool rst_file(const RSTConfig& rst_config, const time_point& previous_restart_output_time) const;
367 void update_date(const time_point& prev_time);
368 void updateSAVE(bool save);
369 bool save() const;
370
371 const std::optional<double>& sumthin() const;
372 void update_sumthin(double sumthin);
373
374 bool rptonly() const;
375 void rptonly(const bool only);
376
377 bool has_gpmaint() const;
378
379 bool hasAnalyticalAquifers() const
380 {
381 return ! this->aqufluxs.empty();
382 }
383
384 /*********************************************************************/
385
386 ptr_member<GConSale> gconsale;
387 ptr_member<GConSump> gconsump;
388 ptr_member<GroupEconProductionLimits> gecon;
389 ptr_member<GuideRateConfig> guide_rate;
390
391 ptr_member<WListManager> wlist_manager;
392 ptr_member<NameOrder> well_order;
393 ptr_member<GroupOrder> group_order;
394
395 ptr_member<Action::Actions> actions;
396 ptr_member<UDQConfig> udq;
397 ptr_member<UDQActive> udq_active;
398
399 ptr_member<PAvg> pavg;
400 ptr_member<WellTestConfig> wtest_config;
401 ptr_member<GasLiftOpt> glo;
402 ptr_member<Network::ExtNetwork> network;
403 ptr_member<Network::Balance> network_balance;
404 ptr_member<ReservoirCoupling::CouplingInfo> rescoup;
405
406 ptr_member<RPTConfig> rpt_config;
407 ptr_member<RFTConfig> rft_config;
408 ptr_member<RSTConfig> rst_config;
409
410 ptr_member<BHPDefaults> bhp_defaults;
411 ptr_member<Source> source;
412
413 template <typename T>
414 ptr_member<T>& get() {
415 return const_cast<ptr_member<T>&>(std::as_const(*this).template get<T>());
416 }
417
418 template <typename T>
419 const ptr_member<T>& get() const
420 {
421 struct always_false1 : std::false_type {};
422
423 if constexpr ( std::is_same_v<T, PAvg> )
424 return this->pavg;
425 else if constexpr ( std::is_same_v<T, WellTestConfig> )
426 return this->wtest_config;
427 else if constexpr ( std::is_same_v<T, GConSale> )
428 return this->gconsale;
429 else if constexpr ( std::is_same_v<T, GConSump> )
430 return this->gconsump;
431 else if constexpr ( std::is_same_v<T, GroupEconProductionLimits> )
432 return this->gecon;
433 else if constexpr ( std::is_same_v<T, WListManager> )
434 return this->wlist_manager;
435 else if constexpr ( std::is_same_v<T, Network::ExtNetwork> )
436 return this->network;
437 else if constexpr ( std::is_same_v<T, Network::Balance> )
438 return this->network_balance;
439 else if constexpr ( std::is_same_v<T, RPTConfig> )
440 return this->rpt_config;
441 else if constexpr ( std::is_same_v<T, Action::Actions> )
442 return this->actions;
443 else if constexpr ( std::is_same_v<T, UDQActive> )
444 return this->udq_active;
445 else if constexpr ( std::is_same_v<T, NameOrder> )
446 return this->well_order;
447 else if constexpr ( std::is_same_v<T, GroupOrder> )
448 return this->group_order;
449 else if constexpr ( std::is_same_v<T, UDQConfig> )
450 return this->udq;
451 else if constexpr ( std::is_same_v<T, GasLiftOpt> )
452 return this->glo;
453 else if constexpr ( std::is_same_v<T, GuideRateConfig> )
454 return this->guide_rate;
455 else if constexpr ( std::is_same_v<T, RFTConfig> )
456 return this->rft_config;
457 else if constexpr ( std::is_same_v<T, RSTConfig> )
458 return this->rst_config;
459 else if constexpr ( std::is_same_v<T, BHPDefaults> )
460 return this->bhp_defaults;
461 else if constexpr ( std::is_same_v<T, Source> )
462 return this->source;
463
464 else
465 static_assert(always_false1::value, "Template type <T> not supported in get()");
466 }
467
468
469 template <typename K, typename T>
470 map_member<K,T>& get_map()
471 {
472 struct always_false2 : std::false_type {};
473 if constexpr ( std::is_same_v<T, VFPProdTable> )
474 return this->vfpprod;
475 else if constexpr ( std::is_same_v<T, VFPInjTable> )
476 return this->vfpinj;
477 else if constexpr ( std::is_same_v<T, Group> )
478 return this->groups;
479 else if constexpr ( std::is_same_v<T, Well> )
480 return this->wells;
481 else
482 static_assert(always_false2::value, "Template type <K,T> not supported in get_map()");
483 }
484
485 map_member<int, VFPProdTable> vfpprod;
486 map_member<int, VFPInjTable> vfpinj;
487 map_member<std::string, Group> groups;
488 map_member<std::string, Well> wells;
489 // constant flux aquifers
490 std::unordered_map<int, SingleAquiferFlux> aqufluxs;
491 BCProp bcprop;
492 std::unordered_map<std::string, double> target_wellpi;
493 std::optional<NextStep> next_tstep;
494
495
496 using WellPIMapType = std::unordered_map<std::string, double>;
497 template<class Serializer>
498 void serializeOp(Serializer& serializer) {
499 serializer(m_start_time);
500 serializer(m_end_time);
501 serializer(m_sim_step);
502 serializer(m_month_num);
503 serializer(m_year_num);
504 serializer(m_first_in_year);
505 serializer(m_first_in_month);
506 serializer(m_save_step);
507 serializer(m_sumthin);
508 serializer(this->m_rptonly);
509 serializer(this->next_tstep);
510 serializer(m_tuning);
511 serializer(m_nupcol);
512 serializer(m_oilvap);
513 serializer(m_events);
514 serializer(m_wellgroup_events);
515 serializer(m_geo_keywords);
516 serializer(m_message_limits);
517 serializer(m_whistctl_mode);
518 serializer(target_wellpi);
519 serializer(aqufluxs);
520 serializer(bcprop);
521 }
522
523
524 private:
525 time_point m_start_time;
526 std::optional<time_point> m_end_time;
527
528 std::size_t m_sim_step = 0;
529 std::size_t m_month_num = 0;
530 std::size_t m_year_num = 0;
531 bool m_first_in_month;
532 bool m_first_in_year;
533 bool m_save_step{false};
534
535 Tuning m_tuning;
536 Nupcol m_nupcol;
537 OilVaporizationProperties m_oilvap;
538 Events m_events;
539 WellGroupEvents m_wellgroup_events;
540 std::vector<DeckKeyword> m_geo_keywords;
541 MessageLimits m_message_limits;
542 WellProducerCMode m_whistctl_mode = WellProducerCMode::CMODE_UNDEFINED;
543 std::optional<double> m_sumthin;
544 bool m_rptonly{false};
545 };
546}
547
548#endif
Definition Events.hpp:154
Definition MessageLimits.hpp:28
Definition Runspec.hpp:424
Definition OilVaporizationProperties.hpp:34
Definition RSTConfig.hpp:202
Definition ScheduleState.hpp:163
Definition ScheduleState.hpp:118
Definition ScheduleState.hpp:94
Class for (de-)serializing.
Definition Serializer.hpp:91
Definition Events.hpp:176
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition ScheduleState.hpp:285
Definition Tuning.hpp:48