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