WellState.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2012 SINTEF ICT, Applied Mathematics.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef OPM_WELLSTATE_HEADER_INCLUDED
21 #define OPM_WELLSTATE_HEADER_INCLUDED
22 
23 #include <opm/core/wells.h>
24 #include <opm/core/well_controls.h>
25 #include <array>
26 #include <map>
27 #include <string>
28 #include <vector>
29 #include <cassert>
30 #include <cstddef>
31 
32 namespace Opm
33 {
34 
36  class WellState
37  {
38  public:
39  typedef std::array< int, 3 > mapentry_t;
40  typedef std::map< std::string, mapentry_t > WellMapType;
41 
47  template <class State>
48  void init(const Wells* wells, const State& state)
49  {
50  // clear old name mapping
51  wellMap_.clear();
52 
53  if (wells) {
54  const int nw = wells->number_of_wells;
55  const int np = wells->number_of_phases;
56  bhp_.resize(nw);
57  thp_.resize(nw);
58  temperature_.resize(nw, 273.15 + 20); // standard temperature for now
59  wellrates_.resize(nw * np, 0.0);
60  for (int w = 0; w < nw; ++w) {
61  assert((wells->type[w] == INJECTOR) || (wells->type[w] == PRODUCER));
62  const WellControls* ctrl = wells->ctrls[w];
63 
64  // setup wellname -> well index mapping
65  {
66  assert( wells->name[ w ] );
67  std::string name( wells->name[ w ] );
68  assert( name.size() > 0 );
69  mapentry_t& wellMapEntry = wellMap_[name];
70  wellMapEntry[ 0 ] = w;
71  wellMapEntry[ 1 ] = wells->well_connpos[w];
72  // also store the number of perforations in this well
73  const int num_perf_this_well = wells->well_connpos[w + 1] - wells->well_connpos[w];
74  wellMapEntry[ 2 ] = num_perf_this_well;
75  }
76 
78  // Stopped well:
79  // 1. Rates: assign zero well rates.
80  for (int p = 0; p < np; ++p) {
81  wellrates_[np*w + p] = 0.0;
82  }
83  // 2. Bhp: assign bhp equal to bhp control, if
84  // applicable, otherwise assign equal to
85  // first perforation cell pressure.
86  if (well_controls_get_current_type(ctrl) == BHP) {
87  bhp_[w] = well_controls_get_current_target( ctrl );
88  } else {
89  const int first_cell = wells->well_cells[wells->well_connpos[w]];
90  bhp_[w] = state.pressure()[first_cell];
91  }
92  // 3. Thp: assign thp equal to thp control, if applicable,
93  // otherwise assign equal to bhp value.
94  if (well_controls_get_current_type(ctrl) == THP) {
95  thp_[w] = well_controls_get_current_target( ctrl );
96  } else {
97  thp_[w] = bhp_[w];
98  }
99  } else {
100  // Open well:
101  // 1. Rates: initialize well rates to match controls
102  // if type is SURFACE_RATE. Otherwise, we
103  // cannot set the correct value here, so we
104  // assign a small rate with the correct
105  // sign so that any logic depending on that
106  // sign will work as expected.
108  const double rate_target = well_controls_get_current_target(ctrl);
109  const double * distr = well_controls_get_current_distr( ctrl );
110  for (int p = 0; p < np; ++p) {
111  wellrates_[np*w + p] = rate_target * distr[p];
112  }
113  } else {
114  const double small_rate = 1e-14;
115  const double sign = (wells->type[w] == INJECTOR) ? 1.0 : -1.0;
116  for (int p = 0; p < np; ++p) {
117  wellrates_[np*w + p] = small_rate * sign;
118  }
119  }
120 
121  // 2. Bhp: initialize bhp to be target pressure if
122  // bhp-controlled well, otherwise set to a
123  // little above or below (depending on if
124  // the well is an injector or producer)
125  // pressure in first perforation cell.
126  if (well_controls_get_current_type(ctrl) == BHP) {
127  bhp_[w] = well_controls_get_current_target( ctrl );
128  } else {
129  const int first_cell = wells->well_cells[wells->well_connpos[w]];
130  const double safety_factor = (wells->type[w] == INJECTOR) ? 1.01 : 0.99;
131  bhp_[w] = safety_factor*state.pressure()[first_cell];
132  }
133 
134  // 3. Thp: assign thp equal to thp control, if applicable,
135  // otherwise assign equal to bhp value.
136  if (well_controls_get_current_type(ctrl) == THP) {
137  thp_[w] = well_controls_get_current_target( ctrl );
138  } else {
139  thp_[w] = bhp_[w];
140  }
141  }
142  }
143 
144  // The perforation rates and perforation pressures are
145  // not expected to be consistent with bhp_ and wellrates_
146  // after init().
147  perfrates_.resize(wells->well_connpos[nw], 0.0);
148  perfpress_.resize(wells->well_connpos[nw], -1e100);
149  }
150  }
151 
153  std::vector<double>& bhp() { return bhp_; }
154  const std::vector<double>& bhp() const { return bhp_; }
155 
157  std::vector<double>& thp() { return thp_; }
158  const std::vector<double>& thp() const { return thp_; }
159 
161  std::vector<double>& temperature() { return temperature_; }
162  const std::vector<double>& temperature() const { return temperature_; }
163 
165  std::vector<double>& wellRates() { return wellrates_; }
166  const std::vector<double>& wellRates() const { return wellrates_; }
167 
169  std::vector<double>& perfRates() { return perfrates_; }
170  const std::vector<double>& perfRates() const { return perfrates_; }
171 
173  std::vector<double>& perfPress() { return perfpress_; }
174  const std::vector<double>& perfPress() const { return perfpress_; }
175 
176  size_t getRestartBhpOffset() const {
177  return 0;
178  }
179 
180  size_t getRestartPerfPressOffset() const {
181  return bhp_.size();
182  }
183 
184  size_t getRestartPerfRatesOffset() const {
185  return getRestartPerfPressOffset() + perfpress_.size();
186  }
187 
189  return getRestartPerfRatesOffset() + perfrates_.size();
190  }
191 
192  size_t getRestartWellRatesOffset() const {
193  return getRestartTemperatureOffset() + temperature_.size();
194  }
195 
196  const WellMapType& wellMap() const { return wellMap_; }
197  WellMapType& wellMap() { return wellMap_; }
198 
200  int numWells() const
201  {
202  return bhp().size();
203  }
204 
206  int numPhases() const
207  {
208  return wellRates().size() / numWells();
209  }
210 
211  private:
212  std::vector<double> bhp_;
213  std::vector<double> thp_;
214  std::vector<double> temperature_;
215  std::vector<double> wellrates_;
216  std::vector<double> perfrates_;
217  std::vector<double> perfpress_;
218 
219  WellMapType wellMap_;
220  };
221 
222 } // namespace Opm
223 
224 #endif // OPM_WELLSTATE_HEADER_INCLUDED
int * well_connpos
Definition: wells.h:81
const std::vector< double > & perfPress() const
Definition: WellState.hpp:174
Definition: well_controls.h:38
Definition: wells.h:50
size_t getRestartTemperatureOffset() const
Definition: WellState.hpp:188
int number_of_wells
Definition: wells.h:52
Definition: AnisotropicEikonal.hpp:43
std::vector< double > & bhp()
One bhp pressure per well.
Definition: WellState.hpp:153
const std::vector< double > & perfRates() const
Definition: WellState.hpp:170
const double * well_controls_get_current_distr(const struct WellControls *ctrl)
const std::vector< double > & bhp() const
Definition: WellState.hpp:154
Definition: well_controls.h:36
std::vector< double > & temperature()
One temperature per well.
Definition: WellState.hpp:161
std::array< int, 3 > mapentry_t
Definition: WellState.hpp:39
int * well_cells
Definition: wells.h:87
int numWells() const
The number of wells present.
Definition: WellState.hpp:200
size_t getRestartWellRatesOffset() const
Definition: WellState.hpp:192
std::vector< double > & perfPress()
One pressure per well connection.
Definition: WellState.hpp:173
const std::vector< double > & wellRates() const
Definition: WellState.hpp:166
int number_of_phases
Definition: wells.h:53
const WellMapType & wellMap() const
Definition: WellState.hpp:196
enum WellType * type
Definition: wells.h:58
char ** name
Definition: wells.h:103
struct WellControls ** ctrls
Definition: wells.h:98
The state of a set of wells.
Definition: WellState.hpp:36
std::map< std::string, mapentry_t > WellMapType
Definition: WellState.hpp:40
std::vector< double > & wellRates()
One rate per well and phase.
Definition: WellState.hpp:165
double well_controls_get_current_target(const struct WellControls *ctrl)
const std::vector< double > & temperature() const
Definition: WellState.hpp:162
bool well_controls_well_is_stopped(const struct WellControls *ctrl)
enum WellControlType well_controls_get_current_type(const struct WellControls *ctrl)
Definition: legacy_well.h:42
size_t getRestartPerfPressOffset() const
Definition: WellState.hpp:180
int numPhases() const
The number of phases present.
Definition: WellState.hpp:206
std::vector< double > & perfRates()
One rate per well connection.
Definition: WellState.hpp:169
size_t getRestartBhpOffset() const
Definition: WellState.hpp:176
void init(const Wells *wells, const State &state)
Definition: WellState.hpp:48
Definition: legacy_well.h:37
size_t getRestartPerfRatesOffset() const
Definition: WellState.hpp:184
Definition: legacy_well.h:37
WellMapType & wellMap()
Definition: WellState.hpp:197
const std::vector< double > & thp() const
Definition: WellState.hpp:158
std::vector< double > & thp()
One thp pressure per well.
Definition: WellState.hpp:157