My Project
WellInterfaceGeneric.hpp
1 /*
2  Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
3  Copyright 2017 Statoil ASA.
4  Copyright 2017 IRIS
5  Copyright 2019 Norce
6 
7  This file is part of the Open Porous Media project (OPM).
8 
9  OPM is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OPM is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OPM. If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 
24 #ifndef OPM_WELLINTERFACE_GENERIC_HEADER_INCLUDED
25 #define OPM_WELLINTERFACE_GENERIC_HEADER_INCLUDED
26 
27 #include <opm/input/eclipse/Schedule/Well/Well.hpp>
28 
29 #include <map>
30 #include <optional>
31 #include <string>
32 #include <vector>
33 
34 namespace Opm
35 {
36 
37 class DeferredLogger;
38 class GuideRate;
39 class ParallelWellInfo;
40 struct PerforationData;
41 struct PhaseUsage;
42 class SummaryState;
43 class VFPProperties;
44 class WellTestState;
45 class WellState;
46 class SingleWellState;
47 class GroupState;
48 class Group;
49 class Schedule;
50 
52 public:
53 
54  static constexpr bool extraBhpAtThpLimitProdOutput = false;
55 
56  WellInterfaceGeneric(const Well& well,
57  const ParallelWellInfo& parallel_well_info,
58  const int time_step,
59  const int pvtRegionIdx,
60  const int num_components,
61  const int num_phases,
62  const int index_of_well,
63  const std::vector<PerforationData>& perf_data);
64 
66  const std::vector<PerforationData>& perforationData() const;
67 
69  const std::string& name() const;
70 
72  bool isInjector() const;
73 
75  bool isProducer() const;
76 
78  const std::vector<int>& cells() const { return well_cells_; }
79 
81  int indexOfWell() const;
82 
83  void adaptRatesForVFP(std::vector<double>& rates) const;
84 
85  const Well& wellEcl() const;
86  const PhaseUsage& phaseUsage() const;
87 
89  bool underPredictionMode() const;
90 
91  // whether the well is operable
92  bool isOperableAndSolvable() const;
93  bool useVfpExplicit () const;
94  bool thpLimitViolatedButNotSwitched() const;
95 
96  void initCompletions();
97  void closeCompletions(const WellTestState& wellTestState);
98 
99  void setVFPProperties(const VFPProperties* vfp_properties_arg);
100  void setGuideRate(const GuideRate* guide_rate_arg);
101  void setWellEfficiencyFactor(const double efficiency_factor);
102  void setRepRadiusPerfLength();
103  void setWsolvent(const double wsolvent);
104  void setDynamicThpLimit(const double thp_limit);
105  std::optional<double> getDynamicThpLimit() const;
106  void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
107 
109  bool wellHasTHPConstraints(const SummaryState& summaryState) const;
110 
111  void stopWell() {
112  this->wellStatus_ = Well::Status::STOP;
113  }
114 
115  void openWell() {
116  this->wellStatus_ = Well::Status::OPEN;
117  }
118 
119  bool wellIsStopped() const {
120  return this->wellStatus_ == Well::Status::STOP;
121  }
122 
123  int currentStep() const {
124  return this->current_step_;
125  }
126 
127  int pvtRegionIdx() const {
128  return pvtRegionIdx_;
129  }
130 
131  const GuideRate* guideRate() const {
132  return guide_rate_;
133  }
134 
135  int numComponents() const {
136  return num_components_;
137  }
138 
139  int numPhases() const {
140  return number_of_phases_;
141  }
142 
143  int numPerfs() const {
144  return number_of_perforations_;
145  }
146 
147  double refDepth() const {
148  return ref_depth_;
149  }
150 
151  double gravity() const {
152  return gravity_;
153  }
154 
155  const VFPProperties* vfpProperties() const {
156  return vfp_properties_;
157  }
158 
159  const ParallelWellInfo& parallelWellInfo() const {
160  return parallel_well_info_;
161  }
162 
163  const std::vector<double>& perfDepth() const {
164  return perf_depth_;
165  }
166 
167  std::vector<double>& perfDepth() {
168  return perf_depth_;
169  }
170 
171  const std::vector<double>& wellIndex() const {
172  return well_index_;
173  }
174 
175  double getTHPConstraint(const SummaryState& summaryState) const;
176  double getALQ(const WellState& well_state) const;
177  double wsolvent() const;
178  double rsRvInj() const;
179 
180  // whether a well is specified with a non-zero and valid VFP table number
181  bool isVFPActive(DeferredLogger& deferred_logger) const;
182 
183  void reportWellSwitching(const SingleWellState& ws, DeferredLogger& deferred_logger) const;
184 
185  bool changedToOpenThisStep() const {
186  return this->changed_to_open_this_step_;
187  }
188  std::optional<double> computeBhpAtThpLimitProdCommon(const std::function<std::vector<double>(const double)>& frates,
189  const SummaryState& summary_state,
190  const double maxPerfPress,
191  const double rho,
192  const double alq_value,
193  DeferredLogger& deferred_logger
194  ) const;
195 
196 
197 
198 protected:
199  bool getAllowCrossFlow() const;
200  double mostStrictBhpFromBhpLimits(const SummaryState& summaryState) const;
201  void updateWellTestStatePhysical(const double simulation_time,
202  const bool write_message_to_opmlog,
203  WellTestState& well_test_state,
204  DeferredLogger& deferred_logger) const;
205 
206  std::optional<double> bhpMax(const std::function<double(const double)>& fflo,
207  const double bhp_limit,
208  const double maxPerfPress,
209  const double vfp_flo_front,
210  DeferredLogger& deferred_logger) const;
211 
212  std::optional<double> computeBhpAtThpLimitCommon(
213  const std::function<std::vector<double>(const double)>& frates,
214  const std::function<double(const std::vector<double>)>& fbhp,
215  const std::array<double, 2>& range,
216  DeferredLogger& deferred_logger) const;
217 
218 
219  bool bruteForceBracket(const std::function<double(const double)>& eq,
220  const std::array<double, 2>& range,
221  double& low, double& high,
222  DeferredLogger& deferred_logger) const;
223 
224  bool bisectBracket(const std::function<double(const double)>& eq,
225  const std::array<double, 2>& range,
226  double& low, double& high,
227  std::optional<double>& approximate_solution,
228  DeferredLogger& deferred_logger) const;
229 
230 
231  // definition of the struct OperabilityStatus
233  bool isOperableAndSolvable() const {
234  if (!operable_under_only_bhp_limit || !solvable || has_negative_potentials) {
235  return false;
236  } else {
237  return ( (isOperableUnderBHPLimit() || isOperableUnderTHPLimit()) );
238  }
239  }
240 
241  bool isOperableUnderBHPLimit() const {
242  return operable_under_only_bhp_limit && obey_thp_limit_under_bhp_limit;
243  }
244 
245  bool isOperableUnderTHPLimit() const {
246  return can_obtain_bhp_with_thp_limit && obey_bhp_limit_with_thp_limit;
247  }
248 
249  void resetOperability() {
250  operable_under_only_bhp_limit = true;
251  obey_thp_limit_under_bhp_limit = true;
252  can_obtain_bhp_with_thp_limit = true;
253  obey_bhp_limit_with_thp_limit = true;
254  }
255 
256  // whether the well can be operated under bhp limit
257  // without considering other limits.
258  // if it is false, then the well is not operable for sure.
259  bool operable_under_only_bhp_limit = true;
260  // if the well can be operated under bhp limit, will it obey(not violate)
261  // the thp limit when operated under bhp limit
262  bool obey_thp_limit_under_bhp_limit = true;
263  // whether the well operate under the thp limit only
264  bool can_obtain_bhp_with_thp_limit = true;
265  // whether the well obey bhp limit when operated under thp limit
266  bool obey_bhp_limit_with_thp_limit = true;
267  // the well is solveable
268  bool solvable = true;
269  // the well have non positive potentials
270  bool has_negative_potentials = false;
271  //thp limit violated but not switched
272  mutable bool thp_limit_violated_but_not_switched = false;
273 
274  bool use_vfpexplicit = false;
275  };
276 
277  OperabilityStatus operability_status_;
278 
279  Well well_ecl_;
280 
281  const ParallelWellInfo& parallel_well_info_;
282  const int current_step_;
283 
284  // The pvt region of the well. We assume
285  // We assume a well to not penetrate more than one pvt region.
286  const int pvtRegionIdx_;
287 
288  const int num_components_;
289 
290  // number of phases
291  int number_of_phases_;
292 
293  // the index of well in Wells struct
294  int index_of_well_;
295 
296  const std::vector<PerforationData>* perf_data_;
297 
298  // the vectors used to describe the inflow performance relationship (IPR)
299  // Q = IPR_A - BHP * IPR_B
300  // TODO: it minght need to go to WellInterface, let us implement it in StandardWell first
301  // it is only updated and used for producers for now
302  mutable std::vector<double> ipr_a_;
303  mutable std::vector<double> ipr_b_;
304 
305  // cell index for each well perforation
306  std::vector<int> well_cells_;
307 
308  // well index for each perforation
309  std::vector<double> well_index_;
310 
311  // number of the perforations for this well
312  int number_of_perforations_;
313 
314  // depth for each perforation
315  std::vector<double> perf_depth_;
316 
317  // representative radius of the perforations, used in shear calculation
318  std::vector<double> perf_rep_radius_;
319 
320  // length of the perforations, use in shear calculation
321  std::vector<double> perf_length_;
322 
323  // well bore diameter
324  std::vector<double> bore_diameters_;
325 
326  /*
327  * completions_ contains the mapping from completion id to connection indices
328  * {
329  * 2 : [ConnectionIndex, ConnectionIndex],
330  * 1 : [ConnectionIndex, ConnectionIndex, ConnectionIndex],
331  * 5 : [ConnectionIndex],
332  * 7 : [ConnectionIndex]
333  * ...
334  * }
335  * The integer IDs correspond to the COMPLETION id given by the COMPLUMP keyword.
336  * When there is no COMPLUMP keyword used, a default completion number will be assigned
337  * based on the order of the declaration of the connections.
338  * Since the connections not OPEN is not included in the Wells, so they will not be considered
339  * in this mapping relation.
340  */
341  std::map<int, std::vector<int>> completions_;
342 
343  // reference depth for the BHP
344  double ref_depth_;
345 
346  // saturation table nubmer for each well perforation
347  std::vector<int> saturation_table_number_;
348 
349  Well::Status wellStatus_;
350 
351  const PhaseUsage* phase_usage_;
352 
353  double gravity_;
354  double wsolvent_;
355  std::optional<double> dynamic_thp_limit_;
356 
357  double well_efficiency_factor_;
358  const VFPProperties* vfp_properties_;
359  const GuideRate* guide_rate_;
360 
361  std::vector< std::string> well_control_log_;
362 
363  bool changed_to_open_this_step_ = true;
364 };
365 
366 }
367 
368 #endif // OPM_WELLINTERFACE_HEADER_INCLUDED
Class encapsulating some information about parallel wells.
Definition: ParallelWellInfo.hpp:243
A thin wrapper class that holds one VFPProdProperties and one VFPInjProperties object.
Definition: VFPProperties.hpp:39
Definition: WellInterfaceGeneric.hpp:51
bool wellHasTHPConstraints(const SummaryState &summaryState) const
Returns true if the well has one or more THP limits/constraints.
Definition: WellInterfaceGeneric.cpp:181
int indexOfWell() const
Index of well in the wells struct and wellState.
Definition: WellInterfaceGeneric.cpp:149
const std::string & name() const
Well name.
Definition: WellInterfaceGeneric.cpp:134
const std::vector< int > & cells() const
Well cells.
Definition: WellInterfaceGeneric.hpp:78
bool underPredictionMode() const
Returns true if the well is currently in prediction mode (i.e. not history mode).
Definition: WellInterfaceGeneric.cpp:236
bool isProducer() const
True if the well is a producer.
Definition: WellInterfaceGeneric.cpp:144
bool isInjector() const
True if the well is an injector.
Definition: WellInterfaceGeneric.cpp:139
const std::vector< PerforationData > & perforationData() const
Get the perforations of the well.
Definition: WellInterfaceGeneric.cpp:129
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27
Definition: BlackoilPhases.hpp:46
Definition: WellInterfaceGeneric.hpp:232