23 #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
24 #include <opm/core/props/phaseUsageFromDeck.hpp>
26 #include <opm/input/eclipse/Units/UnitSystem.hpp>
28 #include <opm/simulators/wells/VFPProperties.hpp>
33 #include <fmt/format.h>
36 template<
typename TypeTag>
37 BlackoilWellModel<TypeTag>::
38 BlackoilWellModel(Simulator& ebosSimulator,
const PhaseUsage& phase_usage)
39 : BlackoilWellModelGeneric(ebosSimulator.vanguard().schedule(),
40 ebosSimulator.vanguard().summaryState(),
41 ebosSimulator.vanguard().eclState(),
43 ebosSimulator.gridView().comm())
44 , ebosSimulator_(ebosSimulator)
46 terminal_output_ = ((ebosSimulator.gridView().comm().rank() == 0) &&
47 EWOMS_GET_PARAM(TypeTag,
bool, EnableTerminalOutput));
49 local_num_cells_ = ebosSimulator_.gridView().size(0);
52 global_num_cells_ = ebosSimulator_.vanguard().globalNumCells();
55 auto& parallel_wells = ebosSimulator.vanguard().parallelWells();
57 this->parallel_well_info_.reserve(parallel_wells.size());
58 for(
const auto& name_bool: parallel_wells)
60 this->parallel_well_info_.emplace_back(name_bool,
61 ebosSimulator_.gridView().comm());
64 this->alternative_well_rate_init_ =
65 EWOMS_GET_PARAM(TypeTag,
bool, AlternativeWellRateInit);
68 template<
typename TypeTag>
69 BlackoilWellModel<TypeTag>::
70 BlackoilWellModel(Simulator& ebosSimulator) :
71 BlackoilWellModel(ebosSimulator,
phaseUsageFromDeck(ebosSimulator.vanguard().eclState()))
75 template<
typename TypeTag>
77 BlackoilWellModel<TypeTag>::
80 extractLegacyCellPvtRegionIndex_();
81 extractLegacyDepth_();
83 gravity_ = ebosSimulator_.problem().gravity()[2];
88 ebosSimulator_.model().addAuxiliaryModule(
this);
90 is_cell_perforated_.resize(local_num_cells_,
false);
94 template<
typename TypeTag>
96 BlackoilWellModel<TypeTag>::
99 for (
auto& wellPtr : this->well_container_) {
100 wellPtr->init(&this->phase_usage_, this->depth_, this->gravity_,
101 this->local_num_cells_, this->B_avg_);
105 template<
typename TypeTag>
107 BlackoilWellModel<TypeTag>::
108 addNeighbors(std::vector<NeighborSet>& neighbors)
const
110 if (!param_.matrix_add_well_contributions_) {
115 const auto& schedule_wells = schedule().getWellsatEnd();
118 for (
const auto& well : schedule_wells)
120 std::vector<int> wellCells;
122 const auto& connectionSet = well.getConnections();
123 wellCells.reserve(connectionSet.size());
125 for (
size_t c=0; c < connectionSet.size(); c++ )
127 const auto& connection = connectionSet.get(c);
128 int compressed_idx = compressedIndexForInterior(connection.global_index());
130 if ( compressed_idx >= 0 ) {
131 wellCells.push_back(compressed_idx);
135 for (
int cellIdx : wellCells) {
136 neighbors[cellIdx].insert(wellCells.begin(),
142 template<
typename TypeTag>
144 BlackoilWellModel<TypeTag>::
145 linearize(SparseMatrixAdapter& jacobian, GlobalEqVector& res)
147 if (!param_.matrix_add_well_contributions_)
149 OPM_BEGIN_PARALLEL_TRY_CATCH();
153 for (
const auto& well: well_container_) {
158 OPM_END_PARALLEL_TRY_CATCH(
"BlackoilWellModel::linearize failed: ",
159 ebosSimulator_.gridView().comm());
163 for (
const auto& well: well_container_) {
164 well->addWellContributions(jacobian);
173 template<
typename TypeTag>
175 BlackoilWellModel<TypeTag>::
176 beginReportStep(
const int timeStepIdx)
178 DeferredLogger local_deferredLogger;
180 report_step_starts_ =
true;
182 const Grid& grid = ebosSimulator_.vanguard().grid();
183 const auto& summaryState = ebosSimulator_.vanguard().summaryState();
185 wells_ecl_ = getLocalWells(timeStepIdx);
186 this->local_parallel_well_info_ = createLocalParallelWellInfo(wells_ecl_);
191 OPM_BEGIN_PARALLEL_TRY_CATCH();
196 this->initializeWellPerfData();
197 this->initializeWellState(timeStepIdx, summaryState);
201 wells_active_ = localWellsActive() ? 1 : 0;
202 wells_active_ = grid.comm().max(wells_active_);
205 if (param_.use_multisegment_well_&& anyMSWellOpenLocal()) {
206 this->wellState().initWellStateMSWell(wells_ecl_, &this->prevWellState());
209 const Group& fieldGroup = schedule().getGroup(
"FIELD", timeStepIdx);
210 WellGroupHelpers::setCmodeGroup(fieldGroup, schedule(), summaryState, timeStepIdx, this->wellState(), this->groupState());
213 rateConverter_.reset(
new RateConverterType (phase_usage_,
214 std::vector<int>(local_num_cells_, 0)));
215 rateConverter_->template defineState<ElementContext>(ebosSimulator_);
218 if (schedule_[timeStepIdx].has_gpmaint()) {
219 const auto& fp = this->eclState_.fieldProps();
220 const auto& fipnum = fp.get_int(
"FIPNUM");
221 regionalAveragePressureCalculator_.reset(
new AverageRegionalPressureType (phase_usage_,fipnum));
225 const auto& sched_state = this->schedule()[timeStepIdx];
227 vfp_properties_.reset(
new VFPProperties( sched_state.vfpinj(), sched_state.vfpprod()) );
228 this->initializeWellProdIndCalculators();
229 if (sched_state.events().hasEvent(ScheduleEvents::Events::WELL_PRODUCTIVITY_INDEX)) {
230 this->runWellPIScaling(timeStepIdx, local_deferredLogger);
234 OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"beginReportStep() failed: ",
235 terminal_output_, grid.comm());
237 this->commitWGState();
242 template<
typename TypeTag>
244 BlackoilWellModel<TypeTag>::
247 updatePerforationIntensiveQuantities();
248 updateAverageFormationFactor();
249 DeferredLogger local_deferredLogger;
251 this->resetWGState();
252 const int reportStepIdx = ebosSimulator_.episodeIndex();
253 updateAndCommunicateGroupData(reportStepIdx,
254 ebosSimulator_.model().newtonMethod().numIterations());
255 this->wellState().gliftTimeStepInit();
256 const double simulationTime = ebosSimulator_.time();
257 OPM_BEGIN_PARALLEL_TRY_CATCH();
260 wellTesting(reportStepIdx, simulationTime, local_deferredLogger);
263 createWellContainer(reportStepIdx);
268 this->initWellContainer();
271 std::fill(is_cell_perforated_.begin(), is_cell_perforated_.end(),
false);
272 for (
auto& well : well_container_) {
273 well->updatePerforatedCell(is_cell_perforated_);
277 calculateEfficiencyFactors(reportStepIdx);
279 if constexpr (has_polymer_)
281 if (PolymerModule::hasPlyshlog() || getPropValue<TypeTag, Properties::EnablePolymerMW>() ) {
282 setRepRadiusPerfLength();
287 OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"beginTimeStep() failed: ",
288 terminal_output_, ebosSimulator_.vanguard().grid().comm());
290 for (
auto& well : well_container_) {
291 well->setVFPProperties(vfp_properties_.get());
292 well->setGuideRate(&guideRate_);
296 for (
auto& well : well_container_) {
297 well->closeCompletions(wellTestState());
300 if (alternative_well_rate_init_) {
305 for (
auto& well : well_container_) {
306 if (well->isProducer()) {
307 well->updateWellStateRates(ebosSimulator_, this->wellState(), local_deferredLogger);
314 updateWellPotentials(reportStepIdx,
316 ebosSimulator_.vanguard().summaryConfig(),
317 local_deferredLogger);
318 }
catch ( std::runtime_error& e ) {
319 const std::string msg =
"A zero well potential is returned for output purposes. ";
320 local_deferredLogger.warning(
"WELL_POTENTIAL_CALCULATION_FAILED", msg);
324 const auto& comm = ebosSimulator_.vanguard().grid().comm();
325 const auto& summaryState = ebosSimulator_.vanguard().summaryState();
326 std::vector<double> pot(numPhases(), 0.0);
327 const Group& fieldGroup = schedule().getGroup(
"FIELD", reportStepIdx);
328 WellGroupHelpers::updateGuideRates(fieldGroup, schedule(), summaryState, this->phase_usage_, reportStepIdx, simulationTime,
329 this->wellState(), this->groupState(), comm, &this->guideRate_, pot, local_deferredLogger);
331 auto exc_type = ExceptionType::NONE;
333 if (schedule_[reportStepIdx].has_gpmaint()) {
334 regionalAveragePressureCalculator_->template defineState<ElementContext>(ebosSimulator_);
335 const double dt = ebosSimulator_.timeStepSize();
336 WellGroupHelpers::updateGpMaintTargetForGroups(fieldGroup,
337 schedule_, *regionalAveragePressureCalculator_, reportStepIdx, dt, this->wellState(), this->groupState());
341 for (
auto& well : well_container_) {
342 const uint64_t effective_events_mask = ScheduleEvents::WELL_STATUS_CHANGE
343 + ScheduleEvents::INJECTION_TYPE_CHANGED
344 + ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER
345 + ScheduleEvents::NEW_WELL;
347 const auto& events = schedule()[reportStepIdx].wellgroup_events();
348 const bool event = report_step_starts_ && events.hasEvent(well->name(), effective_events_mask);
349 const bool dyn_status_change = this->wellState().well(well->name()).status
350 != this->prevWellState().well(well->name()).status;
352 if (event || dyn_status_change) {
354 well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), local_deferredLogger);
355 well->calculateExplicitQuantities(ebosSimulator_, this->wellState(), local_deferredLogger);
356 well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), local_deferredLogger);
357 }
catch (
const std::exception& e) {
358 const std::string msg =
"Compute initial well solution for new well " + well->name() +
" failed. Continue with zero initial rates";
359 local_deferredLogger.warning(
"WELL_INITIAL_SOLVE_FAILED", msg);
365 OPM_PARALLEL_CATCH_CLAUSE(exc_type, exc_msg);
367 if (exc_type != ExceptionType::NONE) {
368 const std::string msg =
"Compute initial well solution for new wells failed. Continue with zero initial rates";
369 local_deferredLogger.warning(
"WELL_INITIAL_SOLVE_FAILED", msg);
372 logAndCheckForExceptionsAndThrow(local_deferredLogger,
373 exc_type,
"beginTimeStep() failed: " + exc_msg, terminal_output_, comm);
377 template<
typename TypeTag>
379 BlackoilWellModel<TypeTag>::wellTesting(
const int timeStepIdx,
380 const double simulationTime,
381 DeferredLogger& deferred_logger)
383 const auto& wtest_config = schedule()[timeStepIdx].wtest_config();
384 if (!wtest_config.empty()) {
385 const std::vector<std::string> wellsForTesting = wellTestState()
386 .test_wells(wtest_config, simulationTime);
387 for (
const std::string& well_name : wellsForTesting) {
389 const Well& wellEcl = schedule().getWell(well_name, timeStepIdx);
390 if (wellEcl.getStatus() == Well::Status::SHUT)
393 WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx, deferred_logger);
395 well->init(&phase_usage_, depth_, gravity_, local_num_cells_, B_avg_);
397 double well_efficiency_factor = wellEcl.getEfficiencyFactor();
398 WellGroupHelpers::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(), timeStepIdx),
399 schedule(), timeStepIdx, well_efficiency_factor);
401 well->setWellEfficiencyFactor(well_efficiency_factor);
402 well->setVFPProperties(vfp_properties_.get());
403 well->setGuideRate(&guideRate_);
405 well->wellTesting(ebosSimulator_, simulationTime, this->wellState(), this->groupState(), wellTestState(), deferred_logger);
415 template<
typename TypeTag>
417 BlackoilWellModel<TypeTag>::
421 for (
auto&& pinfo : this->local_parallel_well_info_)
432 template<
typename TypeTag>
433 const SimulatorReportSingle&
434 BlackoilWellModel<TypeTag>::
435 lastReport()
const {
return last_report_; }
442 template<
typename TypeTag>
444 BlackoilWellModel<TypeTag>::
445 timeStepSucceeded(
const double& simulationTime,
const double dt)
447 this->closed_this_step_.clear();
450 report_step_starts_ =
false;
451 const int reportStepIdx = ebosSimulator_.episodeIndex();
453 DeferredLogger local_deferredLogger;
454 for (
const auto& well : well_container_) {
455 if (getPropValue<TypeTag, Properties::EnablePolymerMW>() && well->isInjector()) {
456 well->updateWaterThroughput(dt, this->wellState());
460 for (
const auto& well : well_container_) {
461 well->reportWellSwitching(this->wellState().well(well->indexOfWell()), local_deferredLogger);
465 rateConverter_->template defineState<ElementContext>(ebosSimulator_);
469 updateWellPotentials(reportStepIdx,
471 ebosSimulator_.vanguard().summaryConfig(),
472 local_deferredLogger);
473 }
catch ( std::runtime_error& e ) {
474 const std::string msg =
"A zero well potential is returned for output purposes. ";
475 local_deferredLogger.warning(
"WELL_POTENTIAL_CALCULATION_FAILED", msg);
478 updateWellTestState(simulationTime, wellTestState());
481 const Group& fieldGroup = schedule_.getGroup(
"FIELD", reportStepIdx);
482 checkGconsaleLimits(fieldGroup, this->wellState(),
483 ebosSimulator_.episodeIndex(), local_deferredLogger);
485 this->calculateProductivityIndexValues(local_deferredLogger);
487 this->commitWGState();
489 const Opm::Parallel::Communication& comm = grid().comm();
491 if (terminal_output_) {
492 global_deferredLogger.logMessages();
496 this->computeWellTemperature();
500 template<
typename TypeTag>
501 template <
class Context>
503 BlackoilWellModel<TypeTag>::
504 computeTotalRatesForDof(RateVector& rate,
505 const Context& context,
507 unsigned timeIdx)
const
510 int elemIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
512 if (!is_cell_perforated_[elemIdx])
515 for (
const auto& well : well_container_)
516 well->addCellRates(rate, elemIdx);
521 template<
typename TypeTag>
523 BlackoilWellModel<TypeTag>::
524 initializeWellState(
const int timeStepIdx,
525 const SummaryState& summaryState)
527 std::vector<double> cellPressures(this->local_num_cells_, 0.0);
528 ElementContext elemCtx(ebosSimulator_);
530 const auto& gridView = ebosSimulator_.vanguard().gridView();
531 const auto& elemEndIt = gridView.template end<0>();
532 OPM_BEGIN_PARALLEL_TRY_CATCH();
534 for (
auto elemIt = gridView.template begin</*codim=*/0>();
538 if (elemIt->partitionType() != Dune::InteriorEntity) {
542 elemCtx.updatePrimaryStencil(*elemIt);
543 elemCtx.updatePrimaryIntensiveQuantities(0);
545 const auto& fs = elemCtx.intensiveQuantities(0, 0).fluidState();
547 double& perf_pressure = cellPressures[elemCtx.globalSpaceIndex(0, 0)];
548 if (Indices::oilEnabled) {
549 perf_pressure = fs.pressure(FluidSystem::oilPhaseIdx).value();
550 }
else if (Indices::waterEnabled) {
551 perf_pressure = fs.pressure(FluidSystem::waterPhaseIdx).value();
553 perf_pressure = fs.pressure(FluidSystem::gasPhaseIdx).value();
556 OPM_END_PARALLEL_TRY_CATCH(
"BlackoilWellModel::initializeWellState() failed: ", ebosSimulator_.vanguard().grid().comm());
558 this->wellState().init(cellPressures, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx,
559 &this->prevWellState(), well_perf_data_,
567 template<
typename TypeTag>
569 BlackoilWellModel<TypeTag>::
570 createWellContainer(
const int time_step)
572 DeferredLogger local_deferredLogger;
574 const int nw = numLocalWells();
576 well_container_.clear();
579 well_container_.reserve(nw);
581 for (
int w = 0; w < nw; ++w) {
582 const Well& well_ecl = wells_ecl_[w];
584 if (well_ecl.getConnections().empty()) {
589 const std::string& well_name = well_ecl.name();
590 const auto well_status = this->schedule()
591 .getWell(well_name, time_step).getStatus();
593 if ((well_ecl.getStatus() == Well::Status::SHUT) ||
594 (well_status == Well::Status::SHUT))
597 if (well_ecl.getStatus() != Well::Status::SHUT) {
598 this->closed_this_step_.insert(well_name);
599 this->wellState().shutWell(w);
606 if (this->wellTestState().well_is_closed(well_name)) {
609 auto& events = this->wellState().well(w).events;
610 if (events.hasEvent(WellState::event_mask)) {
611 if (wellTestState().lastTestTime(well_name) == ebosSimulator_.time()) {
616 events.clearEvent(WellState::event_mask);
618 wellTestState().open_well(well_name);
619 wellTestState().open_completions(well_name);
626 bool wellIsStopped =
false;
627 if (wellTestState().well_is_closed(well_name))
629 if (well_ecl.getAutomaticShutIn()) {
631 this->wellState().shutWell(w);
635 this->wellState().stopWell(w);
636 wellIsStopped =
true;
642 if (!well_ecl.getAllowCrossFlow() && well_ecl.isProducer() && well_ecl.predictionMode()) {
643 const auto& summaryState = ebosSimulator_.vanguard().summaryState();
644 const auto prod_controls = well_ecl.productionControls(summaryState);
646 auto is_zero = [](
const double x)
648 return std::isfinite(x) && !std::isnormal(x);
651 bool zero_rate_control =
false;
652 switch (prod_controls.cmode) {
653 case Well::ProducerCMode::ORAT:
654 zero_rate_control = is_zero(prod_controls.oil_rate);
657 case Well::ProducerCMode::WRAT:
658 zero_rate_control = is_zero(prod_controls.water_rate);
661 case Well::ProducerCMode::GRAT:
662 zero_rate_control = is_zero(prod_controls.gas_rate);
665 case Well::ProducerCMode::LRAT:
666 zero_rate_control = is_zero(prod_controls.liquid_rate);
669 case Well::ProducerCMode::RESV:
670 zero_rate_control = is_zero(prod_controls.resv_rate);
675 zero_rate_control =
false;
679 if (zero_rate_control) {
681 local_deferredLogger.info(
" Well shut due to zero rate control and disallowing crossflow: " + well_ecl.name());
682 this->wellState().shutWell(w);
687 if (well_status == Well::Status::STOP) {
688 this->wellState().stopWell(w);
689 wellIsStopped =
true;
692 well_container_.emplace_back(this->createWellPointer(w, time_step));
695 well_container_.back()->stopWell();
701 const Opm::Parallel::Communication& comm = grid().comm();
703 if (terminal_output_) {
704 global_deferredLogger.logMessages();
707 well_container_generic_.clear();
708 for (
auto& w : well_container_)
709 well_container_generic_.push_back(w.get());
716 template <
typename TypeTag>
717 typename BlackoilWellModel<TypeTag>::WellInterfacePtr
718 BlackoilWellModel<TypeTag>::
719 createWellPointer(
const int wellID,
const int time_step)
const
721 const auto is_multiseg = this->wells_ecl_[wellID].isMultiSegment();
723 if (! (this->param_.use_multisegment_well_ && is_multiseg)) {
724 return this->
template createTypedWellPointer<StandardWell<TypeTag>>(wellID, time_step);
727 return this->
template createTypedWellPointer<MultisegmentWell<TypeTag>>(wellID, time_step);
735 template <
typename TypeTag>
736 template <
typename WellType>
737 std::unique_ptr<WellType>
738 BlackoilWellModel<TypeTag>::
739 createTypedWellPointer(
const int wellID,
const int time_step)
const
742 const auto& perf_data = this->well_perf_data_[wellID];
745 const auto pvtreg = perf_data.empty()
746 ? 0 : pvt_region_idx_[perf_data.front().cell_index];
748 const auto& parallel_well_info = this->local_parallel_well_info_[wellID].get();
749 const auto global_pvtreg = parallel_well_info.broadcastFirstPerforationValue(pvtreg);
751 return std::make_unique<WellType>(this->wells_ecl_[wellID],
755 *this->rateConverter_,
757 this->numComponents(),
767 template<
typename TypeTag>
768 typename BlackoilWellModel<TypeTag>::WellInterfacePtr
769 BlackoilWellModel<TypeTag>::
770 createWellForWellTest(
const std::string& well_name,
771 const int report_step,
772 DeferredLogger& deferred_logger)
const
775 const int nw_wells_ecl = wells_ecl_.size();
776 int index_well_ecl = 0;
777 for (; index_well_ecl < nw_wells_ecl; ++index_well_ecl) {
778 if (well_name == wells_ecl_[index_well_ecl].name()) {
783 if (index_well_ecl == nw_wells_ecl) {
784 OPM_DEFLOG_THROW(std::logic_error,
"Could not find well " << well_name <<
" in wells_ecl ", deferred_logger);
787 return this->createWellPointer(index_well_ecl, report_step);
794 template<
typename TypeTag>
796 BlackoilWellModel<TypeTag>::
797 assemble(
const int iterationIdx,
801 DeferredLogger local_deferredLogger;
802 if (this->glift_debug) {
803 const std::string msg = fmt::format(
804 "assemble() : iteration {}" , iterationIdx);
805 gliftDebug(msg, local_deferredLogger);
807 last_report_ = SimulatorReportSingle();
808 Dune::Timer perfTimer;
811 if ( ! wellsActive() ) {
816 updatePerforationIntensiveQuantities();
818 if (iterationIdx == 0) {
823 OPM_BEGIN_PARALLEL_TRY_CATCH();
825 calculateExplicitQuantities(local_deferredLogger);
826 prepareTimeStep(local_deferredLogger);
828 OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"assemble() failed (It=0): ",
829 terminal_output_, grid().comm());
831 updateWellControls(local_deferredLogger,
true);
833 bool alq_updated =
false;
834 OPM_BEGIN_PARALLEL_TRY_CATCH();
837 initPrimaryVariablesEvaluation();
839 alq_updated = maybeDoGasLiftOptimize(local_deferredLogger);
840 assembleWellEq(dt, local_deferredLogger);
842 OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"assemble() failed: ",
843 terminal_output_, grid().comm());
846 const int reportStepIdx = ebosSimulator_.episodeIndex();
847 if (alq_updated || guideRateUpdateIsNeeded(reportStepIdx)) {
848 const double simulationTime = ebosSimulator_.time();
849 const auto& comm = ebosSimulator_.vanguard().grid().comm();
850 const auto& summaryState = ebosSimulator_.vanguard().summaryState();
851 std::vector<double> pot(numPhases(), 0.0);
852 const Group& fieldGroup = schedule().getGroup(
"FIELD", reportStepIdx);
853 WellGroupHelpers::updateGuideRates(fieldGroup, schedule(), summaryState, this->phase_usage_, reportStepIdx, simulationTime,
854 this->wellState(), this->groupState(), comm, &this->guideRate_, pot, local_deferredLogger);
856 last_report_.converged =
true;
857 last_report_.assemble_time_well += perfTimer.stop();
860 template<
typename TypeTag>
862 BlackoilWellModel<TypeTag>::
863 maybeDoGasLiftOptimize(DeferredLogger& deferred_logger)
865 bool do_glift_optimization =
false;
866 int num_wells_changed = 0;
867 const double simulation_time = ebosSimulator_.time();
868 const double min_wait = ebosSimulator_.vanguard().schedule().glo(ebosSimulator_.episodeIndex()).min_wait();
873 if ( simulation_time == last_glift_opt_time_ || simulation_time >= (last_glift_opt_time_ + min_wait)) {
874 do_glift_optimization =
true;
875 last_glift_opt_time_ = simulation_time;
878 if (do_glift_optimization) {
879 GLiftOptWells glift_wells;
880 GLiftProdWells prod_wells;
881 GLiftWellStateMap state_map;
889 GLiftEclWells ecl_well_map;
890 initGliftEclWellMap(ecl_well_map);
891 GasLiftGroupInfo group_info {
893 ebosSimulator_.vanguard().schedule(),
894 ebosSimulator_.vanguard().summaryState(),
895 ebosSimulator_.episodeIndex(),
896 ebosSimulator_.model().newtonMethod().numIterations(),
900 ebosSimulator_.vanguard().grid().comm(),
903 group_info.initialize();
904 gasLiftOptimizationStage1(
905 deferred_logger, prod_wells, glift_wells, group_info, state_map);
906 gasLiftOptimizationStage2(
907 deferred_logger, prod_wells, glift_wells, state_map,
908 ebosSimulator_.episodeIndex());
909 if (this->glift_debug) gliftDebugShowALQ(deferred_logger);
910 num_wells_changed = glift_wells.size();
912 num_wells_changed = this->comm_.sum(num_wells_changed);
913 return num_wells_changed > 0;
916 template<
typename TypeTag>
918 BlackoilWellModel<TypeTag>::
919 gasLiftOptimizationStage1(DeferredLogger& deferred_logger,
920 GLiftProdWells &prod_wells, GLiftOptWells &glift_wells,
921 GasLiftGroupInfo &group_info, GLiftWellStateMap &state_map)
923 auto comm = ebosSimulator_.vanguard().grid().comm();
924 int num_procs = comm.size();
950 for (
int i = 0; i< num_procs; i++) {
951 int num_rates_to_sync = 0;
952 GLiftSyncGroups groups_to_sync;
953 if (comm.rank() == i) {
955 for (
const auto& well : well_container_) {
957 if (group_info.hasWell(well->name())) {
958 gasLiftOptimizationStage1SingleWell(
959 well.get(), deferred_logger, prod_wells, glift_wells,
960 group_info, state_map, groups_to_sync
964 num_rates_to_sync = groups_to_sync.size();
968 if (i == (num_procs - 1))
970 num_rates_to_sync = comm.sum(num_rates_to_sync);
971 if (num_rates_to_sync > 0) {
972 std::vector<int> group_indexes;
973 group_indexes.reserve(num_rates_to_sync);
974 std::vector<double> group_alq_rates;
975 group_alq_rates.reserve(num_rates_to_sync);
976 std::vector<double> group_oil_rates;
977 group_oil_rates.reserve(num_rates_to_sync);
978 std::vector<double> group_gas_rates;
979 group_gas_rates.reserve(num_rates_to_sync);
980 std::vector<double> group_water_rates;
981 group_water_rates.reserve(num_rates_to_sync);
982 if (comm.rank() == i) {
983 for (
auto idx : groups_to_sync) {
984 auto [oil_rate, gas_rate, water_rate, alq] = group_info.getRates(idx);
985 group_indexes.push_back(idx);
986 group_oil_rates.push_back(oil_rate);
987 group_gas_rates.push_back(gas_rate);
988 group_water_rates.push_back(water_rate);
989 group_alq_rates.push_back(alq);
992 group_indexes.resize(num_rates_to_sync);
993 group_oil_rates.resize(num_rates_to_sync);
994 group_gas_rates.resize(num_rates_to_sync);
995 group_water_rates.resize(num_rates_to_sync);
996 group_alq_rates.resize(num_rates_to_sync);
1006 Mpi::broadcast(comm, i, group_indexes, group_oil_rates,
1007 group_gas_rates, group_water_rates, group_alq_rates);
1008 if (comm.rank() != i) {
1009 for (
int j=0; j<num_rates_to_sync; j++) {
1010 group_info.updateRate(group_indexes[j],
1011 group_oil_rates[j], group_gas_rates[j], group_water_rates[j], group_alq_rates[j]);
1014 if (this->glift_debug) {
1016 if (comm.rank() == i) {
1017 counter = this->wellState().gliftGetDebugCounter();
1019 counter = comm.sum(counter);
1020 if (comm.rank() != i) {
1021 this->wellState().gliftSetDebugCounter(counter);
1031 template<
typename TypeTag>
1033 BlackoilWellModel<TypeTag>::
1034 gasLiftOptimizationStage1SingleWell(WellInterface<TypeTag> *well,
1035 DeferredLogger& deferred_logger,
1036 GLiftProdWells &prod_wells, GLiftOptWells &glift_wells,
1037 GasLiftGroupInfo &group_info, GLiftWellStateMap &state_map,
1038 GLiftSyncGroups& sync_groups)
1040 const auto& summary_state = ebosSimulator_.vanguard().summaryState();
1041 std::unique_ptr<GasLiftSingleWell> glift
1042 = std::make_unique<GasLiftSingleWell>(
1043 *well, ebosSimulator_, summary_state,
1044 deferred_logger, this->wellState(), this->groupState(),
1045 group_info, sync_groups, this->comm_, this->glift_debug);
1046 auto state = glift->runOptimize(
1047 ebosSimulator_.model().newtonMethod().numIterations());
1049 state_map.insert({well->name(), std::move(state)});
1050 glift_wells.insert({well->name(), std::move(glift)});
1053 prod_wells.insert({well->name(), well});
1057 template<
typename TypeTag>
1059 BlackoilWellModel<TypeTag>::
1060 initGliftEclWellMap(GLiftEclWells &ecl_well_map)
1062 for (
const auto& well: well_container_ ) {
1063 ecl_well_map.try_emplace(
1064 well->name(), &(well->wellEcl()), well->indexOfWell());
1069 template<
typename TypeTag>
1071 BlackoilWellModel<TypeTag>::
1072 assembleWellEq(
const double dt, DeferredLogger& deferred_logger)
1074 for (
auto& well : well_container_) {
1075 well->assembleWellEq(ebosSimulator_, dt, this->wellState(), this->groupState(), deferred_logger);
1079 template<
typename TypeTag>
1081 BlackoilWellModel<TypeTag>::
1082 apply( BVector& r)
const
1084 if ( ! localWellsActive() ) {
1088 for (
auto& well : well_container_) {
1095 template<
typename TypeTag>
1097 BlackoilWellModel<TypeTag>::
1098 apply(
const BVector& x, BVector& Ax)
const
1101 if ( ! localWellsActive() ) {
1105 for (
auto& well : well_container_) {
1110 #if HAVE_CUDA || HAVE_OPENCL
1111 template<
typename TypeTag>
1113 BlackoilWellModel<TypeTag>::
1114 getWellContributions(WellContributions& wellContribs)
const
1117 wellContribs.setBlockSize(StandardWell<TypeTag>::Indices::numEq, StandardWell<TypeTag>::numStaticWellEq);
1119 for(
unsigned int i = 0; i < well_container_.size(); i++){
1120 auto& well = well_container_[i];
1121 std::shared_ptr<StandardWell<TypeTag> > derived = std::dynamic_pointer_cast<StandardWell<TypeTag> >(well);
1123 unsigned int numBlocks;
1124 derived->getNumBlocks(numBlocks);
1125 wellContribs.addNumBlocks(numBlocks);
1130 wellContribs.alloc();
1132 for(
unsigned int i = 0; i < well_container_.size(); i++){
1133 auto& well = well_container_[i];
1135 auto derived_std = std::dynamic_pointer_cast<StandardWell<TypeTag> >(well);
1137 derived_std->addWellContribution(wellContribs);
1139 auto derived_ms = std::dynamic_pointer_cast<MultisegmentWell<TypeTag> >(well);
1141 derived_ms->addWellContribution(wellContribs);
1143 OpmLog::warning(
"Warning unknown type of well");
1151 template<
typename TypeTag>
1153 BlackoilWellModel<TypeTag>::
1154 applyScaleAdd(
const Scalar alpha,
const BVector& x, BVector& Ax)
const
1156 if ( ! localWellsActive() ) {
1160 if( scaleAddRes_.size() != Ax.size() ) {
1161 scaleAddRes_.resize( Ax.size() );
1166 apply( x, scaleAddRes_ );
1168 Ax.axpy( alpha, scaleAddRes_ );
1175 template<
typename TypeTag>
1177 BlackoilWellModel<TypeTag>::
1178 recoverWellSolutionAndUpdateWellState(
const BVector& x)
1181 DeferredLogger local_deferredLogger;
1182 OPM_BEGIN_PARALLEL_TRY_CATCH();
1184 if (localWellsActive()) {
1185 for (
auto& well : well_container_) {
1186 well->recoverWellSolutionAndUpdateWellState(x, this->wellState(), local_deferredLogger);
1191 OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
1192 "recoverWellSolutionAndUpdateWellState() failed: ",
1193 terminal_output_, ebosSimulator_.vanguard().grid().comm());
1200 template<
typename TypeTag>
1202 BlackoilWellModel<TypeTag>::
1203 initPrimaryVariablesEvaluation()
const
1205 for (
auto& well : well_container_) {
1206 well->initPrimaryVariablesEvaluation();
1215 template<
typename TypeTag>
1217 BlackoilWellModel<TypeTag>::
1218 getWellConvergence(
const std::vector<Scalar>& B_avg,
bool checkGroupConvergence)
const
1221 DeferredLogger local_deferredLogger;
1223 ConvergenceReport local_report;
1224 const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations();
1225 for (
const auto& well : well_container_) {
1226 if (well->isOperableAndSolvable() || well->wellIsStopped()) {
1227 local_report += well->getWellConvergence(this->wellState(), B_avg, local_deferredLogger, iterationIdx > param_.strict_outer_iter_wells_ );
1229 ConvergenceReport report;
1230 using CR = ConvergenceReport;
1231 report.setWellFailed({CR::WellFailure::Type::Unsolvable, CR::Severity::Normal, -1, well->name()});
1232 local_report += report;
1236 const Opm::Parallel::Communication comm = grid().comm();
1238 if (terminal_output_) {
1239 global_deferredLogger.logMessages();
1242 ConvergenceReport report = gatherConvergenceReport(local_report, comm);
1245 if (terminal_output_) {
1246 for (
const auto& f : report.wellFailures()) {
1247 if (f.severity() == ConvergenceReport::Severity::NotANumber) {
1248 OpmLog::debug(
"NaN residual found with phase " + std::to_string(f.phase()) +
" for well " + f.wellName());
1249 }
else if (f.severity() == ConvergenceReport::Severity::TooLarge) {
1250 OpmLog::debug(
"Too large residual found with phase " + std::to_string(f.phase()) +
" for well " + f.wellName());
1255 if (checkGroupConvergence) {
1256 const int reportStepIdx = ebosSimulator_.episodeIndex();
1257 const Group& fieldGroup = schedule().getGroup(
"FIELD", reportStepIdx);
1258 bool violated = checkGroupConstraints(fieldGroup,
1259 ebosSimulator_.episodeIndex(),
1260 global_deferredLogger);
1261 report.setGroupConverged(!violated);
1270 template<
typename TypeTag>
1276 for (
auto& well : well_container_) {
1285 template<
typename TypeTag>
1293 if( !wellsActive() ) return ;
1295 const int episodeIdx = ebosSimulator_.episodeIndex();
1296 const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations();
1297 const auto& comm = ebosSimulator_.vanguard().grid().comm();
1298 updateAndCommunicateGroupData(episodeIdx, iterationIdx);
1300 updateNetworkPressures(episodeIdx);
1302 std::set<std::string> switched_wells;
1303 std::set<std::string> switched_groups;
1305 if (checkGroupControls) {
1307 bool changed_individual = updateGroupIndividualControls(deferred_logger, switched_groups,
1308 episodeIdx, iterationIdx);
1310 if (changed_individual)
1311 updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
1314 bool changed_higher = updateGroupHigherControls(deferred_logger,
1319 updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
1322 bool changed_well_group =
false;
1323 for (
const auto& well : well_container_) {
1325 const bool changed_well = well->updateWellControl(ebosSimulator_, mode, this->wellState(), this->groupState(), deferred_logger);
1327 switched_wells.insert(well->name());
1328 changed_well_group = changed_well || changed_well_group;
1331 changed_well_group = comm.sum(changed_well_group);
1332 if (changed_well_group)
1333 updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
1337 bool changed_well_individual =
false;
1338 for (
const auto& well : well_container_) {
1339 if (switched_wells.count(well->name())) {
1342 const auto mode = WellInterface<TypeTag>::IndividualOrGroup::Individual;
1343 const bool changed_well = well->updateWellControl(ebosSimulator_, mode, this->wellState(), this->groupState(), deferred_logger);
1345 changed_well_individual = changed_well || changed_well_individual;
1348 changed_well_individual = comm.sum(changed_well_individual);
1349 if (changed_well_individual)
1350 updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
1353 const Group& fieldGroup = schedule().getGroup(
"FIELD", episodeIdx);
1354 updateWsolvent(fieldGroup, episodeIdx, this->nupcolWellState());
1358 template<
typename TypeTag>
1360 BlackoilWellModel<TypeTag>::
1361 updateAndCommunicate(
const int reportStepIdx,
1362 const int iterationIdx,
1363 DeferredLogger& deferred_logger)
1365 updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
1367 for (
const auto& well : well_container_) {
1368 well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), deferred_logger);
1370 updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
1373 template<
typename TypeTag>
1379 for (
const auto& well : well_container_) {
1380 const auto& wname = well->name();
1381 const auto wasClosed = wellTestState.well_is_closed(wname);
1382 well->checkWellOperability(ebosSimulator_, this->wellState(), local_deferredLogger);
1383 well->updateWellTestState(this->wellState().well(wname), simulationTime,
true, wellTestState, local_deferredLogger);
1385 if (!wasClosed && wellTestState.well_is_closed(wname)) {
1386 this->closed_this_step_.insert(wname);
1390 const Opm::Parallel::Communication comm = grid().comm();
1392 if (terminal_output_) {
1398 template<
typename TypeTag>
1402 std::string& exc_msg,
1403 ExceptionType::ExcEnum& exc_type,
1406 const int np = numPhases();
1407 std::vector<double> potentials;
1408 const auto& well= well_container_[widx];
1410 well->computeWellPotentials(ebosSimulator_, well_state_copy, potentials, deferred_logger);
1413 OPM_PARALLEL_CATCH_CLAUSE(exc_type, exc_msg);
1417 auto& ws = this->wellState().well(well->indexOfWell());
1418 for (
int p = 0; p < np; ++p) {
1420 ws.well_potentials[p] = std::max(0.0, potentials[p]);
1426 template <
typename TypeTag>
1428 BlackoilWellModel<TypeTag>::
1429 calculateProductivityIndexValues(DeferredLogger& deferred_logger)
1431 for (
const auto& wellPtr : this->well_container_) {
1432 this->calculateProductivityIndexValues(wellPtr.get(), deferred_logger);
1440 template <
typename TypeTag>
1442 BlackoilWellModel<TypeTag>::
1443 calculateProductivityIndexValuesShutWells(
const int reportStepIdx,
1444 DeferredLogger& deferred_logger)
1451 for (
const auto& shutWell : this->local_shut_wells_) {
1452 if (this->wells_ecl_[shutWell].getConnections().empty()) {
1457 auto wellPtr = this->
template createTypedWellPointer
1458 <StandardWell<TypeTag>>(shutWell, reportStepIdx);
1460 wellPtr->init(&this->phase_usage_, this->depth_, this->gravity_,
1461 this->local_num_cells_, this->B_avg_);
1463 this->calculateProductivityIndexValues(wellPtr.get(), deferred_logger);
1471 template <
typename TypeTag>
1473 BlackoilWellModel<TypeTag>::
1474 calculateProductivityIndexValues(
const WellInterface<TypeTag>* wellPtr,
1475 DeferredLogger& deferred_logger)
1477 wellPtr->updateProductivityIndex(this->ebosSimulator_,
1478 this->prod_index_calc_[wellPtr->indexOfWell()],
1487 template<
typename TypeTag>
1489 BlackoilWellModel<TypeTag>::
1490 prepareTimeStep(DeferredLogger& deferred_logger)
1492 for (
const auto& well : well_container_) {
1493 auto& events = this->wellState().well(well->indexOfWell()).events;
1494 if (events.hasEvent(WellState::event_mask)) {
1495 well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), deferred_logger);
1498 events.clearEvent(WellState::event_mask);
1501 if (param_.solve_welleq_initially_ && well->isOperableAndSolvable()) {
1503 well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), deferred_logger);
1504 }
catch (
const std::exception& e) {
1505 const std::string msg =
"Compute initial well solution for " + well->name() +
" initially failed. Continue with the privious rates";
1506 deferred_logger.warning(
"WELL_INITIAL_SOLVE_FAILED", msg);
1510 updatePrimaryVariables(deferred_logger);
1516 template<
typename TypeTag>
1518 BlackoilWellModel<TypeTag>::
1519 updateAverageFormationFactor()
1521 std::vector< Scalar > B_avg(numComponents(), Scalar() );
1522 const auto& grid = ebosSimulator_.vanguard().grid();
1523 const auto& gridView = grid.leafGridView();
1524 ElementContext elemCtx(ebosSimulator_);
1525 const auto& elemEndIt = gridView.template end<0, Dune::Interior_Partition>();
1526 OPM_BEGIN_PARALLEL_TRY_CATCH();
1528 for (
auto elemIt = gridView.template begin</*codim=*/0, Dune::Interior_Partition>();
1529 elemIt != elemEndIt; ++elemIt)
1531 elemCtx.updatePrimaryStencil(*elemIt);
1532 elemCtx.updatePrimaryIntensiveQuantities(0);
1534 const auto& intQuants = elemCtx.intensiveQuantities(0, 0);
1535 const auto& fs = intQuants.fluidState();
1537 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
1539 if (!FluidSystem::phaseIsActive(phaseIdx)) {
1543 const unsigned compIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::solventComponentIndex(phaseIdx));
1544 auto& B = B_avg[ compIdx ];
1546 B += 1 / fs.invB(phaseIdx).value();
1548 if constexpr (has_solvent_) {
1549 auto& B = B_avg[solventSaturationIdx];
1550 B += 1 / intQuants.solventInverseFormationVolumeFactor().value();
1553 OPM_END_PARALLEL_TRY_CATCH(
"BlackoilWellModel::updateAverageFormationFactor() failed: ", grid.comm())
1556 grid.comm().sum(B_avg.data(), B_avg.size());
1557 for(auto& bval: B_avg)
1559 bval/=global_num_cells_;
1568 template<
typename TypeTag>
1570 BlackoilWellModel<TypeTag>::
1571 updatePrimaryVariables(DeferredLogger& deferred_logger)
1573 for (
const auto& well : well_container_) {
1574 well->updatePrimaryVariables(this->wellState(), deferred_logger);
1578 template<
typename TypeTag>
1580 BlackoilWellModel<TypeTag>::extractLegacyCellPvtRegionIndex_()
1582 const auto& grid = ebosSimulator_.vanguard().grid();
1583 const auto& eclProblem = ebosSimulator_.problem();
1584 const unsigned numCells = grid.size(0);
1586 pvt_region_idx_.resize(numCells);
1587 for (
unsigned cellIdx = 0; cellIdx < numCells; ++cellIdx) {
1588 pvt_region_idx_[cellIdx] =
1589 eclProblem.pvtRegionIndex(cellIdx);
1594 template<
typename TypeTag>
1596 BlackoilWellModel<TypeTag>::numComponents()
const
1598 if (wellsActive() && numPhases() < 3) {
1601 int numComp = FluidSystem::numComponents;
1602 if constexpr (has_solvent_) {
1609 template<
typename TypeTag>
1611 BlackoilWellModel<TypeTag>::extractLegacyDepth_()
1613 const auto& grid = ebosSimulator_.vanguard().grid();
1614 const unsigned numCells = grid.size(0);
1616 depth_.resize(numCells);
1617 for (
unsigned cellIdx = 0; cellIdx < numCells; ++cellIdx) {
1618 depth_[cellIdx] = UgGridHelpers::cellCenterDepth( grid, cellIdx );
1622 template<
typename TypeTag>
1624 BlackoilWellModel<TypeTag>::
1625 updatePerforationIntensiveQuantities() {
1626 ElementContext elemCtx(ebosSimulator_);
1627 const auto& gridView = ebosSimulator_.gridView();
1628 const auto& elemEndIt = gridView.template end<0, Dune::Interior_Partition>();
1629 OPM_BEGIN_PARALLEL_TRY_CATCH();
1630 for (
auto elemIt = gridView.template begin</*codim=*/0, Dune::Interior_Partition>();
1631 elemIt != elemEndIt;
1635 elemCtx.updatePrimaryStencil(*elemIt);
1636 int elemIdx = elemCtx.globalSpaceIndex(0, 0);
1638 if (!is_cell_perforated_[elemIdx]) {
1641 elemCtx.updatePrimaryIntensiveQuantities(0);
1643 OPM_END_PARALLEL_TRY_CATCH(
"BlackoilWellModel::updatePerforationIntensiveQuantities() failed: ", ebosSimulator_.vanguard().grid().comm());
1647 template<
typename TypeTag>
1648 typename BlackoilWellModel<TypeTag>::WellInterfacePtr
1649 BlackoilWellModel<TypeTag>::
1650 getWell(
const std::string& well_name)
const
1653 auto well = std::find_if(well_container_.begin(),
1654 well_container_.end(),
1655 [&well_name](
const WellInterfacePtr& elem)->bool {
1656 return elem->name() == well_name;
1659 assert(well != well_container_.end());
1664 template<
typename TypeTag>
1666 BlackoilWellModel<TypeTag>::
1667 hasWell(
const std::string& well_name)
const
1669 return std::any_of(well_container_.begin(), well_container_.end(),
1670 [&well_name](
const WellInterfacePtr& elem) ->
bool
1672 return elem->name() == well_name;
1679 template <
typename TypeTag>
1681 BlackoilWellModel<TypeTag>::
1682 reportStepIndex()
const
1684 return std::max(this->ebosSimulator_.episodeIndex(), 0);
1691 template<
typename TypeTag>
1693 BlackoilWellModel<TypeTag>::
1694 calcRates(
const int fipnum,
1696 std::vector<double>& resv_coeff)
1698 rateConverter_->calcCoeff(fipnum, pvtreg, resv_coeff);
1701 template<
typename TypeTag>
1703 BlackoilWellModel<TypeTag>::
1704 calcInjRates(
const int fipnum,
1706 std::vector<double>& resv_coeff)
1708 rateConverter_->calcInjCoeff(fipnum, pvtreg, resv_coeff);
1712 template <
typename TypeTag>
1714 BlackoilWellModel<TypeTag>::
1715 computeWellTemperature()
1720 int np = numPhases();
1721 double cellInternalEnergy;
1724 double perfPhaseRate;
1725 const int nw = numLocalWells();
1726 for (
auto wellID = 0*nw; wellID < nw; ++wellID) {
1727 const Well& well = wells_ecl_[wellID];
1728 if (well.isInjector())
1732 for (
int i = 0; i < wellID; ++i) {
1733 connpos += well_perf_data_[i].size();
1736 double weighted_temperature = 0.0;
1737 double total_weight = 0.0;
1739 auto& well_info = local_parallel_well_info_[wellID].get();
1740 const int num_perf_this_well = well_info.communication().sum(well_perf_data_[wellID].size());
1741 auto& ws = this->wellState().well(wellID);
1742 auto& perf_data = ws.perf_data;
1743 auto& perf_phase_rate = perf_data.phase_rates;
1745 for (
int perf = 0; perf < num_perf_this_well; ++perf) {
1746 const int cell_idx = well_perf_data_[wellID][perf].cell_index;
1747 const auto& intQuants = *(ebosSimulator_.model().cachedIntensiveQuantities(cell_idx, 0));
1748 const auto& fs = intQuants.fluidState();
1751 double cellTemperatures = fs.temperature(0).value();
1753 double weight_factor = 0.0;
1754 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
1756 if (!FluidSystem::phaseIsActive(phaseIdx)) {
1759 cellInternalEnergy = fs.enthalpy(phaseIdx).value() - fs.pressure(phaseIdx).value() / fs.density(phaseIdx).value();
1760 cellBinv = fs.invB(phaseIdx).value();
1761 cellDensity = fs.density(phaseIdx).value();
1762 perfPhaseRate = perf_phase_rate[ perf*np + phaseIdx ];
1763 weight_factor += cellDensity * perfPhaseRate/cellBinv * cellInternalEnergy/cellTemperatures;
1765 total_weight += weight_factor;
1766 weighted_temperature += weight_factor * cellTemperatures;
1768 weighted_temperature = well_info.communication().sum(weighted_temperature);
1769 total_weight = well_info.communication().sum(total_weight);
1770 this->wellState().well(wellID).temperature = weighted_temperature/total_weight;
1776 template <
typename TypeTag>
1778 BlackoilWellModel<TypeTag>::
1779 assignWellTracerRates(data::Wells& wsrpt)
const
1781 const auto & wellTracerRates = ebosSimulator_.problem().tracerModel().getWellTracerRates();
1783 if (wellTracerRates.empty())
1786 for (
const auto& wTR : wellTracerRates) {
1787 std::string wellName = wTR.first.first;
1788 auto xwPos = wsrpt.find(wellName);
1789 if (xwPos == wsrpt.end()) {
1792 std::string tracerName = wTR.first.second;
1793 double rate = wTR.second;
1794 xwPos->second.rates.set(data::Rates::opt::tracer, rate, tracerName);
Class for handling the blackoil well model.
Definition: BlackoilWellModel.hpp:94
void calculateExplicitQuantities(DeferredLogger &deferred_logger) const
Calculating the explict quantities used in the well calculation.
Definition: BlackoilWellModel_impl.hpp:1273
Definition: DeferredLogger.hpp:57
void logMessages()
Log all messages to the OpmLog backends, and clear the message container.
Definition: DeferredLogger.cpp:85
Definition: WellInterface.hpp:72
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition: WellState.hpp:56
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27
Opm::DeferredLogger gatherDeferredLogger(const Opm::DeferredLogger &local_deferredlogger, Opm::Parallel::Communication)
Create a global log combining local logs.
Definition: gatherDeferredLogger.cpp:168
PhaseUsage phaseUsageFromDeck(const EclipseState &eclipseState)
Looks at presence of WATER, OIL and GAS keywords in state object to determine active phases.
Definition: phaseUsageFromDeck.cpp:141