opm-simulators
BlackoilWellModel.hpp
1 /*
2  Copyright 2016 SINTEF ICT, Applied Mathematics.
3  Copyright 2016 - 2017 Statoil ASA.
4  Copyright 2017 Dr. Blatt - HPC-Simulation-Software & Services
5  Copyright 2016 - 2018 IRIS AS
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_BLACKOILWELLMODEL_HEADER_INCLUDED
24 #define OPM_BLACKOILWELLMODEL_HEADER_INCLUDED
25 
26 #include <dune/common/fmatrix.hh>
27 
28 #include <dune/istl/bcrsmatrix.hh>
29 #include <dune/istl/matrixmatrix.hh>
30 
31 #include <opm/common/OpmLog/OpmLog.hpp>
32 #include <opm/grid/utility/SparseTable.hpp>
33 
34 #include <opm/input/eclipse/Schedule/Group/Group.hpp>
35 #include <opm/input/eclipse/Schedule/Group/GuideRate.hpp>
36 #include <opm/input/eclipse/Schedule/Schedule.hpp>
37 #include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>
38 
39 #include <opm/material/densead/Math.hpp>
40 
41 #include <opm/simulators/flow/countGlobalCells.hpp>
43 
44 #include <opm/simulators/linalg/matrixblock.hh>
45 #include <opm/simulators/linalg/system/SystemTypes.hpp>
46 
47 #include <opm/simulators/timestepping/SimulatorReport.hpp>
48 #include <opm/simulators/timestepping/gatherConvergenceReport.hpp>
49 
50 #include <opm/simulators/utils/DeferredLogger.hpp>
51 
52 #include <opm/simulators/wells/BlackoilWellModelGasLift.hpp>
53 #include <opm/simulators/wells/BlackoilWellModelGeneric.hpp>
54 #include <opm/simulators/wells/BlackoilWellModelGuideRates.hpp>
55 #include <opm/simulators/wells/BlackoilWellModelNetwork.hpp>
56 #include <opm/simulators/wells/BlackoilWellModelRescoup.hpp>
57 #include <opm/simulators/wells/GasLiftGroupInfo.hpp>
58 #include <opm/simulators/wells/GasLiftSingleWell.hpp>
59 #include <opm/simulators/wells/GasLiftSingleWellGeneric.hpp>
60 #include <opm/simulators/wells/GasLiftWellState.hpp>
61 #include <opm/simulators/wells/GroupStateHelper.hpp>
62 #include <opm/simulators/wells/GuideRateHandler.hpp>
63 #include <opm/simulators/wells/MultisegmentWell.hpp>
64 #include <opm/simulators/wells/ParallelWBPCalculation.hpp>
65 #include <opm/simulators/wells/ParallelWellInfo.hpp>
66 #include <opm/simulators/wells/PerforationData.hpp>
69 #include <opm/simulators/wells/StandardWell.hpp>
70 #include <opm/simulators/wells/VFPInjProperties.hpp>
71 #include <opm/simulators/wells/VFPProdProperties.hpp>
72 #include <opm/simulators/wells/WGState.hpp>
73 #include <opm/simulators/wells/WellConnectionAuxiliaryModule.hpp>
74 #include <opm/simulators/wells/WellInterface.hpp>
75 #include <opm/simulators/wells/WellProdIndexCalculator.hpp>
76 #include <opm/simulators/wells/WellState.hpp>
77 #include <opm/simulators/wells/rescoup/RescoupProxy.hpp>
78 
79 #include <cstddef>
80 #include <map>
81 #include <memory>
82 #include <optional>
83 #include <string>
84 #include <tuple>
85 #include <vector>
86 
87 namespace Opm {
88 
89 template<class Scalar> class BlackoilWellModelNldd;
90 template<class T, template <typename, typename...> class Storage> class SparseTable;
91 
92 #if COMPILE_GPU_BRIDGE
93 template<class Scalar> class WellContributions;
94 #endif
95 
97  template<typename TypeTag>
98  class BlackoilWellModel : public WellConnectionAuxiliaryModule<TypeTag, BlackoilWellModel<TypeTag>>
99  , public BlackoilWellModelGeneric<GetPropType<TypeTag, Properties::Scalar>,
100  typename GetPropType<TypeTag, Properties::FluidSystem>::IndexTraitsType>
101  {
102  public:
103  // --------- Types ---------
113  using SparseMatrixAdapter = GetPropType<TypeTag, Properties::SparseMatrixAdapter>;
114  using ModelParameters = BlackoilModelParameters<Scalar>;
115 
117  using IndexTraits = typename FluidSystem::IndexTraitsType;
118  using GroupStateHelperType = GroupStateHelper<Scalar, IndexTraits>;
119 
120  constexpr static std::size_t pressureVarIndex = GetPropType<TypeTag, Properties::Indices>::pressureSwitchIdx;
121 
122  static const int numEq = Indices::numEq;
123  static const int solventSaturationIdx = Indices::solventSaturationIdx;
124  static constexpr bool has_solvent_ = getPropValue<TypeTag, Properties::EnableSolvent>();
125  static constexpr bool has_polymer_ = getPropValue<TypeTag, Properties::EnablePolymer>();
126  static constexpr EnergyModules energyModuleType_ = getPropValue<TypeTag, Properties::EnergyModuleType>();
127  static constexpr bool has_energy_ = (energyModuleType_ == EnergyModules::FullyImplicitThermal);
128  static constexpr bool has_micp_ = Indices::enableMICP;
129  static constexpr bool has_geochem_ = getPropValue<TypeTag, Properties::EnableGeochemistry>();
130  static constexpr bool has_bioeffects_ = getPropValue<TypeTag, Properties::EnableBioeffects>();
131 
132  // TODO: where we should put these types, WellInterface or Well Model?
133  // or there is some other strategy, like TypeTag
134  using VectorBlockType = Dune::FieldVector<Scalar, numEq>;
135  using BVector = Dune::BlockVector<VectorBlockType>;
136 
137  using PolymerModule = BlackOilPolymerModule<TypeTag, has_polymer_>;
138  using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, has_bioeffects_>;
139 
140  // For the conversion between the surface volume rate and reservoir voidage rate
141  using RateConverterType = RateConverter::
142  SurfaceToReservoirVoidage<FluidSystem, std::vector<int> >;
143 
144  // For computing average pressured used by gpmaint
145  using AverageRegionalPressureType = RegionAverageCalculator::
146  AverageRegionalPressure<FluidSystem, std::vector<int> >;
147 
148  BlackoilWellModel(Simulator& simulator, const NewtonIterationContext& iter_ctx);
149 
150  void init();
151  void initWellContainer(const int reportStepIdx) override;
152 
153  void beginEpisode()
154  {
155  OPM_TIMEBLOCK(beginEpsiode);
156  beginReportStep(simulator_.episodeIndex());
157  }
158 
159  void beginTimeStep();
160 
161  void beginIteration()
162  {
163  OPM_TIMEBLOCK(beginIteration);
164  assemble(simulator_.timeStepSize());
165  }
166 
167  void endIteration()
168  { }
169 
170  void endTimeStep()
171  {
172  OPM_TIMEBLOCK(endTimeStep);
173  timeStepSucceeded(simulator_.time(), simulator_.timeStepSize());
174  }
175 
176  void endEpisode()
177  {
178  endReportStep();
179  }
180 
181  void computeTotalRatesForDof(RateVector& rate,
182  unsigned globalIdx) const;
183 
184  template <class Context>
185  void computeTotalRatesForDof(RateVector& rate,
186  const Context& context,
187  unsigned spaceIdx,
188  unsigned timeIdx) const;
189 
190 
191  using WellInterfacePtr = std::unique_ptr<WellInterface<TypeTag>>;
192 
193  using BlackoilWellModelGeneric<Scalar, IndexTraits>::initFromRestartFile;
194  void initFromRestartFile(const RestartValue& restartValues)
195  {
196  initFromRestartFile(restartValues,
197  this->simulator_.vanguard().transferWTestState(),
198  grid().size(0),
199  this->simulator_.vanguard().enableDistributedWells());
200  }
201 
202  using BlackoilWellModelGeneric<Scalar, IndexTraits>::prepareDeserialize;
203  void prepareDeserialize(const int report_step)
204  {
205  prepareDeserialize(report_step, grid().size(0),
206  this->simulator_.vanguard().enableDistributedWells());
207  }
208 
209  data::Wells wellData() const
210  {
211  auto wsrpt = this->wellState()
212  .report(this->simulator_.vanguard().globalCell().data(),
213  [this](const std::size_t well_index)
214  { return this->wasDynamicallyShutThisTimeStep(well_index); },
215  this->rsConstInfo());
216 
217  BlackoilWellModelGuideRates(*this)
218  .assignWellGuideRates(wsrpt, this->reportStepIndex());
219 
220  this->assignWellTracerRates_(wsrpt);
221 
222  if constexpr (has_geochem_) {
223  this->assignWellSpeciesRates_(wsrpt);
224  }
225 
226  if (const auto& rspec = eclState().runspec();
227  rspec.co2Storage() || rspec.h2Storage())
228  {
229  // The gas reference density (surface condition) is the
230  // same for all PVT regions in CO2STORE/H2STORE runs so,
231  // for simplicity, we use region zero (0) here.
232 
233  this->assignMassGasRate(wsrpt, FluidSystem::referenceDensity(FluidSystem::gasPhaseIdx, 0));
234  }
235 
236  this->assignWellTargets(wsrpt);
237 
238  this->assignDynamicWellStatus(wsrpt);
239 
240  // Assigning (a subset of the) property values in shut
241  // connections should be the last step of wellData().
242  this->assignShutConnections(wsrpt, this->reportStepIndex());
243 
244  return wsrpt;
245  }
246 
247  data::WellBlockAveragePressures wellBlockAveragePressures() const
248  {
249  return this->wbp_.computeWellBlockAveragePressures(this->gravity_);
250  }
251 
252 #if COMPILE_GPU_BRIDGE
253  // accumulate the contributions of all Wells in the WellContributions object
254  void getWellContributions(WellContributions<Scalar>& x) const;
255 #endif
256 
257  // Check if well equations is converged.
258  ConvergenceReport getWellConvergence(const std::vector<Scalar>& B_avg, const bool checkWellGroupControlsAndNetwork = false) const;
259 
260  const SimulatorReportSingle& lastReport() const;
261 
262  void addWellContributions(SparseMatrixAdapter& jacobian) const;
263 
264  // add source from wells to the reservoir matrix
265  void addReservoirSourceTerms(GlobalEqVector& residual,
266  const std::vector<typename SparseMatrixAdapter::MatrixBlock*>& diagMatAddress) const;
267 
268  // called at the beginning of a report step
269  void beginReportStep(const int time_step);
270 
274  void calculateExplicitQuantities() const;
275 
278  void prepareTimeStep(DeferredLogger& deferred_logger);
279 
280  bool
281  updateWellControls(DeferredLogger& deferred_logger);
282 
283  void updateAndCommunicate(const int reportStepIdx);
284 
285  bool updateGroupControls(const Group& group,
286  DeferredLogger& deferred_logger,
287  const int reportStepIdx);
288 
289  static constexpr int numResDofs = Indices::numEq;
290  static constexpr int numWellDofs = numResDofs + 1;//NB will fail for for thermal for now
291  using BMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, numWellDofs, numResDofs>>;
292  using CMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, numResDofs, numWellDofs>>;
293  using DMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, numWellDofs, numWellDofs>>;
294  using WVector = Dune::BlockVector<Dune::FieldVector<Scalar, numWellDofs>>;
295 
296  void addBCDMatrix(std::vector<BMatrix>& b_matrices,
297  std::vector<CMatrix>& c_matrices,
298  std::vector<DMatrix>& d_matrices,
299  Opm::SparseTable<int>& wcells) const;
300 
301  const WellInterface<TypeTag>& getWell(const std::string& well_name) const;
302 
303  using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<Scalar, 1, 1>>;
304 
305  void addWellPressureEquations(PressureMatrix& jacobian,
306  const BVector& weights,
307  const bool use_well_weights) const;
308  void addWellPressureEquationsStruct(PressureMatrix& jacobian) const;
309  void addWellPressureEquationsDomain(PressureMatrix& jacobian,
310  const BVector& weights,
311  const bool use_well_weights,
312  const int domainIndex) const
313  {
314  if (!nldd_) {
315  OPM_THROW(std::logic_error, "Attempt to access NLDD data without a NLDD solver");
316  }
317  return nldd_->addWellPressureEquations(jacobian,
318  weights,
319  use_well_weights,
320  domainIndex);
321  }
322 
324  const std::vector<WellInterfacePtr>& localNonshutWells() const
325  {
326  return well_container_;
327  }
328 
329  const SparseTable<int>& well_local_cells() const
330  {
331  if (!nldd_) {
332  OPM_THROW(std::logic_error, "Attempt to access NLDD data without a NLDD solver");
333  }
334  return nldd_->well_local_cells();
335  }
336 
337  const std::map<std::string, int>& well_domain() const
338  {
339  if (!nldd_) {
340  OPM_THROW(std::logic_error, "Attempt to access NLDD data without a NLDD solver");
341  }
342 
343  return nldd_->well_domain();
344  }
345 
346  auto begin() const { return well_container_.begin(); }
347  auto end() const { return well_container_.end(); }
348  bool empty() const { return well_container_.empty(); }
349 
350  bool addMatrixContributions() const
351  { return param_.matrix_add_well_contributions_; }
352 
353  int numStrictIterations() const
354  { return param_.strict_outer_iter_wells_; }
355 
356  int compressedIndexForInterior(int cartesian_cell_idx) const override
357  {
358  return simulator_.vanguard().compressedIndexForInterior(cartesian_cell_idx);
359  }
360 
361  int compressedIndexForInteriorLGR(const std::string& lgr_tag, const Connection& conn) const override
362  {
363  return simulator_.vanguard().compressedIndexForInteriorLGR(lgr_tag, conn);
364  }
365 
366  // using the solution x to recover the solution xw for wells and applying
367  // xw to update Well State
368  void recoverWellSolutionAndUpdateWellState(const BVector& x);
369 
370  // using the solution x to recover the solution xw for wells and applying
371  // xw to update Well State
372  void recoverWellSolutionAndUpdateWellStateDomain(const BVector& x,
373  const int domainIdx);
374  // Update cellRates_ with contributions from all wells
375  void updateCellRates();
376 
377  // Update cellRates_ with contributions from wells in a specific domain
378  void updateCellRatesForDomain(int domainIndex,
379  const std::map<std::string, int>& well_domain_map);
380 
381  const Grid& grid() const
382  { return simulator_.vanguard().grid(); }
383 
384  const Simulator& simulator() const
385  { return simulator_; }
386  Simulator& simulator()
387  { return simulator_; }
388 
389  BlackoilWellModelNetwork<TypeTag>& network() { return network_; }
390  const BlackoilWellModelNetwork<TypeTag>& network() const { return network_; }
391 
392  std::vector<WellInterfacePtr>& wellContainer() { return well_container_; }
393  const std::vector<WellInterfacePtr>& wellContainer() const { return well_container_; }
394 
395  void setNlddAdapter(BlackoilWellModelNldd<TypeTag>* mod)
396  { nldd_ = mod; }
397 
398  GuideRateHandler<Scalar, IndexTraits>& guideRateHandler()
399  { return guide_rate_handler_; }
400 
401  const GuideRateHandler<Scalar, IndexTraits>& guideRateHandler() const
402  { return guide_rate_handler_; }
403 
404  // === Reservoir Coupling ===
405 
408  const ReservoirCoupling::Proxy<Scalar>& rescoup() const { return rescoup_; }
409 
417  void updateGuideRates(const int report_step_idx,
418  const double sim_time)
419  {
420  this->guide_rate_handler_.updateGuideRates(
421  report_step_idx, sim_time, this->wellState(), this->groupState()
422  );
423  }
424 
426  bool isReservoirCouplingMaster() const { return rescoup_.isMaster(); }
427 
429  bool isReservoirCouplingSlave() const { return rescoup_.isSlave(); }
430 
436  bool isReservoirCouplingMasterGroup(const std::string& group_name) const {
437  return rescoup_.isMasterGroup(group_name);
438  }
439 
443  return rescoup_.master();
444  }
446  return rescoup_.master();
447  }
448 
452  return rescoup_.slave();
453  }
455  return rescoup_.slave();
456  }
457 
458 #ifdef RESERVOIR_COUPLING_ENABLED
459  void setReservoirCouplingMaster(ReservoirCouplingMaster<Scalar>* master)
460  {
461  rescoup_.setMaster(master);
462  this->guide_rate_handler_.setReservoirCouplingMaster(master);
463  this->groupStateHelper().setReservoirCouplingMaster(master);
464  }
465  void setReservoirCouplingSlave(ReservoirCouplingSlave<Scalar>* slave)
466  {
467  rescoup_.setSlave(slave);
468  this->guide_rate_handler_.setReservoirCouplingSlave(slave);
469  this->groupStateHelper().setReservoirCouplingSlave(slave);
470  }
471 #endif
472 
473  bool updateWellControlsAndNetwork(const bool mandatory_network_balance,
474  const double dt,
475  DeferredLogger& local_deferredLogger);
476 
477  // TODO: finding a better naming
478  void assembleWellEqWithoutIteration(const double dt);
479 
480  const std::vector<Scalar>& B_avg() const
481  { return B_avg_; }
482 
483  const ModelParameters& param() const
484  { return param_; }
485 
490  { return !param_.rc_network_loose_coupling_; }
491 
492 #ifdef RESERVOIR_COUPLING_ENABLED
493  BlackoilWellModelRescoup<TypeTag>& rescoupHelper() { return rescoupHelper_; }
497 #endif
498 
499 
500  template<class FluidState, class SingleWellState>
501  static Scalar computeTemperatureWeightFactor(const int perf_index, const int np, const FluidState& fs, const SingleWellState& ws)
502  {
503  const auto& perf_phase_rate = ws.perf_data.phase_rates;
504  // we only have one temperature pr cell any phaseIdx will do
505  Scalar cellTemperatures = fs.temperature(/*phaseIdx*/0).value();
506  Scalar weight_factor = 0.0;
507  for (unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) {
508  if (!FluidSystem::phaseIsActive(phaseIdx)) {
509  continue;
510  }
511  Scalar cellInternalEnergy = fs.enthalpy(phaseIdx).value() -
512  fs.pressure(phaseIdx).value() / fs.density(phaseIdx).value();
513  Scalar cellBinv = fs.invB(phaseIdx).value();
514  Scalar cellDensity = fs.density(phaseIdx).value();
515  Scalar perfPhaseRate = perf_phase_rate[perf_index*np + phaseIdx];
516  weight_factor += cellDensity * (perfPhaseRate / cellBinv) * (cellInternalEnergy / cellTemperatures);
517  }
518  return (std::abs(weight_factor) + 1e-13);
519  }
520 
521  protected:
522  Simulator& simulator_;
523 
524  // a vector of all the wells.
525  std::vector<WellInterfacePtr> well_container_{};
526 
527  std::vector<bool> is_cell_perforated_{};
528 
529  void initializeWellState(const int timeStepIdx);
530 
531  // create the well container
532  void createWellContainer(const int report_step) override;
533 
534  WellInterfacePtr
535  createWellPointer(const int wellID,
536  const int report_step) const;
537 
538  template <typename WellType>
539  std::unique_ptr<WellType>
540  createTypedWellPointer(const int wellID,
541  const int time_step) const;
542 
543  WellInterfacePtr createWellForWellTest(const std::string& well_name,
544  const int report_step,
545  DeferredLogger& deferred_logger) const;
546 
547  const ModelParameters param_;
548  std::size_t global_num_cells_{};
549  // the number of the cells in the local grid
550  std::size_t local_num_cells_{};
551  Scalar gravity_{};
552  std::vector<Scalar> depth_{};
553  bool alternative_well_rate_init_{};
554  std::unique_ptr<RateConverterType> rateConverter_{};
555  std::map<std::string, std::unique_ptr<AverageRegionalPressureType>> regionalAveragePressureCalculator_{};
556 
557  SimulatorReportSingle last_report_{};
558  GuideRateHandler<Scalar, IndexTraits> guide_rate_handler_{};
559  ReservoirCoupling::Proxy<Scalar> rescoup_{};
560 
561  // A flag to tell the convergence report whether we need to take another newton step
562  bool network_needs_more_balancing_force_another_newton_iteration_{false};
563 
564  std::vector<Scalar> B_avg_{};
565 
566  const EquilGrid& equilGrid() const
567  { return simulator_.vanguard().equilGrid(); }
568 
569  const EclipseState& eclState() const
570  { return simulator_.vanguard().eclState(); }
571 
572  // compute the well fluxes and assemble them in to the reservoir equations as source terms
573  // and in the well equations.
574  void assemble(const double dt);
575 
576  // well controls and network pressures affect each other and are solved in an iterative manner.
577  // the function handles one iteration of updating well controls and network pressures.
578  // it is possible to decouple the update of well controls and network pressures further.
579  // the returned two booleans are {continue_due_to_network, well_group_control_changed}, respectively
580  std::tuple<bool, bool, Scalar> updateWellControlsAndNetworkIteration(const bool mandatory_network_balance,
581  const bool relax_network_tolerance,
582  const bool optimize_gas_lift,
583  const double dt,
584  DeferredLogger& local_deferredLogger);
585 
594  void initializeLocalWellStructure(const int reportStepIdx,
595  const bool enableWellPIScaling);
596 
600  void initializeGroupStructure(const int reportStepIdx);
601 
602  // called at the end of a time step
603  void timeStepSucceeded(const double simulationTime, const double dt);
604 
605  // called at the end of a report step
606  void endReportStep();
607 
608  // setting the well_solutions_ based on well_state.
609  void updatePrimaryVariables();
610 
611  void updateAverageFormationFactor();
612 
613  void computePotentials(const std::size_t widx,
614  const WellState<Scalar, IndexTraits>& well_state_copy,
615  std::string& exc_msg,
616  ExceptionType::ExcEnum& exc_type) override;
617 
618  const std::vector<Scalar>& wellPerfEfficiencyFactors() const;
619 
620  void calculateProductivityIndexValuesShutWells(const int reportStepIdx, DeferredLogger& deferred_logger) override;
621  void calculateProductivityIndexValues(DeferredLogger& deferred_logger) override;
622  void calculateProductivityIndexValues(const WellInterface<TypeTag>* wellPtr,
623  DeferredLogger& deferred_logger);
624 
625  // The number of conservation quantities.
626  int numConservationQuantities() const;
627 
628  int reportStepIndex() const;
629 
630  void assembleWellEq(const double dt);
631 
632  void prepareWellsBeforeAssembling(const double dt);
633 
634  void extractLegacyCellPvtRegionIndex_();
635 
636  void extractLegacyDepth_();
637 
639  void updateWellTestState(const double simulationTime, WellTestState& wellTestState);
640 
641  void wellTesting(const int timeStepIdx, const double simulationTime, DeferredLogger& deferred_logger);
642 
643  void calcResvCoeff(const int fipnum,
644  const int pvtreg,
645  const std::vector<Scalar>& production_rates,
646  std::vector<Scalar>& resv_coeff) const override;
647 
648  void calcInjResvCoeff(const int fipnum,
649  const int pvtreg,
650  std::vector<Scalar>& resv_coeff) const override;
651 
652  void computeWellTemperature();
653 
654  private:
655  // Private helper methods (alphabetical order)
656  // --------------------------------------------
657 
658  void assignWellSpeciesRates_(data::Wells& wsrpt) const;
659  void assignWellTracerRates_(data::Wells& wsrpt) const;
660 
669  bool isRescoupCoupledNetworkParticipant_() const;
670 
678  bool isRescoupMasterCoupledNetworkIteration_() const;
679 
687  bool isRescoupSlaveCoupledNetworkIteration_() const;
688 
695  bool isRescoupSlaveOnSyncStepFirstSubstep_() const;
696 
705  bool isRescoupSlaveConnectedToMasterNetwork_() const;
706 
713  bool maybeSendSlaveGroupFlowToMaster_(const int reportStepIdx);
714 
719  void sendSlaveNetworkLoopTerminationSignal_();
720 
723  bool shouldDoPreStepNetworkRebalance_(const int episodeIdx) const;
724 
726  void updateNetworkActiveState_();
727 
728  BlackoilWellModelGasLift<TypeTag> gaslift_;
729  BlackoilWellModelNetwork<TypeTag> network_;
730 #ifdef RESERVOIR_COUPLING_ENABLED
731  BlackoilWellModelRescoup<TypeTag> rescoupHelper_;
732 #endif
733  BlackoilWellModelNldd<TypeTag>* nldd_ = nullptr;
734 
735  // These members are used to avoid reallocation in specific functions
736  // instead of using local variables.
737  // Their state is not relevant between function calls, so they can
738  // (and must) be mutable, as the functions using them are const.
739  mutable BVector x_local_;
740 
741  // Store cell rates after assembling to avoid iterating all wells and connections for every element
742  std::map<int, RateVector> cellRates_;
743 
744  // Cached well solution from the system solver, consumed by
745  // recoverWellSolutionAndUpdateWellState during postSolve.
746  std::optional<WellVector<Scalar>> cachedSystemWellSolution_;
747  std::vector<int> cachedWellDofOffsets_;
748 
749  void assignWellTracerRates(data::Wells& wsrpt) const;
750  void assignWellSpeciesRates(data::Wells& wsrpt) const;
751 
752  [[nodiscard]] auto rsConstInfo() const
753  -> typename WellState<Scalar,IndexTraits>::RsConstInfo;
754  };
755 
756 } // namespace Opm
757 
758 #include "BlackoilWellModel_impl.hpp"
759 
760 #endif // OPM_BLACKOILWELLMODEL_HEADER_INCLUDED
Class for handling the blackoil well model.
Definition: ActionHandler.hpp:39
void initializeLocalWellStructure(const int reportStepIdx, const bool enableWellPIScaling)
Update rank&#39;s notion of intersecting wells and their associate solution variables.
Definition: BlackoilWellModel_impl.hpp:248
void initializeGroupStructure(const int reportStepIdx)
Initialize group control modes/constraints and group solution state.
Definition: BlackoilWellModel_impl.hpp:294
Context for iteration-dependent decisions in the Newton solver.
Definition: NewtonIterationContext.hpp:43
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
bool matrix_add_well_contributions_
Whether to add influences of wells between cells to the matrix and preconditioner matrix...
Definition: BlackoilModelParameters.hpp:315
Class for handling the blackoil well model.
Definition: BlackoilModelProperties.hpp:32
Helper class for grid instantiation of ECL file-format using problems.
bool isReservoirCouplingMaster() const
Check if this process is a reservoir coupling master.
Definition: BlackoilWellModel.hpp:426
Definition: BlackoilWellModel.hpp:90
void calculateExplicitQuantities() const
Calculating the explicit quantities used in the well calculation.
Definition: BlackoilWellModel_impl.hpp:1645
int strict_outer_iter_wells_
Newton iteration where wells are stricly convergent.
Definition: BlackoilModelParameters.hpp:265
Facility for converting component rates at surface conditions to phase (voidage) rates at reservoir c...
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: BlackoilWellModelConstraints.hpp:37
Facility for converting component rates at surface conditions to phase (voidage) rates at reservoir c...
Solver parameters for the NonlinearSystemBlackOilReservoir.
Definition: BlackoilModelParameters.hpp:200
Class for handling the blackoil well model in a NLDD solver.
Definition: BlackoilWellModel.hpp:89
void prepareTimeStep(DeferredLogger &deferred_logger)
One-time initialization at the start of each timestep.
Definition: BlackoilWellModel_impl.hpp:1985
bool useTightRcNetworkCoupling() const
True when tight (per-sub-iteration) reservoir-coupling network coupling is in effect.
Definition: BlackoilWellModel.hpp:489
ReservoirCouplingMaster< Scalar > & reservoirCouplingMaster()
Get reference to reservoir coupling master.
Definition: BlackoilWellModel.hpp:442
This class serves to eliminate the need to include the WellContributions into the matrix (with –matr...
Definition: GpuBridge.hpp:30
int compressedIndexForInterior(int cartesian_cell_idx) const override
get compressed index for interior cells (-1, otherwise
Definition: BlackoilWellModel.hpp:356
ReservoirCoupling::Proxy< Scalar > & rescoup()
Get the reservoir coupling proxy.
Definition: BlackoilWellModel.hpp:407
const std::vector< WellInterfacePtr > & localNonshutWells() const
Get list of local nonshut wells.
Definition: BlackoilWellModel.hpp:324
void assignShutConnections(data::Wells &wsrpt, const int reportStepIndex) const
Assign basic result quantities for shut connections of wells owned by current rank.
Definition: BlackoilWellModelGeneric.cpp:1121
void updateWellTestState(const double simulationTime, WellTestState &wellTestState)
upate the wellTestState related to economic limits
Definition: BlackoilWellModel_impl.hpp:1821
void updateGuideRates(const int report_step_idx, const double sim_time)
Update guide rates for all wells and groups.
Definition: BlackoilWellModel.hpp:417
Definition: ReservoirCouplingMaster.hpp:38
bool isReservoirCouplingSlave() const
Check if this process is a reservoir coupling slave.
Definition: BlackoilWellModel.hpp:429
void assignDynamicWellStatus(data::Wells &wsrpt) const
Assign dynamic well status for each well owned by current rank.
Definition: BlackoilWellModelGeneric.cpp:1102
Definition: ReservoirCouplingSlave.hpp:40
Thin proxy for reservoir coupling master/slave pointers.
Definition: RescoupProxy.hpp:54
bool isReservoirCouplingMasterGroup(const std::string &group_name) const
Check if a group is a reservoir coupling master group.
Definition: BlackoilWellModel.hpp:436
Definition: WellConnectionAuxiliaryModule.hpp:38
ReservoirCouplingSlave< Scalar > & reservoirCouplingSlave()
Get reference to reservoir coupling slave.
Definition: BlackoilWellModel.hpp:451
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
bool rc_network_loose_coupling_
Reservoir coupling: use loose (per-outer-iteration) master/slave network coupling instead of the defa...
Definition: BlackoilModelParameters.hpp:357