My Project
GasLiftOpt.hpp
1/*
2 Copyright 2020 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#ifndef GAS_LIFT_OPT_HPP
20#define GAS_LIFT_OPT_HPP
21
22#include <optional>
23#include <string>
24#include <map>
25#include <opm/io/eclipse/rst/well.hpp>
26#include <opm/io/eclipse/rst/group.hpp>
27
28namespace Opm {
29
31public:
32
33 class Group {
34 public:
35 Group() = default;
36
37 Group(const std::string& name) :
38 m_name(name)
39 {}
40
41 static bool active(const RestartIO::RstGroup& rst_group) {
42 if ((rst_group.glift_max_rate + rst_group.glift_max_supply) != 0)
43 return false;
44
45 return true;
46 }
47
48 explicit Group(const RestartIO::RstGroup& rst_group)
49 : m_name(rst_group.name)
50 , m_max_lift_gas(rst_group.glift_max_supply)
51 , m_max_total_gas(rst_group.glift_max_rate)
52 {}
53
54 const std::optional<double>& max_lift_gas() const {
55 return this->m_max_lift_gas;
56 }
57
58 void max_lift_gas(double value) {
59 if (value >= 0)
60 this->m_max_lift_gas = value;
61 }
62
63 const std::optional<double>& max_total_gas() const {
64 return this->m_max_total_gas;
65 }
66
67 void max_total_gas(double value) {
68 if (value >= 0)
69 this->m_max_total_gas = value;
70 }
71
72 const std::string& name() const {
73 return this->m_name;
74 }
75
76 template<class Serializer>
77 void serializeOp(Serializer& serializer)
78 {
79 serializer(m_name);
80 serializer(m_max_lift_gas);
81 serializer(m_max_total_gas);
82 }
83
84
85 static Group serializationTestObject() {
86 Group group;
87 group.m_name = "GR";
88 group.m_max_lift_gas = 100;
89 group.m_max_total_gas = 200;
90 return group;
91 }
92
93
94 bool operator==(const Group& other) const {
95 return this->m_name == other.m_name &&
96 this->m_max_lift_gas == other.m_max_lift_gas &&
97 this->m_max_total_gas == other.m_max_total_gas;
98 }
99
100 private:
101 std::string m_name;
102 std::optional<double> m_max_lift_gas;
103 std::optional<double> m_max_total_gas;
104 };
105
106
107 class Well {
108 public:
109 Well() = default;
110
111 // Unfortunately it seems just using the rst_well.glift_active flag is
112 // not sufficient to determine whether the well should be included in
113 // gas lift optimization or not. The current implementation based on
114 // numerical values found in the restart file is pure guesswork.
115 static bool active(const RestartIO::RstWell& rst_well) {
116 if ((rst_well.glift_max_rate + rst_well.glift_min_rate + rst_well.glift_weight_factor == 0))
117 return false;
118
119 return true;
120 }
121
122
123 explicit Well(const RestartIO::RstWell& rst_well)
124 : m_name(rst_well.name)
125 , m_max_rate(rst_well.glift_max_rate)
126 , m_min_rate(rst_well.glift_min_rate)
127 , m_use_glo(rst_well.glift_active)
128 , m_weight(rst_well.glift_weight_factor)
129 , m_inc_weight(rst_well.glift_inc_weight_factor)
130 , m_alloc_extra_gas(rst_well.glift_alloc_extra_gas)
131 {}
132
133
134 Well(const std::string& name, bool use_glo) :
135 m_name(name),
136 m_use_glo(use_glo)
137 {}
138
139 const std::string& name() const {
140 return this->m_name;
141 }
142
143 bool use_glo() const {
144 return this->m_use_glo;
145 }
146
147 void max_rate(double value) {
148 this->m_max_rate = value;
149 }
150
151
152 /*
153 The semantics of the max_rate is quite complicated:
154
155 1. If the std::optional<double> has a value that value should be
156 used as the maximum rate and all is fine.
157
158 2. If the std::optional<double> does not a have well we must check
159 the value of Well::use_glo():
160
161 False: The maximum gas lift should have been set with WCONPROD /
162 WELTARG - this code does not provide a value in that case.
163
164 True: If the well should be controlled with gas lift optimization
165 the value to use should be the largest ALQ value in the wells
166 VFP table.
167 */
168 const std::optional<double>& max_rate() const {
169 return this->m_max_rate;
170 }
171
172 void weight_factor(double value) {
173 if (this->m_use_glo)
174 this->m_weight = value;
175 }
176
177 double weight_factor() const {
178 return this->m_weight;
179 }
180
181 void inc_weight_factor(double value) {
182 if (this->m_use_glo)
183 this->m_inc_weight = value;
184 }
185
186 double inc_weight_factor() const {
187 return this->m_inc_weight;
188 }
189
190 void min_rate(double value) {
191 if (this->m_use_glo)
192 this->m_min_rate = value;
193 }
194
195 double min_rate() const {
196 return this->m_min_rate;
197 }
198
199 void alloc_extra_gas(bool value) {
200 if (this->m_use_glo)
201 this->m_alloc_extra_gas = value;
202 }
203
204 bool alloc_extra_gas() const {
205 return this->m_alloc_extra_gas;
206 }
207
208 template<class Serializer>
209 void serializeOp(Serializer& serializer)
210 {
211 serializer(m_name);
212 serializer(m_use_glo);
213 serializer(m_max_rate);
214 serializer(m_min_rate);
215 serializer(m_weight);
216 serializer(m_inc_weight);
217 serializer(m_alloc_extra_gas);
218 }
219
220 static Well serializationTestObject() {
221 Well well;
222 well.m_name = "WELL";
223 well.m_max_rate = 2000;
224 well.m_min_rate = 56;
225 well.m_use_glo = true;
226 well.m_weight = 1.25;
227 well.m_inc_weight = 0.25;
228 well.m_alloc_extra_gas = false;
229 return well;
230 }
231
232 bool operator==(const Well& other) const {
233 return this->m_name == other.m_name &&
234 this->m_max_rate == other.m_max_rate &&
235 this->m_min_rate == other.m_min_rate &&
236 this->m_use_glo == other.m_use_glo &&
237 this->m_weight == other.m_weight &&
238 this->m_inc_weight == other.m_inc_weight &&
239 this->m_alloc_extra_gas == other.m_alloc_extra_gas;
240 }
241
242 private:
243 std::string m_name;
244 std::optional<double> m_max_rate;
245 double m_min_rate = 0;
246 bool m_use_glo = false;
247 double m_weight = 1;
248 double m_inc_weight = 0;
249 bool m_alloc_extra_gas = false;
250 };
251
252 GasLiftOpt() = default;
253
254 const Group& group(const std::string& gname) const;
255 const Well& well(const std::string& wname) const;
256
257 double gaslift_increment() const;
258 void gaslift_increment(double gaslift_increment);
259 double min_eco_gradient() const;
260 void min_eco_gradient(double min_eco_gradient);
261 double min_wait() const;
262 void min_wait(double min_wait);
263 void all_newton(double all_newton);
264 bool all_newton() const;
265 void add_group(const Group& group);
266 void add_well(const Well& well);
267 bool active() const;
268 bool has_well(const std::string& well) const;
269 bool has_group(const std::string& group) const;
270 std::size_t num_wells() const;
271
272 static GasLiftOpt serializationTestObject();
273 bool operator==(const GasLiftOpt& other) const;
274
275 template<class Serializer>
276 void serializeOp(Serializer& serializer)
277 {
278 serializer(m_increment);
279 serializer(m_min_eco_gradient);
280 serializer(m_min_wait);
281 serializer(m_all_newton);
282 serializer(m_groups);
283 serializer(m_wells);
284 }
285private:
286 double m_increment = 0;
287 double m_min_eco_gradient;
288 double m_min_wait;
289 bool m_all_newton = true;
290
291 std::map<std::string, GasLiftOpt::Group> m_groups;
292 std::map<std::string, GasLiftOpt::Well> m_wells;
293};
294
295}
296
297#endif
Definition: GasLiftOpt.hpp:33
Definition: GasLiftOpt.hpp:107
Definition: GasLiftOpt.hpp:30
Class for (de-)serializing.
Definition: Serializer.hpp:75
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29
Definition: group.hpp:33
Definition: well.hpp:43