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> 32 #include <opm/grid/utility/SparseTable.hpp> 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> 39 #include <opm/material/densead/Math.hpp> 41 #include <opm/simulators/flow/countGlobalCells.hpp> 44 #include <opm/simulators/linalg/matrixblock.hh> 45 #include <opm/simulators/linalg/system/SystemTypes.hpp> 47 #include <opm/simulators/timestepping/SimulatorReport.hpp> 48 #include <opm/simulators/timestepping/gatherConvergenceReport.hpp> 50 #include <opm/simulators/utils/DeferredLogger.hpp> 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> 90 template<
class T,
template <
typename,
typename...>
class Storage>
class SparseTable;
92 #if COMPILE_GPU_BRIDGE 97 template<
typename TypeTag>
100 typename GetPropType<TypeTag, Properties::FluidSystem>::IndexTraitsType>
117 using IndexTraits =
typename FluidSystem::IndexTraitsType;
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>();
134 using VectorBlockType = Dune::FieldVector<Scalar, numEq>;
135 using BVector = Dune::BlockVector<VectorBlockType>;
137 using PolymerModule = BlackOilPolymerModule<TypeTag, has_polymer_>;
138 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, has_bioeffects_>;
141 using RateConverterType = RateConverter::
142 SurfaceToReservoirVoidage<FluidSystem, std::vector<int> >;
145 using AverageRegionalPressureType = RegionAverageCalculator::
146 AverageRegionalPressure<FluidSystem, std::vector<int> >;
151 void initWellContainer(
const int reportStepIdx)
override;
155 OPM_TIMEBLOCK(beginEpsiode);
156 beginReportStep(simulator_.episodeIndex());
159 void beginTimeStep();
161 void beginIteration()
163 OPM_TIMEBLOCK(beginIteration);
164 assemble(simulator_.timeStepSize());
172 OPM_TIMEBLOCK(endTimeStep);
173 timeStepSucceeded(simulator_.time(), simulator_.timeStepSize());
181 void computeTotalRatesForDof(RateVector& rate,
182 unsigned globalIdx)
const;
184 template <
class Context>
185 void computeTotalRatesForDof(RateVector& rate,
186 const Context& context,
188 unsigned timeIdx)
const;
191 using WellInterfacePtr = std::unique_ptr<WellInterface<TypeTag>>;
193 using BlackoilWellModelGeneric<Scalar, IndexTraits>::initFromRestartFile;
194 void initFromRestartFile(
const RestartValue& restartValues)
196 initFromRestartFile(restartValues,
197 this->simulator_.vanguard().transferWTestState(),
199 this->simulator_.vanguard().enableDistributedWells());
202 using BlackoilWellModelGeneric<Scalar, IndexTraits>::prepareDeserialize;
203 void prepareDeserialize(
const int report_step)
205 prepareDeserialize(report_step, grid().size(0),
206 this->simulator_.vanguard().enableDistributedWells());
209 data::Wells wellData()
const 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());
217 BlackoilWellModelGuideRates(*
this)
218 .assignWellGuideRates(wsrpt, this->reportStepIndex());
220 this->assignWellTracerRates_(wsrpt);
222 if constexpr (has_geochem_) {
223 this->assignWellSpeciesRates_(wsrpt);
226 if (
const auto& rspec = eclState().runspec();
227 rspec.co2Storage() || rspec.h2Storage())
233 this->assignMassGasRate(wsrpt, FluidSystem::referenceDensity(FluidSystem::gasPhaseIdx, 0));
236 this->assignWellTargets(wsrpt);
247 data::WellBlockAveragePressures wellBlockAveragePressures()
const 249 return this->wbp_.computeWellBlockAveragePressures(this->gravity_);
252 #if COMPILE_GPU_BRIDGE 254 void getWellContributions(WellContributions<Scalar>& x)
const;
258 ConvergenceReport getWellConvergence(
const std::vector<Scalar>& B_avg,
const bool checkWellGroupControlsAndNetwork =
false)
const;
260 const SimulatorReportSingle& lastReport()
const;
262 void addWellContributions(SparseMatrixAdapter& jacobian)
const;
265 void addReservoirSourceTerms(GlobalEqVector& residual,
266 const std::vector<typename SparseMatrixAdapter::MatrixBlock*>& diagMatAddress)
const;
269 void beginReportStep(
const int time_step);
281 updateWellControls(DeferredLogger& deferred_logger);
283 void updateAndCommunicate(
const int reportStepIdx);
285 bool updateGroupControls(
const Group& group,
286 DeferredLogger& deferred_logger,
287 const int reportStepIdx);
289 static constexpr
int numResDofs = Indices::numEq;
290 static constexpr
int numWellDofs = numResDofs + 1;
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>>;
296 void addBCDMatrix(std::vector<BMatrix>& b_matrices,
297 std::vector<CMatrix>& c_matrices,
298 std::vector<DMatrix>& d_matrices,
301 const WellInterface<TypeTag>& getWell(
const std::string& well_name)
const;
303 using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<Scalar, 1, 1>>;
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 315 OPM_THROW(std::logic_error,
"Attempt to access NLDD data without a NLDD solver");
317 return nldd_->addWellPressureEquations(jacobian,
326 return well_container_;
332 OPM_THROW(std::logic_error,
"Attempt to access NLDD data without a NLDD solver");
334 return nldd_->well_local_cells();
337 const std::map<std::string, int>& well_domain()
const 340 OPM_THROW(std::logic_error,
"Attempt to access NLDD data without a NLDD solver");
343 return nldd_->well_domain();
346 auto begin()
const {
return well_container_.begin(); }
347 auto end()
const {
return well_container_.end(); }
348 bool empty()
const {
return well_container_.empty(); }
350 bool addMatrixContributions()
const 353 int numStrictIterations()
const 358 return simulator_.vanguard().compressedIndexForInterior(cartesian_cell_idx);
361 int compressedIndexForInteriorLGR(
const std::string& lgr_tag,
const Connection& conn)
const override 363 return simulator_.vanguard().compressedIndexForInteriorLGR(lgr_tag, conn);
368 void recoverWellSolutionAndUpdateWellState(
const BVector& x);
372 void recoverWellSolutionAndUpdateWellStateDomain(
const BVector& x,
373 const int domainIdx);
375 void updateCellRates();
378 void updateCellRatesForDomain(
int domainIndex,
379 const std::map<std::string, int>& well_domain_map);
381 const Grid& grid()
const 382 {
return simulator_.vanguard().grid(); }
384 const Simulator& simulator()
const 385 {
return simulator_; }
386 Simulator& simulator()
387 {
return simulator_; }
389 BlackoilWellModelNetwork<TypeTag>& network() {
return network_; }
390 const BlackoilWellModelNetwork<TypeTag>& network()
const {
return network_; }
392 std::vector<WellInterfacePtr>& wellContainer() {
return well_container_; }
393 const std::vector<WellInterfacePtr>& wellContainer()
const {
return well_container_; }
395 void setNlddAdapter(BlackoilWellModelNldd<TypeTag>* mod)
398 GuideRateHandler<Scalar, IndexTraits>& guideRateHandler()
399 {
return guide_rate_handler_; }
401 const GuideRateHandler<Scalar, IndexTraits>& guideRateHandler()
const 402 {
return guide_rate_handler_; }
418 const double sim_time)
420 this->guide_rate_handler_.updateGuideRates(
421 report_step_idx, sim_time, this->wellState(), this->groupState()
437 return rescoup_.isMasterGroup(group_name);
443 return rescoup_.master();
446 return rescoup_.master();
452 return rescoup_.slave();
455 return rescoup_.slave();
458 #ifdef RESERVOIR_COUPLING_ENABLED 459 void setReservoirCouplingMaster(ReservoirCouplingMaster<Scalar>* master)
461 rescoup_.setMaster(master);
462 this->guide_rate_handler_.setReservoirCouplingMaster(master);
463 this->groupStateHelper().setReservoirCouplingMaster(master);
465 void setReservoirCouplingSlave(ReservoirCouplingSlave<Scalar>* slave)
467 rescoup_.setSlave(slave);
468 this->guide_rate_handler_.setReservoirCouplingSlave(slave);
469 this->groupStateHelper().setReservoirCouplingSlave(slave);
473 bool updateWellControlsAndNetwork(
const bool mandatory_network_balance,
475 DeferredLogger& local_deferredLogger);
478 void assembleWellEqWithoutIteration(
const double dt);
480 const std::vector<Scalar>& B_avg()
const 483 const ModelParameters& param()
const 492 #ifdef RESERVOIR_COUPLING_ENABLED 493 BlackoilWellModelRescoup<TypeTag>& rescoupHelper() {
return rescoupHelper_; }
500 template<
class Flu
idState,
class SingleWellState>
501 static Scalar computeTemperatureWeightFactor(
const int perf_index,
const int np,
const FluidState& fs,
const SingleWellState& ws)
503 const auto& perf_phase_rate = ws.perf_data.phase_rates;
505 Scalar cellTemperatures = fs.temperature(0).value();
506 Scalar weight_factor = 0.0;
507 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) {
508 if (!FluidSystem::phaseIsActive(phaseIdx)) {
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);
518 return (std::abs(weight_factor) + 1e-13);
522 Simulator& simulator_;
525 std::vector<WellInterfacePtr> well_container_{};
527 std::vector<bool> is_cell_perforated_{};
529 void initializeWellState(
const int timeStepIdx);
532 void createWellContainer(
const int report_step)
override;
535 createWellPointer(
const int wellID,
536 const int report_step)
const;
538 template <
typename WellType>
539 std::unique_ptr<WellType>
540 createTypedWellPointer(
const int wellID,
541 const int time_step)
const;
543 WellInterfacePtr createWellForWellTest(
const std::string& well_name,
544 const int report_step,
545 DeferredLogger& deferred_logger)
const;
547 const ModelParameters param_;
548 std::size_t global_num_cells_{};
550 std::size_t local_num_cells_{};
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_{};
557 SimulatorReportSingle last_report_{};
558 GuideRateHandler<Scalar, IndexTraits> guide_rate_handler_{};
559 ReservoirCoupling::Proxy<Scalar> rescoup_{};
562 bool network_needs_more_balancing_force_another_newton_iteration_{
false};
564 std::vector<Scalar> B_avg_{};
566 const EquilGrid& equilGrid()
const 567 {
return simulator_.vanguard().equilGrid(); }
569 const EclipseState& eclState()
const 570 {
return simulator_.vanguard().eclState(); }
574 void assemble(
const double dt);
580 std::tuple<bool, bool, Scalar> updateWellControlsAndNetworkIteration(
const bool mandatory_network_balance,
581 const bool relax_network_tolerance,
582 const bool optimize_gas_lift,
584 DeferredLogger& local_deferredLogger);
595 const bool enableWellPIScaling);
603 void timeStepSucceeded(
const double simulationTime,
const double dt);
606 void endReportStep();
609 void updatePrimaryVariables();
611 void updateAverageFormationFactor();
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;
618 const std::vector<Scalar>& wellPerfEfficiencyFactors()
const;
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);
626 int numConservationQuantities()
const;
628 int reportStepIndex()
const;
630 void assembleWellEq(
const double dt);
632 void prepareWellsBeforeAssembling(
const double dt);
634 void extractLegacyCellPvtRegionIndex_();
636 void extractLegacyDepth_();
641 void wellTesting(
const int timeStepIdx,
const double simulationTime, DeferredLogger& deferred_logger);
643 void calcResvCoeff(
const int fipnum,
645 const std::vector<Scalar>& production_rates,
646 std::vector<Scalar>& resv_coeff)
const override;
648 void calcInjResvCoeff(
const int fipnum,
650 std::vector<Scalar>& resv_coeff)
const override;
652 void computeWellTemperature();
658 void assignWellSpeciesRates_(data::Wells& wsrpt)
const;
659 void assignWellTracerRates_(data::Wells& wsrpt)
const;
669 bool isRescoupCoupledNetworkParticipant_()
const;
678 bool isRescoupMasterCoupledNetworkIteration_()
const;
687 bool isRescoupSlaveCoupledNetworkIteration_()
const;
695 bool isRescoupSlaveOnSyncStepFirstSubstep_()
const;
705 bool isRescoupSlaveConnectedToMasterNetwork_()
const;
713 bool maybeSendSlaveGroupFlowToMaster_(
const int reportStepIdx);
719 void sendSlaveNetworkLoopTerminationSignal_();
723 bool shouldDoPreStepNetworkRebalance_(
const int episodeIdx)
const;
726 void updateNetworkActiveState_();
728 BlackoilWellModelGasLift<TypeTag> gaslift_;
729 BlackoilWellModelNetwork<TypeTag> network_;
730 #ifdef RESERVOIR_COUPLING_ENABLED 731 BlackoilWellModelRescoup<TypeTag> rescoupHelper_;
733 BlackoilWellModelNldd<TypeTag>* nldd_ =
nullptr;
739 mutable BVector x_local_;
742 std::map<int, RateVector> cellRates_;
746 std::optional<WellVector<Scalar>> cachedSystemWellSolution_;
747 std::vector<int> cachedWellDofOffsets_;
749 void assignWellTracerRates(data::Wells& wsrpt)
const;
750 void assignWellSpeciesRates(data::Wells& wsrpt)
const;
752 [[nodiscard]]
auto rsConstInfo() const
753 -> typename WellState<Scalar,IndexTraits>::RsConstInfo;
758 #include "BlackoilWellModel_impl.hpp" 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'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