opm-simulators
MultisegmentWell.hpp
1 /*
2  Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
3  Copyright 2017 Statoil ASA.
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 
22 #ifndef OPM_MULTISEGMENTWELL_HEADER_INCLUDED
23 #define OPM_MULTISEGMENTWELL_HEADER_INCLUDED
24 
26 
27 #include <opm/simulators/wells/WellInterface.hpp>
28 #include <opm/simulators/wells/MultisegmentWellEval.hpp>
29 
30 namespace Opm {
31 
32  class DeferredLogger;
33 
34  template<typename TypeTag>
35  class MultisegmentWell : public WellInterface<TypeTag>
36  , public MultisegmentWellEval<GetPropType<TypeTag, Properties::FluidSystem>,
37  GetPropType<TypeTag, Properties::Indices>>
38  {
39  public:
43 
44  using typename Base::Simulator;
45  using typename Base::IntensiveQuantities;
46  using typename Base::FluidSystem;
47  using typename Base::IndexTraits;
48  using typename Base::ModelParameters;
49  using typename Base::MaterialLaw;
50  using typename Base::Indices;
51  using typename Base::RateConverterType;
52  using typename Base::SparseMatrixAdapter;
53  using typename Base::FluidState;
54  using typename Base::WellStateType;
55  using typename Base::GroupStateHelperType;
56 
57  using Base::has_solvent;
58  using Base::has_polymer;
59  using Base::Water;
60  using Base::Oil;
61  using Base::Gas;
62 
63  using typename Base::Scalar;
64 
66  using typename Base::BVector;
67  using typename Base::Eval;
68 
69  using typename MSWEval::Equations;
70  using typename MSWEval::EvalWell;
71  using typename MSWEval::BVectorWell;
72  using MSWEval::SPres;
73  using typename Base::PressureMatrix;
74  using FSInfo = std::tuple<Scalar,typename std::decay<decltype(std::declval<decltype(std::declval<const Simulator&>().model().intensiveQuantities(0, 0).fluidState())>().saltConcentration())>::type>;
75 
76  MultisegmentWell(const Well& well,
77  const ParallelWellInfo<Scalar>& pw_info,
78  const int time_step,
79  const ModelParameters& param,
80  const RateConverterType& rate_converter,
81  const int pvtRegionIdx,
82  const int num_conservation_quantities,
83  const int num_phases,
84  const int index_of_well,
85  const std::vector<PerforationData<Scalar>>& perf_data);
86 
87  void init(const std::vector<Scalar>& depth_arg,
88  const Scalar gravity_arg,
89  const std::vector<Scalar>& B_avg,
90  const bool changed_to_open_this_step) override;
91 
93  void updateWellStateWithTarget(const Simulator& simulator,
94  const GroupStateHelperType& groupStateHelper,
95  WellStateType& well_state) const override;
96 
98  void scaleSegmentRatesAndPressure(WellStateType& well_state) const override;
99 
102  const std::vector<Scalar>& B_avg,
103  const bool relax_tolerance) const override;
104 
106  void apply(const BVector& x, BVector& Ax) const override;
108  void apply(BVector& r) const override;
109 
112  void recoverWellSolutionAndUpdateWellState(const Simulator& simulator,
113  const BVector& x,
114  const GroupStateHelperType& groupStateHelper,
115  WellStateType& well_state) override;
116 
118  void computeWellPotentials(const Simulator& simulator,
119  const WellStateType& well_state,
120  const GroupStateHelperType& groupStateHelper,
121  std::vector<Scalar>& well_potentials) override;
122 
123  void updatePrimaryVariables(const GroupStateHelperType& groupStateHelper) override;
124 
125  void solveEqAndUpdateWellState(const Simulator& simulator,
126  const GroupStateHelperType& groupStateHelper,
127  WellStateType& well_state) override; // const?
128 
129  void calculateExplicitQuantities(const Simulator& simulator,
130  const GroupStateHelperType& groupStateHelper) override; // should be const?
131 
132  void updateIPRImplicit(const Simulator& simulator,
133  const GroupStateHelperType& groupStateHelper,
134  WellStateType& well_state) override;
135 
136  void updateProductivityIndex(const Simulator& simulator,
137  const WellProdIndexCalculator<Scalar>& wellPICalc,
138  WellStateType& well_state,
139  DeferredLogger& deferred_logger) const override;
140 
141  Scalar connectionDensity(const int globalConnIdx,
142  const int openConnIdx) const override;
143 
144  void addWellContributions(SparseMatrixAdapter& jacobian) const override;
145 
146  void addWellPressureEquations(PressureMatrix& mat,
147  const BVector& x,
148  const int pressureVarIndex,
149  const bool use_well_weights,
150  const WellStateType& well_state) const override;
151 
152  std::vector<Scalar>
153  computeCurrentWellRates(const Simulator& simulator,
154  DeferredLogger& deferred_logger) const override;
155 
156  std::optional<Scalar>
157  computeBhpAtThpLimitProdWithAlq(const Simulator& simulator,
158  const GroupStateHelperType& groupStateHelper,
159  const SummaryState& summary_state,
160  const Scalar alq_value,
161  bool iterate_if_no_solution) const override;
162 
163  std::vector<Scalar> getPrimaryVars() const override;
164 
165  int setPrimaryVars(typename std::vector<Scalar>::const_iterator it) override;
166 
167  protected:
168  // regularize msw equation
169  bool regularize_;
170 
171  // the intial amount of fluids in each segment under surface condition
172  std::vector<std::vector<Scalar> > segment_fluid_initial_;
173 
174  mutable int debug_cost_counter_ = 0;
175 
176  // updating the well_state based on well solution dwells
177  void updateWellState(const Simulator& simulator,
178  const BVectorWell& dwells,
179  const GroupStateHelperType& groupStateHelper,
180  WellStateType& well_state,
181  const Scalar relaxation_factor = 1.0);
182 
183  // computing the accumulation term for later use in well mass equations
184  void computeInitialSegmentFluids(const Simulator& simulator, DeferredLogger& deferred_logger);
185 
186  // compute the pressure difference between the perforation and cell center
187  void computePerfCellPressDiffs(const Simulator& simulator);
188 
189  template<class Value>
190  void computePerfRate(const IntensiveQuantities& int_quants,
191  const std::vector<Value>& mob_perfcells,
192  const std::vector<Value>& Tw,
193  const int seg,
194  const int perf,
195  const Value& segment_pressure,
196  const bool& allow_cf,
197  std::vector<Value>& cq_s,
198  Value& perf_press,
199  PerforationRates<Scalar>& perf_rates,
200  DeferredLogger& deferred_logger) const;
201 
202  template<class Value>
203  void computePerfRate(const Value& pressure_cell,
204  const Value& rs,
205  const Value& rv,
206  const std::vector<Value>& b_perfcells,
207  const std::vector<Value>& mob_perfcells,
208  const std::vector<Value>& Tw,
209  const int perf,
210  const Value& segment_pressure,
211  const Value& segment_density,
212  const bool& allow_cf,
213  const std::vector<Value>& cmix_s,
214  std::vector<Value>& cq_s,
215  Value& perf_press,
216  PerforationRates<Scalar>& perf_rates,
217  DeferredLogger& deferred_logger) const;
218 
219  // compute the fluid properties, such as densities, viscosities, and so on, in the segments
220  // They will be treated implicitly, so they need to be of Evaluation type
221  void computeSegmentFluidProperties(const Simulator& simulator,
222  DeferredLogger& deferred_logger);
223 
224  // get the transmissibility multiplier for specific perforation
225  template<class Value>
226  void getTransMult(Value& trans_mult,
227  const Simulator& simulator,
228  const int cell_indx) const;
229 
230  // get the mobility for specific perforation
231  template<class Value>
232  void getMobility(const Simulator& simulator,
233  const int local_perf_index,
234  std::vector<Value>& mob,
235  DeferredLogger& deferred_logger) const;
236 
237  void computeWellRatesAtBhpLimit(const Simulator& simulator,
238  const GroupStateHelperType& groupStateHelper,
239  std::vector<Scalar>& well_flux) const;
240 
241  void computeWellRatesWithBhp(const Simulator& simulator,
242  const Scalar& bhp,
243  std::vector<Scalar>& well_flux,
244  DeferredLogger& deferred_logger) const override;
245 
246  void computeWellRatesWithBhpIterations(const Simulator& simulator,
247  const Scalar& bhp,
248  const GroupStateHelperType& groupStateHelper,
249  std::vector<Scalar>& well_flux) const override;
250 
251  std::vector<Scalar>
252  computeWellPotentialWithTHP(const WellStateType& well_state,
253  const Simulator& simulator,
254  const GroupStateHelperType& groupStateHelper) const;
255 
256  bool computeWellPotentialsImplicit(const Simulator& simulator,
257  const GroupStateHelperType& groupStateHelper,
258  std::vector<Scalar>& well_potentials) const;
259 
260  Scalar getRefDensity() const override;
261 
262  bool iterateWellEqWithControl(const Simulator& simulator,
263  const double dt,
264  const Well::InjectionControls& inj_controls,
265  const Well::ProductionControls& prod_controls,
266  const GroupStateHelperType& groupStateHelper,
267  WellStateType& well_state) override;
268 
269  bool iterateWellEqWithSwitching(const Simulator& simulator,
270  const double dt,
271  const Well::InjectionControls& inj_controls,
272  const Well::ProductionControls& prod_controls,
273  const GroupStateHelperType& groupStateHelper,
274  WellStateType& well_state,
275  const bool fixed_control,
276  const bool fixed_status,
277  const bool solving_with_zero_rate) override;
278 
279  void assembleWellEqWithoutIteration(const Simulator& simulator,
280  const GroupStateHelperType& groupStateHelper,
281  const double dt,
282  const Well::InjectionControls& inj_controls,
283  const Well::ProductionControls& prod_controls,
284  WellStateType& well_state,
285  const bool solving_with_zero_rate) override;
286 
287  void updateWaterThroughput(const double dt, WellStateType& well_state) const override;
288 
289  EvalWell getSegmentSurfaceVolume(const Simulator& simulator,
290  const int seg_idx,
291  DeferredLogger& deferred_logger) const;
292 
293  // turn on crossflow to avoid singular well equations
294  // when the well is banned from cross-flow and the BHP is not properly initialized,
295  // we turn on crossflow to avoid singular well equations. It can result in wrong-signed
296  // well rates, it can cause problem for THP calculation
297  // TODO: looking for better alternative to avoid wrong-signed well rates
298  bool openCrossFlowAvoidSingularity(const Simulator& simulator) const;
299 
300  // for a well, when all drawdown are in the wrong direction, then this well will not
301  // be able to produce/inject .
302  bool allDrawDownWrongDirection(const Simulator& simulator) const;
303 
304  std::optional<Scalar>
305  computeBhpAtThpLimitProd(const WellStateType& well_state,
306  const Simulator& ebos_simulator,
307  const GroupStateHelperType& groupStateHelper,
308  const SummaryState& summary_state) const;
309 
310  std::optional<Scalar>
311  computeBhpAtThpLimitInj(const Simulator& ebos_simulator,
312  const GroupStateHelperType& groupStateHelper,
313  const SummaryState& summary_state) const;
314 
315  Scalar maxPerfPress(const Simulator& simulator) const override;
316 
317  // check whether the well is operable under BHP limit with current reservoir condition
318  void checkOperabilityUnderBHPLimit(const WellStateType& well_state,
319  const Simulator& ebos_simulator,
320  DeferredLogger& deferred_logger) override;
321 
322  // check whether the well is operable under THP limit with current reservoir condition
323  void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator,
324  const WellStateType& well_state,
325  const GroupStateHelperType& groupStateHelper) override;
326 
327  // updating the inflow based on the current reservoir condition
328  void updateIPR(const Simulator& ebos_simulator,
329  DeferredLogger& deferred_logger) const override;
330 
331  FSInfo getFirstPerforationFluidStateInfo(const Simulator& simulator) const;
332  };
333 
334 }
335 
336 #include "MultisegmentWell_impl.hpp"
337 
338 #endif // OPM_MULTISEGMENTWELL_HEADER_INCLUDED
ConvergenceReport getWellConvergence(const GroupStateHelperType &groupStateHelper, const std::vector< Scalar > &B_avg, const bool relax_tolerance) const override
check whether the well equations get converged for this well
Definition: MultisegmentWell_impl.hpp:202
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
Definition: propertysystem.hh:233
void computeWellPotentials(const Simulator &simulator, const WellStateType &well_state, const GroupStateHelperType &groupStateHelper, std::vector< Scalar > &well_potentials) override
computing the well potentials for group control
Definition: MultisegmentWell_impl.hpp:296
Defines the common properties required by the porous medium multi-phase models.
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Definition: BlackoilWellModelConstraints.hpp:37
void scaleSegmentRatesAndPressure(WellStateType &well_state) const override
updating the segment pressure and rates based the current bhp and well rates
Definition: MultisegmentWell_impl.hpp:172
Definition: BlackoilWellModelGasLift.hpp:38
Definition: PerforationData.hpp:40
void apply(const BVector &x, BVector &Ax) const override
Ax = Ax - C D^-1 B x.
Definition: MultisegmentWell_impl.hpp:228
Definition: MultisegmentWellEval.hpp:46
Class encapsulating some information about parallel wells.
Definition: MSWellHelpers.hpp:34
std::vector< Scalar > computeCurrentWellRates(const Simulator &simulator, DeferredLogger &deferred_logger) const override
Compute well rates based on current reservoir conditions and well variables.
Definition: MultisegmentWell_impl.hpp:2277
Definition: DeferredLogger.hpp:56
Collect per-connection static information to enable calculating connection-level or well-level produc...
Definition: WellProdIndexCalculator.hpp:36
Static data associated with a well perforation.
Definition: BlackoilWellModelRestart.hpp:41
void recoverWellSolutionAndUpdateWellState(const Simulator &simulator, const BVector &x, const GroupStateHelperType &groupStateHelper, WellStateType &well_state) override
using the solution x to recover the solution xw for wells and applying xw to update Well State ...
Definition: MultisegmentWell_impl.hpp:263
void updateWellStateWithTarget(const Simulator &simulator, const GroupStateHelperType &groupStateHelper, WellStateType &well_state) const override
updating the well state based the current control mode
Definition: MultisegmentWell_impl.hpp:183
Represents the convergence status of the whole simulator, to make it possible to query and store the ...
Definition: ConvergenceReport.hpp:37
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition: TemperatureModel.hpp:61
Definition: MultisegmentWell.hpp:35