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