opm-simulators
Loading...
Searching...
No Matches
WellInterface.hpp
1/*
2 Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
3 Copyright 2017 Statoil ASA.
4 Copyright 2017 IRIS
5 Copyright 2019 Norce
6
7 This file is part of the Open Porous Media project (OPM).
8
9 OPM is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 OPM is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with OPM. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#ifndef OPM_WELLINTERFACE_HEADER_INCLUDED
24#define OPM_WELLINTERFACE_HEADER_INCLUDED
25
26// NOTE: GasLiftSingleWell.hpp includes StandardWell.hpp which includes ourself
27// (WellInterface.hpp), so we need to forward declare GasLiftSingleWell
28// for it to be defined in this file. Similar for BlackoilWellModel
29namespace Opm {
30 template<typename TypeTag> class GasLiftSingleWell;
31 template<typename TypeTag> class BlackoilWellModel;
32}
33
34#include <opm/common/OpmLog/OpmLog.hpp>
35#include <opm/common/ErrorMacros.hpp>
36#include <opm/common/Exceptions.hpp>
37
38#include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>
39
40#include <opm/material/fluidstates/BlackOilFluidState.hpp>
41
43
45
46#include <opm/simulators/wells/BlackoilWellModel.hpp>
47#include <opm/simulators/wells/GasLiftGroupInfo.hpp>
48#include <opm/simulators/wells/GasLiftSingleWell.hpp>
49#include <opm/simulators/wells/GasLiftSingleWellGeneric.hpp>
50#include <opm/simulators/wells/PerforationData.hpp>
51#include <opm/simulators/wells/WellInterfaceIndices.hpp>
52#include <opm/simulators/wells/WellProdIndexCalculator.hpp>
53#include <opm/simulators/wells/WellState.hpp>
54
55#include <opm/simulators/timestepping/ConvergenceReport.hpp>
56
57#include <opm/simulators/utils/DeferredLogger.hpp>
58
59#include <dune/common/fmatrix.hh>
60#include <dune/istl/bcrsmatrix.hh>
61#include <dune/istl/matrixmatrix.hh>
62
63#include <opm/material/densead/Evaluation.hpp>
64
65#include <vector>
66
67namespace Opm
68{
69
70class WellInjectionProperties;
71class WellProductionProperties;
72template<typename Scalar, typename IndexTraits> class GroupStateHelper;
73
74template<typename TypeTag>
75class WellInterface : public WellInterfaceIndices<GetPropType<TypeTag, Properties::FluidSystem>,
76 GetPropType<TypeTag, Properties::Indices>>
77{
78 using Base = WellInterfaceIndices<GetPropType<TypeTag, Properties::FluidSystem>,
80public:
85 using IndexTraits = typename FluidSystem::IndexTraitsType;
91 using GasLiftSingleWell = ::Opm::GasLiftSingleWell<TypeTag>;
92 using GLiftEclWells = typename GasLiftGroupInfo<Scalar, IndexTraits>::GLiftEclWells;
93
94 using VectorBlockType = Dune::FieldVector<Scalar, Indices::numEq>;
95 using MatrixBlockType = Dune::FieldMatrix<Scalar, Indices::numEq, Indices::numEq>;
96 using Eval = typename Base::Eval;
97 using BVector = Dune::BlockVector<VectorBlockType>;
98 using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<Scalar, 1, 1>>;
99
100 using WellStateType = WellState<Scalar, IndexTraits>;
101 using SingleWellStateType = SingleWellState<Scalar, IndexTraits>;
102 using GroupStateHelperType = GroupStateHelper<Scalar, IndexTraits>;
103
104 using RateConverterType =
105 typename WellInterfaceFluidSystem<FluidSystem>::RateConverterType;
106
107 using WellInterfaceFluidSystem<FluidSystem>::Gas;
108 using WellInterfaceFluidSystem<FluidSystem>::Oil;
109 using WellInterfaceFluidSystem<FluidSystem>::Water;
110
111 using ModelParameters = typename Base::ModelParameters;
112
113 static constexpr bool has_solvent = getPropValue<TypeTag, Properties::EnableSolvent>();
114 static constexpr bool has_zFraction = getPropValue<TypeTag, Properties::EnableExtbo>();
115 static constexpr bool has_polymer = getPropValue<TypeTag, Properties::EnablePolymer>();
116 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
117 static constexpr bool has_energy = energyModuleType == EnergyModules::FullyImplicitThermal;
118
119 // flag for polymer molecular weight related
120 static constexpr bool has_polymermw = getPropValue<TypeTag, Properties::EnablePolymerMW>();
121 static constexpr bool has_foam = getPropValue<TypeTag, Properties::EnableFoam>();
122 static constexpr bool has_brine = getPropValue<TypeTag, Properties::EnableBrine>();
123 static constexpr bool has_watVapor = getPropValue<TypeTag, Properties::EnableVapwat>();
124 static constexpr bool has_disgas_in_water = getPropValue<TypeTag, Properties::EnableDisgasInWater>();
125 static constexpr bool has_saltPrecip = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
126 static constexpr bool has_bioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
127 static constexpr bool has_micp = Indices::enableMICP;
128
129 // For the conversion between the surface volume rate and reservoir voidage rate
130 using FluidState = BlackOilFluidState<Eval,
131 FluidSystem,
132 energyModuleType != EnergyModules::NoTemperature,
133 energyModuleType == EnergyModules::FullyImplicitThermal,
134 Indices::compositionSwitchIdx >= 0,
135 has_watVapor,
136 has_brine,
137 has_saltPrecip,
138 has_disgas_in_water,
139 has_solvent,
140 Indices::numPhases >;
142 WellInterface(const Well& well,
143 const ParallelWellInfo<Scalar>& pw_info,
144 const int time_step,
145 const ModelParameters& param,
146 const RateConverterType& rate_converter,
147 const int pvtRegionIdx,
148 const int num_conservation_quantities,
149 const int num_phases,
150 const int index_of_well,
151 const std::vector<PerforationData<Scalar>>& perf_data);
152
154 virtual ~WellInterface() = default;
155
156 virtual void init(const std::vector<Scalar>& depth_arg,
157 const Scalar gravity_arg,
158 const std::vector<Scalar>& B_avg,
159 const bool changed_to_open_this_step);
160
161 virtual ConvergenceReport getWellConvergence(const GroupStateHelperType& groupStateHelper,
162 const std::vector<Scalar>& B_avg,
163 const bool relax_tolerance) const = 0;
164
165 virtual void solveEqAndUpdateWellState(const Simulator& simulator,
166 const GroupStateHelperType& groupStateHelper,
167 WellStateType& well_state) = 0;
168
169 void assembleWellEq(const Simulator& simulator,
170 const double dt,
171 const GroupStateHelperType& groupStateHelper,
172 WellStateType& well_state);
173
174 void assembleWellEqWithoutIteration(const Simulator& simulator,
175 const GroupStateHelperType& groupStateHelper,
176 const double dt,
177 WellStateType& well_state,
178 const bool solving_with_zero_rate);
179
180 // TODO: better name or further refactoring the function to make it more clear
181 void prepareWellBeforeAssembling(const Simulator& simulator,
182 const double dt,
183 const GroupStateHelperType& groupStateHelper,
184 WellStateType& well_state);
185
186 virtual void computeWellRatesWithBhp(const Simulator& ebosSimulator,
187 const Scalar& bhp,
188 std::vector<Scalar>& well_flux,
189 DeferredLogger& deferred_logger) const = 0;
190
191 virtual std::optional<Scalar>
192 computeBhpAtThpLimitProdWithAlq(const Simulator& ebos_simulator,
193 const GroupStateHelperType& groupStateHelper,
194 const SummaryState& summary_state,
195 const Scalar alq_value,
196 bool iterate_if_no_solution) const = 0;
197
198 std::optional<Scalar>
199 computeBhpAtThpLimitProdWithAlqUsingIPR(const Simulator& simulator,
200 const WellStateType& well_state,
201 Scalar bhp,
202 const SummaryState& summary_state,
203 const Scalar alq_value);
206 virtual void recoverWellSolutionAndUpdateWellState(const Simulator& simulator,
207 const BVector& x,
208 const GroupStateHelperType& groupStateHelper,
209 WellStateType& well_state) = 0;
210
212 virtual void apply(const BVector& x, BVector& Ax) const = 0;
213
215 virtual void apply(BVector& r) const = 0;
216
217 // TODO: before we decide to put more information under mutable, this function is not const
218 virtual void computeWellPotentials(const Simulator& simulator,
219 const WellStateType& well_state,
220 const GroupStateHelperType& groupStateHelper,
221 std::vector<Scalar>& well_potentials) = 0;
222
223 virtual void updateWellStateWithTarget(const Simulator& simulator,
224 const GroupStateHelperType& groupStateHelper,
225 WellStateType& well_state) const;
226
227 virtual void scaleSegmentRatesAndPressure(WellStateType& well_state) const;
228
229 virtual void computeWellRatesWithBhpIterations(const Simulator& simulator,
230 const Scalar& bhp,
231 const GroupStateHelperType& groupStateHelper,
232 std::vector<Scalar>& well_flux) const = 0;
233
234 bool wellUnderZeroRateTarget(const GroupStateHelperType& groupStateHelper) const;
235
236 bool stoppedOrZeroRateTarget(const GroupStateHelperType& groupStateHelper) const;
237
238 bool updateWellStateWithTHPTargetProd(const Simulator& simulator,
239 WellStateType& well_state,
240 const GroupStateHelperType& groupStateHelper) const;
241
242 bool wellUnderZeroGroupRateTarget(const GroupStateHelperType& groupStateHelper,
243 const std::optional<bool> group_control = std::nullopt) const;
244
245 enum class IndividualOrGroup { Individual, Group, Both };
246 bool updateWellControl(const Simulator& simulator,
247 const IndividualOrGroup iog,
248 const GroupStateHelperType& groupStateHelper,
249 WellStateType& well_state) /* const */;
250
251 bool updateWellControlAndStatusLocalIteration(const Simulator& simulator,
252 const GroupStateHelperType& groupStateHelper,
253 const Well::InjectionControls& inj_controls,
254 const Well::ProductionControls& prod_controls,
255 const Scalar WQTotal,
256 WellStateType& well_state,
257 const bool fixed_control,
258 const bool fixed_status,
259 const bool solving_with_zero_rate);
260
261 virtual void updatePrimaryVariables(const GroupStateHelperType& groupStateHelper) = 0;
262
263 virtual void calculateExplicitQuantities(const Simulator& simulator,
264 const GroupStateHelperType& groupStateHelper) = 0; // should be const?
265
266 virtual void updateProductivityIndex(const Simulator& simulator,
267 const WellProdIndexCalculator<Scalar>& wellPICalc,
268 WellStateType& well_state,
269 DeferredLogger& deferred_logger) const = 0;
270
271 // Add well contributions to matrix
272 virtual void addWellContributions(SparseMatrixAdapter&) const = 0;
273
274 virtual void addWellPressureEquations(PressureMatrix& mat,
275 const BVector& x,
276 const int pressureVarIndex,
277 const bool use_well_weights,
278 const WellStateType& well_state) const = 0;
279
280 void addCellRates(std::map<int, RateVector>& cellRates_) const;
281
282 Scalar volumetricSurfaceRateForConnection(int cellIdx, int phaseIdx) const;
283
284 // TODO: theoretically, it should be a const function
285 // Simulator is not const is because that assembleWellEq is non-const Simulator
286 void wellTesting(const Simulator& simulator,
287 const double simulation_time,
288 const GroupStateHelperType& groupStateHelper,
289 WellStateType& well_state,
290 WellTestState& welltest_state,
291 GLiftEclWells& ecl_well_map,
292 std::map<std::string, double>& open_times);
293
294 void checkWellOperability(const Simulator& simulator,
295 const WellStateType& well_state,
296 const GroupStateHelperType& groupStateHelper);
297
298 void gliftBeginTimeStepWellTestUpdateALQ(const Simulator& simulator,
299 WellStateType& well_state,
300 const GroupState<Scalar>& group_state,
301 GLiftEclWells& ecl_well_map,
302 DeferredLogger& deferred_logger);
303
304 // check whether the well is operable under the current reservoir condition
305 // mostly related to BHP limit and THP limit
306 void updateWellOperability(const Simulator& simulator,
307 const WellStateType& well_state,
308 const GroupStateHelperType& groupStateHelper);
309
310 bool updateWellOperabilityFromWellEq(const Simulator& simulator,
311 const GroupStateHelperType& groupStateHelper);
312
313 // update perforation water throughput based on solved water rate
314 virtual void updateWaterThroughput(const double dt,
315 WellStateType& well_state) const = 0;
316
319 virtual std::vector<Scalar>
320 computeCurrentWellRates(const Simulator& simulator,
321 DeferredLogger& deferred_logger) const = 0;
322
326 void initializeProducerWellState(const Simulator& simulator,
327 WellStateType& well_state,
328 DeferredLogger& deferred_logger) const;
329
330 void solveWellEquation(const Simulator& simulator,
331 const GroupStateHelperType& groupStateHelper,
332 WellStateType& well_state);
333
334 const std::vector<RateVector>& connectionRates() const
335 {
336 return connectionRates_;
337 }
338
339 void updateConnectionDFactor(const Simulator& simulator,
340 SingleWellStateType& ws) const;
341
342 void updateConnectionTransmissibilityFactor(const Simulator& simulator,
343 SingleWellStateType& ws) const;
344
345 virtual bool iterateWellEqWithSwitching(const Simulator& simulator,
346 const double dt,
347 const WellInjectionControls& inj_controls,
348 const WellProductionControls& prod_controls,
349 const GroupStateHelperType& groupStateHelper,
350 WellStateType& well_state,
351 const bool fixed_control,
352 const bool fixed_status,
353 const bool solving_with_zero_rate) = 0;
354
355 virtual Scalar maxPerfPress(const Simulator& simulator) const = 0;
356
357 virtual void updateIPRImplicit(const Simulator& simulator,
358 const GroupStateHelperType& groupStateHelper,
359 WellStateType& well_state) = 0;
360
361protected:
362 // simulation parameters
363 std::vector<RateVector> connectionRates_;
364 std::vector<Scalar> B_avg_;
365 bool changed_to_stopped_this_step_ = false;
366 bool thp_update_iterations = false;
367 int number_of_well_reopenings_{0};
368
369 Scalar wpolymer() const;
370 Scalar wfoam() const;
371 Scalar wsalt() const;
372 Scalar wmicrobes() const;
373 Scalar woxygen() const;
374 Scalar wurea() const;
375
376 virtual Scalar getRefDensity() const = 0;
377
378 std::vector<Scalar>
379 initialWellRateFractions(const Simulator& ebosSimulator,
380 const WellStateType& well_state) const;
381
382 // check whether the well is operable under BHP limit with current reservoir condition
383 virtual void checkOperabilityUnderBHPLimit(const WellStateType& well_state,
384 const Simulator& simulator,
385 DeferredLogger& deferred_logger) = 0;
386
387 // check whether the well is operable under THP limit with current reservoir condition
388 virtual void checkOperabilityUnderTHPLimit(const Simulator& simulator,
389 const WellStateType& well_state,
390 const GroupStateHelperType& groupStateHelper) = 0;
391
392 virtual void updateIPR(const Simulator& simulator,
393 DeferredLogger& deferred_logger) const = 0;
394
395 virtual void assembleWellEqWithoutIteration(const Simulator& simulator,
396 const GroupStateHelperType& groupStateHelper,
397 const double dt,
398 const WellInjectionControls& inj_controls,
399 const WellProductionControls& prod_controls,
400 WellStateType& well_state,
401 const bool solving_with_zero_rate) = 0;
402
403 // iterate well equations with the specified control until converged
404 virtual bool iterateWellEqWithControl(const Simulator& simulator,
405 const double dt,
406 const WellInjectionControls& inj_controls,
407 const WellProductionControls& prod_controls,
408 const GroupStateHelperType& groupStateHelper,
409 WellStateType& well_state) = 0;
410
411 bool iterateWellEquations(const Simulator& simulator,
412 const double dt,
413 const GroupStateHelperType& groupStateHelper,
414 WellStateType& well_state);
415
416 bool solveWellWithOperabilityCheck(const Simulator& simulator,
417 const double dt,
418 const Well::InjectionControls& inj_controls,
419 const Well::ProductionControls& prod_controls,
420 const GroupStateHelperType& groupStateHelper,
421 WellStateType& well_state);
422
423 std::optional<Scalar>
424 estimateOperableBhp(const Simulator& ebos_simulator,
425 const double dt,
426 const GroupStateHelperType& groupStateHelper,
427 const SummaryState& summary_state,
428 WellStateType& well_state);
429
430 bool solveWellWithBhp(const Simulator& simulator,
431 const double dt,
432 const Scalar bhp,
433 const GroupStateHelperType& groupStateHelper,
434 WellStateType& well_state);
435
436 bool solveWellWithZeroRate(const Simulator& simulator,
437 const double dt,
438 const GroupStateHelperType& groupStateHelper,
439 WellStateType& well_state);
440
441 bool solveWellForTesting(const Simulator& simulator,
442 const GroupStateHelperType& groupStateHelper,
443 WellStateType& well_state);
444
445
446 template<class GasLiftSingleWell>
447 std::unique_ptr<GasLiftSingleWell> initializeGliftWellTest_(const Simulator& simulator,
448 WellStateType& well_state,
449 const GroupState<Scalar>& group_state,
450 GLiftEclWells& ecl_well_map,
451 DeferredLogger& deferred_logger);
452
453 Eval getPerfCellPressure(const FluidState& fs) const;
454
455 // get the transmissibility multiplier for specific perforation
456 template<class Value, class Callback>
457 void getTransMult(Value& trans_mult,
458 const Simulator& simulator,
459 const int cell_idx,
460 Callback& extendEval) const;
461
462 // get the well transmissibility for specific perforation
463 template<class Value>
464 void getTw(std::vector<Value>& wi,
465 const int perf,
466 const IntensiveQuantities& intQuants,
467 const Value& trans_mult,
468 const SingleWellStateType& ws) const;
469
470 // get the mobility for specific perforation
471 template<class Value, class Callback>
472 void getMobility(const Simulator& simulator,
473 const int local_perf_index,
474 std::vector<Value>& mob,
475 Callback& extendEval,
476 [[maybe_unused]] DeferredLogger& deferred_logger) const;
477
478 void computeConnLevelProdInd(const FluidState& fs,
479 const std::function<Scalar(const Scalar)>& connPICalc,
480 const std::vector<Scalar>& mobility,
481 Scalar* connPI) const;
482
483 void computeConnLevelInjInd(const FluidState& fs,
484 const Phase preferred_phase,
485 const std::function<Scalar(const Scalar)>& connIICalc,
486 const std::vector<Scalar>& mobility,
487 Scalar* connII,
488 DeferredLogger& deferred_logger) const;
489
490 Scalar computeConnectionDFactor(const int perf,
491 const IntensiveQuantities& intQuants,
492 const SingleWellStateType& ws) const;
493};
494
495} // namespace Opm
496
497#include "WellInterface_impl.hpp"
498
499#endif // OPM_WELLINTERFACE_HEADER_INCLUDED
Declares the properties required by the black oil model.
Class for handling the blackoil well model.
Definition BlackoilWellModel.hpp:98
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 GasLiftSingleWell.hpp:39
Definition GroupStateHelper.hpp:57
Definition GroupState.hpp:41
Class encapsulating some information about parallel wells.
Definition ParallelWellInfo.hpp:198
Manages the initializing and running of time dependent problems.
Definition simulator.hh:84
Definition SingleWellState.hpp:43
Definition WellInterfaceFluidSystem.hpp:50
virtual std::vector< Scalar > computeCurrentWellRates(const Simulator &simulator, DeferredLogger &deferred_logger) const =0
Compute well rates based on current reservoir conditions and well variables.
virtual void recoverWellSolutionAndUpdateWellState(const Simulator &simulator, const BVector &x, const GroupStateHelperType &groupStateHelper, WellStateType &well_state)=0
using the solution x to recover the solution xw for wells and applying xw to update Well State
virtual void apply(const BVector &x, BVector &Ax) const =0
Ax = Ax - C D^-1 B x.
void initializeProducerWellState(const Simulator &simulator, WellStateType &well_state, DeferredLogger &deferred_logger) const
Modify the well_state's rates if there is only one nonzero rate.
Definition WellInterface_impl.hpp:1797
virtual void apply(BVector &r) const =0
r = r - C D^-1 Rw
virtual ~WellInterface()=default
Virtual destructor.
WellInterface(const Well &well, const ParallelWellInfo< Scalar > &pw_info, const int time_step, const ModelParameters &param, const RateConverterType &rate_converter, const int pvtRegionIdx, const int num_conservation_quantities, const int num_phases, const int index_of_well, const std::vector< PerforationData< Scalar > > &perf_data)
Constructor.
Definition WellInterface_impl.hpp:59
Collect per-connection static information to enable calculating connection-level or well-level produc...
Definition WellProdIndexCalculator.hpp:37
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition WellState.hpp:66
Declares the properties required by the black oil model.
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilbioeffectsmodules.hh:45
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
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:240
Static data associated with a well perforation.
Definition PerforationData.hpp:30