96class BlackoilWellModelGeneric
100 BlackoilWellModelGeneric(Schedule& schedule,
103 const SummaryState& summaryState,
104 const EclipseState& eclState,
106 const Parallel::Communication& comm);
108 virtual ~BlackoilWellModelGeneric() =
default;
109 virtual int compressedIndexForInteriorLGR([[maybe_unused]]
const std::string& lgr_tag,
110 [[maybe_unused]]
const Connection& conn)
const
112 throw std::runtime_error(
"compressedIndexForInteriorLGR not implemented");
115 int numLocalWells()
const;
116 int numLocalWellsEnd()
const;
117 int numLocalNonshutWells()
const;
118 int numPhases()
const;
130 bool anyMSWellOpenLocal()
const;
132 const std::vector<Well>& eclWells()
const
133 {
return wells_ecl_; }
135 bool terminalOutput()
const
136 {
return terminal_output_; }
138 const Well& getWellEcl(
const std::string& well_name)
const;
139 std::vector<Well> getLocalWells(
const int timeStepIdx)
const;
140 const Schedule& schedule()
const {
return schedule_; }
142 const GroupState<Scalar>& groupState()
const {
return this->active_wgstate_.group_state; }
143 std::vector<const WellInterfaceGeneric<Scalar, IndexTraits>*> genericWells()
const
144 {
return {well_container_generic_.begin(), well_container_generic_.end()}; }
146 std::vector<WellInterfaceGeneric<Scalar, IndexTraits>*> genericWells()
147 {
return well_container_generic_; }
154 return this->active_wgstate_.well_state;
162 return this->active_wgstate_.well_state;
175 return this->nupcol_wgstate_.well_state;
179 return this->nupcol_wgstate_.well_state;
183 WellTestState& wellTestState() {
return this->active_wgstate_.well_test_state; }
185 const WellTestState& wellTestState()
const {
return this->active_wgstate_.well_test_state; }
187 Scalar wellPI(
const int well_index)
const;
188 Scalar wellPI(
const std::string& well_name)
const;
190 void updateEclWells(
const int timeStepIdx,
191 const SimulatorUpdate& sim_update,
192 const SummaryState& st);
194 void initFromRestartFile(
const RestartValue& restartValues,
195 std::unique_ptr<WellTestState> wtestState,
196 const std::size_t numCells,
198 bool enable_distributed_wells);
200 void prepareDeserialize(
int report_step,
201 const std::size_t numCells,
203 bool enable_distributed_wells);
211 void commitWGState();
213 data::GroupAndNetworkValues groupAndNetworkData(
const int reportStepIdx)
const;
218 const double simulation_time,
219 const bool dont_shut_grup_wells);
221 const std::vector<PerforationData<Scalar>>& perfData(
const int well_idx)
const
222 {
return well_perf_data_[well_idx]; }
224 const Parallel::Communication& comm()
const {
return comm_; }
226 const EclipseState& eclipseState()
const {
return eclState_; }
228 const SummaryState& summaryState()
const {
return summaryState_; }
230 const GuideRate& guideRate()
const {
return guideRate_; }
231 GuideRate& guideRate() {
return guideRate_; }
233 const std::map<std::string, double>& wellOpenTimes()
const {
return well_open_times_; }
234 const std::map<std::string, double>& wellCloseTimes()
const {
return well_close_times_; }
237 std::vector<int> getCellsForConnections(
const Well& well)
const;
239 bool reportStepStarts()
const {
return report_step_starts_; }
241 void updateClosedWellsThisStep(
const std::string& well_name)
const
243 this->closed_this_step_.insert(well_name);
245 bool wasDynamicallyShutThisTimeStep(
const std::string& well_name)
const;
247 void logPrimaryVars()
const;
249 template<
class Serializer>
250 void serializeOp(Serializer& serializer)
252 serializer(initial_step_);
253 serializer(report_step_starts_);
254 serializer(last_run_wellpi_);
255 serializer(local_shut_wells_);
256 serializer(closed_this_step_);
257 serializer(guideRate_);
258 serializer(genNetwork_);
259 serializer(prev_inj_multipliers_);
260 serializer(active_wgstate_);
261 serializer(last_valid_wgstate_);
262 serializer(nupcol_wgstate_);
263 serializer(switched_prod_groups_);
264 serializer(switched_inj_groups_);
265 serializer(closed_offending_wells_);
266 serializer(gen_gaslift_);
269 bool operator==(
const BlackoilWellModelGeneric& rhs)
const;
272 parallelWellInfo(
const std::size_t idx)
const
273 {
return local_parallel_well_info_[idx].get(); }
275 bool isOwner(
const std::string& wname)
const
277 return this->parallelWellSatisfies
278 (wname, [](
const auto& pwInfo) {
return pwInfo.isOwner(); });
281 bool hasLocalCells(
const std::string& wname)
const
283 return this->parallelWellSatisfies
284 (wname, [](
const auto& pwInfo) {
return pwInfo.hasLocalCells(); });
288 {
return conn_idx_map_[idx]; }
290 GroupStateHelperType& groupStateHelper() {
return group_state_helper_; }
291 const GroupStateHelperType& groupStateHelper()
const {
return group_state_helper_; }
292 std::pair<int, int> getGroupFipnumAndPvtreg()
const;
294 virtual void calcResvCoeff(
const int fipnum,
296 const std::vector<Scalar>& production_rates,
297 std::vector<Scalar>& resv_coeff)
const = 0;
298 virtual void calcInjResvCoeff(
const int fipnum,
300 std::vector<Scalar>& resv_coeff)
const = 0;
304 return *vfp_properties_;
307 void updateAndCommunicateGroupData(
const int reportStepIdx,
309 const Scalar tol_nupcol,
312 const bool update_wellgrouptarget);
314 const EclipseState& eclState()
const
315 {
return eclState_; }
347 return this->last_valid_wgstate_.well_state;
352 return this->last_valid_wgstate_;
362 this->last_valid_wgstate_ = std::move(wgstate);
372 this->active_wgstate_ = this->last_valid_wgstate_;
373 this->genNetwork_.resetState();
375 this->group_state_helper_.updateState(this->wellState(), this->groupState());
383 void updateNupcolWGState()
385 this->nupcol_wgstate_ = this->active_wgstate_;
388 void reportGroupSwitching(
DeferredLogger& local_deferredLogger)
const;
392 std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>
395 void initializeWellProdIndCalculators();
396 void initializeWellPerfData();
398 bool wasDynamicallyShutThisTimeStep(
const int well_index)
const;
400 void updateWsolvent(
const Group& group,
401 const int reportStepIdx,
403 void setWsolvent(
const Group& group,
404 const int reportStepIdx,
425 const int reportStepIndex)
const;
427 void assignWellTargets(data::Wells& wsrpt)
const;
428 void assignProductionWellTargets(
const Well& well, data::WellControlLimits& limits)
const;
429 void assignInjectionWellTargets(
const Well& well, data::WellControlLimits& limits)
const;
431 void assignGroupControl(
const Group& group,
432 data::GroupData& gdata)
const;
433 void assignGroupValues(
const int reportStepIdx,
434 std::map<std::string, data::GroupData>& gvalues)
const;
436 void calculateEfficiencyFactors(
const int reportStepIdx);
438 void checkGconsaleLimits(
const Group& group,
440 const int reportStepIdx,
443 void checkGEconLimits(
const Group& group,
444 const double simulation_time,
445 const int report_step_idx,
448 bool checkGroupHigherConstraints(
const Group& group,
450 const int reportStepIdx,
451 const int max_number_of_group_switch,
452 const bool update_group_switching_log);
454 void inferLocalShutWells();
456 void setRepRadiusPerfLength();
458 virtual void computePotentials(
const std::size_t widx,
460 std::string& exc_msg,
461 ExceptionType::ExcEnum& exc_type) = 0;
464 void updateWellPotentials(
const int reportStepIdx,
465 const bool onlyAfterEvent,
466 const SummaryConfig& summaryConfig,
474 void updateFiltrationModelsPostStep(
const double dt,
475 const std::size_t water_index,
478 void updateFiltrationModelsPreStep(
DeferredLogger& deferred_logger);
481 virtual void createWellContainer(
const int time_step) = 0;
482 virtual void initWellContainer(
const int reportStepIdx) = 0;
484 virtual void calculateProductivityIndexValuesShutWells(
const int reportStepIdx,
486 virtual void calculateProductivityIndexValues(
DeferredLogger& deferred_logger) = 0;
488 void runWellPIScaling(
const int reportStepIdx,
494 std::vector<std::vector<int>> getMaxWellConnections()
const;
496 std::vector<std::string> getWellsForTesting(
const int timeStepIdx,
497 const double simulationTime);
499 using WellTracerRates = std::unordered_map<int, std::vector<WellTracerRate<Scalar>>>;
500 void assignWellTracerRates(data::Wells& wsrpt,
501 const WellTracerRates& wellTracerRates,
502 const unsigned reportStep)
const;
504 using MswTracerRates = std::unordered_map<int, std::vector<MSWellTracerRate<Scalar>>>;
505 void assignMswTracerRates(data::Wells& wsrpt,
506 const MswTracerRates& mswTracerRates,
507 const unsigned reportStep)
const;
509 void assignMassGasRate(data::Wells& wsrpt,
510 const Scalar gasDensity)
const;
514 const SummaryState& summaryState_;
515 const EclipseState& eclState_;
516 const Parallel::Communication& comm_;
521 bool terminal_output_{
false};
522 bool wells_active_{
false};
523 bool initial_step_{};
524 bool report_step_starts_{};
526 std::optional<int> last_run_wellpi_{};
528 std::vector<Well> wells_ecl_;
529 std::vector<std::vector<PerforationData<Scalar>>> well_perf_data_;
532 std::map<std::string, double> well_open_times_;
535 std::map<std::string, double> well_close_times_;
537 std::vector<ConnectionIndexMap> conn_idx_map_{};
538 std::function<bool(
const std::string&)> not_on_process_{};
541 std::vector<WellInterfaceGeneric<Scalar, IndexTraits>*> well_container_generic_{};
543 std::vector<int> local_shut_wells_{};
545 std::vector<ParallelWellInfo<Scalar>> parallel_well_info_;
546 std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>> local_parallel_well_info_;
548 std::vector<WellProdIndexCalculator<Scalar>> prod_index_calc_;
550 std::vector<int> pvt_region_idx_;
552 mutable std::unordered_set<std::string> closed_this_step_;
554 GuideRate guideRate_;
555 std::unique_ptr<VFPProperties<Scalar, IndexTraits>> vfp_properties_{};
558 std::unordered_map<std::string, std::vector<Scalar>> prev_inj_multipliers_;
561 std::unordered_map<std::string, WellFilterCake<Scalar, IndexTraits>> filter_cake_;
569 WGState<Scalar, IndexTraits> active_wgstate_;
570 WGState<Scalar, IndexTraits> last_valid_wgstate_;
571 WGState<Scalar, IndexTraits> nupcol_wgstate_;
572 GroupStateHelperType group_state_helper_;
575 bool wellStructureChangedDynamically_{
false};
578 std::map<std::string, std::vector<Group::ProductionCMode>> switched_prod_groups_;
579 std::map<std::string, std::array<std::vector<Group::InjectionCMode>, 3>> switched_inj_groups_;
581 std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_;
588 template <
typename Iter,
typename Body>
589 void wellUpdateLoop(Iter first, Iter last,
const int timeStepIdx, Body&& body);
591 void updateEclWellsConstraints(
const int timeStepIdx,
592 const SimulatorUpdate& sim_update,
593 const SummaryState& st);
595 void updateEclWellsCTFFromAction(
const int timeStepIdx,
596 const SimulatorUpdate& sim_update);
611 template <
typename Predicate>
612 bool parallelWellSatisfies(
const std::string& wname, Predicate&& p)
const
614 const auto pwInfoPos =
615 std::ranges::find_if(this->parallel_well_info_,
616 [&wname](
const auto& pwInfo)
617 {
return pwInfo.name() == wname; });
619 return (pwInfoPos != this->parallel_well_info_.end())
638 template <
typename LoopBody>
639 void loopOwnedWells(LoopBody&& loopBody)
const;