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