From bd370c6470a918a7ba03cc148c33f5690d368317 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Thu, 5 Nov 2020 13:05:01 +0100 Subject: [PATCH 1/2] fixes to the wlift implementation --- opm/simulators/wells/GasLiftRuntime.hpp | 3 +-- opm/simulators/wells/GasLiftRuntime_impl.hpp | 15 +++++++++++++-- opm/simulators/wells/StandardWell_impl.hpp | 3 +-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/opm/simulators/wells/GasLiftRuntime.hpp b/opm/simulators/wells/GasLiftRuntime.hpp index 0ac23478d..ed2ceed0f 100644 --- a/opm/simulators/wells/GasLiftRuntime.hpp +++ b/opm/simulators/wells/GasLiftRuntime.hpp @@ -67,7 +67,6 @@ namespace Opm const Simulator &ebos_simulator, const SummaryState &summary_state, DeferredLogger &deferred_logger, - std::vector &potentials, const WellState &well_state, const Well::ProductionControls &controls ); @@ -95,7 +94,7 @@ namespace Opm const Well::ProductionControls &controls_; DeferredLogger &deferred_logger_; const Simulator &ebos_simulator_; - std::vector &potentials_; + std::vector potentials_; const StdWell &std_well_; const SummaryState &summary_state_; const WellState &well_state_; diff --git a/opm/simulators/wells/GasLiftRuntime_impl.hpp b/opm/simulators/wells/GasLiftRuntime_impl.hpp index 0648f2145..52deb4fc0 100644 --- a/opm/simulators/wells/GasLiftRuntime_impl.hpp +++ b/opm/simulators/wells/GasLiftRuntime_impl.hpp @@ -35,14 +35,13 @@ GasLiftRuntime( const Simulator &ebos_simulator, const SummaryState &summary_state, DeferredLogger &deferred_logger, - std::vector &potentials, const WellState &well_state, const Well::ProductionControls &controls ) : controls_{controls}, deferred_logger_{deferred_logger}, ebos_simulator_{ebos_simulator}, - potentials_{potentials}, + potentials_(well_state.numPhases(),0.0), std_well_{std_well}, summary_state_{summary_state}, well_state_{well_state}, @@ -237,6 +236,15 @@ getOilRateWithLimit_(std::vector &potentials) if (new_rate > target) new_rate = target; } + if (this->controls_.hasControl(Well::ProducerCMode::LRAT)) { + auto target = this->controls_.liquid_rate; + auto oil_rate = -potentials[this->oil_pos_]; + auto water_rate = -potentials[this->water_pos_]; + auto liq_rate = oil_rate + water_rate; + if (liq_rate > target) { + new_rate = oil_rate * (target/liq_rate); + } + } return new_rate; } @@ -342,6 +350,9 @@ runOptimizeLoop_(bool increase) auto gas_rate = -cur_potentials[this->gas_pos_]; bool success = false; // did we succeed to increase alq? auto cur_alq = this->orig_alq_; + if (cur_alq == 0 && !increase) // we don't decrease alq below zero + return false; + auto alq = cur_alq; OptimizeState state {*this, increase}; if (this->debug) debugShowStartIteration_(alq, increase); diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index 924cd63b7..62ce51153 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -2758,12 +2758,11 @@ namespace Opm = well_state.currentProductionControls()[this->index_of_well_]; if ( this->Base::wellHasTHPConstraints(summary_state) && current_control != Well::ProducerCMode::BHP ) { - std::vector potentials = well_state.wellPotentials(); if (doGasLiftOptimize(well_state, ebos_simulator, deferred_logger)) { const auto& controls = well.productionControls(summary_state); GasLiftHandler glift { *this, ebos_simulator, summary_state, - deferred_logger, potentials, well_state, controls }; + deferred_logger, well_state, controls }; glift.runOptimize(); } } From 2795d1713f2179ef96e65365587619ec6abd4cc8 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Thu, 5 Nov 2020 15:54:07 +0100 Subject: [PATCH 2/2] avoid oscilating between decreasing and increasing when rates are limited --- opm/simulators/wells/GasLiftRuntime.hpp | 4 +-- opm/simulators/wells/GasLiftRuntime_impl.hpp | 37 +++++++++++++------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/opm/simulators/wells/GasLiftRuntime.hpp b/opm/simulators/wells/GasLiftRuntime.hpp index ed2ceed0f..0376a63b9 100644 --- a/opm/simulators/wells/GasLiftRuntime.hpp +++ b/opm/simulators/wells/GasLiftRuntime.hpp @@ -79,8 +79,8 @@ namespace Opm void displayDebugMessage_(const std::string &msg); void displayWarning_(); void displayWarning_(std::string warning); - double getGasRateWithLimit_(std::vector &potentials); - double getOilRateWithLimit_(std::vector &potentials); + bool getGasRateWithLimit_(double& new_rate, const std::vector &potentials); + bool getOilRateWithLimit_(double& new_rate, const std::vector &potentials); void logSuccess_(); bool runOptimizeLoop_(bool increase); void setAlqMaxRate_(const GasLiftOpt::Well &well); diff --git a/opm/simulators/wells/GasLiftRuntime_impl.hpp b/opm/simulators/wells/GasLiftRuntime_impl.hpp index 52deb4fc0..32b65ffcc 100644 --- a/opm/simulators/wells/GasLiftRuntime_impl.hpp +++ b/opm/simulators/wells/GasLiftRuntime_impl.hpp @@ -202,17 +202,20 @@ displayWarning_(std::string msg) // computation of the economic gradient making the gradient // smaller than it should be since the term appears in the denominator. template -double +bool Opm::GasLiftRuntime:: -getGasRateWithLimit_(std::vector &potentials) +getGasRateWithLimit_(double& new_rate, const std::vector &potentials) { - auto new_rate = -potentials[this->gas_pos_]; + new_rate = -potentials[this->gas_pos_]; + bool limit = false; if (this->controls_.hasControl(Well::ProducerCMode::GRAT)) { auto target = this->controls_.gas_rate; - if (new_rate > target) + if (new_rate > target) { new_rate = target; + limit = true; + } } - return new_rate; + return limit; } @@ -226,15 +229,18 @@ getGasRateWithLimit_(std::vector &potentials) // also since we also reduced the rate. This might involve // some sort of iteration though.. template -double +bool Opm::GasLiftRuntime:: -getOilRateWithLimit_(std::vector &potentials) +getOilRateWithLimit_(double& new_rate, const std::vector &potentials) { - auto new_rate = -potentials[this->oil_pos_]; + new_rate = -potentials[this->oil_pos_]; + bool limit = false; if (this->controls_.hasControl(Well::ProducerCMode::ORAT)) { auto target = this->controls_.oil_rate; - if (new_rate > target) + if (new_rate > target) { new_rate = target; + limit = true; + } } if (this->controls_.hasControl(Well::ProducerCMode::LRAT)) { auto target = this->controls_.liquid_rate; @@ -243,9 +249,10 @@ getOilRateWithLimit_(std::vector &potentials) auto liq_rate = oil_rate + water_rate; if (liq_rate > target) { new_rate = oil_rate * (target/liq_rate); + limit = true; } } - return new_rate; + return limit; } template @@ -365,8 +372,14 @@ runOptimizeLoop_(bool increase) // NOTE: if BHP is below limit, we set state.stop_iteration = true auto bhp = state.getBhpWithLimit(); computeWellRates_(bhp, cur_potentials); - auto new_oil_rate = getOilRateWithLimit_(cur_potentials); - auto new_gas_rate = getGasRateWithLimit_(cur_potentials); + double new_oil_rate = 0.0; + bool oil_is_limited = getOilRateWithLimit_(new_oil_rate, cur_potentials); + if (oil_is_limited && !increase) //if oil is limited we do not want to decrease + break; + double new_gas_rate = 0.0; + bool gas_is_limited = getGasRateWithLimit_(new_gas_rate, cur_potentials); + if (gas_is_limited && increase) // if gas is limited we do not want to increase + break; auto gradient = state.calcGradient( oil_rate, new_oil_rate, gas_rate, new_gas_rate); if (state.checkEcoGradient(gradient)) {