WellStateFullyImplicitBlackoil.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2014 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_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
21 #define OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
22 
23 
24 #include <opm/core/wells.h>
25 #include <opm/core/well_controls.h>
26 #include <opm/core/simulator/WellState.hpp>
27 #include <opm/common/ErrorMacros.hpp>
28 #include <vector>
29 #include <cassert>
30 #include <string>
31 #include <utility>
32 #include <map>
33 #include <algorithm>
34 #include <array>
35 
36 namespace Opm
37 {
38 
42  : public WellState
43  {
44  typedef WellState BaseType;
45  public:
46  typedef BaseType :: WellMapType WellMapType;
47 
48  using BaseType :: wellRates;
49  using BaseType :: bhp;
50  using BaseType :: perfPress;
51  using BaseType :: wellMap;
52  using BaseType :: numWells;
53  using BaseType :: numPhases;
54 
58  template <class State, class PrevState>
59  void init(const Wells* wells, const State& state, const PrevState& prevState)
60  {
61  // call init on base class
62  BaseType :: init(wells, state);
63 
64  // if there are no well, do nothing in init
65  if (wells == 0) {
66  return;
67  }
68 
69  const int nw = wells->number_of_wells;
70  if( nw == 0 ) return ;
71 
72  // Initialize perfphaserates_, which must be done here.
73  const int np = wells->number_of_phases;
74  const int nperf = wells->well_connpos[nw];
75  // Ensure that we start out with zero rates by default.
76  perfphaserates_.clear();
77  perfphaserates_.resize(nperf * np, 0.0);
78  for (int w = 0; w < nw; ++w) {
79  assert((wells->type[w] == INJECTOR) || (wells->type[w] == PRODUCER));
80  const WellControls* ctrl = wells->ctrls[w];
81 
82  if (well_controls_well_is_stopped(ctrl)) {
83  // Shut well: perfphaserates_ are all zero.
84  } else {
85  const int num_perf_this_well = wells->well_connpos[w + 1] - wells->well_connpos[w];
86  // Open well: Initialize perfphaserates_ to well
87  // rates divided by the number of perforations.
88  for (int perf = wells->well_connpos[w]; perf < wells->well_connpos[w + 1]; ++perf) {
89  for (int p = 0; p < np; ++p) {
90  perfphaserates_[np*perf + p] = wellRates()[np*w + p] / double(num_perf_this_well);
91  }
92  perfPress()[perf] = state.pressure()[wells->well_cells[perf]];
93  }
94  }
95  }
96 
97  // Initialize current_controls_.
98  // The controls set in the Wells object are treated as defaults,
99  // and also used for initial values.
100  current_controls_.resize(nw);
101  for (int w = 0; w < nw; ++w) {
102  current_controls_[w] = well_controls_get_current(wells->ctrls[w]);
103  }
104 
105  // intialize wells that have been there before
106  // order may change so the mapping is based on the well name
107  if( ! prevState.wellMap().empty() )
108  {
109  typedef typename WellMapType :: const_iterator const_iterator;
110  const_iterator end = prevState.wellMap().end();
111  for (int w = 0; w < nw; ++w) {
112  std::string name( wells->name[ w ] );
113  const_iterator it = prevState.wellMap().find( name );
114  if( it != end )
115  {
116  const int oldIndex = (*it).second[ 0 ];
117  const int newIndex = w;
118 
119  // bhp
120  bhp()[ newIndex ] = prevState.bhp()[ oldIndex ];
121 
122  // wellrates
123  for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
124  {
125  wellRates()[ idx ] = prevState.wellRates()[ oldidx ];
126  }
127 
128  // perfPhaseRates
129  int oldPerf_idx = (*it).second[ 1 ];
130  const int num_perf_old_well = (*it).second[ 2 ];
131  const int num_perf_this_well = wells->well_connpos[newIndex + 1] - wells->well_connpos[newIndex];
132  // copy perforation rates when the number of perforations is equal,
133  // otherwise initialize perfphaserates to well rates divided by the number of perforations.
134  if( num_perf_old_well == num_perf_this_well )
135  {
136  int oldPerf = oldPerf_idx *np;
137  for (int perf = wells->well_connpos[ newIndex ]*np;
138  perf < wells->well_connpos[ newIndex + 1]*np; ++perf, ++oldPerf )
139  {
140  perfPhaseRates()[ perf ] = prevState.perfPhaseRates()[ oldPerf ];
141  }
142  } else {
143  for (int perf = wells->well_connpos[newIndex]; perf < wells->well_connpos[newIndex + 1]; ++perf) {
144  for (int p = 0; p < np; ++p) {
145  perfPhaseRates()[np*perf + p] = wellRates()[np*newIndex + p] / double(num_perf_this_well);
146  }
147  }
148  }
149  // perfPressures
150  if( num_perf_old_well == num_perf_this_well )
151  {
152  for (int perf = wells->well_connpos[ newIndex ];
153  perf < wells->well_connpos[ newIndex + 1]; ++perf, ++oldPerf_idx )
154  {
155  perfPress()[ perf ] = prevState.perfPress()[ oldPerf_idx ];
156  }
157  }
158 
159  // currentControls
160  const int old_control_index = prevState.currentControls()[ oldIndex ];
161  if (old_control_index < well_controls_get_num(wells->ctrls[w])) {
162  // If the set of controls have changed, this may not be identical
163  // to the last control, but it must be a valid control.
164  currentControls()[ newIndex ] = old_control_index;
165  }
166 
167  }
168  }
169  }
170  }
171 
173  std::vector<double>& perfPhaseRates() { return perfphaserates_; }
174  const std::vector<double>& perfPhaseRates() const { return perfphaserates_; }
175 
177  std::vector<int>& currentControls() { return current_controls_; }
178  const std::vector<int>& currentControls() const { return current_controls_; }
179 
180  private:
181  std::vector<double> perfphaserates_;
182  std::vector<int> current_controls_;
183  };
184 
185 } // namespace Opm
186 
187 
188 #endif // OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
VFPEvaluation bhp(const VFPProdTable *table, const double &aqua, const double &liquid, const double &vapour, const double &thp, const double &alq)
Definition: VFPHelpers.hpp:517
const std::vector< int > & currentControls() const
Definition: WellStateFullyImplicitBlackoil.hpp:178
Definition: AdditionalObjectDeleter.hpp:22
Definition: WellStateFullyImplicitBlackoil.hpp:41
BaseType::WellMapType WellMapType
Definition: WellStateFullyImplicitBlackoil.hpp:46
std::vector< double > & perfPhaseRates()
One rate per phase and well connection.
Definition: WellStateFullyImplicitBlackoil.hpp:173
void init(const Wells *wells, const State &state, const PrevState &prevState)
Definition: WellStateFullyImplicitBlackoil.hpp:59
std::vector< int > & currentControls()
One current control per well.
Definition: WellStateFullyImplicitBlackoil.hpp:177
const std::vector< double > & perfPhaseRates() const
Definition: WellStateFullyImplicitBlackoil.hpp:174