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