From 4bdf7c1b587b823c3d070031e680626535233f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20H=C3=A6gland?= Date: Mon, 20 Dec 2021 00:29:06 +0100 Subject: [PATCH] Refactor methods getXyzRateWithLimit_() Refactors getOilRateWithLimit_(), getGasRateWithLimit_(), and getWaterRateWithLimit_() in GasLiftSingleWellGeneric.cpp. The common part of the methods is split out into a new method called getRateWithLimit_(). The purpose of the refactorization is to reduce reptetive code and make the code easier to maintain. --- .../wells/GasLiftSingleWellGeneric.cpp | 151 +++++++++++++----- .../wells/GasLiftSingleWellGeneric.hpp | 33 ++-- 2 files changed, 126 insertions(+), 58 deletions(-) diff --git a/opm/simulators/wells/GasLiftSingleWellGeneric.cpp b/opm/simulators/wells/GasLiftSingleWellGeneric.cpp index 2bca1228f..27cc4d817 100644 --- a/opm/simulators/wells/GasLiftSingleWellGeneric.cpp +++ b/opm/simulators/wells/GasLiftSingleWellGeneric.cpp @@ -530,32 +530,7 @@ std::pair GasLiftSingleWellGeneric:: getGasRateWithLimit_(const std::vector& potentials) const { - double 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) { - new_rate = target; - limit = true; - } - } - return { new_rate, limit}; -} - -std::pair -GasLiftSingleWellGeneric:: -getWaterRateWithLimit_(const std::vector& potentials) const -{ - double new_rate = -potentials[this->water_pos_]; - bool limit = false; - if (this->controls_.hasControl(Well::ProducerCMode::WRAT)) { - auto target = this->controls_.water_rate; - if (new_rate > target) { - new_rate = target; - limit = true; - } - } - return { new_rate, limit}; + return getRateWithLimit_(Rate::gas, potentials); } // NOTE: If the computed oil rate is larger than the target @@ -571,32 +546,100 @@ std::pair GasLiftSingleWellGeneric:: getOilRateWithLimit_(const std::vector& potentials) const { - double oil_rate = -potentials[this->oil_pos_]; - double new_rate = oil_rate; + return getRateWithLimit_(Rate::oil, potentials); +} + +std::pair +GasLiftSingleWellGeneric:: +getWaterRateWithLimit_(const std::vector& potentials) const +{ + return getRateWithLimit_(Rate::water, potentials); +} + +double +GasLiftSingleWellGeneric:: +getRate_(Rate rate, const std::vector& potentials) const +{ + switch (rate) { + case Rate::oil: + return -potentials[this->oil_pos_]; + case Rate::gas: + return -potentials[this->gas_pos_]; + case Rate::water: + return -potentials[this->water_pos_]; + case Rate::liquid: + return -potentials[this->oil_pos_] - potentials[this->water_pos_]; + default: + // Need this to avoid compiler warning : control reaches end of non-void function + throw std::runtime_error("This should not happen"); + } +} + +double +GasLiftSingleWellGeneric:: +getProductionTarget_(Rate rate) const +{ + switch (rate) { + case Rate::oil: + return this->controls_.oil_rate; + case Rate::gas: + return this->controls_.gas_rate; + case Rate::water: + return this->controls_.water_rate; + case Rate::liquid: + return this->controls_.liquid_rate; + default: + // Need this to avoid compiler warning : control reaches end of non-void function + throw std::runtime_error("This should not happen"); + } +} + +std::pair +GasLiftSingleWellGeneric:: +getRateWithLimit_(Rate rate_type, const std::vector& potentials) const +{ + double new_rate = getRate_(rate_type, potentials); bool limited = false; - if (this->controls_.hasControl(Well::ProducerCMode::ORAT)) { - auto target = this->controls_.oil_rate; - if (oil_rate > target) { - const std::string msg = fmt::format("limiting oil rate to target: " - "computed rate: {}, target: {}", new_rate, target); - displayDebugMessage_(msg); + if (hasProductionControl_(rate_type)) { + auto target = getProductionTarget_(rate_type); + if (new_rate > target) { new_rate = target; limited = true; + const std::string msg = fmt::format("limiting {} rate to target: " + "computed rate: {}, target: {}", + GasLiftGroupInfo::rateToString(rate_type), new_rate, target); + displayDebugMessage_(msg); } } - if (this->controls_.hasControl(Well::ProducerCMode::LRAT)) { - auto target = this->controls_.liquid_rate; - double water_rate = -potentials[this->water_pos_]; - double liq_rate = oil_rate + water_rate; - if (liq_rate > target) { - double oil_fraction = oil_rate / liq_rate; - new_rate = std::min(new_rate, oil_fraction * target); + if ((rate_type == Rate::oil) || (rate_type == Rate::water)) { + double rate2; + if (rate_type == Rate::oil) { + rate2 = getRate_(Rate::water, potentials); + } + else { + rate2 = getRate_(Rate::oil, potentials); + } + double liq_rate = new_rate + rate2; + auto liq_target = getProductionTarget_(Rate::liquid); + if (liq_rate > liq_target) { + double fraction = new_rate / liq_rate; + // NOTE: since + // fraction * liq_rate = new_rate, + // we must have + // fraction * liq_target < new_rate + // since + // liq_target < liq_rate + // therefore new_rate will become less than it original was and + // limited = true. + new_rate = fraction * liq_target; limited = true; const std::string msg = fmt::format( - "limiting oil rate due to LRAT target: " - "computed rate: {}, target: {}", oil_rate, new_rate); + "limiting {} rate to {} due to LRAT target: " + "computed LRAT: {}, target LRAT: {}", + GasLiftGroupInfo::rateToString(rate_type), new_rate, + liq_rate, liq_target); displayDebugMessage_(msg); - } + } } return { new_rate, limited}; } @@ -746,6 +789,26 @@ getInitialRatesWithLimit_(const std::vector& potentials) return std::make_tuple(oil_rate, gas_rate, water_rate, oil_is_limited, gas_is_limited, water_is_limited); } +bool +GasLiftSingleWellGeneric:: +hasProductionControl_(Rate rate) const +{ + switch (rate) { + case Rate::oil: + return this->controls_.hasControl(Well::ProducerCMode::ORAT); + case Rate::gas: + return this->controls_.hasControl(Well::ProducerCMode::GRAT); + case Rate::water: + return this->controls_.hasControl(Well::ProducerCMode::WRAT); + case Rate::liquid: + return this->controls_.hasControl(Well::ProducerCMode::LRAT); + default: + // Need this to avoid compiler warning : control reaches end of non-void function + throw std::runtime_error("This should not happen"); + } +} + + std::tuple GasLiftSingleWellGeneric:: increaseALQtoPositiveOilRate_(double alq, diff --git a/opm/simulators/wells/GasLiftSingleWellGeneric.hpp b/opm/simulators/wells/GasLiftSingleWellGeneric.hpp index 0d2bfa879..d2d283f67 100644 --- a/opm/simulators/wells/GasLiftSingleWellGeneric.hpp +++ b/opm/simulators/wells/GasLiftSingleWellGeneric.hpp @@ -178,25 +178,30 @@ protected: void displayWarning_(const std::string& warning); std::pair getBhpWithLimit_(double bhp) const; - std::pair getGasRateWithLimit_(const std::vector& potentials) const; - std::tuple - getInitialRatesWithLimit_(const std::vector& potentials); - std::tuple getRateWithGroupLimit_( - Rate rate_type, const double new_rate, const double old_rate) const; - std::pair getOilRateWithLimit_( - const std::vector& potentials) const; - std::pair getWaterRateWithLimit_( - const std::vector& potentials) const; - - std::pair getOilRateWithGroupLimit_( - double new_oil_rate, double oil_rate) const; + std::pair getGasRateWithLimit_( + const std::vector& potentials) const; std::pair getGasRateWithGroupLimit_( double new_gas_rate, double gas_rate) const; - std::pair getWaterRateWithGroupLimit_( - double new_water_rate, double water_rate) const; + std::tuple getInitialRatesWithLimit_( + const std::vector& potentials); std::tuple getLiquidRateWithGroupLimit_( const double new_oil_rate, const double oil_rate, const double new_water_rate, const double water_rate) const; + std::pair getOilRateWithGroupLimit_( + double new_oil_rate, double oil_rate) const; + std::pair getOilRateWithLimit_( + const std::vector& potentials) const; + double getProductionTarget_(Rate rate) const; + double getRate_(Rate rate_type, const std::vector& potentials) const; + std::pair getRateWithLimit_( + Rate rate_type, const std::vector& potentials) const; + std::tuple getRateWithGroupLimit_( + Rate rate_type, const double new_rate, const double old_rate) const; + std::pair getWaterRateWithGroupLimit_( + double new_water_rate, double water_rate) const; + std::pair getWaterRateWithLimit_( + const std::vector& potentials) const; + bool hasProductionControl_(Rate rate) const; std::tuple increaseALQtoPositiveOilRate_(double alq,