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