opm-simulators
GasLiftStage2.hpp
1 /*
2  Copyright 2021 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 
20 #ifndef OPM_GASLIFT_STAGE2_HEADER_INCLUDED
21 #define OPM_GASLIFT_STAGE2_HEADER_INCLUDED
22 
23 #include <opm/simulators/wells/GasLiftSingleWellGeneric.hpp>
24 
25 #include <map>
26 #include <memory>
27 #include <optional>
28 #include <string>
29 #include <tuple>
30 #include <vector>
31 
32 namespace Opm {
33 
34 class DeferredLogger;
35 class GasLiftOpt;
36 template<class Scalar> class GasLiftWellState;
37 class Group;
38 template<class Scalar> class GroupState;
39 class Schedule;
40 template<typename Scalar, typename IndexTraits> class WellInterfaceGeneric;
41 template<typename Scalar, typename IndexTraits> class WellState;
42 
43 template<typename Scalar, typename IndexTraits>
44 class GasLiftStage2 : public GasLiftCommon<Scalar, IndexTraits>
45 {
47  using GLiftOptWells = std::map<std::string,std::unique_ptr<GasLiftSingleWell>>;
48  using GLiftProdWells = std::map<std::string,const WellInterfaceGeneric<Scalar, IndexTraits>*>;
49  using GLiftWellStateMap = std::map<std::string,std::unique_ptr<GasLiftWellState<Scalar>>>;
50  using GradPair = std::pair<std::string, Scalar>;
51  using GradPairItr = typename std::vector<GradPair>::iterator;
53  using GradMap = std::map<std::string, GradInfo>;
54  using MessageType = typename GasLiftCommon<Scalar, IndexTraits>::MessageType;
55 
56 public:
57  GasLiftStage2(const int report_step_idx,
58  const Parallel::Communication& comm,
59  const Schedule& schedule,
60  const SummaryState& summary_state,
61  DeferredLogger& deferred_logger,
63  const GroupState<Scalar>& group_state,
64  GLiftProdWells& prod_wells,
65  GLiftOptWells& glift_wells,
67  GLiftWellStateMap& state_map,
68  bool glift_debug);
69 
70  void runOptimize();
71 
72 protected:
73  void addOrRemoveALQincrement_(GradMap& grad_map,
74  const std::string& well_name,
75  bool add);
76 
77  std::optional<GradInfo> calcIncOrDecGrad_(const std::string name,
78  const GasLiftSingleWell& gs_well,
79  const std::string& gr_name_dont_limit,
80  bool increase);
81 
82  bool checkRateAlreadyLimited_(const std::string& well_name,
84  bool increase);
85 
86  GradInfo deleteDecGradItem_(const std::string& name);
87  GradInfo deleteIncGradItem_(const std::string& name);
88  GradInfo deleteGrad_(const std::string& name, bool increase);
89 
90  void displayDebugMessage_(const std::string& msg) const override;
91  void displayDebugMessage2B_(const std::string& msg);
92  void displayDebugMessage_(const std::string& msg,
93  const std::string& group_name);
94  void displayWarning_(const std::string& msg,
95  const std::string& group_name);
96  void displayWarning_(const std::string& msg);
97 
98  std::tuple<Scalar, Scalar, Scalar, Scalar>
99  getCurrentGroupRates_(const Group& group);
100 
101  std::optional<Scalar> getGroupMaxALQ_(const Group& group);
102  std::optional<Scalar> getGroupMaxTotalGas_(const Group& group);
103 
104  std::vector<GasLiftSingleWell*> getGroupGliftWells_(const Group& group);
105 
106  void getGroupGliftWellsRecursive_(const Group& group,
107  std::vector<GasLiftSingleWell*>& wells);
108 
109  void optimizeGroup_(const Group& group);
110  void optimizeGroupsRecursive_(const Group& group);
111 
112  void recalculateGradientAndUpdateData_(GradPairItr& grad_itr,
113  const std::string& gr_name_dont_limit,
114  bool increase,
115  std::vector<GradPair>& grads,
116  std::vector<GradPair>& other_grads);
117 
118  void redistributeALQ_(std::vector<GasLiftSingleWell*>& wells,
119  const Group& group,
120  std::vector<GradPair>& inc_grads,
121  std::vector<GradPair>& dec_grads);
122 
123  void removeSurplusALQ_(const Group& group,
124  std::vector<GradPair>& dec_grads);
125 
126  void saveGrad_(GradMap& map, const std::string& name, GradInfo& grad);
127  void saveDecGrad_(const std::string& name, GradInfo& grad);
128  void saveIncGrad_(const std::string& name, GradInfo& grad);
129  void sortGradients_(std::vector<GradPair>& grads);
130 
131  std::optional<GradInfo> updateGrad_(const std::string& name,
132  GradInfo& grad, bool increase);
133 
134  void updateGradVector_(const std::string& name,
135  std::vector<GradPair>& grads,
136  Scalar grad);
137 
138  void mpiSyncGlobalGradVector_(std::vector<GradPair>& grads_global) const;
139  void mpiSyncLocalToGlobalGradVector_(const std::vector<GradPair>& grads_local,
140  std::vector<GradPair>& grads_global) const;
141 
142  std::array<Scalar, 4> computeDelta(const std::string& name, bool add);
143  void updateGroupInfo(const std::string& name, bool add);
144 
145 
146  GLiftProdWells& prod_wells_;
147  GLiftOptWells& stage1_wells_;
149  GLiftWellStateMap& well_state_map_;
150 
151  int report_step_idx_;
152  const SummaryState& summary_state_;
153  const Schedule& schedule_;
154  const GasLiftOpt& glo_;
155  GradMap inc_grads_;
156  GradMap dec_grads_;
157  int max_iterations_ = 1000;
158  //int time_step_idx_;
159 
161  {
162  OptimizeState(GasLiftStage2& parent_, const Group& group_)
163  : parent{parent_}
164  , group{group_}
165  , it{0}
166  {}
167 
168  GasLiftStage2& parent;
169  const Group& group;
170  int it;
171 
172  using GradInfo = typename GasLiftStage2::GradInfo;
173  using GradPair = typename GasLiftStage2::GradPair;
174  using GradPairItr = typename GasLiftStage2::GradPairItr;
175  using GradMap = typename GasLiftStage2::GradMap;
176 
177  void calculateEcoGradients(std::vector<GasLiftSingleWell*>& wells,
178  std::vector<GradPair>& inc_grads,
179  std::vector<GradPair>& dec_grads);
180 
181  bool checkAtLeastTwoWells(std::vector<GasLiftSingleWell*>& wells);
182 
183  void debugShowIterationInfo();
184 
185  std::pair<std::optional<GradPairItr>,std::optional<GradPairItr>>
186  getEcoGradients(std::vector<GradPair>& inc_grads,
187  std::vector<GradPair>& dec_grads);
188 
189  void recalculateGradients(std::vector<GradPair>& inc_grads,
190  std::vector<GradPair>& dec_grads,
191  GradPairItr& min_dec_grad_itr,
192  GradPairItr &max_inc_grad_itr);
193 
194  void redistributeALQ( GradPairItr& min_dec_grad,
195  GradPairItr& max_inc_grad);
196 
197  private:
198  void displayDebugMessage_(const std::string& msg);
199  void displayWarning_(const std::string& msg);
200  };
201 
203  {
204  SurplusState(GasLiftStage2& parent_,
205  const Group& group_,
206  const WellState<Scalar, IndexTraits>& well_state_,
207  Scalar oil_rate_,
208  Scalar gas_rate_,
209  Scalar water_rate_,
210  Scalar alq_,
211  Scalar min_eco_grad_,
212  Scalar oil_target_,
213  Scalar gas_target_,
214  Scalar water_target_,
215  Scalar liquid_target_,
216  std::optional<Scalar> max_glift_,
217  std::optional<Scalar> max_total_gas_)
218  : parent{parent_}
219  , group{group_}
220  , well_state(well_state_)
221  , oil_rate{oil_rate_}
222  , gas_rate{gas_rate_}
223  , water_rate{water_rate_}
224  , alq{alq_}
225  , min_eco_grad{min_eco_grad_}
226  , oil_target{oil_target_}
227  , gas_target{gas_target_}
228  , water_target(water_target_)
229  , liquid_target{liquid_target_}
230  , max_glift{max_glift_}
231  , max_total_gas{max_total_gas_}
232  , it{0}
233  {}
234 
235  GasLiftStage2 &parent;
236  const Group &group;
237  const WellState<Scalar, IndexTraits>& well_state;
238  Scalar oil_rate;
239  Scalar gas_rate;
240  Scalar water_rate;
241  Scalar alq;
242  const Scalar min_eco_grad;
243  const Scalar oil_target;
244  const Scalar gas_target;
245  const Scalar water_target;
246  const Scalar liquid_target;
247  std::optional<Scalar> max_glift;
248  std::optional<Scalar> max_total_gas;
249  int it;
250 
251  void addOrRemoveALQincrement(GradMap &grad_map,
252  const std::string& well_name,
253  bool add);
254 
255  bool checkALQlimit();
256  bool checkEcoGradient(const std::string& well_name, Scalar eco_grad);
257  bool checkGasTarget(Scalar delta_gas);
258  bool checkLiquidTarget(Scalar delta_liquid);
259  bool checkOilTarget(Scalar delta_oil);
260  bool checkWaterTarget(Scalar delta_water);
261  std::array<Scalar, 4> computeDelta(const std::string& name);
262  void updateRates(const std::array<Scalar, 4>& delta);
263  };
264 };
265 
266 } // namespace Opm
267 
268 #endif // OPM_GASLIFT_STAGE2_HEADER_INCLUDED
Definition: BlackoilWellModelGeneric.hpp:66
Definition: BlackoilWellModelConstraints.hpp:34
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Definition: BlackoilWellModelGeneric.hpp:65
Definition: GasLiftSingleWellGeneric.hpp:61
Definition: DeferredLogger.hpp:56
Definition: BlackoilWellModelGeneric.hpp:67
Definition: GasLiftStage2.hpp:44
Definition: GasLiftCommon.hpp:34
Definition: GasLiftStage2.hpp:160
Definition: GasLiftStage2.hpp:202
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition: TemperatureModel.hpp:61