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