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)) {