opm-common
WellTestState.hpp
1 /*
2  Copyright 2018 Statoil 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 #ifndef WELLTEST_STATE_H
20 #define WELLTEST_STATE_H
21 
22 #include <opm/input/eclipse/Schedule/Well/WellTestConfig.hpp>
23 
24 #include <opm/io/eclipse/rst/state.hpp>
25 
26 #include <cstddef>
27 #include <ctime>
28 #include <optional>
29 #include <string>
30 #include <unordered_map>
31 #include <utility>
32 #include <vector>
33 
34 namespace {
35 
36 template<class BufferType, class M>
37 void pack_map(BufferType& buffer, const M& m) {
38  buffer.write(m.size());
39  for (const auto& [k,v] : m) {
40  buffer.write(k);
41  v.pack(buffer);
42  }
43 }
44 
45 template<class BufferType, class M>
46 void unpack_map(BufferType& buffer, M& m) {
47  typename M::size_type size;
48  buffer.read(size);
49  for (std::size_t i = 0; i < size; i++) {
50  typename M::key_type k;
51  typename M::mapped_type v;
52  buffer.read(k);
53  v.unpack(buffer);
54  m.emplace(std::move(k), std::move(v));
55  }
56 }
57 
58 }
59 
60 namespace Opm {
61 
62 class WellTestConfig;
63 namespace WTest { enum class Reason; }
64 
66 public:
67  /*
68  This class implements a small mutable state object which keeps track of
69  which wells have been automatically closed by the simulator through the
70  WTEST mechanism.
71 
72  The default behavior of the container is to manage *closed* wells, but
73  since the counter mechanism for the maximum number of opening attempts
74  should maintain the same counter through open/close events we need to
75  manage the well object also after they have been opened up again.
76  */
77  struct RestartWell {
78  std::string name;
79  double test_interval;
80  int num_test;
81  double startup_time;
82 
83  int config_reasons;
84  int close_reason;
85 
86  RestartWell(const std::string& wname, double ti, int num, double st, int r1, int r2)
87  : name(wname)
88  , test_interval(ti)
89  , num_test(num)
90  , startup_time(st)
91  , config_reasons(r1)
92  , close_reason(r2)
93  {};
94  };
95 
96  struct WTestWell {
97  std::string name{};
98  WTest::Reason reason{WTest::Reason::NONE};
99  double last_test{};
100 
101  int num_attempt{0};
102  bool closed{true};
103  std::optional<int> wtest_report_step{};
104 
105  WTestWell() = default;
106  WTestWell(const std::string& wname, WTest::Reason reason_, double last_test);
107 
108  int int_reason() const;
109  static WTest::Reason inverse_ecl_reason(int ecl_reason);
110 
111  bool operator==(const WTestWell& other) const {
112  return this->name == other.name &&
113  this->reason == other.reason &&
114  this->last_test == other.last_test &&
115  this->num_attempt == other.num_attempt &&
116  this->closed == other.closed &&
117  this->wtest_report_step == other.wtest_report_step;
118  }
119 
120  static WTestWell serializationTestObject();
121 
122  template<class Serializer>
123  void serializeOp(Serializer& serializer)
124  {
125  serializer(this->name);
126  serializer(this->reason);
127  serializer(this->last_test);
128  serializer(this->num_attempt);
129  serializer(this->closed);
130  serializer(this->wtest_report_step);
131  }
132 
133  template<class BufferType>
134  void pack(BufferType& buffer) const {
135  buffer.write(this->name);
136  buffer.write(this->reason);
137  buffer.write(this->last_test);
138  buffer.write(this->num_attempt);
139  buffer.write(this->closed);
140  buffer.write(this->wtest_report_step);
141  }
142 
143  template<class BufferType>
144  void unpack(BufferType& buffer) {
145  buffer.read(this->name);
146  buffer.read(this->reason);
147  buffer.read(this->last_test);
148  buffer.read(this->num_attempt);
149  buffer.read(this->closed);
150  buffer.read(this->wtest_report_step);
151  }
152  };
153 
154 
156  std::string wellName{};
157  int complnum{};
158  double last_test{};
159  int num_attempt{};
160 
161  bool operator==(const ClosedCompletion& other) const {
162  return this->wellName == other.wellName &&
163  this->complnum == other.complnum &&
164  this->last_test == other.last_test &&
165  this->num_attempt == other.num_attempt;
166  }
167 
168  static ClosedCompletion serializationTestObject();
169 
170  template<class Serializer>
171  void serializeOp(Serializer& serializer)
172  {
173  serializer(this->wellName);
174  serializer(this->complnum);
175  serializer(this->last_test);
176  serializer(this->num_attempt);
177  }
178 
179  template<class BufferType>
180  void pack(BufferType& buffer) const {
181  buffer.write(this->wellName);
182  buffer.write(this->complnum);
183  buffer.write(this->last_test);
184  buffer.write(this->num_attempt);
185  }
186 
187  template<class BufferType>
188  void unpack(BufferType& buffer) {
189  buffer.read(this->wellName);
190  buffer.read(this->complnum);
191  buffer.read(this->last_test);
192  buffer.read(this->num_attempt);
193  }
194  };
195 
196  WellTestState() = default;
197  WellTestState(std::time_t start_time, const RestartIO::RstState& rst_state);
198 
199 
200  std::vector<std::string> test_wells(const WellTestConfig& config, double sim_time);
201  void filter_wells(const std::vector<std::string>& existing_wells);
202  /*
203  The purpose of this container is to manage explicitly *closed wells*,
204  since the class has no relation to the set of of wells defined in the
205  Schedule section the concept of open wells and totally unknown wells is
206  slightly murky:
207 
208  well_is_closed("UNKOWN_WELL") -> false
209 
210  This implies that we have not explicitly closed a well with name
211  'UNKNOWN_WELL', but since we do not know whether the well is at all
212  defined it does not make sense to extrapolate to:
213 
214  well_is_open("UNKNOWN_WELL") -> true.
215 
216  That is the reason we do not have any xxx_is_open() predicates.
217  */
218  void close_well(const std::string& well_name, WTest::Reason reason, double sim_time);
219  bool well_is_closed(const std::string& well_name) const;
220  void open_well(const std::string& well_name);
221  std::size_t num_closed_wells() const;
222  double lastTestTime(const std::string& well_name) const;
223 
224  void close_completion(const std::string& well_name, int complnum, double sim_time);
225  void open_completion(const std::string& well_name, int complnum);
226  void open_completions(const std::string& well_name);
227  bool completion_is_closed(const std::string& well_name, const int complnum) const;
228  std::size_t num_closed_completions() const;
229 
230  void clear();
231 
232 
233  template<class BufferType>
234  void pack(BufferType& buffer) const {
235  pack_map(buffer, this->wells);
236 
237  buffer.write(this->completions.size());
238  for (const auto& [well, cmap] : this->completions) {
239  buffer.write(well);
240  pack_map(buffer, cmap);
241  }
242  }
243 
244  template<class BufferType>
245  void unpack(BufferType& buffer) {
246  unpack_map(buffer, this->wells);
247  std::size_t size;
248  buffer.read(size);
249  for (std::size_t i = 0; i < size; i++) {
250  std::string well;
251  std::unordered_map<int, ClosedCompletion> cmap;
252 
253  buffer.read(well);
254  unpack_map(buffer, cmap);
255  this->completions.emplace(std::move(well), std::move(cmap));
256  }
257  }
258 
259  template<class Serializer>
260  void serializeOp(Serializer& serializer)
261  {
262  serializer(this->wells);
263  serializer(this->completions);
264  }
265 
266  static WellTestState serializationTestObject();
267  bool operator==(const WellTestState& other) const;
268 
269  std::optional<WellTestState::RestartWell> restart_well(const Opm::WellTestConfig& config, const std::string& wname) const;
270 
271 private:
272  std::map<std::string, WTestWell> wells; // distributed wells must be ordered uniformly across ranks
273  std::unordered_map<std::string, std::unordered_map<int, ClosedCompletion>> completions;
274 
275  std::vector<std::pair<std::string, int>> updateCompletion(const WellTestConfig& config, double sim_time);
276 };
277 
278 
279 }
280 
281 #endif
Definition: state.hpp:56
Definition: WellTestState.hpp:96
Definition: WellTestState.hpp:155
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Definition: WellTestState.hpp:65
Definition: WellTestConfig.hpp:67
Class for (de-)serializing.
Definition: Serializer.hpp:94
Definition: WellTestState.hpp:77