opm-simulators
Loading...
Searching...
No Matches
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
32namespace Opm {
33
34class DeferredLogger;
35class GasLiftOpt;
36template<class Scalar> class GasLiftWellState;
37class Group;
38template<class Scalar> class GroupState;
39class Schedule;
40template<typename Scalar, typename IndexTraits> class WellInterfaceGeneric;
41template<typename Scalar, typename IndexTraits> class WellState;
42
43template<typename Scalar, typename IndexTraits>
44class GasLiftStage2 : public GasLiftCommon<Scalar, IndexTraits>
45{
46 using GasLiftSingleWell = GasLiftSingleWellGeneric<Scalar, IndexTraits>;
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
56public:
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
72protected:
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
160 struct OptimizeState
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
202 struct SurplusState
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 DeferredLogger.hpp:57
Definition GasLiftGroupInfo.hpp:46
Definition GasLiftSingleWellGeneric.hpp:48
Definition GasLiftWellState.hpp:30
Definition GroupState.hpp:41
Definition WellInterfaceGeneric.hpp:53
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition WellState.hpp:66
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilbioeffectsmodules.hh:43
Definition GasLiftSingleWellGeneric.hpp:62