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 
28 namespace Opm {
29 
30 class GasLiftOpt {
31 public:
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 serializeObject() {
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 serializeObject() {
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 serializeObject();
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.map(m_groups);
283  serializer.map(m_wells);
284  }
285 private:
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
Definition: Serializer.hpp:38
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:39