My Project
Loading...
Searching...
No Matches
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,
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 setPrevSurfaceRates(WellState& well_state, const WellState& prev_well_state) const;
98 void setGuideRate(const GuideRate* guide_rate_arg);
99 void setWellEfficiencyFactor(const double efficiency_factor);
100 void setRepRadiusPerfLength();
101 void setWsolvent(const double wsolvent);
102 void setDynamicThpLimit(const double thp_limit);
103 std::optional<double> getDynamicThpLimit() const;
104 void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
105
107 bool wellHasTHPConstraints(const SummaryState& summaryState) const;
108
109 void stopWell() {
110 this->wellStatus_ = Well::Status::STOP;
111 }
112
113 void openWell() {
114 this->wellStatus_ = Well::Status::OPEN;
115 }
116
117 bool wellIsStopped() const {
118 return this->wellStatus_ == Well::Status::STOP;
119 }
120
121 int currentStep() const {
122 return this->current_step_;
123 }
124
125 int pvtRegionIdx() const {
126 return pvtRegionIdx_;
127 }
128
129 const GuideRate* guideRate() const {
130 return guide_rate_;
131 }
132
133 int numComponents() const {
134 return num_components_;
135 }
136
137 int numPhases() const {
138 return number_of_phases_;
139 }
140
141 int numPerfs() const {
142 return number_of_perforations_;
143 }
144
145 double refDepth() const {
146 return ref_depth_;
147 }
148
149 double gravity() const {
150 return gravity_;
151 }
152
153 const VFPProperties* vfpProperties() const {
154 return vfp_properties_;
155 }
156
157 const ParallelWellInfo& parallelWellInfo() const {
158 return parallel_well_info_;
159 }
160
161 const std::vector<double>& perfDepth() const {
162 return perf_depth_;
163 }
164
165 std::vector<double>& perfDepth() {
166 return perf_depth_;
167 }
168
169 const std::vector<double>& wellIndex() const {
170 return well_index_;
171 }
172
173 const std::map<int,std::vector<int>>& getCompletions() const {
174 return completions_;
175 }
176
177 double getTHPConstraint(const SummaryState& summaryState) const;
178 double getALQ(const WellState& well_state) const;
179 double wsolvent() const;
180 double rsRvInj() const;
181
182 // at the beginning of the time step, we check what inj_multiplier from the previous running
183 void initInjMult(const std::vector<double>& max_inj_mult);
184
185 // update the InjMult information at the end of the time step, so it can be used for later.
186 void updateInjMult(std::vector<double>& inj_multipliers, DeferredLogger& deferred_logger) const;
187
188 // Note:: for multisegment wells, bhp is actually segment pressure in practice based on observation
189 // it might change in the future
190 double getInjMult(const int perf, const double bhp, const double perf_pres) const;
191
192 // whether a well is specified with a non-zero and valid VFP table number
193 bool isVFPActive(DeferredLogger& deferred_logger) const;
194
195 void reportWellSwitching(const SingleWellState& ws, DeferredLogger& deferred_logger) const;
196
197 bool changedToOpenThisStep() const {
198 return this->changed_to_open_this_step_;
199 }
200
201 void updateWellTestState(const SingleWellState& ws,
202 const double& simulationTime,
203 const bool& writeMessageToOPMLog,
204 WellTestState& wellTestState,
205 DeferredLogger& deferred_logger) const;
206
207 bool isPressureControlled(const WellState& well_state) const;
208
209 bool stopppedOrZeroRateTarget(const SummaryState& summary_state,
210 const WellState& well_state) const;
211
212 double wellEfficiencyFactor() const
213 { return well_efficiency_factor_; }
214
216 void updateFilterCakeMultipliers(const std::vector<double>& inj_fc_multiplier)
217 {
218 inj_fc_multiplier_ = inj_fc_multiplier;
219 }
220
221 void resetWellOperability();
222
223protected:
224 bool getAllowCrossFlow() const;
225
226 double wmicrobes_() const;
227 double wfoam_() const;
228 double woxygen_() const;
229 double wpolymer_() const;
230 double wsalt_() const;
231 double wurea_() const;
232
233 int polymerTable_() const;
234 int polymerInjTable_() const;
235 int polymerWaterTable_() const;
236
237 bool wellUnderZeroRateTarget(const SummaryState& summary_state,
238 const WellState& well_state) const;
239
240 std::pair<bool,bool>
241 computeWellPotentials(std::vector<double>& well_potentials,
242 const WellState& well_state);
243
244 void checkNegativeWellPotentials(std::vector<double>& well_potentials,
245 const bool checkOperability,
247
248 // definition of the struct OperabilityStatus
250 bool isOperableAndSolvable() const {
251 if (!operable_under_only_bhp_limit || !solvable || has_negative_potentials) {
252 return false;
253 } else {
254 return ( (isOperableUnderBHPLimit() || isOperableUnderTHPLimit()) );
255 }
256 }
257
258 bool isOperableUnderBHPLimit() const {
259 return operable_under_only_bhp_limit && obey_thp_limit_under_bhp_limit;
260 }
261
262 bool isOperableUnderTHPLimit() const {
263 return can_obtain_bhp_with_thp_limit && obey_bhp_limit_with_thp_limit;
264 }
265
266 void resetOperability() {
267 operable_under_only_bhp_limit = true;
268 obey_thp_limit_under_bhp_limit = true;
269 can_obtain_bhp_with_thp_limit = true;
270 obey_bhp_limit_with_thp_limit = true;
271 }
272
273 // whether the well can be operated under bhp limit
274 // without considering other limits.
275 // if it is false, then the well is not operable for sure.
276 bool operable_under_only_bhp_limit = true;
277 // if the well can be operated under bhp limit, will it obey(not violate)
278 // the thp limit when operated under bhp limit
279 bool obey_thp_limit_under_bhp_limit = true;
280 // whether the well operate under the thp limit only
281 bool can_obtain_bhp_with_thp_limit = true;
282 // whether the well obey bhp limit when operated under thp limit
283 bool obey_bhp_limit_with_thp_limit = true;
284 // the well is solveable
285 bool solvable = true;
286 // the well have non positive potentials
287 bool has_negative_potentials = false;
288 //thp limit violated but not switched
289 mutable bool thp_limit_violated_but_not_switched = false;
290
291 bool use_vfpexplicit = false;
292 };
293
294 OperabilityStatus operability_status_;
295
296 Well well_ecl_;
297
298 const ParallelWellInfo& parallel_well_info_;
299 const int current_step_;
300
301 // The pvt region of the well. We assume
302 // We assume a well to not penetrate more than one pvt region.
303 const int pvtRegionIdx_;
304
305 const int num_components_;
306
307 // number of phases
308 int number_of_phases_;
309
310 // the index of well in Wells struct
311 int index_of_well_;
312
313 const std::vector<PerforationData>* perf_data_;
314
315 // the vectors used to describe the inflow performance relationship (IPR)
316 // Q = IPR_A - BHP * IPR_B
317 // TODO: it minght need to go to WellInterface, let us implement it in StandardWell first
318 // it is only updated and used for producers for now
319 mutable std::vector<double> ipr_a_;
320 mutable std::vector<double> ipr_b_;
321
322 // cell index for each well perforation
323 std::vector<int> well_cells_;
324
325 // well index for each perforation
326 std::vector<double> well_index_;
327
328 // number of the perforations for this well
329 int number_of_perforations_;
330
331 // depth for each perforation
332 std::vector<double> perf_depth_;
333
334 // representative radius of the perforations, used in shear calculation
335 std::vector<double> perf_rep_radius_;
336
337 // length of the perforations, use in shear calculation
338 std::vector<double> perf_length_;
339
340 // well bore diameter
341 std::vector<double> bore_diameters_;
342
343 /*
344 * completions_ contains the mapping from completion id to connection indices
345 * {
346 * 2 : [ConnectionIndex, ConnectionIndex],
347 * 1 : [ConnectionIndex, ConnectionIndex, ConnectionIndex],
348 * 5 : [ConnectionIndex],
349 * 7 : [ConnectionIndex]
350 * ...
351 * }
352 * The integer IDs correspond to the COMPLETION id given by the COMPLUMP keyword.
353 * When there is no COMPLUMP keyword used, a default completion number will be assigned
354 * based on the order of the declaration of the connections.
355 * Since the connections not OPEN is not included in the Wells, so they will not be considered
356 * in this mapping relation.
357 */
358 std::map<int, std::vector<int>> completions_;
359
360 // reference depth for the BHP
361 double ref_depth_;
362
363 // saturation table nubmer for each well perforation
364 std::vector<int> saturation_table_number_;
365
366 Well::Status wellStatus_;
367
368 const PhaseUsage* phase_usage_;
369
370 double gravity_;
371 double wsolvent_;
372 std::optional<double> dynamic_thp_limit_;
373
374 // recording the multiplier calculate from the keyword WINJMULT during the time step
375 mutable std::vector<double> inj_multiplier_;
376
377 // the injection multiplier from the previous running, it is mostly used for CIRR mode
378 // which intends to keep the fracturing open
379 std::vector<double> prev_inj_multiplier_;
380
381 // the multiplier due to injection filtration cake
382 std::vector<double> inj_fc_multiplier_;
383
384 double well_efficiency_factor_;
385 const VFPProperties* vfp_properties_;
386 const GuideRate* guide_rate_;
387
388 std::vector< std::string> well_control_log_;
389
390 bool changed_to_open_this_step_ = true;
391};
392
393}
394
395#endif // OPM_WELLINTERFACE_HEADER_INCLUDED
Definition AquiferInterface.hpp:35
Definition DeferredLogger.hpp:57
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:40
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:256
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:162
const std::string & name() const
Well name.
Definition WellInterfaceGeneric.cpp:147
void updateFilterCakeMultipliers(const std::vector< double > &inj_fc_multiplier)
Update filter cake multipliers.
Definition WellInterfaceGeneric.hpp:216
bool underPredictionMode() const
Returns true if the well is currently in prediction mode (i.e. not history mode).
Definition WellInterfaceGeneric.cpp:296
bool isProducer() const
True if the well is a producer.
Definition WellInterfaceGeneric.cpp:157
bool isInjector() const
True if the well is an injector.
Definition WellInterfaceGeneric.cpp:152
const std::vector< PerforationData > & perforationData() const
Get the perforations of the well.
Definition WellInterfaceGeneric.cpp:142
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition WellState.hpp:60
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition BlackoilPhases.hpp:27
Definition BlackoilPhases.hpp:46
Definition WellInterfaceGeneric.hpp:249