23 #ifndef OPM_BLACKOILWELLMODEL_HEADER_INCLUDED 24 #define OPM_BLACKOILWELLMODEL_HEADER_INCLUDED 26 #include <dune/common/fmatrix.hh> 28 #include <dune/istl/bcrsmatrix.hh> 29 #include <dune/istl/matrixmatrix.hh> 31 #include <opm/common/OpmLog/OpmLog.hpp> 33 #include <opm/input/eclipse/Schedule/Group/Group.hpp> 34 #include <opm/input/eclipse/Schedule/Group/GuideRate.hpp> 35 #include <opm/input/eclipse/Schedule/Schedule.hpp> 36 #include <opm/input/eclipse/Schedule/Well/WellTestState.hpp> 38 #include <opm/material/densead/Math.hpp> 40 #include <opm/simulators/flow/countGlobalCells.hpp> 43 #include <opm/simulators/linalg/matrixblock.hh> 45 #include <opm/simulators/timestepping/SimulatorReport.hpp> 46 #include <opm/simulators/timestepping/gatherConvergenceReport.hpp> 48 #include <opm/simulators/utils/DeferredLogger.hpp> 50 #include <opm/simulators/wells/BlackoilWellModelGasLift.hpp> 51 #include <opm/simulators/wells/BlackoilWellModelGeneric.hpp> 52 #include <opm/simulators/wells/BlackoilWellModelGuideRates.hpp> 53 #include <opm/simulators/wells/BlackoilWellModelNetwork.hpp> 54 #include <opm/simulators/wells/GasLiftGroupInfo.hpp> 55 #include <opm/simulators/wells/GasLiftSingleWell.hpp> 56 #include <opm/simulators/wells/GasLiftSingleWellGeneric.hpp> 57 #include <opm/simulators/wells/GasLiftWellState.hpp> 58 #include <opm/simulators/wells/GroupStateHelper.hpp> 59 #include <opm/simulators/wells/GuideRateHandler.hpp> 60 #include <opm/simulators/wells/MultisegmentWell.hpp> 61 #include <opm/simulators/wells/ParallelWBPCalculation.hpp> 62 #include <opm/simulators/wells/ParallelWellInfo.hpp> 63 #include <opm/simulators/wells/PerforationData.hpp> 66 #include <opm/simulators/wells/StandardWell.hpp> 67 #include <opm/simulators/wells/VFPInjProperties.hpp> 68 #include <opm/simulators/wells/VFPProdProperties.hpp> 69 #include <opm/simulators/wells/WGState.hpp> 70 #include <opm/simulators/wells/WellConnectionAuxiliaryModule.hpp> 71 #include <opm/simulators/wells/WellInterface.hpp> 72 #include <opm/simulators/wells/WellProdIndexCalculator.hpp> 73 #include <opm/simulators/wells/WellState.hpp> 74 #include <opm/simulators/wells/rescoup/RescoupProxy.hpp> 87 template<
class T,
template <
typename,
typename...>
class Storage>
class SparseTable;
89 #if COMPILE_GPU_BRIDGE 94 template<
typename TypeTag>
97 typename GetPropType<TypeTag, Properties::FluidSystem>::IndexTraitsType>
114 using IndexTraits =
typename FluidSystem::IndexTraitsType;
119 static const int numEq = Indices::numEq;
120 static const int solventSaturationIdx = Indices::solventSaturationIdx;
121 static constexpr
bool has_solvent_ = getPropValue<TypeTag, Properties::EnableSolvent>();
122 static constexpr
bool has_polymer_ = getPropValue<TypeTag, Properties::EnablePolymer>();
123 static constexpr EnergyModules energyModuleType_ = getPropValue<TypeTag, Properties::EnergyModuleType>();
124 static constexpr
bool has_energy_ = (energyModuleType_ == EnergyModules::FullyImplicitThermal);
125 static constexpr
bool has_micp_ = Indices::enableMICP;
126 static constexpr
bool has_geochem_ = getPropValue<TypeTag, Properties::EnableGeochemistry>();
130 using VectorBlockType = Dune::FieldVector<Scalar, numEq>;
131 using BVector = Dune::BlockVector<VectorBlockType>;
137 using RateConverterType = RateConverter::
138 SurfaceToReservoirVoidage<FluidSystem, std::vector<int> >;
141 using AverageRegionalPressureType = RegionAverageCalculator::
142 AverageRegionalPressure<FluidSystem, std::vector<int> >;
147 void initWellContainer(
const int reportStepIdx)
override;
151 OPM_TIMEBLOCK(beginEpsiode);
152 beginReportStep(simulator_.episodeIndex());
155 void beginTimeStep();
157 void beginIteration()
159 OPM_TIMEBLOCK(beginIteration);
160 assemble(simulator_.timeStepSize());
168 OPM_TIMEBLOCK(endTimeStep);
169 timeStepSucceeded(simulator_.time(), simulator_.timeStepSize());
177 void computeTotalRatesForDof(RateVector& rate,
178 unsigned globalIdx)
const;
180 template <
class Context>
181 void computeTotalRatesForDof(RateVector& rate,
182 const Context& context,
184 unsigned timeIdx)
const;
187 using WellInterfacePtr = std::unique_ptr<WellInterface<TypeTag>>;
189 using BlackoilWellModelGeneric<Scalar, IndexTraits>::initFromRestartFile;
190 void initFromRestartFile(
const RestartValue& restartValues)
192 initFromRestartFile(restartValues,
193 this->simulator_.vanguard().transferWTestState(),
196 this->simulator_.vanguard().enableDistributedWells());
199 using BlackoilWellModelGeneric<Scalar, IndexTraits>::prepareDeserialize;
200 void prepareDeserialize(
const int report_step)
202 prepareDeserialize(report_step, grid().size(0),
204 this->simulator_.vanguard().enableDistributedWells());
207 data::Wells wellData()
const 209 auto wsrpt = this->wellState()
210 .report(this->simulator_.vanguard().globalCell().data(),
211 [
this](
const int well_index)
212 {
return this->wasDynamicallyShutThisTimeStep(well_index); },
213 this->rsConstInfo());
215 BlackoilWellModelGuideRates(*
this)
216 .assignWellGuideRates(wsrpt, this->reportStepIndex());
218 this->assignWellTracerRates(wsrpt);
220 if constexpr (has_geochem_) {
221 this->assignWellSpeciesRates(wsrpt);
224 if (
const auto& rspec = eclState().runspec();
225 rspec.co2Storage() || rspec.h2Storage())
231 this->assignMassGasRate(wsrpt, FluidSystem::referenceDensity(FluidSystem::gasPhaseIdx, 0));
234 this->assignWellTargets(wsrpt);
245 data::WellBlockAveragePressures wellBlockAveragePressures()
const 247 return this->wbp_.computeWellBlockAveragePressures(this->gravity_);
250 #if COMPILE_GPU_BRIDGE 252 void getWellContributions(WellContributions<Scalar>& x)
const;
256 ConvergenceReport getWellConvergence(
const std::vector<Scalar>& B_avg,
const bool checkWellGroupControlsAndNetwork =
false)
const;
258 const SimulatorReportSingle& lastReport()
const;
260 void addWellContributions(SparseMatrixAdapter& jacobian)
const;
263 void addReservoirSourceTerms(GlobalEqVector& residual,
264 const std::vector<typename SparseMatrixAdapter::MatrixBlock*>& diagMatAddress)
const;
267 void beginReportStep(
const int time_step);
279 updateWellControls(DeferredLogger& deferred_logger);
281 void updateAndCommunicate(
const int reportStepIdx);
283 bool updateGroupControls(
const Group& group,
284 DeferredLogger& deferred_logger,
285 const int reportStepIdx);
287 const WellInterface<TypeTag>& getWell(
const std::string& well_name)
const;
289 using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<Scalar, 1, 1>>;
291 void addWellPressureEquations(PressureMatrix& jacobian,
292 const BVector& weights,
293 const bool use_well_weights)
const;
294 void addWellPressureEquationsStruct(PressureMatrix& jacobian)
const;
295 void addWellPressureEquationsDomain(PressureMatrix& jacobian,
296 const BVector& weights,
297 const bool use_well_weights,
298 const int domainIndex)
const 301 OPM_THROW(std::logic_error,
"Attempt to access NLDD data without a NLDD solver");
303 return nldd_->addWellPressureEquations(jacobian,
312 return well_container_;
318 OPM_THROW(std::logic_error,
"Attempt to access NLDD data without a NLDD solver");
320 return nldd_->well_local_cells();
323 const std::map<std::string, int>& well_domain()
const 326 OPM_THROW(std::logic_error,
"Attempt to access NLDD data without a NLDD solver");
329 return nldd_->well_domain();
332 auto begin()
const {
return well_container_.begin(); }
333 auto end()
const {
return well_container_.end(); }
334 bool empty()
const {
return well_container_.empty(); }
336 bool addMatrixContributions()
const 339 int numStrictIterations()
const 344 return simulator_.vanguard().compressedIndexForInterior(cartesian_cell_idx);
347 int compressedIndexForInteriorLGR(
const std::string& lgr_tag,
const Connection& conn)
const override 349 return simulator_.vanguard().compressedIndexForInteriorLGR(lgr_tag, conn);
354 void recoverWellSolutionAndUpdateWellState(
const BVector& x);
358 void recoverWellSolutionAndUpdateWellStateDomain(
const BVector& x,
359 const int domainIdx);
361 void updateCellRates();
364 void updateCellRatesForDomain(
int domainIndex,
365 const std::map<std::string, int>& well_domain_map);
367 const Grid& grid()
const 368 {
return simulator_.vanguard().grid(); }
370 const Simulator& simulator()
const 371 {
return simulator_; }
373 void setNlddAdapter(BlackoilWellModelNldd<TypeTag>* mod)
390 const double sim_time)
392 this->guide_rate_handler_.updateGuideRates(
393 report_step_idx, sim_time, this->wellState(), this->groupState()
406 return rescoup_.master();
412 return rescoup_.slave();
415 #ifdef RESERVOIR_COUPLING_ENABLED 418 rescoup_.setMaster(master);
419 this->guide_rate_handler_.setReservoirCouplingMaster(master);
420 this->groupStateHelper().setReservoirCouplingMaster(master);
422 void setReservoirCouplingSlave(ReservoirCouplingSlave<Scalar>* slave)
424 rescoup_.setSlave(slave);
425 this->guide_rate_handler_.setReservoirCouplingSlave(slave);
426 this->groupStateHelper().setReservoirCouplingSlave(slave);
430 void sendSlaveGroupDataToMaster();
433 void receiveSlaveGroupData();
435 void receiveGroupConstraintsFromMaster();
436 void sendMasterGroupConstraintsToSlaves();
437 void rescoupSyncSummaryData();
447 std::optional<ReservoirCoupling::ScopedLoggerGuard>
448 setupRescoupScopedLogger(DeferredLogger& local_logger);
451 bool updateWellControlsAndNetwork(
const bool mandatory_network_balance,
453 DeferredLogger& local_deferredLogger);
456 void assembleWellEqWithoutIteration(
const double dt);
458 const std::vector<Scalar>& B_avg()
const 461 const ModelParameters& param()
const 465 template<
class Flu
idState,
class SingleWellState>
466 static Scalar computeTemperatureWeightFactor(
const int perf_index,
const int np,
const FluidState& fs,
const SingleWellState& ws)
468 const auto& perf_phase_rate = ws.perf_data.phase_rates;
470 Scalar cellTemperatures = fs.temperature(0).value();
471 Scalar weight_factor = 0.0;
472 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) {
473 if (!FluidSystem::phaseIsActive(phaseIdx)) {
476 Scalar cellInternalEnergy = fs.enthalpy(phaseIdx).value() -
477 fs.pressure(phaseIdx).value() / fs.density(phaseIdx).value();
478 Scalar cellBinv = fs.invB(phaseIdx).value();
479 Scalar cellDensity = fs.density(phaseIdx).value();
480 Scalar perfPhaseRate = perf_phase_rate[perf_index*np + phaseIdx];
481 weight_factor += cellDensity * (perfPhaseRate / cellBinv) * (cellInternalEnergy / cellTemperatures);
483 return (std::abs(weight_factor) + 1e-13);
487 Simulator& simulator_;
490 std::vector<WellInterfacePtr> well_container_{};
492 std::vector<bool> is_cell_perforated_{};
494 void initializeWellState(
const int timeStepIdx);
497 void createWellContainer(
const int report_step)
override;
500 createWellPointer(
const int wellID,
501 const int report_step)
const;
503 template <
typename WellType>
504 std::unique_ptr<WellType>
505 createTypedWellPointer(
const int wellID,
506 const int time_step)
const;
508 WellInterfacePtr createWellForWellTest(
const std::string& well_name,
509 const int report_step,
510 DeferredLogger& deferred_logger)
const;
512 const ModelParameters param_;
513 std::size_t global_num_cells_{};
515 std::size_t local_num_cells_{};
517 std::vector<Scalar> depth_{};
518 bool alternative_well_rate_init_{};
519 std::unique_ptr<RateConverterType> rateConverter_{};
520 std::map<std::string, std::unique_ptr<AverageRegionalPressureType>> regionalAveragePressureCalculator_{};
522 SimulatorReportSingle last_report_{};
523 GuideRateHandler<Scalar, IndexTraits> guide_rate_handler_{};
524 ReservoirCoupling::Proxy<Scalar> rescoup_{};
527 bool network_needs_more_balancing_force_another_newton_iteration_{
false};
529 std::vector<Scalar> B_avg_{};
531 const EquilGrid& equilGrid()
const 532 {
return simulator_.vanguard().equilGrid(); }
534 const EclipseState& eclState()
const 535 {
return simulator_.vanguard().eclState(); }
539 void assemble(
const double dt);
545 std::tuple<bool, bool, Scalar> updateWellControlsAndNetworkIteration(
const bool mandatory_network_balance,
546 const bool relax_network_tolerance,
547 const bool optimize_gas_lift,
549 DeferredLogger& local_deferredLogger);
560 const bool enableWellPIScaling);
568 void timeStepSucceeded(
const double simulationTime,
const double dt);
571 void endReportStep();
574 void updatePrimaryVariables();
576 void updateAverageFormationFactor();
578 void computePotentials(
const std::size_t widx,
579 const WellState<Scalar, IndexTraits>& well_state_copy,
580 std::string& exc_msg,
581 ExceptionType::ExcEnum& exc_type)
override;
583 const std::vector<Scalar>& wellPerfEfficiencyFactors()
const;
585 void calculateProductivityIndexValuesShutWells(
const int reportStepIdx, DeferredLogger& deferred_logger)
override;
586 void calculateProductivityIndexValues(DeferredLogger& deferred_logger)
override;
587 void calculateProductivityIndexValues(
const WellInterface<TypeTag>* wellPtr,
588 DeferredLogger& deferred_logger);
591 int numConservationQuantities()
const;
593 int reportStepIndex()
const;
595 void assembleWellEq(
const double dt);
597 void prepareWellsBeforeAssembling(
const double dt);
599 void extractLegacyCellPvtRegionIndex_();
601 void extractLegacyDepth_();
606 void wellTesting(
const int timeStepIdx,
const double simulationTime, DeferredLogger& deferred_logger);
608 void calcResvCoeff(
const int fipnum,
610 const std::vector<Scalar>& production_rates,
611 std::vector<Scalar>& resv_coeff)
const override;
613 void calcInjResvCoeff(
const int fipnum,
615 std::vector<Scalar>& resv_coeff)
const override;
617 void computeWellTemperature();
620 BlackoilWellModelGasLift<TypeTag> gaslift_;
621 BlackoilWellModelNetwork<TypeTag> network_;
622 BlackoilWellModelNldd<TypeTag>* nldd_ =
nullptr;
628 mutable BVector x_local_;
631 std::map<int, RateVector> cellRates_;
633 void assignWellTracerRates(data::Wells& wsrpt)
const;
634 void assignWellSpeciesRates(data::Wells& wsrpt)
const;
636 [[nodiscard]]
auto rsConstInfo() const
637 -> typename WellState<Scalar,IndexTraits>::RsConstInfo;
642 #include "BlackoilWellModel_impl.hpp" 644 #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's notion of intersecting wells and their associate solution variables.
Definition: BlackoilWellModel_impl.hpp:251
void initializeGroupStructure(const int reportStepIdx)
Initialize group control modes/constraints and group solution state.
Definition: BlackoilWellModel_impl.hpp:297
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:308
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:398
Definition: BlackoilWellModel.hpp:87
void calculateExplicitQuantities() const
Calculating the explicit quantities used in the well calculation.
Definition: BlackoilWellModel_impl.hpp:1682
int strict_outer_iter_wells_
Newton iteration where wells are stricly convergent.
Definition: BlackoilModelParameters.hpp:258
Facility for converting component rates at surface conditions to phase (voidage) rates at reservoir c...
This file contains a set of helper functions used by VFPProd / VFPInj.
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 BlackoilModel.
Definition: BlackoilModelParameters.hpp:193
Class for handling the blackoil well model in a NLDD solver.
Definition: BlackoilWellModel.hpp:86
void prepareTimeStep(DeferredLogger &deferred_logger)
One-time initialization at the start of each timestep.
Definition: BlackoilWellModel_impl.hpp:2020
ReservoirCouplingMaster< Scalar > & reservoirCouplingMaster()
Get reference to reservoir coupling master.
Definition: BlackoilWellModel.hpp:405
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:342
ReservoirCoupling::Proxy< Scalar > & rescoup()
Get the reservoir coupling proxy.
Definition: BlackoilWellModel.hpp:379
const std::vector< WellInterfacePtr > & localNonshutWells() const
Get list of local nonshut wells.
Definition: BlackoilWellModel.hpp:310
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:1102
void updateWellTestState(const double simulationTime, WellTestState &wellTestState)
upate the wellTestState related to economic limits
Definition: BlackoilWellModel_impl.hpp:1856
void updateGuideRates(const int report_step_idx, const double sim_time)
Update guide rates for all wells and groups.
Definition: BlackoilWellModel.hpp:389
Definition: ReservoirCouplingMaster.hpp:38
bool isReservoirCouplingSlave() const
Check if this process is a reservoir coupling slave.
Definition: BlackoilWellModel.hpp:401
void assignDynamicWellStatus(data::Wells &wsrpt) const
Assign dynamic well status for each well owned by current rank.
Definition: BlackoilWellModelGeneric.cpp:1083
Definition: ReservoirCouplingSlave.hpp:40
Thin proxy for reservoir coupling master/slave pointers.
Definition: RescoupProxy.hpp:54
Definition: WellConnectionAuxiliaryModule.hpp:38
ReservoirCouplingSlave< Scalar > & reservoirCouplingSlave()
Get reference to reservoir coupling slave.
Definition: BlackoilWellModel.hpp:411
Contains the high level supplements required to extend the black oil model by bioeffects.
Definition: blackoilbioeffectsmodules.hh:94
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
Contains the high level supplements required to extend the black oil model by polymer.
Definition: blackoilpolymermodules.hh:64
bool use_multisegment_well_
Whether to use MultisegmentWell to handle multisegment wells it is something temporary before the mul...
Definition: BlackoilModelParameters.hpp:302