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