My Project
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 
25 #include <opm/simulators/wells/WellInterface.hpp>
26 #include <opm/simulators/wells/MultisegmentWellEval.hpp>
27 
28 #include <opm/parser/eclipse/EclipseState/Runspec.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  GetPropType<TypeTag, Properties::Scalar>>
39  {
40  public:
43  GetPropType<TypeTag, Properties::Indices>,
44  GetPropType<TypeTag, Properties::Scalar>>;
45 
46  using typename Base::Simulator;
47  using typename Base::IntensiveQuantities;
48  using typename Base::FluidSystem;
49  using typename Base::ModelParameters;
50  using typename Base::MaterialLaw;
51  using typename Base::Indices;
52  using typename Base::RateConverterType;
53  using typename Base::SparseMatrixAdapter;
54  using typename Base::FluidState;
55  using typename Base::GasLiftSingleWell;
56  using typename Base::GLiftProdWells;
57  using typename Base::GLiftOptWells;
58  using typename Base::GLiftWellStateMap;
59  using typename Base::GLiftSyncGroups;
60 
61  using Base::has_solvent;
62  using Base::has_polymer;
63  using Base::Water;
64  using Base::Oil;
65  using Base::Gas;
66 
67  using typename Base::Scalar;
68 
70  using typename Base::BVector;
71  using typename Base::Eval;
72 
73  using typename MSWEval::EvalWell;
74  using typename MSWEval::BVectorWell;
75  using typename MSWEval::DiagMatWell;
76  using typename MSWEval::OffDiagMatrixBlockWellType;
77  using MSWEval::GFrac;
78  using MSWEval::WFrac;
79  using MSWEval::GTotal;
80  using MSWEval::SPres;
81  using MSWEval::numWellEq;
82 
83  MultisegmentWell(const Well& well,
84  const ParallelWellInfo& pw_info,
85  const int time_step,
86  const ModelParameters& param,
87  const RateConverterType& rate_converter,
88  const int pvtRegionIdx,
89  const int num_components,
90  const int num_phases,
91  const int index_of_well,
92  const std::vector<PerforationData>& perf_data);
93 
94  virtual void init(const PhaseUsage* phase_usage_arg,
95  const std::vector<double>& depth_arg,
96  const double gravity_arg,
97  const int num_cells,
98  const std::vector< Scalar >& B_avg) override;
99 
100  virtual void initPrimaryVariablesEvaluation() const override;
101 
102  virtual void gasLiftOptimizationStage1 (
103  WellState&,
104  const GroupState&,
105  const Simulator&,
107  GLiftProdWells &,
108  GLiftOptWells &,
109  GLiftWellStateMap &,
111  GLiftSyncGroups &
112  ) const override {
113  // Not implemented yet
114  }
115 
117  virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
118  const GroupState& group_state,
119  WellState& well_state,
120  DeferredLogger& deferred_logger) const override;
121 
123  virtual ConvergenceReport getWellConvergence(const WellState& well_state,
124  const std::vector<double>& B_avg,
125  DeferredLogger& deferred_logger,
126  const bool relax_tolerance = false) const override;
127 
129  virtual void apply(const BVector& x, BVector& Ax) const override;
131  virtual void apply(BVector& r) const override;
132 
135  virtual void recoverWellSolutionAndUpdateWellState(const BVector& x,
136  WellState& well_state,
137  DeferredLogger& deferred_logger) const override;
138 
140  virtual void computeWellPotentials(const Simulator& ebosSimulator,
141  const WellState& well_state,
142  std::vector<double>& well_potentials,
143  DeferredLogger& deferred_logger) override;
144 
145  virtual void updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) const override;
146 
147  virtual void solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger) override; // const?
148 
149  virtual void calculateExplicitQuantities(const Simulator& ebosSimulator,
150  const WellState& well_state,
151  DeferredLogger& deferred_logger) override; // should be const?
152 
153  virtual void updateProductivityIndex(const Simulator& ebosSimulator,
154  const WellProdIndexCalculator& wellPICalc,
155  WellState& well_state,
156  DeferredLogger& deferred_logger) const override;
157 
158  virtual void addWellContributions(SparseMatrixAdapter& jacobian) const override;
159 
160  virtual std::vector<double> computeCurrentWellRates(const Simulator& ebosSimulator,
161  DeferredLogger& deferred_logger) const override;
162 
163  void computeConnLevelProdInd(const FluidState& fs,
164  const std::function<double(const double)>& connPICalc,
165  const std::vector<Scalar>& mobility,
166  double* connPI) const;
167 
168  void computeConnLevelInjInd(const FluidState& fs,
169  const Phase preferred_phase,
170  const std::function<double(const double)>& connIICalc,
171  const std::vector<Scalar>& mobility,
172  double* connII,
173  DeferredLogger& deferred_logger) const;
174 
175  protected:
176  int number_segments_;
177 
178  // components of the pressure drop to be included
179  WellSegments::CompPressureDrop compPressureDrop() const;
180  // multi-phase flow model
181  WellSegments::MultiPhaseModel multiphaseModel() const;
182 
183  // the intial amount of fluids in each segment under surface condition
184  std::vector<std::vector<double> > segment_fluid_initial_;
185 
186  mutable int debug_cost_counter_ = 0;
187 
188  // updating the well_state based on well solution dwells
189  void updateWellState(const BVectorWell& dwells,
190  WellState& well_state,
191  DeferredLogger& deferred_logger,
192  const double relaxation_factor=1.0) const;
193 
194 
195  // computing the accumulation term for later use in well mass equations
196  void computeInitialSegmentFluids(const Simulator& ebos_simulator);
197 
198  // compute the pressure difference between the perforation and cell center
199  void computePerfCellPressDiffs(const Simulator& ebosSimulator);
200 
201  void computePerfRateScalar(const IntensiveQuantities& int_quants,
202  const std::vector<Scalar>& mob_perfcells,
203  const double Tw,
204  const int seg,
205  const int perf,
206  const Scalar& segment_pressure,
207  const bool& allow_cf,
208  std::vector<Scalar>& cq_s,
209  DeferredLogger& deferred_logger) const;
210 
211  void computePerfRateEval(const IntensiveQuantities& int_quants,
212  const std::vector<EvalWell>& mob_perfcells,
213  const double Tw,
214  const int seg,
215  const int perf,
216  const EvalWell& segment_pressure,
217  const bool& allow_cf,
218  std::vector<EvalWell>& cq_s,
219  EvalWell& perf_press,
220  double& perf_dis_gas_rate,
221  double& perf_vap_oil_rate,
222  DeferredLogger& deferred_logger) const;
223 
224  template<class Value>
225  void computePerfRate(const Value& pressure_cell,
226  const Value& rs,
227  const Value& rv,
228  const std::vector<Value>& b_perfcells,
229  const std::vector<Value>& mob_perfcells,
230  const double Tw,
231  const int perf,
232  const Value& segment_pressure,
233  const Value& segment_density,
234  const bool& allow_cf,
235  const std::vector<Value>& cmix_s,
236  std::vector<Value>& cq_s,
237  Value& perf_press,
238  double& perf_dis_gas_rate,
239  double& perf_vap_oil_rate,
240  DeferredLogger& deferred_logger) const;
241 
242  // compute the fluid properties, such as densities, viscosities, and so on, in the segments
243  // They will be treated implicitly, so they need to be of Evaluation type
244  void computeSegmentFluidProperties(const Simulator& ebosSimulator);
245 
246  // get the mobility for specific perforation
247  void getMobilityEval(const Simulator& ebosSimulator,
248  const int perf,
249  std::vector<EvalWell>& mob) const;
250 
251  // get the mobility for specific perforation
252  void getMobilityScalar(const Simulator& ebosSimulator,
253  const int perf,
254  std::vector<Scalar>& mob) const;
255 
256  void computeWellRatesAtBhpLimit(const Simulator& ebosSimulator,
257  std::vector<double>& well_flux,
258  DeferredLogger& deferred_logger) const;
259 
260  void computeWellRatesWithBhp(const Simulator& ebosSimulator,
261  const Scalar& bhp,
262  std::vector<double>& well_flux,
263  DeferredLogger& deferred_logger) const;
264 
265  void computeWellRatesWithBhpIterations(const Simulator& ebosSimulator,
266  const Scalar& bhp,
267  std::vector<double>& well_flux,
268  DeferredLogger& deferred_logger) const;
269 
270  std::vector<double>
271  computeWellPotentialWithTHP(const Simulator& ebos_simulator,
272  DeferredLogger& deferred_logger) const;
273 
274  virtual double getRefDensity() const override;
275 
276  virtual bool iterateWellEqWithControl(const Simulator& ebosSimulator,
277  const double dt,
278  const Well::InjectionControls& inj_controls,
279  const Well::ProductionControls& prod_controls,
280  WellState& well_state,
281  const GroupState& group_state,
282  DeferredLogger& deferred_logger) override;
283 
284  virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
285  const double dt,
286  const Well::InjectionControls& inj_controls,
287  const Well::ProductionControls& prod_controls,
288  WellState& well_state,
289  const GroupState& group_state,
290  DeferredLogger& deferred_logger) override;
291 
292  virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
293 
294  EvalWell getSegmentSurfaceVolume(const Simulator& ebos_simulator, const int seg_idx) const;
295 
296  // turn on crossflow to avoid singular well equations
297  // when the well is banned from cross-flow and the BHP is not properly initialized,
298  // we turn on crossflow to avoid singular well equations. It can result in wrong-signed
299  // well rates, it can cause problem for THP calculation
300  // TODO: looking for better alternative to avoid wrong-signed well rates
301  bool openCrossFlowAvoidSingularity(const Simulator& ebos_simulator) const;
302 
303  // for a well, when all drawdown are in the wrong direction, then this well will not
304  // be able to produce/inject .
305  bool allDrawDownWrongDirection(const Simulator& ebos_simulator) const;
306 
307 
308  std::optional<double> computeBhpAtThpLimitProd(const Simulator& ebos_simulator,
309  const SummaryState& summary_state,
310  DeferredLogger& deferred_logger) const;
311 
312  std::optional<double> computeBhpAtThpLimitInj(const Simulator& ebos_simulator,
313  const SummaryState& summary_state,
314  DeferredLogger& deferred_logger) const;
315 
316  double maxPerfPress(const Simulator& ebos_simulator) const;
317 
318  // check whether the well is operable under BHP limit with current reservoir condition
319  virtual void checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
320 
321  // check whether the well is operable under THP limit with current reservoir condition
322  virtual void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
323 
324  // updating the inflow based on the current reservoir condition
325  virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const override;
326  };
327 
328 }
329 
330 #include "MultisegmentWell_impl.hpp"
331 
332 #endif // OPM_MULTISEGMENTWELL_HEADER_INCLUDED
Represents the convergence status of the whole simulator, to make it possible to query and store the ...
Definition: ConvergenceReport.hpp:36
Definition: DeferredLogger.hpp:57
Definition: GasLiftGroupInfo.hpp:46
Definition: GasLiftSingleWell.hpp:46
Definition: GroupState.hpp:34
Definition: MultisegmentWellEval.hpp:52
Definition: MultisegmentWell.hpp:39
virtual void updateWellStateWithTarget(const Simulator &ebos_simulator, const GroupState &group_state, WellState &well_state, DeferredLogger &deferred_logger) const override
updating the well state based the current control mode
Definition: MultisegmentWell_impl.hpp:142
virtual void recoverWellSolutionAndUpdateWellState(const BVector &x, WellState &well_state, DeferredLogger &deferred_logger) const override
using the solution x to recover the solution xw for wells and applying xw to update Well State
Definition: MultisegmentWell_impl.hpp:226
virtual void apply(const BVector &x, BVector &Ax) const override
Ax = Ax - C D^-1 B x.
Definition: MultisegmentWell_impl.hpp:184
virtual std::vector< double > computeCurrentWellRates(const Simulator &ebosSimulator, DeferredLogger &deferred_logger) const override
Compute well rates based on current reservoir conditions and well variables.
Definition: MultisegmentWell_impl.hpp:1848
virtual void computeWellPotentials(const Simulator &ebosSimulator, const WellState &well_state, std::vector< double > &well_potentials, DeferredLogger &deferred_logger) override
computing the well potentials for group control
Definition: MultisegmentWell_impl.hpp:244
virtual ConvergenceReport getWellConvergence(const WellState &well_state, const std::vector< double > &B_avg, DeferredLogger &deferred_logger, const bool relax_tolerance=false) const override
check whether the well equations get converged for this well
Definition: MultisegmentWell_impl.hpp:161
Class encapsulating some information about parallel wells.
Definition: ParallelWellInfo.hpp:252
Definition: WellInterface.hpp:71
Collect per-connection static information to enable calculating connection-level or well-level produc...
Definition: WellProdIndexCalculator.hpp:36
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition: WellState.hpp:56
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:26
Solver parameters for the BlackoilModel.
Definition: BlackoilModelParametersEbos.hpp:327
Definition: BlackoilPhases.hpp:45