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