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
34namespace Opm
35{
36
37class DeferredLogger;
38class GuideRate;
39class ParallelWellInfo;
40struct PerforationData;
41struct PhaseUsage;
42class SummaryState;
43class VFPProperties;
44class WellTestState;
45class WellState;
46class SingleWellState;
47class GroupState;
48class Group;
49class Schedule;
50
52public:
53 WellInterfaceGeneric(const Well& well,
54 const ParallelWellInfo& parallel_well_info,
55 const int time_step,
56 const int pvtRegionIdx,
57 const int num_components,
58 const int num_phases,
59 const int index_of_well,
60 const std::vector<PerforationData>& perf_data);
61
63 const std::vector<PerforationData>& perforationData() const;
64
66 const std::string& name() const;
67
69 bool isInjector() const;
70
72 bool isProducer() const;
73
75 const std::vector<int>& cells() const { return well_cells_; }
76
78 int indexOfWell() const;
79
80 void adaptRatesForVFP(std::vector<double>& rates) const;
81
82 const Well& wellEcl() const;
83 const PhaseUsage& phaseUsage() const;
84
86 bool underPredictionMode() const;
87
88 // whether the well is operable
89 bool isOperableAndSolvable() const;
90 bool useVfpExplicit () const;
91 bool thpLimitViolatedButNotSwitched() const;
92
93 void initCompletions();
94 void closeCompletions(const WellTestState& wellTestState);
95
96 void setVFPProperties(const VFPProperties* vfp_properties_arg);
97 void setGuideRate(const GuideRate* guide_rate_arg);
98 void setWellEfficiencyFactor(const double efficiency_factor);
99 void setRepRadiusPerfLength();
100 void setWsolvent(const double wsolvent);
101 void setDynamicThpLimit(const double thp_limit);
102 std::optional<double> getDynamicThpLimit() const;
103 void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
104
106 bool wellHasTHPConstraints(const SummaryState& summaryState) const;
107
108 void stopWell() {
109 this->wellStatus_ = Well::Status::STOP;
110 }
111
112 void openWell() {
113 this->wellStatus_ = Well::Status::OPEN;
114 }
115
116 bool wellIsStopped() const {
117 return this->wellStatus_ == Well::Status::STOP;
118 }
119
120 int currentStep() const {
121 return this->current_step_;
122 }
123
124 int pvtRegionIdx() const {
125 return pvtRegionIdx_;
126 }
127
128 const GuideRate* guideRate() const {
129 return guide_rate_;
130 }
131
132 int numComponents() const {
133 return num_components_;
134 }
135
136 int numPhases() const {
137 return number_of_phases_;
138 }
139
140 int numPerfs() const {
141 return number_of_perforations_;
142 }
143
144 double refDepth() const {
145 return ref_depth_;
146 }
147
148 double gravity() const {
149 return gravity_;
150 }
151
152 const VFPProperties* vfpProperties() const {
153 return vfp_properties_;
154 }
155
156 const ParallelWellInfo& parallelWellInfo() const {
157 return parallel_well_info_;
158 }
159
160 const std::vector<double>& perfDepth() const {
161 return perf_depth_;
162 }
163
164 std::vector<double>& perfDepth() {
165 return perf_depth_;
166 }
167
168 const std::vector<double>& wellIndex() const {
169 return well_index_;
170 }
171
172 const std::map<int,std::vector<int>>& getCompletions() const {
173 return completions_;
174 }
175
176 double getTHPConstraint(const SummaryState& summaryState) const;
177 double getALQ(const WellState& well_state) const;
178 double wsolvent() const;
179 double rsRvInj() const;
180
181 // whether a well is specified with a non-zero and valid VFP table number
182 bool isVFPActive(DeferredLogger& deferred_logger) const;
183
184 void reportWellSwitching(const SingleWellState& ws, DeferredLogger& deferred_logger) const;
185
186 bool changedToOpenThisStep() const {
187 return this->changed_to_open_this_step_;
188 }
189
190 void updateWellTestState(const SingleWellState& ws,
191 const double& simulationTime,
192 const bool& writeMessageToOPMLog,
193 WellTestState& wellTestState,
194 DeferredLogger& deferred_logger) const;
195
196 bool isPressureControlled(const WellState& well_state) const;
197
198 bool stopppedOrZeroRateTarget(const SummaryState& summary_state,
199 const WellState& well_state) const;
200protected:
201 bool getAllowCrossFlow() const;
202
203 double wmicrobes_() const;
204 double wfoam_() const;
205 double woxygen_() const;
206 double wpolymer_() const;
207 double wsalt_() const;
208 double wurea_() const;
209
210 int polymerTable_() const;
211 int polymerInjTable_() const;
212 int polymerWaterTable_() const;
213
214 bool wellUnderZeroRateTarget(const SummaryState& summary_state,
215 const WellState& well_state) const;
216
217 // definition of the struct OperabilityStatus
219 bool isOperableAndSolvable() const {
220 if (!operable_under_only_bhp_limit || !solvable || has_negative_potentials) {
221 return false;
222 } else {
223 return ( (isOperableUnderBHPLimit() || isOperableUnderTHPLimit()) );
224 }
225 }
226
227 bool isOperableUnderBHPLimit() const {
228 return operable_under_only_bhp_limit && obey_thp_limit_under_bhp_limit;
229 }
230
231 bool isOperableUnderTHPLimit() const {
232 return can_obtain_bhp_with_thp_limit && obey_bhp_limit_with_thp_limit;
233 }
234
235 void resetOperability() {
236 operable_under_only_bhp_limit = true;
237 obey_thp_limit_under_bhp_limit = true;
238 can_obtain_bhp_with_thp_limit = true;
239 obey_bhp_limit_with_thp_limit = true;
240 }
241
242 // whether the well can be operated under bhp limit
243 // without considering other limits.
244 // if it is false, then the well is not operable for sure.
245 bool operable_under_only_bhp_limit = true;
246 // if the well can be operated under bhp limit, will it obey(not violate)
247 // the thp limit when operated under bhp limit
248 bool obey_thp_limit_under_bhp_limit = true;
249 // whether the well operate under the thp limit only
250 bool can_obtain_bhp_with_thp_limit = true;
251 // whether the well obey bhp limit when operated under thp limit
252 bool obey_bhp_limit_with_thp_limit = true;
253 // the well is solveable
254 bool solvable = true;
255 // the well have non positive potentials
256 bool has_negative_potentials = false;
257 //thp limit violated but not switched
258 mutable bool thp_limit_violated_but_not_switched = false;
259
260 bool use_vfpexplicit = false;
261 };
262
263 OperabilityStatus operability_status_;
264
265 Well well_ecl_;
266
267 const ParallelWellInfo& parallel_well_info_;
268 const int current_step_;
269
270 // The pvt region of the well. We assume
271 // We assume a well to not penetrate more than one pvt region.
272 const int pvtRegionIdx_;
273
274 const int num_components_;
275
276 // number of phases
277 int number_of_phases_;
278
279 // the index of well in Wells struct
280 int index_of_well_;
281
282 const std::vector<PerforationData>* perf_data_;
283
284 // the vectors used to describe the inflow performance relationship (IPR)
285 // Q = IPR_A - BHP * IPR_B
286 // TODO: it minght need to go to WellInterface, let us implement it in StandardWell first
287 // it is only updated and used for producers for now
288 mutable std::vector<double> ipr_a_;
289 mutable std::vector<double> ipr_b_;
290
291 // cell index for each well perforation
292 std::vector<int> well_cells_;
293
294 // well index for each perforation
295 std::vector<double> well_index_;
296
297 // number of the perforations for this well
298 int number_of_perforations_;
299
300 // depth for each perforation
301 std::vector<double> perf_depth_;
302
303 // representative radius of the perforations, used in shear calculation
304 std::vector<double> perf_rep_radius_;
305
306 // length of the perforations, use in shear calculation
307 std::vector<double> perf_length_;
308
309 // well bore diameter
310 std::vector<double> bore_diameters_;
311
312 /*
313 * completions_ contains the mapping from completion id to connection indices
314 * {
315 * 2 : [ConnectionIndex, ConnectionIndex],
316 * 1 : [ConnectionIndex, ConnectionIndex, ConnectionIndex],
317 * 5 : [ConnectionIndex],
318 * 7 : [ConnectionIndex]
319 * ...
320 * }
321 * The integer IDs correspond to the COMPLETION id given by the COMPLUMP keyword.
322 * When there is no COMPLUMP keyword used, a default completion number will be assigned
323 * based on the order of the declaration of the connections.
324 * Since the connections not OPEN is not included in the Wells, so they will not be considered
325 * in this mapping relation.
326 */
327 std::map<int, std::vector<int>> completions_;
328
329 // reference depth for the BHP
330 double ref_depth_;
331
332 // saturation table nubmer for each well perforation
333 std::vector<int> saturation_table_number_;
334
335 Well::Status wellStatus_;
336
337 const PhaseUsage* phase_usage_;
338
339 double gravity_;
340 double wsolvent_;
341 std::optional<double> dynamic_thp_limit_;
342
343 double well_efficiency_factor_;
344 const VFPProperties* vfp_properties_;
345 const GuideRate* guide_rate_;
346
347 std::vector< std::string> well_control_log_;
348
349 bool changed_to_open_this_step_ = true;
350};
351
352}
353
354#endif // OPM_WELLINTERFACE_HEADER_INCLUDED
Class encapsulating some information about parallel wells.
Definition: ParallelWellInfo.hpp:184
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:193
const std::vector< int > & cells() const
Well cells.
Definition: WellInterfaceGeneric.hpp:75
int indexOfWell() const
Index of well in the wells struct and wellState.
Definition: WellInterfaceGeneric.cpp:161
const std::string & name() const
Well name.
Definition: WellInterfaceGeneric.cpp:146
bool underPredictionMode() const
Returns true if the well is currently in prediction mode (i.e. not history mode).
Definition: WellInterfaceGeneric.cpp:228
bool isProducer() const
True if the well is a producer.
Definition: WellInterfaceGeneric.cpp:156
bool isInjector() const
True if the well is an injector.
Definition: WellInterfaceGeneric.cpp:151
const std::vector< PerforationData > & perforationData() const
Get the perforations of the well.
Definition: WellInterfaceGeneric.cpp:141
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27
Definition: BlackoilPhases.hpp:46
Definition: WellInterfaceGeneric.hpp:218