From 0c8d0764d61e266a697dd55546b1be25232abb9a Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Tue, 8 Feb 2022 15:46:08 +0100 Subject: [PATCH] update well potensials in well state along with alq and update guide rates accordingly --- opm/simulators/wells/BlackoilWellModel.hpp | 2 +- .../wells/BlackoilWellModel_impl.hpp | 13 ++++++++---- .../wells/GasLiftSingleWellGeneric.cpp | 20 +++++++++++++++---- .../wells/GasLiftSingleWellGeneric.hpp | 5 +++++ opm/simulators/wells/GasLiftStage2.cpp | 14 +++++++++++-- opm/simulators/wells/GasLiftWellState.hpp | 8 ++++++-- 6 files changed, 49 insertions(+), 13 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel.hpp b/opm/simulators/wells/BlackoilWellModel.hpp index 5810d75f4..1f1d63e17 100644 --- a/opm/simulators/wells/BlackoilWellModel.hpp +++ b/opm/simulators/wells/BlackoilWellModel.hpp @@ -392,7 +392,7 @@ namespace Opm { void assembleWellEq(const double dt, DeferredLogger& deferred_logger); - void maybeDoGasLiftOptimize(DeferredLogger& deferred_logger); + bool maybeDoGasLiftOptimize(DeferredLogger& deferred_logger); void gasLiftOptimizationStage1(DeferredLogger& deferred_logger, GLiftProdWells &prod_wells, GLiftOptWells &glift_wells, diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 79edd0db8..66d8f878a 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -830,12 +830,13 @@ namespace Opm { } updateWellControls(local_deferredLogger, /* check group controls */ true); + bool alq_updated = false; OPM_BEGIN_PARALLEL_TRY_CATCH(); { // Set the well primary variables based on the value of well solutions initPrimaryVariablesEvaluation(); - maybeDoGasLiftOptimize(local_deferredLogger); + alq_updated = maybeDoGasLiftOptimize(local_deferredLogger); assembleWellEq(dt, local_deferredLogger); } OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "assemble() failed: ", @@ -843,7 +844,7 @@ namespace Opm { //update guide rates const int reportStepIdx = ebosSimulator_.episodeIndex(); - if (guideRateUpdateIsNeeded(reportStepIdx)) { + if (alq_updated || guideRateUpdateIsNeeded(reportStepIdx)) { const double simulationTime = ebosSimulator_.time(); const auto& comm = ebosSimulator_.vanguard().grid().comm(); const auto& summaryState = ebosSimulator_.vanguard().summaryState(); @@ -857,12 +858,12 @@ namespace Opm { } template - void + bool BlackoilWellModel:: maybeDoGasLiftOptimize(DeferredLogger& deferred_logger) { bool do_glift_optimization = false; - + int num_wells_changed = 0; const double simulation_time = ebosSimulator_.time(); const double min_wait = ebosSimulator_.vanguard().schedule().glo(ebosSimulator_.episodeIndex()).min_wait(); // We only optimize if a min_wait time has past. @@ -906,7 +907,11 @@ namespace Opm { deferred_logger, prod_wells, glift_wells, state_map, ebosSimulator_.episodeIndex()); if (this->glift_debug) gliftDebugShowALQ(deferred_logger); + num_wells_changed = glift_wells.size(); } + auto comm = ebosSimulator_.vanguard().grid().comm(); + num_wells_changed = comm.sum(num_wells_changed); + return num_wells_changed > 0; } template diff --git a/opm/simulators/wells/GasLiftSingleWellGeneric.cpp b/opm/simulators/wells/GasLiftSingleWellGeneric.cpp index 4b686090c..1e77480bd 100644 --- a/opm/simulators/wells/GasLiftSingleWellGeneric.cpp +++ b/opm/simulators/wells/GasLiftSingleWellGeneric.cpp @@ -100,17 +100,19 @@ calcIncOrDecGradient(double oil_rate, double gas_rate, double alq, bool increase auto [new_bhp, bhp_is_limited] = getBhpWithLimit_(*bhp); // TODO: What to do if BHP is limited? auto rates = computeWellRates_(new_bhp, bhp_is_limited); - double new_oil_rate, new_gas_rate; - bool oil_is_limited, gas_is_limited; + double new_oil_rate, new_gas_rate, new_water_rate; + bool oil_is_limited, gas_is_limited, water_is_limited; std::tie(new_oil_rate, oil_is_limited) = getOilRateWithLimit_(rates); std::tie(new_gas_rate, gas_is_limited) = getGasRateWithLimit_(rates); + std::tie(new_water_rate, water_is_limited) = getWaterRateWithLimit_(rates); if (!increase && new_oil_rate < 0 ) { return std::nullopt; } auto grad = calcEcoGradient_( oil_rate, new_oil_rate, gas_rate, new_gas_rate, increase); return GradInfo(grad, new_oil_rate, oil_is_limited, - new_gas_rate, gas_is_limited, new_alq, alq_is_limited); + new_gas_rate, gas_is_limited, new_water_rate, water_is_limited, + new_alq, alq_is_limited); } else { return std::nullopt; @@ -138,6 +140,16 @@ runOptimize(const int iteration_idx) if (this->debug) logSuccess_(alq, iteration_idx); this->well_state_.setALQ(this->well_name_, alq); + const auto& pu = this->phase_usage_; + std::vector well_pot(pu.num_phases, 0.0); + if(pu.phase_used[BlackoilPhases::PhaseIndex::Liquid]) + well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Liquid]] = state->oilRate(); + if(pu.phase_used[BlackoilPhases::PhaseIndex::Aqua]) + well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Aqua]] = state->waterRate(); + if(pu.phase_used[BlackoilPhases::PhaseIndex::Vapour]) + well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Vapour]] = state->gasRate(); + + this->well_state_[this->well_name_].well_potentials = well_pot; } } } @@ -1215,7 +1227,7 @@ runOptimizeLoop_(bool increase) ret_value = std::make_unique( new_rates.oil, new_rates.oil_is_limited, new_rates.gas, new_rates.gas_is_limited, - cur_alq, alq_is_limited, increase_opt); + cur_alq, alq_is_limited, new_rates.water, increase_opt); return ret_value; } diff --git a/opm/simulators/wells/GasLiftSingleWellGeneric.hpp b/opm/simulators/wells/GasLiftSingleWellGeneric.hpp index f9083c8b5..10d8534ba 100644 --- a/opm/simulators/wells/GasLiftSingleWellGeneric.hpp +++ b/opm/simulators/wells/GasLiftSingleWellGeneric.hpp @@ -65,12 +65,15 @@ public: GradInfo(double grad_, double new_oil_rate_, bool oil_is_limited_, double new_gas_rate_, bool gas_is_limited_, + double new_water_rate_, bool water_is_limited_, double alq_, bool alq_is_limited_) : grad{grad_}, new_oil_rate{new_oil_rate_}, oil_is_limited{oil_is_limited_}, new_gas_rate{new_gas_rate_}, gas_is_limited{gas_is_limited_}, + new_water_rate{new_water_rate_}, + water_is_limited{water_is_limited_}, alq{alq_}, alq_is_limited{alq_is_limited_} {} double grad; @@ -78,6 +81,8 @@ public: bool oil_is_limited; double new_gas_rate; bool gas_is_limited; + double new_water_rate; + bool water_is_limited; double alq; bool alq_is_limited; }; diff --git a/opm/simulators/wells/GasLiftStage2.cpp b/opm/simulators/wells/GasLiftStage2.cpp index ec96b4e6c..bf702da33 100644 --- a/opm/simulators/wells/GasLiftStage2.cpp +++ b/opm/simulators/wells/GasLiftStage2.cpp @@ -115,8 +115,18 @@ addOrRemoveALQincrement_(GradMap &grad_map, const std::string& well_name, bool a } state.update(gi.new_oil_rate, gi.oil_is_limited, gi.new_gas_rate, gi.gas_is_limited, - gi.alq, gi.alq_is_limited, add); - this->well_state_.setALQ(well_name, gi.alq); + gi.alq, gi.alq_is_limited, gi.new_water_rate, add); + this->well_state_.setALQ(well_name, gi.alq); + const auto& pu = this->well_state_.phaseUsage(); + std::vector well_pot(pu.num_phases, 0.0); + if(pu.phase_used[BlackoilPhases::PhaseIndex::Liquid]) + well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Liquid]] = gi.new_oil_rate; + if(pu.phase_used[BlackoilPhases::PhaseIndex::Aqua]) + well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Aqua]] = gi.new_water_rate; + if(pu.phase_used[BlackoilPhases::PhaseIndex::Vapour]) + well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Vapour]] = gi.new_gas_rate; + + this->well_state_[well_name].well_potentials = well_pot; } std::optional diff --git a/opm/simulators/wells/GasLiftWellState.hpp b/opm/simulators/wells/GasLiftWellState.hpp index fe4802114..204ed7534 100644 --- a/opm/simulators/wells/GasLiftWellState.hpp +++ b/opm/simulators/wells/GasLiftWellState.hpp @@ -31,13 +31,14 @@ namespace Opm //GasLiftWellState() { } GasLiftWellState(double oil_rate, bool oil_is_limited, double gas_rate, bool gas_is_limited, - double alq, bool alq_is_limited, std::optional increase) : + double alq, bool alq_is_limited, double water_rate, std::optional increase) : oil_rate_{oil_rate}, oil_is_limited_{oil_is_limited}, gas_rate_{gas_rate}, gas_is_limited_{gas_is_limited}, alq_{alq}, alq_is_limited_{alq_is_limited}, + water_rate_{water_rate}, increase_{increase} {} double alq() const { return alq_; } @@ -49,9 +50,10 @@ namespace Opm std::optional increase() const { return increase_; } bool oilIsLimited() const { return oil_is_limited_; } double oilRate() const { return oil_rate_; } + double waterRate() const { return water_rate_; } void update(double oil_rate, bool oil_is_limited, double gas_rate, bool gas_is_limited, - double alq, bool alq_is_limited, + double alq, bool alq_is_limited, double water_rate, bool increase) { oil_rate_ = oil_rate; @@ -60,6 +62,7 @@ namespace Opm gas_is_limited_ = gas_is_limited; alq_ = alq; alq_is_limited_ = alq_is_limited; + water_rate_ = water_rate; increase_ = increase; } private: @@ -69,6 +72,7 @@ namespace Opm bool gas_is_limited_; double alq_; bool alq_is_limited_; + double water_rate_; std::optional increase_; };