My Project
WellState.hpp
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 <opm/simulators/wells/ALQState.hpp>
25 #include <opm/simulators/wells/SingleWellState.hpp>
26 #include <opm/simulators/wells/GlobalWellInfo.hpp>
27 #include <opm/simulators/wells/SegmentState.hpp>
28 #include <opm/simulators/wells/WellContainer.hpp>
29 #include <opm/core/props/BlackoilPhases.hpp>
30 #include <opm/simulators/wells/PerforationData.hpp>
31 #include <opm/simulators/wells/PerfData.hpp>
32 #include <opm/output/data/Wells.hpp>
33 
34 #include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
35 #include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
36 
37 #include <dune/common/version.hh>
38 #include <dune/common/parallel/mpihelper.hh>
39 
40 #include <functional>
41 #include <map>
42 #include <optional>
43 #include <string>
44 #include <utility>
45 #include <vector>
46 
47 namespace Opm
48 {
49 
50 class ParallelWellInfo;
51 class Schedule;
52 
55 class WellState
56 {
57 public:
58  static const uint64_t event_mask = ScheduleEvents::WELL_STATUS_CHANGE + ScheduleEvents::PRODUCTION_UPDATE + ScheduleEvents::INJECTION_UPDATE;
59 
60  virtual ~WellState() = default;
61 
62  // TODO: same definition with WellInterface, eventually they should go to a common header file.
63  static const int Water = BlackoilPhases::Aqua;
64  static const int Oil = BlackoilPhases::Liquid;
65  static const int Gas = BlackoilPhases::Vapour;
66 
67  explicit WellState(const PhaseUsage& pu)
68  {
69  this->phase_usage_ = pu;
70  }
71 
72  std::size_t size() const {
73  return this->wells_.size();
74  }
75 
76 
77  int numWells() const
78  {
79  return this->size();
80  }
81 
82  const ParallelWellInfo& parallelWellInfo(std::size_t well_index) const;
83 
84 
85 
89  void init(const std::vector<double>& cellPressures,
90  const Schedule& schedule,
91  const std::vector<Well>& wells_ecl,
92  const std::vector<std::reference_wrapper<ParallelWellInfo>>& parallel_well_info,
93  const int report_step,
94  const WellState* prevState,
95  const std::vector<std::vector<PerforationData>>& well_perf_data,
96  const SummaryState& summary_state);
97 
98  void resize(const std::vector<Well>& wells_ecl,
99  const std::vector<std::reference_wrapper<ParallelWellInfo>>& parallel_well_info,
100  const Schedule& schedule,
101  const bool handle_ms_well,
102  const size_t numCells,
103  const std::vector<std::vector<PerforationData>>& well_perf_data,
104  const SummaryState& summary_state);
105 
106  void setCurrentWellRates(const std::string& wellName, const std::vector<double>& new_rates ) {
107  auto& [owner, rates] = this->well_rates.at(wellName);
108  if (owner)
109  rates = new_rates;
110  }
111 
112  const std::vector<double>& currentWellRates(const std::string& wellName) const;
113 
114  bool hasWellRates(const std::string& wellName) const {
115  return this->well_rates.find(wellName) != this->well_rates.end();
116  }
117 
118  template<class Communication>
119  void gatherVectorsOnRoot(const std::vector< data::Connection >& from_connections,
120  std::vector< data::Connection >& to_connections,
121  const Communication& comm) const;
122 
123  data::Wells
124  report(const int* globalCellIdxMap,
125  const std::function<bool(const int)>& wasDynamicallyClosed) const;
126 
127  void reportConnections(std::vector<data::Connection>& connections, const PhaseUsage &pu,
128  std::size_t well_index,
129  const int* globalCellIdxMap) const;
130 
132  void initWellStateMSWell(const std::vector<Well>& wells_ecl,
133  const WellState* prev_well_state);
134 
135  static void calculateSegmentRates(const std::vector<std::vector<int>>& segment_inlets, const std::vector<std::vector<int>>&segment_perforations,
136  const std::vector<double>& perforation_rates, const int np, const int segment, std::vector<double>& segment_rates);
137 
138 
139  template<class Comm>
140  void communicateGroupRates(const Comm& comm);
141 
142  template<class Comm>
143  void updateGlobalIsGrup(const Comm& comm);
144 
145  bool isInjectionGrup(const std::string& name) const {
146  return this->global_well_info.value().in_injecting_group(name);
147  }
148 
149  bool isProductionGrup(const std::string& name) const {
150  return this->global_well_info.value().in_producing_group(name);
151  }
152 
153  double getALQ( const std::string& name) const
154  {
155  return this->alq_state.get(name);
156  }
157 
158  void setALQ( const std::string& name, double value)
159  {
160  this->alq_state.set(name, value);
161  }
162 
163  bool gliftCheckAlqOscillation(const std::string &name) const {
164  return this->alq_state.oscillation(name);
165  }
166 
167  int gliftGetAlqDecreaseCount(const std::string &name) {
168  return this->alq_state.get_decrement_count(name);
169  }
170 
171  int gliftGetAlqIncreaseCount(const std::string &name) {
172  return this->alq_state.get_increment_count(name);
173  }
174 
175  void gliftUpdateAlqIncreaseCount(const std::string &name, bool increase) {
176  this->alq_state.update_count(name, increase);
177  }
178 
179  void gliftTimeStepInit() {
180  this->alq_state.reset_count();
181  }
182 
183  int wellNameToGlobalIdx(const std::string &name) {
184  return this->global_well_info.value().well_index(name);
185  }
186 
187  std::string globalIdxToWellName(const int index) {
188  return this->global_well_info.value().well_name(index);
189  }
190 
191  bool wellIsOwned(std::size_t well_index,
192  const std::string& wellName) const;
193 
194  bool wellIsOwned(const std::string& wellName) const;
195 
205  void resetConnectionTransFactors(const int well_index,
206  const std::vector<PerforationData>& well_perf_data);
207 
208  void updateStatus(int well_index, Well::Status status);
209 
210  void openWell(int well_index);
211  void shutWell(int well_index);
212  void stopWell(int well_index);
213 
215  int numPhases() const
216  {
217  return this->phase_usage_.num_phases;
218  }
219 
220  const PhaseUsage& phaseUsage() const {
221  return this->phase_usage_;
222  }
223 
225  std::vector<double>& wellRates(std::size_t well_index) { return this->wells_[well_index].surface_rates; }
226  const std::vector<double>& wellRates(std::size_t well_index) const { return this->wells_[well_index].surface_rates; }
227 
228  const std::string& name(std::size_t well_index) const {
229  return this->wells_.well_name(well_index);
230  }
231 
232  std::optional<std::size_t> index(const std::string& well_name) const {
233  return this->wells_.well_index(well_name);
234  }
235 
236  const SingleWellState& well(std::size_t well_index) const {
237  return this->wells_[well_index];
238  }
239 
240  const SingleWellState& well(const std::string& well_name) const {
241  return this->wells_[well_name];
242  }
243 
244  SingleWellState& well(std::size_t well_index) {
245  return this->wells_[well_index];
246  }
247 
248  SingleWellState& well(const std::string& well_name) {
249  return this->wells_[well_name];
250  }
251 
252  bool has(const std::string& well_name) const {
253  return this->wells_.has(well_name);
254  }
255 
256 private:
257  PhaseUsage phase_usage_;
258 
259  // The wells_ variable is essentially a map of all the wells on the current
260  // process. Observe that since a well can be split over several processes a
261  // well might appear in the WellContainer on different processes.
262  WellContainer<SingleWellState> wells_;
263 
264  // The members alq_state, global_well_info and well_rates are map like
265  // structures which will have entries for *all* the wells in the system.
266 
267  // Use of std::optional<> here is a technical crutch, the
268  // WellStateFullyImplicitBlackoil class should be default constructible,
269  // whereas the GlobalWellInfo is not.
270  std::optional<GlobalWellInfo> global_well_info;
271  ALQState alq_state;
272 
273  // The well_rates variable is defined for all wells on all processors. The
274  // bool in the value pair is whether the current process owns the well or
275  // not.
276  std::map<std::string, std::pair<bool, std::vector<double>>> well_rates;
277 
278  data::Segment
279  reportSegmentResults(const int well_id,
280  const int seg_ix,
281  const int seg_no) const;
282 
283  // If the ALQ has changed since the previous report step,
284  // reset current_alq and update default_alq. ALQ is used for
285  // constant lift gas injection and for gas lift optimization
286  // (THP controlled wells).
287 
288  void updateWellsDefaultALQ(const std::vector<Well>& wells_ecl);
289 
295  void base_init(const std::vector<double>& cellPressures,
296  const std::vector<Well>& wells_ecl,
297  const std::vector<std::reference_wrapper<ParallelWellInfo>>& parallel_well_info,
298  const std::vector<std::vector<PerforationData>>& well_perf_data,
299  const SummaryState& summary_state);
300 
301  void initSingleWell(const std::vector<double>& cellPressures,
302  const Well& well,
303  const std::vector<PerforationData>& well_perf_data,
304  const ParallelWellInfo& well_info,
305  const SummaryState& summary_state);
306 
307 
308 
309 };
310 
311 } // namespace Opm
312 
313 
314 #endif // OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
Class encapsulating some information about parallel wells.
Definition: ParallelWellInfo.hpp:252
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition: WellState.hpp:56
void initWellStateMSWell(const std::vector< Well > &wells_ecl, const WellState *prev_well_state)
init the MS well related.
Definition: WellState.cpp:589
void resetConnectionTransFactors(const int well_index, const std::vector< PerforationData > &well_perf_data)
Special purpose method to support dynamically rescaling a well's CTFs through WELPI.
Definition: WellState.cpp:914
std::vector< double > & wellRates(std::size_t well_index)
One rate per well and phase.
Definition: WellState.hpp:225
int numPhases() const
The number of phases present.
Definition: WellState.hpp:215
void init(const std::vector< double > &cellPressures, const Schedule &schedule, const std::vector< Well > &wells_ecl, const std::vector< std::reference_wrapper< ParallelWellInfo >> &parallel_well_info, const int report_step, const WellState *prevState, const std::vector< std::vector< PerforationData >> &well_perf_data, const SummaryState &summary_state)
Allocate and initialize if wells is non-null.
Definition: WellState.cpp:194
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:26
Definition: BlackoilPhases.hpp:45