From 7d7b2803a550cfbd3b1651cc8f54dbe86174ccf4 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Wed, 16 Nov 2022 09:18:35 +0100 Subject: [PATCH] renaming and adding more comments based on review --- opm/simulators/wells/GasLiftGroupInfo.hpp | 2 + .../wells/GasLiftSingleWellGeneric.cpp | 36 ++++++++++-------- .../wells/GasLiftSingleWellGeneric.hpp | 15 ++++---- opm/simulators/wells/GasLiftStage2.cpp | 38 +++++++++++-------- opm/simulators/wells/GasLiftStage2.hpp | 8 ++-- 5 files changed, 57 insertions(+), 42 deletions(-) diff --git a/opm/simulators/wells/GasLiftGroupInfo.hpp b/opm/simulators/wells/GasLiftGroupInfo.hpp index 351d21870..d4322ec5b 100644 --- a/opm/simulators/wells/GasLiftGroupInfo.hpp +++ b/opm/simulators/wells/GasLiftGroupInfo.hpp @@ -196,6 +196,8 @@ protected: gas_rate_ += delta_gas; water_rate_ += delta_water; alq_ += delta_alq; + // Note. We don't updata the potentials at this point. They + // are only needed initially. } private: double oil_rate_; diff --git a/opm/simulators/wells/GasLiftSingleWellGeneric.cpp b/opm/simulators/wells/GasLiftSingleWellGeneric.cpp index 1dee331b6..c14ccb9e4 100644 --- a/opm/simulators/wells/GasLiftSingleWellGeneric.cpp +++ b/opm/simulators/wells/GasLiftSingleWellGeneric.cpp @@ -86,7 +86,7 @@ GasLiftSingleWellGeneric::GasLiftSingleWellGeneric(DeferredLogger& deferred_logg // NOTE: Used from GasLiftStage2 std::optional GasLiftSingleWellGeneric::calcIncOrDecGradient( - double oil_rate, double gas_rate, double water_rate, double alq, const Group& group, bool increase) const + double oil_rate, double gas_rate, double water_rate, double alq, const std::string& gr_name_dont_limit, bool increase) const { auto [new_alq_opt, alq_is_limited] = addOrSubtractAlqIncrement_(alq, increase); // TODO: What to do if ALQ is limited and new_alq != alq? @@ -96,7 +96,7 @@ GasLiftSingleWellGeneric::calcIncOrDecGradient( double new_alq = *new_alq_opt; auto delta_alq = new_alq - alq; - if (checkGroupALQrateExceeded(delta_alq, group.name())) + if (checkGroupALQrateExceeded(delta_alq, gr_name_dont_limit)) return std::nullopt; if (auto bhp = computeBhpAtThpLimit_(new_alq)) { @@ -110,7 +110,7 @@ GasLiftSingleWellGeneric::calcIncOrDecGradient( // std::tie(new_water_rate, water_is_limited) = getWaterRateWithLimit_(rates); const auto ratesLimited = getLimitedRatesFromRates_(rates); BasicRates oldrates = {oil_rate, gas_rate, water_rate, false}; - const auto new_rates = updateRatesToGroupLimits_(oldrates, ratesLimited, group.name()); + const auto new_rates = updateRatesToGroupLimits_(oldrates, ratesLimited, gr_name_dont_limit); if (!increase && new_rates.oil < 0) { return std::nullopt; @@ -673,25 +673,25 @@ GasLiftSingleWellGeneric::getRateWithLimit_(Rate rate_type, const BasicRates& ra } std::pair -GasLiftSingleWellGeneric::getOilRateWithGroupLimit_(double new_oil_rate, double oil_rate, const std::string& gr_name_no_check) const +GasLiftSingleWellGeneric::getOilRateWithGroupLimit_(double new_oil_rate, double oil_rate, const std::string& gr_name_dont_limit) const { - [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::oil, new_oil_rate, oil_rate, gr_name_no_check); + [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::oil, new_oil_rate, oil_rate, gr_name_dont_limit); bool limited = gr_name != nullptr; return {rate, limited}; } std::pair -GasLiftSingleWellGeneric::getGasRateWithGroupLimit_(double new_gas_rate, double gas_rate, const std::string& gr_name_no_check) const +GasLiftSingleWellGeneric::getGasRateWithGroupLimit_(double new_gas_rate, double gas_rate, const std::string& gr_name_dont_limit) const { - [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::gas, new_gas_rate, gas_rate, gr_name_no_check); + [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::gas, new_gas_rate, gas_rate, gr_name_dont_limit); bool limited = gr_name != nullptr; return {rate, limited}; } std::pair -GasLiftSingleWellGeneric::getWaterRateWithGroupLimit_(double new_water_rate, double water_rate, const std::string& gr_name_no_check) const +GasLiftSingleWellGeneric::getWaterRateWithGroupLimit_(double new_water_rate, double water_rate, const std::string& gr_name_dont_limit) const { - [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::water, new_water_rate, water_rate, gr_name_no_check); + [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::water, new_water_rate, water_rate, gr_name_dont_limit); bool limited = gr_name != nullptr; return {rate, limited}; } @@ -701,12 +701,12 @@ GasLiftSingleWellGeneric::getLiquidRateWithGroupLimit_(const double new_oil_rate const double oil_rate, const double new_water_rate, const double water_rate, - const std::string& gr_name_no_check) const + const std::string& gr_name_dont_limit) const { auto liquid_rate = oil_rate + water_rate; auto new_liquid_rate = new_oil_rate + new_water_rate; auto [liquid_rate_limited, group_name, efficiency] - = getRateWithGroupLimit_(Rate::liquid, new_liquid_rate, liquid_rate, gr_name_no_check); + = getRateWithGroupLimit_(Rate::liquid, new_liquid_rate, liquid_rate, gr_name_dont_limit); bool limited = group_name != nullptr; if (limited) { // the oil, gas, and water cases can be handled directly by @@ -737,7 +737,7 @@ GasLiftSingleWellGeneric::getLiquidRateWithGroupLimit_(const double new_oil_rate } std::tuple -GasLiftSingleWellGeneric::getRateWithGroupLimit_(Rate rate_type, const double new_rate, const double old_rate, const std::string& gr_name_no_check) const +GasLiftSingleWellGeneric::getRateWithGroupLimit_(Rate rate_type, const double new_rate, const double old_rate, const std::string& gr_name_dont_limit) const { const double delta_rate = new_rate - old_rate; if (delta_rate > 0) { @@ -750,7 +750,9 @@ GasLiftSingleWellGeneric::getRateWithGroupLimit_(Rate rate_type, const double ne double gr_target, new_gr_rate, efficiency; const std::string* group_name = nullptr; for (const auto& [group_name_temp, efficiency_temp] : pairs) { - if (gr_name_no_check == group_name_temp) { + // in stage 2 we don't want to limit the rate to the group + // target we are trying to redistribute the gaslift within + if (gr_name_dont_limit == group_name_temp) { continue; } @@ -1583,12 +1585,14 @@ GasLiftSingleWellGeneric::OptimizeState::checkAlqOutsideLimits(double alq, [[may } bool -GasLiftSingleWellGeneric::checkGroupALQrateExceeded(double delta_alq, const std::string& gr_name_no_check) const +GasLiftSingleWellGeneric::checkGroupALQrateExceeded(double delta_alq, const std::string& gr_name_dont_limit) const { const auto& pairs = group_info_.getWellGroups(well_name_); for (const auto& [group_name, efficiency] : pairs) { - if (gr_name_no_check == group_name) - continue; + // in stage 2 we don't want to limit the rate to the group + // target we are trying to redistribute the gaslift within + if (gr_name_dont_limit == group_name) + continue; auto max_alq_opt = group_info_.maxAlq(group_name); if (max_alq_opt) { double alq = group_info_.alqRate(group_name) + efficiency * delta_alq; diff --git a/opm/simulators/wells/GasLiftSingleWellGeneric.hpp b/opm/simulators/wells/GasLiftSingleWellGeneric.hpp index 24853cdb8..b958bda81 100644 --- a/opm/simulators/wells/GasLiftSingleWellGeneric.hpp +++ b/opm/simulators/wells/GasLiftSingleWellGeneric.hpp @@ -96,7 +96,8 @@ public: std::optional calcIncOrDecGradient(double oil_rate, double gas_rate, double water_rate, double alq, - const Group& group, bool increase) const; + const std::string& gr_name_dont_limit, + bool increase) const; std::unique_ptr runOptimize(const int iteration_idx); @@ -240,7 +241,7 @@ protected: double getBhpWithLimit(); void warn_(std::string msg) {parent.displayWarning_(msg);} }; - bool checkGroupALQrateExceeded(double delta_alq, const std::string& gr_name_no_check = "") const; + bool checkGroupALQrateExceeded(double delta_alq, const std::string& gr_name_dont_limit = "") const; bool checkGroupTotalRateExceeded(double delta_alq, double delta_gas_rate) const; std::pair, bool> addOrSubtractAlqIncrement_( @@ -275,14 +276,14 @@ protected: std::pair getGasRateWithLimit_( const BasicRates& rates) const; std::pair getGasRateWithGroupLimit_( - double new_gas_rate, double gas_rate, const std::string& gr_name_no_check) const; + double new_gas_rate, double gas_rate, const std::string& gr_name_dont_limit) const; std::pair,double> getInitialRatesWithLimit_() const; LimitedRates getLimitedRatesFromRates_(const BasicRates& rates) const; std::tuple getLiquidRateWithGroupLimit_( const double new_oil_rate, const double oil_rate, - const double new_water_rate, const double water_rate, const std::string& gr_name_no_check) const; + const double new_water_rate, const double water_rate, const std::string& gr_name_dont_limit) const; std::pair getOilRateWithGroupLimit_( - double new_oil_rate, double oil_rate, const std::string& gr_name_no_check) const; + double new_oil_rate, double oil_rate, const std::string& gr_name_dont_limit) const; std::pair getOilRateWithLimit_(const BasicRates& rates) const; std::pair> getOilRateWithLimit2_( const BasicRates& rates) const; @@ -291,9 +292,9 @@ protected: std::pair> getRateWithLimit_( Rate rate_type, const BasicRates& rates) const; std::tuple getRateWithGroupLimit_( - Rate rate_type, const double new_rate, const double old_rate, const std::string& gr_name_no_check) const; + Rate rate_type, const double new_rate, const double old_rate, const std::string& gr_name_dont_limit) const; std::pair getWaterRateWithGroupLimit_( - double new_water_rate, double water_rate, const std::string& gr_name_no_check) const; + double new_water_rate, double water_rate, const std::string& gr_name_dont_limit) const; std::pair getWaterRateWithLimit_(const BasicRates& rates) const; std::pair> getWaterRateWithLimit2_( const BasicRates& rates) const; diff --git a/opm/simulators/wells/GasLiftStage2.cpp b/opm/simulators/wells/GasLiftStage2.cpp index 2a9527051..c6f89bc6b 100644 --- a/opm/simulators/wells/GasLiftStage2.cpp +++ b/opm/simulators/wells/GasLiftStage2.cpp @@ -135,7 +135,7 @@ addOrRemoveALQincrement_(GradMap &grad_map, const std::string& well_name, bool a std::optional GasLiftStage2:: calcIncOrDecGrad_( - const std::string well_name, const GasLiftSingleWell &gs_well, const Group& group, bool increase) + const std::string well_name, const GasLiftSingleWell &gs_well, const std::string& gr_name_dont_limit, bool increase) { // only applies to wells in the well_state_map (i.e. wells on this rank) @@ -161,7 +161,7 @@ calcIncOrDecGrad_( else { auto [oil_rate, gas_rate] = state.getRates(); auto alq = state.alq(); - auto grad = gs_well.calcIncOrDecGradient(oil_rate, gas_rate, state.waterRate(), alq, group, increase); + auto grad = gs_well.calcIncOrDecGradient(oil_rate, gas_rate, state.waterRate(), alq, gr_name_dont_limit, increase); if (grad) { const std::string msg = fmt::format( "well {} : adding {} gradient = {}", @@ -441,7 +441,7 @@ optimizeGroupsRecursive_(const Group &group) void GasLiftStage2:: recalculateGradientAndUpdateData_( - GradPairItr &grad_itr, const Group& group, bool increase, + GradPairItr &grad_itr, const std::string& gr_name_dont_limit, bool increase, //incremental and decremental gradients, if 'grads' are incremental, then // 'other_grads' are decremental, or conversely, if 'grads' are decremental, then @@ -457,7 +457,7 @@ recalculateGradientAndUpdateData_( // the grads and other grads are synchronized later if(this->stage1_wells_.count(name) > 0) { GasLiftSingleWell &gs_well = *(this->stage1_wells_.at(name).get()); - auto grad = calcIncOrDecGrad_(name, gs_well, group, increase); + auto grad = calcIncOrDecGrad_(name, gs_well, gr_name_dont_limit, increase); if (grad) { grad_itr->second = grad->grad; old_grad = updateGrad_(name, *grad, increase); @@ -627,8 +627,8 @@ removeSurplusALQ_(const Group &group, const auto well_name = dec_grad_itr->first; auto eco_grad = dec_grad_itr->second; bool remove = false; - if (state.checkOilTarget(eco_grad) || state.checkGasTarget(eco_grad) - || state.checkLiquidTarget(eco_grad) || state.checkWaterTarget(eco_grad) || state.checkALQlimit()) + if (state.checkOilTarget(eco_grad) || state.checkGasTarget() + || state.checkLiquidTarget(eco_grad) || state.checkWaterTarget() || state.checkALQlimit()) { remove = true; } @@ -643,8 +643,12 @@ removeSurplusALQ_(const Group &group, if (remove) { state.updateRates(well_name); state.addOrRemoveALQincrement( this->dec_grads_, well_name, /*add=*/false); + // We pass the current group rate in order to avoid limiting the rates + // and gaslift based on the current group limits. In other words we want to reduce + // the gasslift as much as possible as long as we are able to produce the group + // targets recalculateGradientAndUpdateData_( - dec_grad_itr, group, /*increase=*/false, dec_grads, inc_grads); + dec_grad_itr, group.name(), /*increase=*/false, dec_grads, inc_grads); // The dec_grads and inc_grads needs to be syncronized across ranks mpiSyncGlobalGradVector_(dec_grads); @@ -751,12 +755,12 @@ calculateEcoGradients(std::vector &wells, for (auto well_ptr : wells) { const auto &gs_well = *well_ptr; // gs = GasLiftSingleWell const auto &name = gs_well.name(); - auto inc_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group, /*increase=*/true); + auto inc_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group.name(), /*increase=*/true); if (inc_grad) { inc_grads.emplace_back(std::make_pair(name, inc_grad->grad)); this->parent.saveIncGrad_(name, *inc_grad); } - auto dec_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group, /*increase=*/false); + auto dec_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group.name(), /*increase=*/false); if (dec_grad) { dec_grads.emplace_back(std::make_pair(name, dec_grad->grad)); this->parent.saveDecGrad_(name, *dec_grad); @@ -843,9 +847,9 @@ recalculateGradients( GradPairItr &min_dec_grad_itr, GradPairItr &max_inc_grad_itr) { this->parent.recalculateGradientAndUpdateData_( - max_inc_grad_itr, this->group, /*increase=*/true, inc_grads, dec_grads); + max_inc_grad_itr, this->group.name(), /*increase=*/true, inc_grads, dec_grads); this->parent.recalculateGradientAndUpdateData_( - min_dec_grad_itr, this->group, /*increase=*/false, dec_grads, inc_grads); + min_dec_grad_itr, this->group.name(), /*increase=*/false, dec_grads, inc_grads); // The dec_grads and inc_grads needs to be syncronized across ranks this->parent.mpiSyncGlobalGradVector_(dec_grads); @@ -944,10 +948,10 @@ checkEcoGradient(const std::string &well_name, double eco_grad) bool GasLiftStage2::SurplusState:: -checkGasTarget(double eco_grad) +checkGasTarget() { if (this->group.has_control(Group::ProductionCMode::GRAT)) { - if (this->gas_target < (this->gas_rate - eco_grad) ) { + if (this->gas_target < (this->gas_rate) ) { if (this->parent.debug) { const std::string msg = fmt::format("group: {} : " "gas rate {} is greater than gas target {}", this->group.name(), @@ -965,6 +969,8 @@ checkLiquidTarget(double eco_grad) { if (this->group.has_control(Group::ProductionCMode::LRAT)) { auto liquid_rate = this->oil_rate + this->water_rate; + // the eco_grad is subtracted from the rate to make sure the + // group still can produce its target if (this->liquid_target < (liquid_rate - eco_grad) ) { if (this->parent.debug) { const std::string msg = fmt::format("group: {} : " @@ -983,6 +989,8 @@ GasLiftStage2::SurplusState:: checkOilTarget(double eco_grad) { if (this->group.has_control(Group::ProductionCMode::ORAT)) { + // the eco_grad is subtracted from the rate to make sure the + // group still can produce its target if (this->oil_target < (this->oil_rate - eco_grad) ) { if (this->parent.debug) { const std::string msg = fmt::format("group: {} : " @@ -998,10 +1006,10 @@ checkOilTarget(double eco_grad) bool GasLiftStage2::SurplusState:: -checkWaterTarget(double eco_grad) +checkWaterTarget() { if (this->group.has_control(Group::ProductionCMode::WRAT)) { - if (this->water_target < (this->water_rate - eco_grad) ) { + if (this->water_target < (this->water_rate) ) { if (this->parent.debug) { const std::string msg = fmt::format("group: {} : " "water rate {} is greater than oil target {}", this->group.name(), diff --git a/opm/simulators/wells/GasLiftStage2.hpp b/opm/simulators/wells/GasLiftStage2.hpp index c999fecf2..f3321d65e 100644 --- a/opm/simulators/wells/GasLiftStage2.hpp +++ b/opm/simulators/wells/GasLiftStage2.hpp @@ -79,7 +79,7 @@ protected: void addOrRemoveALQincrement_( GradMap& grad_map, const std::string& well_name, bool add); std::optional calcIncOrDecGrad_( - const std::string name, const GasLiftSingleWell& gs_well, const Group& group, bool increase); + const std::string name, const GasLiftSingleWell& gs_well, const std::string& gr_name_dont_limit, bool increase); bool checkRateAlreadyLimited_(GasLiftWellState& state, bool increase); GradInfo deleteDecGradItem_(const std::string& name); GradInfo deleteIncGradItem_(const std::string& name); @@ -99,7 +99,7 @@ protected: void optimizeGroup_(const Group& group); void optimizeGroupsRecursive_(const Group& group); void recalculateGradientAndUpdateData_( - GradPairItr& grad_itr, const Group& group, bool increase, + GradPairItr& grad_itr, const std::string& gr_name_dont_limit, bool increase, std::vector& grads, std::vector& other_grads); void redistributeALQ_( std::vector& wells, const Group& group, @@ -205,10 +205,10 @@ protected: GradMap &grad_map, const std::string& well_name, bool add); bool checkALQlimit(); bool checkEcoGradient(const std::string& well_name, double eco_grad); - bool checkGasTarget(double eco_grad); + bool checkGasTarget(); bool checkLiquidTarget(double eco_grad); bool checkOilTarget(double eco_grad); - bool checkWaterTarget(double eco_grad); + bool checkWaterTarget(); void updateRates(const std::string& name); }; };