WellState.hpp
Go to the documentation of this file.
1/*
2 Copyright 2014 SINTEF ICT, Applied Mathematics.
3 Copyright 2017 IRIS AS
4
5 This file is part of the Open Porous Media project (OPM).
6
7 OPM is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 OPM is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with OPM. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#ifndef OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
22#define OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
23
24#include <dune/common/version.hh>
25#include <dune/common/parallel/mpihelper.hh>
26
27#include <opm/common/ErrorMacros.hpp>
28
29#include <opm/input/eclipse/Schedule/Events.hpp>
30
31#include <opm/output/data/Wells.hpp>
32
38
41
42#include <algorithm>
43#include <cstddef>
44#include <cstdint>
45#include <functional>
46#include <map>
47#include <optional>
48#include <string>
49#include <utility>
50#include <vector>
51
52namespace Opm
53{
54
55template<class Scalar> class ParallelWellInfo;
56template<class Scalar> struct PerforationData;
57template<class Scalar> class ConnFracStatistics;
58class Schedule;
59enum class WellStatus;
60
63template<class Scalar>
65{
66public:
67 static const std::uint64_t event_mask = ScheduleEvents::WELL_STATUS_CHANGE
68 | ScheduleEvents::PRODUCTION_UPDATE
69 | ScheduleEvents::INJECTION_UPDATE;
70
71 // TODO: same definition with WellInterface, eventually they should go to a common header file.
72 static const int Water = BlackoilPhases::Aqua;
73 static const int Oil = BlackoilPhases::Liquid;
74 static const int Gas = BlackoilPhases::Vapour;
75
76 // Only usable for testing purposes
77 explicit WellState(const ParallelWellInfo<Scalar>& pinfo);
78
79 explicit WellState(const PhaseUsage& pu)
80 : phase_usage_(pu)
81 {}
82
84
85 std::size_t size() const
86 {
87 return this->wells_.size();
88 }
89
90 std::vector<std::string> wells() const
91 {
92 return this->wells_.wells();
93 }
94
95 int numWells() const
96 {
97 return this->size();
98 }
99
100 const ParallelWellInfo<Scalar>& parallelWellInfo(std::size_t well_index) const;
101
105 void init(const std::vector<Scalar>& cellPressures,
106 const std::vector<Scalar>& cellTemperatures,
107 const Schedule& schedule,
108 const std::vector<Well>& wells_ecl,
109 const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
110 const int report_step,
111 const WellState* prevState,
112 const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
113 const SummaryState& summary_state,
114 const bool enableDistributedWells);
115
116 void resize(const std::vector<Well>& wells_ecl,
117 const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
118 const Schedule& schedule,
119 const bool handle_ms_well,
120 const std::size_t numCells,
121 const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
122 const SummaryState& summary_state,
123 const bool enable_distributed_wells);
124
125 void setCurrentWellRates(const std::string& wellName,
126 const std::vector<Scalar>& new_rates)
127 {
128 auto& [owner, rates] = this->well_rates.at(wellName);
129 if (owner)
130 rates = new_rates;
131 }
132
133 const std::vector<Scalar>& currentWellRates(const std::string& wellName) const;
134
135 bool hasWellRates(const std::string& wellName) const
136 {
137 return this->well_rates.find(wellName) != this->well_rates.end();
138 }
139
141 {
142 this->well_rates.clear();
143 }
144
145 void gatherVectorsOnRoot(const std::vector<data::Connection>& from_connections,
146 std::vector<data::Connection>& to_connections,
147 const Parallel::Communication& comm) const;
148
149 data::Wells
150 report(const int* globalCellIdxMap,
151 const std::function<bool(const int)>& wasDynamicallyClosed) const;
152
153 void reportConnections(std::vector<data::Connection>& connections,
154 const PhaseUsage &pu,
155 std::size_t well_index,
156 const int* globalCellIdxMap) const;
157
159 void initWellStateMSWell(const std::vector<Well>& wells_ecl,
160 const WellState* prev_well_state);
161
163 const std::vector<std::vector<int>>& segment_inlets,
164 const std::vector<std::vector<int>>& segment_perforations,
165 const std::vector<Scalar>& perforation_rates,
166 const int np,
167 const int segment,
168 std::vector<Scalar>& segment_rates);
169
170
172
174 void updateEfficiencyScalingFactor(const std::string& wellName,
175 const Scalar value);
176
177 bool isInjectionGrup(const std::string& name) const
178 {
179 return this->global_well_info.value().in_injecting_group(name);
180 }
181
182 bool isProductionGrup(const std::string& name) const
183 {
184 return this->global_well_info.value().in_producing_group(name);
185 }
186
187 bool isOpen(const std::string& name) const
188 {
189 return this->global_well_info.value().is_open(name);
190 }
191
192 Scalar getGlobalEfficiencyScalingFactor(const std::string& name) const
193 {
194 return this->global_well_info.value().efficiency_scaling_factor(name);
195 }
196
197 // If the ALQ has changed since the previous time step,
198 // reset current_alq and update default_alq. ALQ is used for
199 // constant lift gas injection and for gas lift optimization
200 // (THP controlled wells).
201 void updateWellsDefaultALQ(const Schedule& schedule,
202 const int report_step,
203 const SummaryState& summary_state);
204
206 {
207 for (size_t i = 0; i < this->size(); ++i) {
208 this->wells_[i].alq_state.reset_count();
209 }
210 }
211
212
213 int wellNameToGlobalIdx(const std::string& name)
214 {
215 return this->global_well_info.value().well_index(name);
216 }
217
218 std::string globalIdxToWellName(const int index)
219 {
220 return this->global_well_info.value().well_name(index);
221 }
222
223 bool wellIsOwned(std::size_t well_index,
224 const std::string& wellName) const;
225
226 bool wellIsOwned(const std::string& wellName) const;
227
228 bool isRank0() const {
229 return this->global_well_info.value().isRank0();
230 }
231
232 void updateStatus(int well_index, WellStatus status);
233
234 void openWell(int well_index);
235 void shutWell(int well_index);
236 void stopWell(int well_index);
237
239 int numPhases() const
240 {
241 return this->phase_usage_.num_phases;
242 }
243
244 const PhaseUsage& phaseUsage() const
245 {
246 return this->phase_usage_;
247 }
248
250 std::vector<Scalar>& wellRates(std::size_t well_index)
251 { return this->wells_[well_index].surface_rates; }
252 const std::vector<Scalar>& wellRates(std::size_t well_index) const
253 { return this->wells_[well_index].surface_rates; }
254
255 const std::string& name(std::size_t well_index) const
256 {
257 return this->wells_.well_name(well_index);
258 }
259
260 std::optional<std::size_t> index(const std::string& well_name) const
261 {
262 return this->wells_.well_index(well_name);
263 }
264
265 const SingleWellState<Scalar>& operator[](std::size_t well_index) const
266 {
267 return this->wells_[well_index];
268 }
269
270 const SingleWellState<Scalar>& operator[](const std::string& well_name) const
271 {
272 return this->wells_[well_name];
273 }
274
275 SingleWellState<Scalar>& operator[](std::size_t well_index)
276 {
277 return this->wells_[well_index];
278 }
279
280 SingleWellState<Scalar>& operator[](const std::string& well_name)
281 {
282 return this->wells_[well_name];
283 }
284
285 const SingleWellState<Scalar>& well(std::size_t well_index) const
286 {
287 return this->operator[](well_index);
288 }
289
290 const SingleWellState<Scalar>& well(const std::string& well_name) const
291 {
292 return this->operator[](well_name);
293 }
294
295 SingleWellState<Scalar>& well(std::size_t well_index)
296 {
297 return this->operator[](well_index);
298 }
299
300 SingleWellState<Scalar>& well(const std::string& well_name)
301 {
302 return this->operator[](well_name);
303 }
304
305 bool has(const std::string& well_name) const
306 {
307 return this->wells_.has(well_name);
308 }
309
310 bool operator==(const WellState&) const;
311
312 template<class Serializer>
313 void serializeOp(Serializer& serializer)
314 {
315 serializer(well_rates);
316 if (serializer.isSerializing()) {
317 serializer(wells_.size());
318 } else {
319 std::size_t size = 0;
320 serializer(size);
321 if (size != wells_.size()) {
322 OPM_THROW(std::runtime_error, "Error deserializing WellState: size mismatch");
323 }
324 }
325 for (auto& w : wells_) {
326 serializer(w);
327 }
328 serializer(permanently_inactive_well_names_);
329 }
330
331 bool is_permanently_inactive_well(const std::string& wname) const {
332 return std::find(this->permanently_inactive_well_names_.begin(), this->permanently_inactive_well_names_.end(), wname) != this->permanently_inactive_well_names_.end();
333 }
334
335private:
336 bool enableDistributedWells_ = false;
337
338 PhaseUsage phase_usage_;
339
340 // The wells_ variable is essentially a map of all the wells on the current
341 // process. Observe that since a well can be split over several processes a
342 // well might appear in the WellContainer on different processes.
344
345 // The members global_well_info and well_rates are map like
346 // structures which will have entries for *all* the wells in the system.
347
348 // Use of std::optional<> here is a technical crutch, the
349 // WellStateFullyImplicitBlackoil class should be default constructible,
350 // whereas the GlobalWellInfo is not.
351 std::optional<GlobalWellInfo<Scalar>> global_well_info;
352
353 // The well_rates variable is defined for all wells on all processors. The
354 // bool in the value pair is whether the current process owns the well or
355 // not.
356 std::map<std::string, std::pair<bool, std::vector<Scalar>>> well_rates;
357
358 // Keep track of permanently inactive well names
359 std::vector<std::string> permanently_inactive_well_names_;
360
361 data::Segment
362 reportSegmentResults(const int well_id,
363 const int seg_ix,
364 const int seg_no) const;
365
366
372 void base_init(const std::vector<Scalar>& cellPressures,
373 const std::vector<Scalar>& cellTemperatures,
374 const std::vector<Well>& wells_ecl,
375 const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
376 const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
377 const SummaryState& summary_state);
378
379 void initSingleWell(const std::vector<Scalar>& cellPressures,
380 const std::vector<Scalar>& cellTemperatures,
381 const Well& well,
382 const std::vector<PerforationData<Scalar>>& well_perf_data,
383 const ParallelWellInfo<Scalar>& well_info,
384 const SummaryState& summary_state);
385
386 void initSingleProducer(const Well& well,
387 const ParallelWellInfo<Scalar>& well_info,
388 Scalar pressure_first_connection,
389 const std::vector<PerforationData<Scalar>>& well_perf_data,
390 const SummaryState& summary_state);
391
392 void initSingleInjector(const Well& well,
393 const ParallelWellInfo<Scalar>& well_info,
394 Scalar pressure_first_connection,
395 Scalar temperature_first_connection,
396 const std::vector<PerforationData<Scalar>>& well_perf_data,
397 const SummaryState& summary_state);
398
399 static void calculateSegmentRatesBeforeSum(const ParallelWellInfo<Scalar>& pw_info,
400 const std::vector<std::vector<int>>& segment_inlets,
401 const std::vector<std::vector<int>>& segment_perforations,
402 const std::vector<Scalar>& perforation_rates,
403 const int np,
404 const int segment,
405 std::vector<Scalar>& segment_rates);
406
407 void reportConnectionFactors(const std::size_t well_index,
408 std::vector<data::Connection>& connections) const;
409
410 void reportConnectionPressuresAndRates(const std::size_t well_index,
411 const PhaseUsage& pu,
412 std::vector<data::Connection>& connections) const;
413
414 void reportConnectionFilterCake(const std::size_t well_index,
415 std::vector<data::Connection>& connections) const;
416
417 void reportFractureStatistics(const std::vector<ConnFracStatistics<Scalar>>& stats,
418 std::vector<data::Connection>& connections) const;
419};
420
421} // namespace Opm
422
423#endif // OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
@ Liquid
Definition: BlackoilPhases.hpp:42
@ Aqua
Definition: BlackoilPhases.hpp:42
@ Vapour
Definition: BlackoilPhases.hpp:42
Definition: ConnFracStatistics.hpp:37
Class encapsulating some information about parallel wells.
Definition: ParallelWellInfo.hpp:195
Definition: SingleWellState.hpp:42
Definition: WellContainer.hpp:46
Definition: WellState.hpp:65
data::Wells report(const int *globalCellIdxMap, const std::function< bool(const int)> &wasDynamicallyClosed) const
std::vector< std::string > wells() const
Definition: WellState.hpp:90
bool isInjectionGrup(const std::string &name) const
Definition: WellState.hpp:177
std::string globalIdxToWellName(const int index)
Definition: WellState.hpp:218
bool is_permanently_inactive_well(const std::string &wname) const
Definition: WellState.hpp:331
void initWellStateMSWell(const std::vector< Well > &wells_ecl, const WellState *prev_well_state)
init the MS well related.
static const std::uint64_t event_mask
Definition: WellState.hpp:67
const SingleWellState< Scalar > & well(const std::string &well_name) const
Definition: WellState.hpp:290
SingleWellState< Scalar > & well(std::size_t well_index)
Definition: WellState.hpp:295
const SingleWellState< Scalar > & well(std::size_t well_index) const
Definition: WellState.hpp:285
const SingleWellState< Scalar > & operator[](std::size_t well_index) const
Definition: WellState.hpp:265
void reportConnections(std::vector< data::Connection > &connections, const PhaseUsage &pu, std::size_t well_index, const int *globalCellIdxMap) const
const std::vector< Scalar > & currentWellRates(const std::string &wellName) const
bool operator==(const WellState &) const
const ParallelWellInfo< Scalar > & parallelWellInfo(std::size_t well_index) const
SingleWellState< Scalar > & well(const std::string &well_name)
Definition: WellState.hpp:300
bool wellIsOwned(std::size_t well_index, const std::string &wellName) const
int numPhases() const
The number of phases present.
Definition: WellState.hpp:239
bool isOpen(const std::string &name) const
Definition: WellState.hpp:187
void serializeOp(Serializer &serializer)
Definition: WellState.hpp:313
void openWell(int well_index)
void resize(const std::vector< Well > &wells_ecl, const std::vector< std::reference_wrapper< ParallelWellInfo< Scalar > > > &parallel_well_info, const Schedule &schedule, const bool handle_ms_well, const std::size_t numCells, const std::vector< std::vector< PerforationData< Scalar > > > &well_perf_data, const SummaryState &summary_state, const bool enable_distributed_wells)
std::optional< std::size_t > index(const std::string &well_name) const
Definition: WellState.hpp:260
void gliftTimeStepInit()
Definition: WellState.hpp:205
const PhaseUsage & phaseUsage() const
Definition: WellState.hpp:244
void updateEfficiencyScalingFactor(const std::string &wellName, const Scalar value)
bool wellIsOwned(const std::string &wellName) const
void init(const std::vector< Scalar > &cellPressures, const std::vector< Scalar > &cellTemperatures, const Schedule &schedule, const std::vector< Well > &wells_ecl, const std::vector< std::reference_wrapper< ParallelWellInfo< Scalar > > > &parallel_well_info, const int report_step, const WellState *prevState, const std::vector< std::vector< PerforationData< Scalar > > > &well_perf_data, const SummaryState &summary_state, const bool enableDistributedWells)
const std::vector< Scalar > & wellRates(std::size_t well_index) const
Definition: WellState.hpp:252
void communicateGroupRates(const Parallel::Communication &comm)
bool has(const std::string &well_name) const
Definition: WellState.hpp:305
void clearWellRates()
Definition: WellState.hpp:140
int wellNameToGlobalIdx(const std::string &name)
Definition: WellState.hpp:213
SingleWellState< Scalar > & operator[](std::size_t well_index)
Definition: WellState.hpp:275
static WellState serializationTestObject(const ParallelWellInfo< Scalar > &pinfo)
const std::string & name(std::size_t well_index) const
Definition: WellState.hpp:255
bool hasWellRates(const std::string &wellName) const
Definition: WellState.hpp:135
void updateWellsDefaultALQ(const Schedule &schedule, const int report_step, const SummaryState &summary_state)
void setCurrentWellRates(const std::string &wellName, const std::vector< Scalar > &new_rates)
Definition: WellState.hpp:125
void updateStatus(int well_index, WellStatus status)
SingleWellState< Scalar > & operator[](const std::string &well_name)
Definition: WellState.hpp:280
const SingleWellState< Scalar > & operator[](const std::string &well_name) const
Definition: WellState.hpp:270
bool isProductionGrup(const std::string &name) const
Definition: WellState.hpp:182
void gatherVectorsOnRoot(const std::vector< data::Connection > &from_connections, std::vector< data::Connection > &to_connections, const Parallel::Communication &comm) const
WellState(const ParallelWellInfo< Scalar > &pinfo)
void stopWell(int well_index)
void shutWell(int well_index)
static const int Gas
Definition: WellState.hpp:74
static const int Oil
Definition: WellState.hpp:73
WellState(const PhaseUsage &pu)
Definition: WellState.hpp:79
std::vector< Scalar > & wellRates(std::size_t well_index)
One rate per well and phase.
Definition: WellState.hpp:250
std::size_t size() const
Definition: WellState.hpp:85
bool isRank0() const
Definition: WellState.hpp:228
int numWells() const
Definition: WellState.hpp:95
void updateGlobalIsGrup(const Parallel::Communication &comm)
static const int Water
Definition: WellState.hpp:72
Scalar getGlobalEfficiencyScalingFactor(const std::string &name) const
Definition: WellState.hpp:192
static void calculateSegmentRates(const ParallelWellInfo< Scalar > &pw_info, const std::vector< std::vector< int > > &segment_inlets, const std::vector< std::vector< int > > &segment_perforations, const std::vector< Scalar > &perforation_rates, const int np, const int segment, std::vector< Scalar > &segment_rates)
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Definition: blackoilboundaryratevector.hh:39
Static data associated with a well perforation.
Definition: PerforationData.hpp:30
Definition: BlackoilPhases.hpp:46
int num_phases
Definition: BlackoilPhases.hpp:54