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