opm-common
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/common/utility/gpuDecorators.hpp>
24#include <opm/common/utility/TimeService.hpp>
25
26#include <opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp>
27#include <opm/input/eclipse/EclipseState/Runspec.hpp>
28
29#include <opm/input/eclipse/Schedule/BCProp.hpp>
30#include <opm/input/eclipse/Schedule/Events.hpp>
31#include <opm/input/eclipse/Schedule/Group/Group.hpp>
32#include <opm/input/eclipse/Schedule/MessageLimits.hpp>
33#include <opm/input/eclipse/Schedule/OilVaporizationProperties.hpp>
34#include <opm/input/eclipse/Schedule/RSTConfig.hpp>
35#include <opm/input/eclipse/Schedule/Source.hpp>
36#include <opm/input/eclipse/Schedule/Tuning.hpp>
37#include <opm/input/eclipse/Schedule/VFPInjTable.hpp>
38#include <opm/input/eclipse/Schedule/VFPProdTable.hpp>
39#include <opm/input/eclipse/Schedule/Well/PAvg.hpp>
40#include <opm/input/eclipse/Schedule/Well/WCYCLE.hpp>
41#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
42
43#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
44
45#include <array>
46#include <cstddef>
47#include <iterator>
48#include <memory>
49#include <optional>
50#include <stdexcept>
51#include <string>
52#include <type_traits>
53#include <unordered_map>
54#include <utility>
55#include <vector>
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}
68
69namespace Opm {
70
71 namespace Action {
72 class Actions;
73 }
74 class GasLiftOpt;
75 class GConSale;
76 class GConSump;
78 class GroupOrder;
80 class GSatProd;
81 class GuideRateConfig;
82 class NameOrder;
83 namespace Network {
84 class Balance;
85 class ExtNetwork;
86 }
87 namespace ReservoirCoupling {
88 class CouplingInfo;
89 }
90 class RFTConfig;
91 class RPTConfig;
92 class UDQActive;
93 class UDQConfig;
94 class Well;
96 class WellTestConfig;
97 class WListManager;
98
99 /*
100 The purpose of the ScheduleState class is to hold the entire Schedule
101 information, i.e. wells and groups and so on, at exactly one point in
102 time. The ScheduleState class itself has no dynamic behavior, the dynamics
103 is handled by the Schedule instance owning the ScheduleState instance.
104 */
105
106 class ScheduleState {
107 public:
108 /*
109 In the SCHEDULE section typically all information is a function of
110 time, and the ScheduleState class is used to manage a snapshot of
111 state at one point in time. Typically a large part of the
112 configuration does not change between timesteps and consecutive
113 ScheduleState instances are very similar, to handle this many of the
114 ScheduleState members are implemented as std::shared_ptr<>s.
115
116 The ptr_member<T> class is a small wrapper around the
117 std::shared_ptr<T>. The ptr_member<T> class is meant to be internal to
118 the Schedule implementation and downstream should only access this
119 indirectly like e.g.
120
121 const auto& gconsum = sched_state.gconsump();
122
123 The remaining details of the ptr_member<T> class are heavily
124 influenced by the code used to serialize the Schedule information.
125 */
126
127
128
129 template <typename T>
131 public:
132 const T& get() const {
133 return *this->m_data;
134 }
135
136 /*
137 This will allocate new storage and assign @object to the new
138 storage.
139 */
140 void update(T object)
141 {
142 this->m_data = std::make_shared<T>( std::move(object) );
143 }
144
145 /*
146 Will reassign the pointer to point to existing shared instance
147 @other.
148 */
149 void update(const ptr_member<T>& other)
150 {
151 this->m_data = other.m_data;
152 }
153
154 const T& operator()() const {
155 return *this->m_data;
156 }
157
158 template<class Serializer>
159 void serializeOp(Serializer& serializer)
160 {
161 serializer(m_data);
162 }
163
164 private:
165 std::shared_ptr<T> m_data;
166 };
167
168
169 /*
170 The map_member class is a quite specialized class used to internalize
171 the map variables managed in the ScheduleState. The actual value
172 objects will be stored as std::shared_ptr<T>, and only the unique
173 objects have dedicated storage. The class T must implement the method:
174
175 const K& T::name() const;
176
177 Which is used to get the storage key for the objects.
178 */
179
180 template <typename K, typename T>
182 public:
183 std::vector<K> keys() const {
184 std::vector<K> key_vector;
185 std::ranges::transform(this->m_data, std::back_inserter(key_vector),
186 [](const auto& pair) { return pair.first; });
187 return key_vector;
188 }
189
190
191 template <typename Predicate>
192 const T* find(Predicate&& predicate) const {
193 const auto iter = std::ranges::find_if(this->m_data, std::forward<Predicate>(predicate));
194 if (iter == this->m_data.end()) {
195 return nullptr;
196 }
197
198 return iter->second.get();
199 }
200
201
202 const std::shared_ptr<T> get_ptr(const K& key) const {
203 auto iter = this->m_data.find(key);
204 if (iter != this->m_data.end())
205 return iter->second;
206
207 return {};
208 }
209
210
211 bool has(const K& key) const {
212 auto ptr = this->get_ptr(key);
213 return (ptr != nullptr);
214 }
215
216 void update(const K& key, std::shared_ptr<T> value) {
217 this->m_data.insert_or_assign(key, std::move(value));
218 }
219
220 void update(T object) {
221 auto key = object.name();
222 this->m_data[key] = std::make_shared<T>( std::move(object) );
223 }
224
225 void update(const K& key, const map_member<K,T>& other) {
226 auto other_ptr = other.get_ptr(key);
227 if (other_ptr)
228 this->m_data[key] = other.get_ptr(key);
229 else
230 throw std::logic_error(std::string{"Tried to update member: "} + as_string(key) + std::string{"with uninitialized object"});
231 }
232
233 const T& operator()(const K& key) const {
234 return this->get(key);
235 }
236
237 const T& get(const K& key) const {
238 return *this->m_data.at(key);
239 }
240
241 T& get(const K& key) {
242 return *this->m_data.at(key);
243 }
244
245
246 std::vector<std::reference_wrapper<const T>> operator()() const {
247 std::vector<std::reference_wrapper<const T>> as_vector;
248 for (const auto& [_, elm_ptr] : this->m_data) {
249 (void)_;
250 as_vector.push_back( std::cref(*elm_ptr));
251 }
252 return as_vector;
253 }
254
255
256 std::vector<std::reference_wrapper<T>> operator()() {
257 std::vector<std::reference_wrapper<T>> as_vector;
258 for (const auto& [_, elm_ptr] : this->m_data) {
259 (void)_;
260 as_vector.push_back( std::ref(*elm_ptr));
261 }
262 return as_vector;
263 }
264
265
266 bool operator==(const map_member<K,T>& other) const {
267 if (this->m_data.size() != other.m_data.size())
268 return false;
269
270 for (const auto& [key1, ptr1] : this->m_data) {
271 const auto& ptr2 = other.get_ptr(key1);
272 if (!ptr2)
273 return false;
274
275 if (!(*ptr1 == *ptr2))
276 return false;
277 }
278 return true;
279 }
280
281
282 std::size_t size() const {
283 return this->m_data.size();
284 }
285
286 typename std::unordered_map<K, std::shared_ptr<T>>::const_iterator begin() const {
287 return this->m_data.begin();
288 }
289
290 typename std::unordered_map<K, std::shared_ptr<T>>::const_iterator end() const {
291 return this->m_data.end();
292 }
293
294
295 static map_member<K,T> serializationTestObject() {
296 map_member<K,T> map_object;
297 T value_object = T::serializationTestObject();
298 K key = value_object.name();
299 map_object.m_data.emplace( key, std::make_shared<T>( std::move(value_object) ));
300 return map_object;
301 }
302
303 template<class Serializer>
304 void serializeOp(Serializer& serializer)
305 {
306 serializer(m_data);
307 }
308
309 private:
310 std::unordered_map<K, std::shared_ptr<T>> m_data;
311 };
312
313 struct BHPDefaults {
314 std::optional<double> prod_target;
315 std::optional<double> inj_limit;
316
317 static BHPDefaults serializationTestObject()
318 {
319 return BHPDefaults{1.0, 2.0};
320 }
321
322 bool operator==(const BHPDefaults& rhs) const
323 {
324 return this->prod_target == rhs.prod_target
325 && this->inj_limit == rhs.inj_limit;
326 }
327
328 template<class Serializer>
329 void serializeOp(Serializer& serializer)
330 {
331 serializer(prod_target);
332 serializer(inj_limit);
333 }
334 };
335
338 {
339 private:
341 enum class Ix : std::size_t {
343 Static,
344
346 Action,
347
349 Num,
350 };
351
357 static constexpr auto index(const Ix i)
358 {
359 return static_cast<std::underlying_type_t<Ix>>(i);
360 }
361
362 public:
367 {
368 this->listsChanged_[ index(Ix::Static) ] = true;
369 }
370
374 {
375 this->listsChanged_[ index(Ix::Action) ] = true;
376 }
377
380 bool changedLists() const
381 {
382 return this->listsChanged_[ index(Ix::Static) ];
383 }
384
392
395
403 bool operator==(const WellListChangeTracker& that) const
404 {
405 return this->listsChanged_ == that.listsChanged_;
406 }
407
413 template <class Serializer>
414 void serializeOp(Serializer& serializer)
415 {
416 serializer(this->listsChanged_);
417 }
418
419 private:
421 using ListChangeStatus = std::array
422 <bool, static_cast<std::underlying_type_t<Ix>>(Ix::Num)>;
423
428 ListChangeStatus listsChanged_{{false, false}};
429 };
430
431 ScheduleState() = default;
432 explicit ScheduleState(const time_point& start_time);
433 ScheduleState(const time_point& start_time, const time_point& end_time);
434 ScheduleState(const ScheduleState& src, const time_point& start_time);
435 ScheduleState(const ScheduleState& src, const time_point& start_time, const time_point& end_time);
436
437
438 time_point start_time() const;
439 time_point end_time() const;
440 ScheduleState next(const time_point& next_start);
441
442 // The sim_step() is the report step we are currently simulating on. The
443 // results when we have completed sim_step=N are stored in report_step
444 // N+1.
445 std::size_t sim_step() const;
446
447 // The month_num and year_num() functions return the accumulated number
448 // of full months/years to the start of the current block.
449 std::size_t month_num() const;
450 std::size_t year_num() const;
451 bool first_in_month() const;
452 bool first_in_year() const;
453 bool well_group_contains_lgr(const Group& grp, const std::string& lgr_tag) const;
454 bool group_contains_lgr(const Group& grp, const std::string& lgr_tag) const;
455
456 std::size_t num_lgr_well_in_group(const Group& grp, const std::string& lgr_tag) const;
457 std::size_t num_lgr_groups_in_group(const Group& grp, const std::string& lgr_tag) const;
458
459
460 bool operator==(const ScheduleState& other) const;
461 static ScheduleState serializationTestObject();
462
463 // ---- TUNING ----
464 void update_tuning(Tuning tuning);
465 Tuning& tuning();
466 const Tuning& tuning() const;
467 double max_next_tstep(const bool enableTUNING = false) const;
468
469 // ---- TUNINGDP ----
470 void update_tuning_dp(TuningDp tuningDp);
471 TuningDp& tuning_dp();
472 const TuningDp& tuning_dp() const;
473
474 void init_nupcol(Nupcol nupcol);
475 void update_nupcol(int nupcol);
476 int nupcol() const;
477
478 void update_events(Events events);
479 Events& events();
480 const Events& events() const;
481
482 void update_wellgroup_events(WellGroupEvents wgevents);
483 WellGroupEvents& wellgroup_events();
484 const WellGroupEvents& wellgroup_events() const;
485
486 void update_geo_keywords(std::vector<DeckKeyword> geo_keywords);
487 std::vector<DeckKeyword>& geo_keywords();
488 const std::vector<DeckKeyword>& geo_keywords() const;
489
490 void update_message_limits(MessageLimits message_limits);
491 MessageLimits& message_limits();
492 const MessageLimits& message_limits() const;
493
494 WellProducerCMode whistctl() const;
495 void update_whistctl(WellProducerCMode whistctl);
496
497 bool rst_file(const RSTConfig& rst_config, const time_point& previous_restart_output_time) const;
498 void update_date(const time_point& prev_time);
499 void updateSAVE(bool save);
500 bool save() const;
501
502 const std::optional<double>& sumthin() const;
503 void update_sumthin(double sumthin);
504
505 bool rptonly() const;
506 void rptonly(const bool only);
507
508 bool has_gpmaint() const;
509
510 bool hasAnalyticalAquifers() const
511 {
512 return ! this->aqufluxs.empty();
513 }
514
515 /*********************************************************************/
516
517 ptr_member<GConSale> gconsale;
518 ptr_member<GConSump> gconsump;
519 ptr_member<GSatProd> gsatprod;
522
523 ptr_member<WListManager> wlist_manager;
524 ptr_member<NameOrder> well_order;
525 ptr_member<GroupOrder> group_order;
526
529 ptr_member<UDQActive> udq_active;
530
531 ptr_member<PAvg> pavg;
532 ptr_member<WellTestConfig> wtest_config;
535 ptr_member<Network::Balance> network_balance;
537
538 ptr_member<RPTConfig> rpt_config;
539 ptr_member<RFTConfig> rft_config;
540 ptr_member<RSTConfig> rst_config;
541
543
544 ptr_member<BHPDefaults> bhp_defaults;
545 ptr_member<Source> source;
546 ptr_member<WCYCLE> wcycle;
547
549
550 template <typename T>
551 ptr_member<T>& get() {
552 return const_cast<ptr_member<T>&>(std::as_const(*this).template get<T>());
553 }
554
555 template <typename T>
556 const ptr_member<T>& get() const
557 {
558 struct always_false1 : std::false_type {};
559
560 if constexpr ( std::is_same_v<T, PAvg> )
561 return this->pavg;
562 else if constexpr ( std::is_same_v<T, WellTestConfig> )
563 return this->wtest_config;
564 else if constexpr ( std::is_same_v<T, GConSale> )
565 return this->gconsale;
566 else if constexpr ( std::is_same_v<T, GConSump> )
567 return this->gconsump;
568 else if constexpr ( std::is_same_v<T, GSatProd> )
569 return this->gsatprod;
570 else if constexpr ( std::is_same_v<T, GroupEconProductionLimits> )
571 return this->gecon;
572 else if constexpr ( std::is_same_v<T, WListManager> )
573 return this->wlist_manager;
574 else if constexpr ( std::is_same_v<T, Network::ExtNetwork> )
575 return this->network;
576 else if constexpr ( std::is_same_v<T, Network::Balance> )
577 return this->network_balance;
578 else if constexpr ( std::is_same_v<T, ReservoirCoupling::CouplingInfo> )
579 return this->rescoup;
580 else if constexpr ( std::is_same_v<T, RPTConfig> )
581 return this->rpt_config;
582 else if constexpr ( std::is_same_v<T, Action::Actions> )
583 return this->actions;
584 else if constexpr ( std::is_same_v<T, UDQActive> )
585 return this->udq_active;
586 else if constexpr ( std::is_same_v<T, NameOrder> )
587 return this->well_order;
588 else if constexpr ( std::is_same_v<T, GroupOrder> )
589 return this->group_order;
590 else if constexpr ( std::is_same_v<T, UDQConfig> )
591 return this->udq;
592 else if constexpr ( std::is_same_v<T, GasLiftOpt> )
593 return this->glo;
594 else if constexpr ( std::is_same_v<T, GuideRateConfig> )
595 return this->guide_rate;
596 else if constexpr ( std::is_same_v<T, RFTConfig> )
597 return this->rft_config;
598 else if constexpr ( std::is_same_v<T, RSTConfig> )
599 return this->rst_config;
600 else if constexpr ( std::is_same_v<T, OilVaporizationProperties> )
601 return this->oilvap;
602 else if constexpr ( std::is_same_v<T, BHPDefaults> )
603 return this->bhp_defaults;
604 else if constexpr ( std::is_same_v<T, Source> )
605 return this->source;
606 else if constexpr ( std::is_same_v<T, WCYCLE> )
607 return this->wcycle;
608 else if constexpr ( std::is_same_v<T, WellListChangeTracker> )
609 return this->wlist_tracker;
610 else {
611 #if !OPM_IS_COMPILING_WITH_GPU_COMPILER // NVCC evaluates this branch for some reason
612 static_assert(always_false1::value, "Template type <T> not supported in get()");
613 #endif
614 }
615 }
616
621
624
628
629 // constant flux aquifers
630 std::unordered_map<int, SingleAquiferFlux> aqufluxs;
631 BCProp bcprop;
632 // injection streams for compostional STREAM injection using WINJGAS
634
635 std::unordered_map<std::string, double> target_wellpi;
636 std::optional<NextStep> next_tstep;
637
638 template<class Serializer>
639 void serializeOp(Serializer& serializer)
640 {
641 serializer(gconsale);
642 serializer(gconsump);
643 serializer(gsatprod);
644 serializer(gecon);
645 serializer(guide_rate);
646 serializer(wlist_manager);
647 serializer(well_order);
648 serializer(group_order);
649 serializer(actions);
650 serializer(udq);
651 serializer(udq_active);
652 serializer(pavg);
653 serializer(wtest_config);
654 serializer(glo);
655 serializer(network);
656 serializer(network_balance);
657 serializer(rescoup);
658 serializer(rpt_config);
659 serializer(rft_config);
660 serializer(rst_config);
661 serializer(this->oilvap);
662 serializer(bhp_defaults);
663 serializer(source);
664 serializer(wcycle);
665 serializer(this->wlist_tracker);
666 serializer(vfpprod);
667 serializer(vfpinj);
668 serializer(groups);
669 serializer(wells);
670 serializer(this->satelliteInjection);
671 serializer(wseed);
672 serializer(aqufluxs);
673 serializer(bcprop);
674 serializer(inj_streams);
675 serializer(target_wellpi);
676 serializer(this->next_tstep);
677 serializer(m_start_time);
678 serializer(m_end_time);
679 serializer(m_sim_step);
680 serializer(m_month_num);
681 serializer(m_year_num);
682 serializer(m_first_in_year);
683 serializer(m_first_in_month);
684 serializer(m_save_step);
685 serializer(m_tuning);
686 serializer(m_tuning_dp);
687 serializer(m_nupcol);
688 serializer(m_events);
689 serializer(m_wellgroup_events);
690 serializer(m_geo_keywords);
691 serializer(m_message_limits);
692 serializer(m_whistctl_mode);
693 serializer(m_sumthin);
694 serializer(this->m_rptonly);
695 }
696
697 private:
698 time_point m_start_time{};
699 std::optional<time_point> m_end_time{};
700
701 std::size_t m_sim_step = 0;
702 std::size_t m_month_num = 0;
703 std::size_t m_year_num = 0;
704 bool m_first_in_month{false};
705 bool m_first_in_year{false};
706 bool m_save_step{false};
707
708 Tuning m_tuning{};
709 TuningDp m_tuning_dp{};
710 Nupcol m_nupcol{};
711 Events m_events{};
712 WellGroupEvents m_wellgroup_events{};
713 std::vector<DeckKeyword> m_geo_keywords{};
714 MessageLimits m_message_limits{};
715 WellProducerCMode m_whistctl_mode = WellProducerCMode::CMODE_UNDEFINED;
716 std::optional<double> m_sumthin{};
717 bool m_rptonly{false};
718 };
719
720} // namespace Opm
721
722#endif // SCHEDULE_TSTEP_HPP
Container of action keywords.
Definition Actions.hpp:44
Definition BCProp.hpp:92
Definition GConSale.hpp:33
Definition GConSump.hpp:33
Group level satellite production.
Definition GSatProd.hpp:37
Gas lift optimisation parameters for all wells and groups.
Definition GasLiftOpt.hpp:356
Definition GroupEconProductionLimits.hpp:36
Collection of group names with built-in ordering.
Definition NameOrder.hpp:69
Group level satellite production.
Definition GroupSatelliteInjection.hpp:33
Definition GuideRateConfig.hpp:36
Definition NameOrder.hpp:35
Definition Balance.hpp:38
Definition ExtNetwork.hpp:40
Definition RFTConfig.hpp:31
Configuration manager for RPTSCHED and RPTSOL keywords.
Definition RPTConfig.hpp:40
Definition ReservoirCouplingInfo.hpp:34
Flag for structural changes to the run's well list.
Definition ScheduleState.hpp:338
bool operator==(const WellListChangeTracker &that) const
Equality predicate.
Definition ScheduleState.hpp:403
bool changedLists() const
Report whether or not any well lists have changed since the previous report step.
Definition ScheduleState.hpp:380
void recordStaticChangedLists()
Record that one or more well lists have changed structurally in response to a WLIST keyword entered i...
Definition ScheduleState.hpp:366
static WellListChangeTracker serializationTestObject()
Create a serialisation test object.
Definition ScheduleState.cpp:85
void recordActionChangedLists()
Record that one or more well lists have changed structurally in response to a WLIST keyword entered i...
Definition ScheduleState.hpp:373
void prepareNextReportStep()
Prepare internal structure to record changes at the next report step.
Definition ScheduleState.cpp:76
void serializeOp(Serializer &serializer)
Convert between byte array and object representation.
Definition ScheduleState.hpp:414
Definition ScheduleState.hpp:181
Definition ScheduleState.hpp:130
map_member< std::string, GroupSatelliteInjection > satelliteInjection
Group level satellite injection rates.
Definition ScheduleState.hpp:623
map_member< std::string, WellFractureSeeds > wseed
Well fracturing seed points and associate fracture plane normal vectors.
Definition ScheduleState.hpp:627
Class for (de-)serializing.
Definition Serializer.hpp:94
Internalised representation of all UDAs in a simulation run.
Definition UDQActive.hpp:50
Collection of all user-defined quantities in the current simulation run.
Definition UDQConfig.hpp:69
Collection of run's known well lists.
Definition WListManager.hpp:41
Fracture seed points attached to a single well.
Definition WellFractureSeeds.hpp:32
Definition WellTestConfig.hpp:67
Definition Well.hpp:78
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition ScheduleState.hpp:313