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