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
28namespace Opm
29{
30 class DeferredLogger;
31
32 template<typename TypeTag>
33 class MultisegmentWell : public WellInterface<TypeTag>
34 , public MultisegmentWellEval<GetPropType<TypeTag, Properties::FluidSystem>,
35 GetPropType<TypeTag, Properties::Indices>,
36 GetPropType<TypeTag, Properties::Scalar>>
37 {
38 public:
41 GetPropType<TypeTag, Properties::Indices>,
42 GetPropType<TypeTag, Properties::Scalar>>;
43
44 using typename Base::Simulator;
45 using typename Base::IntensiveQuantities;
46 using typename Base::FluidSystem;
47 using typename Base::ModelParameters;
48 using typename Base::MaterialLaw;
49 using typename Base::Indices;
50 using typename Base::RateConverterType;
51 using typename Base::SparseMatrixAdapter;
52 using typename Base::FluidState;
53
54 using Base::has_solvent;
55 using Base::has_polymer;
56 using Base::Water;
57 using Base::Oil;
58 using Base::Gas;
59
60 using typename Base::Scalar;
61
63 using typename Base::BVector;
64 using typename Base::Eval;
65
66 using typename MSWEval::Equations;
67 using typename MSWEval::EvalWell;
68 using typename MSWEval::BVectorWell;
69 using MSWEval::SPres;
70 using typename Base::PressureMatrix;
71
72 MultisegmentWell(const Well& well,
73 const ParallelWellInfo& pw_info,
74 const int time_step,
75 const ModelParameters& param,
76 const RateConverterType& rate_converter,
77 const int pvtRegionIdx,
78 const int num_components,
79 const int num_phases,
80 const int index_of_well,
81 const std::vector<PerforationData>& perf_data);
82
83 virtual void init(const PhaseUsage* phase_usage_arg,
84 const std::vector<double>& depth_arg,
85 const double gravity_arg,
86 const int num_cells,
87 const std::vector< Scalar >& B_avg,
88 const bool changed_to_open_this_step) override;
89
90 void initPrimaryVariablesEvaluation() override;
91
93 virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
94 const GroupState& group_state,
95 WellState& well_state,
96 DeferredLogger& deferred_logger) const override;
97
99 virtual ConvergenceReport getWellConvergence(const WellState& well_state,
100 const std::vector<double>& B_avg,
101 DeferredLogger& deferred_logger,
102 const bool relax_tolerance = false) const override;
103
105 virtual void apply(const BVector& x, BVector& Ax) const override;
107 virtual void apply(BVector& r) const override;
108
111 void recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
112 const BVector& x,
113 WellState& well_state,
114 DeferredLogger& deferred_logger) override;
115
117 virtual void computeWellPotentials(const Simulator& ebosSimulator,
118 const WellState& well_state,
119 std::vector<double>& well_potentials,
120 DeferredLogger& deferred_logger) override;
121
122 void updatePrimaryVariables(const SummaryState& summary_state,
123 const WellState& well_state,
124 DeferredLogger& deferred_logger) override;
125
126 virtual void calculateExplicitQuantities(const Simulator& ebosSimulator,
127 const WellState& well_state,
128 DeferredLogger& deferred_logger) override; // should be const?
129
130 virtual void updateProductivityIndex(const Simulator& ebosSimulator,
131 const WellProdIndexCalculator& wellPICalc,
132 WellState& well_state,
133 DeferredLogger& deferred_logger) const override;
134
135 void addWellContributions(SparseMatrixAdapter& jacobian) const override;
136
137 void addWellPressureEquations(PressureMatrix& mat,
138 const BVector& x,
139 const int pressureVarIndex,
140 const bool use_well_weights,
141 const WellState& well_state) const override;
142
143 virtual std::vector<double> computeCurrentWellRates(const Simulator& ebosSimulator,
144 DeferredLogger& deferred_logger) const override;
145
146 void computeConnLevelProdInd(const FluidState& fs,
147 const std::function<double(const double)>& connPICalc,
148 const std::vector<Scalar>& mobility,
149 double* connPI) const;
150
151 void computeConnLevelInjInd(const FluidState& fs,
152 const Phase preferred_phase,
153 const std::function<double(const double)>& connIICalc,
154 const std::vector<Scalar>& mobility,
155 double* connII,
156 DeferredLogger& deferred_logger) const;
157
158 std::optional<double>
159 computeBhpAtThpLimitProdWithAlq(const Simulator& ebos_simulator,
160 const SummaryState& summary_state,
161 const double alq_value,
162 DeferredLogger& deferred_logger) const override;
163
164 protected:
165
166 // regularize msw equation
167 bool regularize_;
168
169 // the intial amount of fluids in each segment under surface condition
170 std::vector<std::vector<double> > segment_fluid_initial_;
171
172 mutable int debug_cost_counter_ = 0;
173
174 // updating the well_state based on well solution dwells
175 void updateWellState(const SummaryState& summary_state,
176 const BVectorWell& dwells,
177 WellState& well_state,
178 DeferredLogger& deferred_logger,
179 const double relaxation_factor = 1.0);
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 bool updateWellStateWithTHPTargetProd(const Simulator& ebos_simulator,
264 WellState& well_state,
265 DeferredLogger& deferred_logger) const override;
266
267 virtual double getRefDensity() const override;
268
269 virtual bool iterateWellEqWithControl(const Simulator& ebosSimulator,
270 const double dt,
271 const Well::InjectionControls& inj_controls,
272 const Well::ProductionControls& prod_controls,
273 WellState& well_state,
274 const GroupState& group_state,
275 DeferredLogger& deferred_logger) override;
276
277 virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
278 const double dt,
279 const Well::InjectionControls& inj_controls,
280 const Well::ProductionControls& prod_controls,
281 WellState& well_state,
282 const GroupState& group_state,
283 DeferredLogger& deferred_logger) override;
284
285 virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
286
287 EvalWell getSegmentSurfaceVolume(const Simulator& ebos_simulator, const int seg_idx) const;
288
289 // turn on crossflow to avoid singular well equations
290 // when the well is banned from cross-flow and the BHP is not properly initialized,
291 // we turn on crossflow to avoid singular well equations. It can result in wrong-signed
292 // well rates, it can cause problem for THP calculation
293 // TODO: looking for better alternative to avoid wrong-signed well rates
294 bool openCrossFlowAvoidSingularity(const Simulator& ebos_simulator) const;
295
296 // for a well, when all drawdown are in the wrong direction, then this well will not
297 // be able to produce/inject .
298 bool allDrawDownWrongDirection(const Simulator& ebos_simulator) const;
299
300
301
302 std::optional<double> computeBhpAtThpLimitProd(
303 const WellState& well_state,
304 const Simulator& ebos_simulator,
305 const SummaryState& summary_state,
306 DeferredLogger& deferred_logger) const;
307
308 std::optional<double> computeBhpAtThpLimitInj(const Simulator& ebos_simulator,
309 const SummaryState& summary_state,
310 DeferredLogger& deferred_logger) const;
311
312 double maxPerfPress(const Simulator& ebos_simulator) const;
313
314 // check whether the well is operable under BHP limit with current reservoir condition
315 virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
316
317 // check whether the well is operable under THP limit with current reservoir condition
318 virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
319
320 // updating the inflow based on the current reservoir condition
321 virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const override;
322 };
323
324}
325
326#include "MultisegmentWell_impl.hpp"
327
328#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:38
Definition: DeferredLogger.hpp:57
Definition: GroupState.hpp:34
Definition: MultisegmentWellEval.hpp:49
Definition: MultisegmentWell.hpp:37
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:167
virtual void apply(const BVector &x, BVector &Ax) const override
Ax = Ax - C D^-1 B x.
Definition: MultisegmentWell_impl.hpp:211
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:1915
void recoverWellSolutionAndUpdateWellState(const SummaryState &summary_state, const BVector &x, WellState &well_state, DeferredLogger &deferred_logger) override
using the solution x to recover the solution xw for wells and applying xw to update Well State
Definition: MultisegmentWell_impl.hpp:246
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:267
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:188
Class encapsulating some information about parallel wells.
Definition: ParallelWellInfo.hpp:184
Definition: WellInterface.hpp:74
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:60
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