My Project
Loading...
Searching...
No Matches
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
34namespace {
35
36template<class BufferType, class M>
37void 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
45template<class BufferType, class M>
46void 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
60namespace Opm {
61
62class WellTestConfig;
63namespace WTest { enum class Reason; }
64
66public:
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 if (serializer.isSerializing()) {
264 std::size_t size = this->completions.size();
265 serializer(size);
266 for (auto& [well, comp_map] : this->completions) {
267 serializer(well);
268 serializer(comp_map);
269 }
270 } else {
271 std::size_t size = 0;
272 serializer(size);
273 for (std::size_t i=0; i < size; i++) {
274 std::string well;
275 std::unordered_map<int, ClosedCompletion> comp_map;
276
277 serializer(well);
278 serializer(comp_map);
279 this->completions.emplace(well, std::move(comp_map));
280 }
281 }
282 }
283
284
285 static WellTestState serializationTestObject();
286 bool operator==(const WellTestState& other) const;
287
288 std::optional<WellTestState::RestartWell> restart_well(const Opm::WellTestConfig& config, const std::string& wname) const;
289
290private:
291 std::unordered_map<std::string, WTestWell> wells;
292 std::unordered_map<std::string, std::unordered_map<int, ClosedCompletion>> completions;
293
294 std::vector<std::pair<std::string, int>> updateCompletion(const WellTestConfig& config, double sim_time);
295};
296
297
298}
299
300#endif
301
Class for (de-)serializing.
Definition Serializer.hpp:91
Definition WellTestConfig.hpp:67
Definition WellTestState.hpp:65
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition state.hpp:55
Definition WellTestState.hpp:155
Definition WellTestState.hpp:77
Definition WellTestState.hpp:96