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/input/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 
56  using Base::has_solvent;
57  using Base::has_polymer;
58  using Base::Water;
59  using Base::Oil;
60  using Base::Gas;
61 
62  using typename Base::Scalar;
63 
65  using typename Base::BVector;
66  using typename Base::Eval;
67 
68  using typename MSWEval::EvalWell;
69  using typename MSWEval::BVectorWell;
70  using typename MSWEval::DiagMatWell;
71  using typename MSWEval::OffDiagMatrixBlockWellType;
72  using MSWEval::GFrac;
73  using MSWEval::WFrac;
74  using MSWEval::GTotal;
75  using MSWEval::SPres;
76  using MSWEval::numWellEq;
77 
78  MultisegmentWell(const Well& well,
79  const ParallelWellInfo& pw_info,
80  const int time_step,
81  const ModelParameters& param,
82  const RateConverterType& rate_converter,
83  const int pvtRegionIdx,
84  const int num_components,
85  const int num_phases,
86  const int index_of_well,
87  const std::vector<PerforationData>& perf_data);
88 
89  virtual void init(const PhaseUsage* phase_usage_arg,
90  const std::vector<double>& depth_arg,
91  const double gravity_arg,
92  const int num_cells,
93  const std::vector< Scalar >& B_avg) override;
94 
95  virtual void initPrimaryVariablesEvaluation() const override;
96 
98  virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
99  const GroupState& group_state,
100  WellState& well_state,
101  DeferredLogger& deferred_logger) const override;
102 
104  virtual ConvergenceReport getWellConvergence(const WellState& well_state,
105  const std::vector<double>& B_avg,
106  DeferredLogger& deferred_logger,
107  const bool relax_tolerance = false) const override;
108 
110  virtual void apply(const BVector& x, BVector& Ax) const override;
112  virtual void apply(BVector& r) const override;
113 
116  virtual void recoverWellSolutionAndUpdateWellState(const BVector& x,
117  WellState& well_state,
118  DeferredLogger& deferred_logger) const override;
119 
121  virtual void computeWellPotentials(const Simulator& ebosSimulator,
122  const WellState& well_state,
123  std::vector<double>& well_potentials,
124  DeferredLogger& deferred_logger) override;
125 
126  virtual void updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) const override;
127 
128  virtual void solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger) override; // const?
129 
130  virtual void calculateExplicitQuantities(const Simulator& ebosSimulator,
131  const WellState& well_state,
132  DeferredLogger& deferred_logger) override; // should be const?
133 
134  virtual void updateProductivityIndex(const Simulator& ebosSimulator,
135  const WellProdIndexCalculator& wellPICalc,
136  WellState& well_state,
137  DeferredLogger& deferred_logger) const override;
138 
139  virtual void addWellContributions(SparseMatrixAdapter& jacobian) const override;
140 
141  virtual std::vector<double> computeCurrentWellRates(const Simulator& ebosSimulator,
142  DeferredLogger& deferred_logger) const override;
143 
144  void computeConnLevelProdInd(const FluidState& fs,
145  const std::function<double(const double)>& connPICalc,
146  const std::vector<Scalar>& mobility,
147  double* connPI) const;
148 
149  void computeConnLevelInjInd(const FluidState& fs,
150  const Phase preferred_phase,
151  const std::function<double(const double)>& connIICalc,
152  const std::vector<Scalar>& mobility,
153  double* connII,
154  DeferredLogger& deferred_logger) const;
155 
156  virtual std::optional<double> computeBhpAtThpLimitProdWithAlq(
157  const Simulator& ebos_simulator,
158  const SummaryState& summary_state,
159  DeferredLogger& deferred_logger,
160  double alq_value) const override;
161 
162  protected:
163  int number_segments_;
164 
165  // components of the pressure drop to be included
166  WellSegments::CompPressureDrop compPressureDrop() const;
167  // multi-phase flow model
168  WellSegments::MultiPhaseModel multiphaseModel() const;
169 
170  // the intial amount of fluids in each segment under surface condition
171  std::vector<std::vector<double> > segment_fluid_initial_;
172 
173  mutable int debug_cost_counter_ = 0;
174 
175  // updating the well_state based on well solution dwells
176  void updateWellState(const BVectorWell& dwells,
177  WellState& well_state,
178  DeferredLogger& deferred_logger,
179  const double relaxation_factor=1.0) const;
180 
181 
182  // computing the accumulation term for later use in well mass equations
183  void computeInitialSegmentFluids(const Simulator& ebos_simulator);
184 
185  // compute the pressure difference between the perforation and cell center
186  void computePerfCellPressDiffs(const Simulator& ebosSimulator);
187 
188  void computePerfRateScalar(const IntensiveQuantities& int_quants,
189  const std::vector<Scalar>& mob_perfcells,
190  const double Tw,
191  const int seg,
192  const int perf,
193  const Scalar& segment_pressure,
194  const bool& allow_cf,
195  std::vector<Scalar>& cq_s,
196  DeferredLogger& deferred_logger) const;
197 
198  void computePerfRateEval(const IntensiveQuantities& int_quants,
199  const std::vector<EvalWell>& mob_perfcells,
200  const double Tw,
201  const int seg,
202  const int perf,
203  const EvalWell& segment_pressure,
204  const bool& allow_cf,
205  std::vector<EvalWell>& cq_s,
206  EvalWell& perf_press,
207  double& perf_dis_gas_rate,
208  double& perf_vap_oil_rate,
209  DeferredLogger& deferred_logger) const;
210 
211  template<class Value>
212  void computePerfRate(const Value& pressure_cell,
213  const Value& rs,
214  const Value& rv,
215  const std::vector<Value>& b_perfcells,
216  const std::vector<Value>& mob_perfcells,
217  const double Tw,
218  const int perf,
219  const Value& segment_pressure,
220  const Value& segment_density,
221  const bool& allow_cf,
222  const std::vector<Value>& cmix_s,
223  std::vector<Value>& cq_s,
224  Value& perf_press,
225  double& perf_dis_gas_rate,
226  double& perf_vap_oil_rate,
227  DeferredLogger& deferred_logger) const;
228 
229  // compute the fluid properties, such as densities, viscosities, and so on, in the segments
230  // They will be treated implicitly, so they need to be of Evaluation type
231  void computeSegmentFluidProperties(const Simulator& ebosSimulator,
232  DeferredLogger& deferred_logger);
233 
234  // get the mobility for specific perforation
235  void getMobilityEval(const Simulator& ebosSimulator,
236  const int perf,
237  std::vector<EvalWell>& mob) const;
238 
239  // get the mobility for specific perforation
240  void getMobilityScalar(const Simulator& ebosSimulator,
241  const int perf,
242  std::vector<Scalar>& mob) const;
243 
244  void computeWellRatesAtBhpLimit(const Simulator& ebosSimulator,
245  std::vector<double>& well_flux,
246  DeferredLogger& deferred_logger) const;
247 
248  virtual void computeWellRatesWithBhp(const Simulator& ebosSimulator,
249  const double& bhp,
250  std::vector<double>& well_flux,
251  DeferredLogger& deferred_logger) const override;
252 
253  void computeWellRatesWithBhpIterations(const Simulator& ebosSimulator,
254  const Scalar& bhp,
255  std::vector<double>& well_flux,
256  DeferredLogger& deferred_logger) const;
257 
258  std::vector<double> computeWellPotentialWithTHP(
259  const WellState& well_state,
260  const Simulator& ebos_simulator,
261  DeferredLogger& deferred_logger) const;
262 
263  virtual double getRefDensity() const override;
264 
265  virtual bool iterateWellEqWithControl(const Simulator& ebosSimulator,
266  const double dt,
267  const Well::InjectionControls& inj_controls,
268  const Well::ProductionControls& prod_controls,
269  WellState& well_state,
270  const GroupState& group_state,
271  DeferredLogger& deferred_logger) override;
272 
273  virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
274  const double dt,
275  const Well::InjectionControls& inj_controls,
276  const Well::ProductionControls& prod_controls,
277  WellState& well_state,
278  const GroupState& group_state,
279  DeferredLogger& deferred_logger) override;
280 
281  virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
282 
283  EvalWell getSegmentSurfaceVolume(const Simulator& ebos_simulator, const int seg_idx) const;
284 
285  // turn on crossflow to avoid singular well equations
286  // when the well is banned from cross-flow and the BHP is not properly initialized,
287  // we turn on crossflow to avoid singular well equations. It can result in wrong-signed
288  // well rates, it can cause problem for THP calculation
289  // TODO: looking for better alternative to avoid wrong-signed well rates
290  bool openCrossFlowAvoidSingularity(const Simulator& ebos_simulator) const;
291 
292  // for a well, when all drawdown are in the wrong direction, then this well will not
293  // be able to produce/inject .
294  bool allDrawDownWrongDirection(const Simulator& ebos_simulator) const;
295 
296 
297 
298  std::optional<double> computeBhpAtThpLimitProd(
299  const WellState& well_state,
300  const Simulator& ebos_simulator,
301  const SummaryState& summary_state,
302  DeferredLogger& deferred_logger) const;
303 
304  std::optional<double> computeBhpAtThpLimitInj(const Simulator& ebos_simulator,
305  const SummaryState& summary_state,
306  DeferredLogger& deferred_logger) const;
307 
308  double maxPerfPress(const Simulator& ebos_simulator) const;
309 
310  // check whether the well is operable under BHP limit with current reservoir condition
311  virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
312 
313  // check whether the well is operable under THP limit with current reservoir condition
314  virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
315 
316  // updating the inflow based on the current reservoir condition
317  virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const override;
318  };
319 
320 }
321 
322 #include "MultisegmentWell_impl.hpp"
323 
324 #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: 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:1909
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:72
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:27
Solver parameters for the BlackoilModel.
Definition: BlackoilModelParametersEbos.hpp:327
Definition: BlackoilPhases.hpp:46