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/material/fluidsystems/PhaseUsageInfo.hpp>
30
31#include <opm/input/eclipse/Schedule/Events.hpp>
32
33#include <opm/output/data/Wells.hpp>
34
40
42
43#include <algorithm>
44#include <cstddef>
45#include <cstdint>
46#include <functional>
47#include <map>
48#include <optional>
49#include <string>
50#include <utility>
51#include <vector>
52
53namespace Opm
54{
55
56template<class Scalar> class ParallelWellInfo;
57template<class Scalar> struct PerforationData;
58template<class Scalar> class ConnFracStatistics;
59class Schedule;
60enum class WellStatus;
61
64template<typename Scalar, typename IndexTraits>
66{
67public:
68 static const std::uint64_t event_mask = ScheduleEvents::WELL_STATUS_CHANGE
69 | ScheduleEvents::PRODUCTION_UPDATE
70 | ScheduleEvents::INJECTION_UPDATE;
71
72 // TODO: same definition with WellInterface, eventually they should go to a common header file.
73
74 // TODO: trying to PhasedIdx to make it more explicit as phase index, will evaluate how it goes.
75 // TODO: eventually, we should distinguish phase index and component index
76 static const int waterPhaseIdx = IndexTraits::waterPhaseIdx;
77 static const int oilPhaseIdx = IndexTraits::oilPhaseIdx;
78 static const int gasPhaseIdx = IndexTraits::gasPhaseIdx;
79
80 // Only usable for testing purposes
81 explicit WellState(const ParallelWellInfo<Scalar>& pinfo);
82
84 : phaseUsageInfo_(pu)
85 {}
86
88
89 std::size_t size() const
90 {
91 return this->wells_.size();
92 }
93
94 std::vector<std::string> wells() const
95 {
96 return this->wells_.wells();
97 }
98
99 int numWells() const
100 {
101 return this->size();
102 }
103
104 // TODO: temporary naming during development, will change to phaseUsage() later
106 {
107 return this->phaseUsageInfo_;
108 }
109
110 const ParallelWellInfo<Scalar>& parallelWellInfo(std::size_t well_index) const;
111
115 void init(const std::vector<Scalar>& cellPressures,
116 const std::vector<Scalar>& cellTemperatures,
117 const Schedule& schedule,
118 const std::vector<Well>& wells_ecl,
119 const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
120 const int report_step,
121 const WellState* prevState,
122 const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
123 const SummaryState& summary_state,
124 const bool enableDistributedWells);
125
126 void resize(const std::vector<Well>& wells_ecl,
127 const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
128 const Schedule& schedule,
129 const bool handle_ms_well,
130 const std::size_t numCells,
131 const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
132 const SummaryState& summary_state,
133 const bool enable_distributed_wells);
134
135 void setCurrentWellRates(const std::string& wellName,
136 const std::vector<Scalar>& new_rates)
137 {
138 auto& [owner, rates] = this->well_rates.at(wellName);
139 if (owner)
140 rates = new_rates;
141 }
142
143 const std::vector<Scalar>& currentWellRates(const std::string& wellName) const;
144
145 bool hasWellRates(const std::string& wellName) const
146 {
147 return this->well_rates.find(wellName) != this->well_rates.end();
148 }
149
151 {
152 this->well_rates.clear();
153 }
154
155 void gatherVectorsOnRoot(const std::vector<data::Connection>& from_connections,
156 std::vector<data::Connection>& to_connections,
157 const Parallel::Communication& comm) const;
158
159 data::Wells
160 report(const int* globalCellIdxMap,
161 const std::function<bool(const int)>& wasDynamicallyClosed) const;
162
163 void reportConnections(std::vector<data::Connection>& connections,
164 std::size_t well_index,
165 const int* globalCellIdxMap) const;
166
168 void initWellStateMSWell(const std::vector<Well>& wells_ecl,
169 const WellState* prev_well_state);
170
172 const std::vector<std::vector<int>>& segment_inlets,
173 const std::vector<std::vector<int>>& segment_perforations,
174 const std::vector<Scalar>& perforation_rates,
175 const int np,
176 const int segment,
177 std::vector<Scalar>& segment_rates);
178
179
181
183 void updateEfficiencyScalingFactor(const std::string& wellName,
184 const Scalar value);
185
186 bool isInjectionGrup(const std::string& name) const
187 {
188 return this->global_well_info.value().in_injecting_group(name);
189 }
190
191 bool isProductionGrup(const std::string& name) const
192 {
193 return this->global_well_info.value().in_producing_group(name);
194 }
195
196 bool isOpen(const std::string& name) const
197 {
198 return this->global_well_info.value().is_open(name);
199 }
200
201 Scalar getGlobalEfficiencyScalingFactor(const std::string& name) const
202 {
203 return this->global_well_info.value().efficiency_scaling_factor(name);
204 }
205
206 // If the ALQ has changed since the previous time step,
207 // reset current_alq and update default_alq. ALQ is used for
208 // constant lift gas injection and for gas lift optimization
209 // (THP controlled wells).
210 void updateWellsDefaultALQ(const Schedule& schedule,
211 const int report_step,
212 const SummaryState& summary_state);
213
215 {
216 for (size_t i = 0; i < this->size(); ++i) {
217 this->wells_[i].alq_state.reset_count();
218 }
219 }
220
221
222 int wellNameToGlobalIdx(const std::string& name)
223 {
224 return this->global_well_info.value().well_index(name);
225 }
226
227 std::string globalIdxToWellName(const int index)
228 {
229 return this->global_well_info.value().well_name(index);
230 }
231
232 bool wellIsOwned(std::size_t well_index,
233 const std::string& wellName) const;
234
235 bool wellIsOwned(const std::string& wellName) const;
236
237 bool isRank0() const {
238 return this->global_well_info.value().isRank0();
239 }
240
241 void updateStatus(int well_index, WellStatus status);
242
243 void openWell(int well_index);
244 void shutWell(int well_index);
245 void stopWell(int well_index);
246
248 constexpr int numPhases() const
249 {
250 return phaseUsageInfo_.numActivePhases();
251 }
252
254 std::vector<Scalar>& wellRates(std::size_t well_index)
255 { return this->wells_[well_index].surface_rates; }
256 const std::vector<Scalar>& wellRates(std::size_t well_index) const
257 { return this->wells_[well_index].surface_rates; }
258
259 const std::string& name(std::size_t well_index) const
260 {
261 return this->wells_.well_name(well_index);
262 }
263
264 std::optional<std::size_t> index(const std::string& well_name) const
265 {
266 return this->wells_.well_index(well_name);
267 }
268
269 const SingleWellState<Scalar, IndexTraits>& operator[](std::size_t well_index) const
270 {
271 return this->wells_[well_index];
272 }
273
274 const SingleWellState<Scalar, IndexTraits>& operator[](const std::string& well_name) const
275 {
276 return this->wells_[well_name];
277 }
278
280 {
281 return this->wells_[well_index];
282 }
283
285 {
286 return this->wells_[well_name];
287 }
288
289 const SingleWellState<Scalar, IndexTraits>& well(std::size_t well_index) const
290 {
291 return this->operator[](well_index);
292 }
293
294 const SingleWellState<Scalar, IndexTraits>& well(const std::string& well_name) const
295 {
296 return this->operator[](well_name);
297 }
298
300 {
301 return this->operator[](well_index);
302 }
303
304 SingleWellState<Scalar, IndexTraits>& well(const std::string& well_name)
305 {
306 return this->operator[](well_name);
307 }
308
309 bool has(const std::string& well_name) const
310 {
311 return this->wells_.has(well_name);
312 }
313
314 bool operator==(const WellState&) const;
315
316 template<class Serializer>
317 void serializeOp(Serializer& serializer)
318 {
319 serializer(well_rates);
320 if (serializer.isSerializing()) {
321 serializer(wells_.size());
322 } else {
323 std::size_t size = 0;
324 serializer(size);
325 if (size != wells_.size()) {
326 OPM_THROW(std::runtime_error, "Error deserializing WellState: size mismatch");
327 }
328 }
329 for (auto& w : wells_) {
330 serializer(w);
331 }
332 serializer(permanently_inactive_well_names_);
333 }
334
335 bool is_permanently_inactive_well(const std::string& wname) const {
336 return std::find(this->permanently_inactive_well_names_.begin(), this->permanently_inactive_well_names_.end(), wname) != this->permanently_inactive_well_names_.end();
337 }
338
339private:
340 bool enableDistributedWells_ = false;
341
342 PhaseUsageInfo<IndexTraits> phaseUsageInfo_;
343
344 // The wells_ variable is essentially a map of all the wells on the current
345 // process. Observe that since a well can be split over several processes a
346 // well might appear in the WellContainer on different processes.
348
349 // The members global_well_info and well_rates are map like
350 // structures which will have entries for *all* the wells in the system.
351
352 // Use of std::optional<> here is a technical crutch, the
353 // WellStateFullyImplicitBlackoil class should be default constructible,
354 // whereas the GlobalWellInfo is not.
355 std::optional<GlobalWellInfo<Scalar>> global_well_info;
356
357 // The well_rates variable is defined for all wells on all processors. The
358 // bool in the value pair is whether the current process owns the well or
359 // not.
360 std::map<std::string, std::pair<bool, std::vector<Scalar>>> well_rates;
361
362 // Keep track of permanently inactive well names
363 std::vector<std::string> permanently_inactive_well_names_;
364
365 data::Segment
366 reportSegmentResults(const int well_id,
367 const int seg_ix,
368 const int seg_no) const;
369
370
376 void base_init(const std::vector<Scalar>& cellPressures,
377 const std::vector<Scalar>& cellTemperatures,
378 const std::vector<Well>& wells_ecl,
379 const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
380 const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
381 const SummaryState& summary_state);
382
383 void initSingleWell(const std::vector<Scalar>& cellPressures,
384 const std::vector<Scalar>& cellTemperatures,
385 const Well& well,
386 const std::vector<PerforationData<Scalar>>& well_perf_data,
387 const ParallelWellInfo<Scalar>& well_info,
388 const SummaryState& summary_state);
389
390 void initSingleProducer(const Well& well,
391 const ParallelWellInfo<Scalar>& well_info,
392 Scalar pressure_first_connection,
393 const std::vector<PerforationData<Scalar>>& well_perf_data,
394 const SummaryState& summary_state);
395
396 void initSingleInjector(const Well& well,
397 const ParallelWellInfo<Scalar>& well_info,
398 Scalar pressure_first_connection,
399 Scalar temperature_first_connection,
400 const std::vector<PerforationData<Scalar>>& well_perf_data,
401 const SummaryState& summary_state);
402
403 static void calculateSegmentRatesBeforeSum(const ParallelWellInfo<Scalar>& pw_info,
404 const std::vector<std::vector<int>>& segment_inlets,
405 const std::vector<std::vector<int>>& segment_perforations,
406 const std::vector<Scalar>& perforation_rates,
407 const int np,
408 const int segment,
409 std::vector<Scalar>& segment_rates);
410
411 void reportConnectionFactors(const std::size_t well_index,
412 std::vector<data::Connection>& connections) const;
413
414 void reportConnectionPressuresAndRates(const std::size_t well_index,
415 std::vector<data::Connection>& connections) const;
416
417 void reportConnectionFilterCake(const std::size_t well_index,
418 std::vector<data::Connection>& connections) const;
419
420 void reportFractureStatistics(const std::vector<ConnFracStatistics<Scalar>>& stats,
421 std::vector<data::Connection>& connections) const;
422};
423
424} // namespace Opm
425
426// TODO: we are missing pu, while it was not there in the first place
427#endif // OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
Definition: ConnFracStatistics.hpp:37
Class encapsulating some information about parallel wells.
Definition: ParallelWellInfo.hpp:198
Definition: GasLiftGroupInfo.hpp:37
Definition: SingleWellState.hpp:43
Definition: WellContainer.hpp:46
Definition: WellState.hpp:66
bool has(const std::string &well_name) const
Definition: WellState.hpp:309
void reportConnections(std::vector< data::Connection > &connections, std::size_t well_index, const int *globalCellIdxMap) const
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)
void clearWellRates()
Definition: WellState.hpp:150
bool isProductionGrup(const std::string &name) const
Definition: WellState.hpp:191
bool wellIsOwned(std::size_t well_index, const std::string &wellName) const
void openWell(int well_index)
SingleWellState< Scalar, IndexTraits > & operator[](std::size_t well_index)
Definition: WellState.hpp:279
constexpr int numPhases() const
The number of phases present.
Definition: WellState.hpp:248
SingleWellState< Scalar, IndexTraits > & well(std::size_t well_index)
Definition: WellState.hpp:299
bool hasWellRates(const std::string &wellName) const
Definition: WellState.hpp:145
bool is_permanently_inactive_well(const std::string &wname) const
Definition: WellState.hpp:335
std::string globalIdxToWellName(const int index)
Definition: WellState.hpp:227
const ParallelWellInfo< Scalar > & parallelWellInfo(std::size_t well_index) const
void communicateGroupRates(const Parallel::Communication &comm)
static const int gasPhaseIdx
Definition: WellState.hpp:78
bool isInjectionGrup(const std::string &name) const
Definition: WellState.hpp:186
void initWellStateMSWell(const std::vector< Well > &wells_ecl, const WellState *prev_well_state)
init the MS well related.
int wellNameToGlobalIdx(const std::string &name)
Definition: WellState.hpp:222
static const int waterPhaseIdx
Definition: WellState.hpp:76
void stopWell(int well_index)
void gatherVectorsOnRoot(const std::vector< data::Connection > &from_connections, std::vector< data::Connection > &to_connections, const Parallel::Communication &comm) const
void gliftTimeStepInit()
Definition: WellState.hpp:214
const SingleWellState< Scalar, IndexTraits > & operator[](const std::string &well_name) const
Definition: WellState.hpp:274
bool operator==(const WellState &) const
WellState(const ParallelWellInfo< Scalar > &pinfo)
void setCurrentWellRates(const std::string &wellName, const std::vector< Scalar > &new_rates)
Definition: WellState.hpp:135
int numWells() const
Definition: WellState.hpp:99
static const int oilPhaseIdx
Definition: WellState.hpp:77
Scalar getGlobalEfficiencyScalingFactor(const std::string &name) const
Definition: WellState.hpp:201
const std::vector< Scalar > & currentWellRates(const std::string &wellName) const
const PhaseUsageInfo< IndexTraits > & phaseUsageInfo() const
Definition: WellState.hpp:105
std::vector< std::string > wells() const
Definition: WellState.hpp:94
bool isRank0() const
Definition: WellState.hpp:237
const SingleWellState< Scalar, IndexTraits > & well(const std::string &well_name) const
Definition: WellState.hpp:294
static const std::uint64_t event_mask
Definition: WellState.hpp:68
static WellState serializationTestObject(const ParallelWellInfo< Scalar > &pinfo)
std::size_t size() const
Definition: WellState.hpp:89
WellState(const PhaseUsageInfo< IndexTraits > &pu)
Definition: WellState.hpp:83
void updateStatus(int well_index, WellStatus status)
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)
void updateEfficiencyScalingFactor(const std::string &wellName, const Scalar value)
const SingleWellState< Scalar, IndexTraits > & well(std::size_t well_index) const
Definition: WellState.hpp:289
const SingleWellState< Scalar, IndexTraits > & operator[](std::size_t well_index) const
Definition: WellState.hpp:269
bool isOpen(const std::string &name) const
Definition: WellState.hpp:196
bool wellIsOwned(const std::string &wellName) const
const std::vector< Scalar > & wellRates(std::size_t well_index) const
Definition: WellState.hpp:256
data::Wells report(const int *globalCellIdxMap, const std::function< bool(const int)> &wasDynamicallyClosed) const
std::vector< Scalar > & wellRates(std::size_t well_index)
One rate per well and phase.
Definition: WellState.hpp:254
void updateWellsDefaultALQ(const Schedule &schedule, const int report_step, const SummaryState &summary_state)
void serializeOp(Serializer &serializer)
Definition: WellState.hpp:317
SingleWellState< Scalar, IndexTraits > & operator[](const std::string &well_name)
Definition: WellState.hpp:284
std::optional< std::size_t > index(const std::string &well_name) const
Definition: WellState.hpp:264
void shutWell(int well_index)
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)
void updateGlobalIsGrup(const Parallel::Communication &comm)
SingleWellState< Scalar, IndexTraits > & well(const std::string &well_name)
Definition: WellState.hpp:304
const std::string & name(std::size_t well_index) const
Definition: WellState.hpp:259
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Definition: blackoilboundaryratevector.hh:39
Static data associated with a well perforation.
Definition: PerforationData.hpp:30