opm-simulators
GasLiftGroupInfo.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_GROUP_INFO_HEADER_INCLUDED
21 #define OPM_GASLIFT_GROUP_INFO_HEADER_INCLUDED
22 
23 #include <opm/simulators/flow/NewtonIterationContext.hpp>
24 #include <opm/simulators/wells/GasLiftCommon.hpp>
25 
26 #include <map>
27 #include <optional>
28 #include <string>
29 #include <tuple>
30 #include <vector>
31 
32 namespace Opm {
33 
34 class DeferredLogger;
35 class GasLiftOpt;
36 class Group;
37 template<class Scalar> class GroupState;
38 template<typename IndexTraits> class PhaseUsageInfo;
39 class Schedule;
40 class SummaryState;
41 class Well;
42 template<typename Scalar, typename IndexTraits> class WellState;
43 
44 
45 template<typename Scalar, typename IndexTraits>
46 class GasLiftGroupInfo : public GasLiftCommon<Scalar, IndexTraits>
47 {
48 protected:
49  class GroupRates;
50  // NOTE: In the Well2GroupMap below, in the std::vector value we store
51  // pairs of group names and efficiency factors. The efficiency factors
52  // are the product of the wells efficiency factor and all the efficiency
53  // factors of the child groups of the group all the way down
54  // to the well group.
55  using Well2GroupMap =
56  std::map<std::string, std::vector<std::pair<std::string, Scalar>>>;
57  using GroupRateMap =
58  std::map<std::string, GroupRates>;
59  using GroupIdxMap = std::map<std::string, int>;
60  using Communication = Dune::Communication<Dune::MPIHelper::MPICommunicator>;
61 
62 public:
63  enum class Rate {oil, gas, water, liquid};
64 
65  using GLiftEclWells = std::map<std::string,std::pair<const Well *,int>>;
66  GasLiftGroupInfo(GLiftEclWells& ecl_wells,
67  const Schedule& schedule,
68  const SummaryState& summary_state,
69  const int report_step_idx,
70  const NewtonIterationContext& iterCtx,
71  DeferredLogger& deferred_logger,
73  const GroupState<Scalar>& group_state,
74  const Parallel::Communication& comm,
75  bool glift_debug);
76 
77  std::vector<std::pair<std::string,Scalar>>&
78  getWellGroups(const std::string& well_name);
79 
80  Scalar alqRate(const std::string& group_name);
81  Scalar gasRate(const std::string& group_name) const;
82  Scalar gasPotential(const std::string& group_name) const;
83  Scalar waterPotential(const std::string& group_name) const;
84  Scalar oilPotential(const std::string& group_name) const;
85  int getGroupIdx(const std::string& group_name);
86  Scalar getRate(Rate rate_type, const std::string& group_name) const;
87  Scalar getPotential(Rate rate_type, const std::string& group_name) const;
88  std::tuple<Scalar,Scalar,Scalar,Scalar> getRates(const int group_idx) const;
89  std::optional<Scalar> gasTarget(const std::string& group_name) const;
90  std::optional<Scalar> getTarget(Rate rate_type, const std::string& group_name) const;
91  const std::string& groupIdxToName(int group_idx) const;
92  bool hasAnyTarget(const std::string& group_name) const;
93  bool hasWell(const std::string& well_name);
94  void initialize();
95  std::optional<Scalar> liquidTarget(const std::string& group_name) const;
96  std::optional<Scalar> maxAlq(const std::string& group_name);
97  std::optional<Scalar> maxTotalGasRate(const std::string& group_name);
98  Scalar oilRate(const std::string& group_name) const;
99  std::optional<Scalar> oilTarget(const std::string& group_name) const;
100  static const std::string rateToString(Rate rate);
101  Scalar waterRate(const std::string& group_name) const;
102  std::optional<Scalar> waterTarget(const std::string& group_name) const;
103  void update(const std::string& well_name,
104  Scalar delta_oil,
105  Scalar delta_gas,
106  Scalar delta_water,
107  Scalar delta_alq);
108  void updateRate(int idx,
109  Scalar oil_rate,
110  Scalar gas_rate,
111  Scalar water_rate,
112  Scalar alq);
113  const Well2GroupMap& wellGroupMap() { return well_group_map_; }
114 
115 protected:
116  bool checkDoGasLiftOptimization_(const std::string& well_name);
117  bool checkNewtonIterationIdxOk_(const std::string& well_name);
118  void debugDisplayWellContribution_(const std::string& gr_name,
119  const std::string& well_name,
120  Scalar eff_factor,
121  Scalar well_oil_rate,
122  Scalar well_gas_rate,
123  Scalar well_water_rate,
124  Scalar well_alq,
125  Scalar oil_rate,
126  Scalar gas_rate,
127  Scalar water_rate,
128  Scalar alq) const;
129  void debugDisplayUpdatedGroupRates(const std::string& name,
130  Scalar oil_rate,
131  Scalar gas_rate,
132  Scalar water_rate,
133  Scalar alq) const;
134  void debugEndInitializeGroup(const std::string& name) const;
135  void debugStartInitializeGroup(const std::string& name) const;
136  void displayDebugMessage_(const std::string& msg) const override;
137  void displayDebugMessage_(const std::string& msg, const std::string& well_name);
138 
139  std::tuple<Scalar, Scalar, Scalar, Scalar, Scalar, Scalar>
140  getProducerWellRates_(const Well* well, const int index);
141 
142  std::tuple<Scalar, Scalar, Scalar, Scalar, Scalar, Scalar, Scalar>
143  initializeGroupRatesRecursive_(const Group &group);
144 
145  void initializeWell2GroupMapRecursive_(const Group& group,
146  std::vector<std::string>& group_names,
147  std::vector<Scalar>& group_efficiency,
148  Scalar cur_efficiency);
149  void updateGroupIdxMap_(const std::string& group_name);
150 
151  class GroupRates {
152  public:
153  GroupRates(Scalar oil_rate,
154  Scalar gas_rate,
155  Scalar water_rate,
156  Scalar alq,
157  Scalar oil_potential,
158  Scalar gas_potential,
159  Scalar water_potential,
160  std::optional<Scalar> oil_target,
161  std::optional<Scalar> gas_target,
162  std::optional<Scalar> water_target,
163  std::optional<Scalar> liquid_target,
164  std::optional<Scalar> total_gas,
165  std::optional<Scalar> max_alq)
166  : oil_rate_{oil_rate}
167  , gas_rate_{gas_rate}
168  , water_rate_{water_rate}
169  , alq_{alq}
170  , oil_potential_{oil_potential}
171  , gas_potential_{gas_potential}
172  , water_potential_{water_potential}
173  , oil_target_{oil_target}
174  , gas_target_{gas_target}
175  , water_target_{water_target}
176  , liquid_target_{liquid_target}
177  , total_gas_{total_gas}
178  , max_alq_{max_alq}
179  {}
180 
181  Scalar alq() const { return alq_; }
182  void assign(Scalar oil_rate,
183  Scalar gas_rate,
184  Scalar water_rate,
185  Scalar alq)
186  {
187  oil_rate_ = oil_rate;
188  gas_rate_ = gas_rate;
189  water_rate_ = water_rate;
190  alq_ = alq;
191  }
192  Scalar gasRate() const { return gas_rate_; }
193  Scalar waterRate() const { return water_rate_; }
194  std::optional<Scalar> gasTarget() const { return gas_target_; }
195  std::optional<Scalar> waterTarget() const { return water_target_; }
196  std::optional<Scalar> maxAlq() const { return max_alq_; }
197  std::optional<Scalar > maxTotalGasRate() const { return total_gas_; }
198  Scalar oilRate() const { return oil_rate_; }
199  std::optional<Scalar> oilTarget() const { return oil_target_; }
200  std::optional<Scalar> liquidTarget() const { return liquid_target_; }
201  Scalar oilPotential() const { return oil_potential_; }
202  Scalar gasPotential() const { return gas_potential_; }
203  Scalar waterPotential() const { return water_potential_; }
204 
205  void update(Scalar delta_oil,
206  Scalar delta_gas,
207  Scalar delta_water,
208  Scalar delta_alq)
209  {
210  oil_rate_ += delta_oil;
211  gas_rate_ += delta_gas;
212  water_rate_ += delta_water;
213  alq_ += delta_alq;
214  // Note. We don't updata the potentials at this point. They
215  // are only needed initially.
216  }
217 
218  private:
219  Scalar oil_rate_;
220  Scalar gas_rate_;
221  Scalar water_rate_;
222  Scalar alq_;
223  Scalar oil_potential_;
224  Scalar gas_potential_;
225  Scalar water_potential_;
226  std::optional<Scalar> oil_target_;
227  std::optional<Scalar> gas_target_;
228  std::optional<Scalar> water_target_;
229  std::optional<Scalar> liquid_target_;
230  std::optional<Scalar> total_gas_;
231  std::optional<Scalar> max_alq_;
232  };
233 
234  GLiftEclWells& ecl_wells_;
235  const Schedule& schedule_;
236  const SummaryState& summary_state_;
237  const int report_step_idx_;
238  const NewtonIterationContext& iterCtx_;
239  const PhaseUsageInfo<IndexTraits>& phase_usage_;
240  const GasLiftOpt& glo_;
241  GroupRateMap group_rate_map_;
242  Well2GroupMap well_group_map_;
243  GroupIdxMap group_idx_;
244  int next_group_idx_ = 0;
245  // Optimize only wells under THP control
246  bool optimize_only_thp_wells_ = false;
247 };
248 
249 } // namespace Opm
250 
251 #endif // OPM_GASLIFT_GROUP_INFO_INCLUDED
Context for iteration-dependent decisions in the Newton solver.
Definition: NewtonIterationContext.hpp:43
Definition: GasLiftGroupInfo.hpp:151
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: DeferredLogger.hpp:56
Definition: GasLiftGroupInfo.hpp:38
Definition: GasLiftCommon.hpp:34
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition: TemperatureModel.hpp:61