pass group name to getRateWithGroupLimit to avoid checking for that

This commit is contained in:
Tor Harald Sandve 2022-10-26 08:51:38 +02:00
parent c313a0a4b2
commit cd09c130b3
4 changed files with 49 additions and 36 deletions

View File

@ -86,13 +86,19 @@ GasLiftSingleWellGeneric::GasLiftSingleWellGeneric(DeferredLogger& deferred_logg
// NOTE: Used from GasLiftStage2 // NOTE: Used from GasLiftStage2
std::optional<GasLiftSingleWellGeneric::GradInfo> std::optional<GasLiftSingleWellGeneric::GradInfo>
GasLiftSingleWellGeneric::calcIncOrDecGradient( GasLiftSingleWellGeneric::calcIncOrDecGradient(
double oil_rate, double gas_rate, double water_rate, double alq, bool increase) const double oil_rate, double gas_rate, double water_rate, double alq, const Group& group, bool increase) const
{ {
auto [new_alq_opt, alq_is_limited] = addOrSubtractAlqIncrement_(alq, increase); auto [new_alq_opt, alq_is_limited] = addOrSubtractAlqIncrement_(alq, increase);
// TODO: What to do if ALQ is limited and new_alq != alq? // TODO: What to do if ALQ is limited and new_alq != alq?
if (!new_alq_opt) if (!new_alq_opt)
return std::nullopt; return std::nullopt;
double new_alq = *new_alq_opt; double new_alq = *new_alq_opt;
auto delta_alq = new_alq - alq;
if (checkGroupALQrateExceeded(delta_alq, group.name()))
return std::nullopt;
if (auto bhp = computeBhpAtThpLimit_(new_alq)) { if (auto bhp = computeBhpAtThpLimit_(new_alq)) {
auto [new_bhp, bhp_is_limited] = getBhpWithLimit_(*bhp); auto [new_bhp, bhp_is_limited] = getBhpWithLimit_(*bhp);
// TODO: What to do if BHP is limited? // TODO: What to do if BHP is limited?
@ -104,7 +110,7 @@ GasLiftSingleWellGeneric::calcIncOrDecGradient(
// std::tie(new_water_rate, water_is_limited) = getWaterRateWithLimit_(rates); // std::tie(new_water_rate, water_is_limited) = getWaterRateWithLimit_(rates);
const auto ratesLimited = getLimitedRatesFromRates_(rates); const auto ratesLimited = getLimitedRatesFromRates_(rates);
BasicRates oldrates = {oil_rate, gas_rate, water_rate, false}; BasicRates oldrates = {oil_rate, gas_rate, water_rate, false};
const auto new_rates = updateRatesToGroupLimits_(oldrates, ratesLimited); const auto new_rates = updateRatesToGroupLimits_(oldrates, ratesLimited, group.name());
if (!increase && new_rates.oil < 0) { if (!increase && new_rates.oil < 0) {
return std::nullopt; return std::nullopt;
@ -667,25 +673,25 @@ GasLiftSingleWellGeneric::getRateWithLimit_(Rate rate_type, const BasicRates& ra
} }
std::pair<double, bool> std::pair<double, bool>
GasLiftSingleWellGeneric::getOilRateWithGroupLimit_(double new_oil_rate, double oil_rate) const GasLiftSingleWellGeneric::getOilRateWithGroupLimit_(double new_oil_rate, double oil_rate, const std::string& gr_name_no_check) const
{ {
[[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::oil, new_oil_rate, oil_rate); [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::oil, new_oil_rate, oil_rate, gr_name_no_check);
bool limited = gr_name != nullptr; bool limited = gr_name != nullptr;
return {rate, limited}; return {rate, limited};
} }
std::pair<double, bool> std::pair<double, bool>
GasLiftSingleWellGeneric::getGasRateWithGroupLimit_(double new_gas_rate, double gas_rate) const GasLiftSingleWellGeneric::getGasRateWithGroupLimit_(double new_gas_rate, double gas_rate, const std::string& gr_name_no_check) const
{ {
[[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::gas, new_gas_rate, gas_rate); [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::gas, new_gas_rate, gas_rate, gr_name_no_check);
bool limited = gr_name != nullptr; bool limited = gr_name != nullptr;
return {rate, limited}; return {rate, limited};
} }
std::pair<double, bool> std::pair<double, bool>
GasLiftSingleWellGeneric::getWaterRateWithGroupLimit_(double new_water_rate, double water_rate) const GasLiftSingleWellGeneric::getWaterRateWithGroupLimit_(double new_water_rate, double water_rate, const std::string& gr_name_no_check) const
{ {
[[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::water, new_water_rate, water_rate); [[maybe_unused]] auto [rate, gr_name, efficiency] = getRateWithGroupLimit_(Rate::water, new_water_rate, water_rate, gr_name_no_check);
bool limited = gr_name != nullptr; bool limited = gr_name != nullptr;
return {rate, limited}; return {rate, limited};
} }
@ -694,12 +700,13 @@ std::tuple<double, double, bool, bool>
GasLiftSingleWellGeneric::getLiquidRateWithGroupLimit_(const double new_oil_rate, GasLiftSingleWellGeneric::getLiquidRateWithGroupLimit_(const double new_oil_rate,
const double oil_rate, const double oil_rate,
const double new_water_rate, const double new_water_rate,
const double water_rate) const const double water_rate,
const std::string& gr_name_no_check) const
{ {
auto liquid_rate = oil_rate + water_rate; auto liquid_rate = oil_rate + water_rate;
auto new_liquid_rate = new_oil_rate + new_water_rate; auto new_liquid_rate = new_oil_rate + new_water_rate;
auto [liquid_rate_limited, group_name, efficiency] auto [liquid_rate_limited, group_name, efficiency]
= getRateWithGroupLimit_(Rate::liquid, new_liquid_rate, liquid_rate); = getRateWithGroupLimit_(Rate::liquid, new_liquid_rate, liquid_rate, gr_name_no_check);
bool limited = group_name != nullptr; bool limited = group_name != nullptr;
if (limited) { if (limited) {
// the oil, gas, and water cases can be handled directly by // the oil, gas, and water cases can be handled directly by
@ -730,7 +737,7 @@ GasLiftSingleWellGeneric::getLiquidRateWithGroupLimit_(const double new_oil_rate
} }
std::tuple<double, const std::string*, double> std::tuple<double, const std::string*, double>
GasLiftSingleWellGeneric::getRateWithGroupLimit_(Rate rate_type, const double new_rate, const double old_rate) const GasLiftSingleWellGeneric::getRateWithGroupLimit_(Rate rate_type, const double new_rate, const double old_rate, const std::string& gr_name_no_check) const
{ {
const double delta_rate = new_rate - old_rate; const double delta_rate = new_rate - old_rate;
if (delta_rate > 0) { if (delta_rate > 0) {
@ -743,6 +750,9 @@ GasLiftSingleWellGeneric::getRateWithGroupLimit_(Rate rate_type, const double ne
double gr_target, new_gr_rate, efficiency; double gr_target, new_gr_rate, efficiency;
const std::string* group_name = nullptr; const std::string* group_name = nullptr;
for (const auto& [group_name_temp, efficiency_temp] : pairs) { for (const auto& [group_name_temp, efficiency_temp] : pairs) {
if (gr_name_no_check == group_name_temp)
continue;
auto gr_target_opt = this->group_info_.getTarget(rate_type, group_name_temp); auto gr_target_opt = this->group_info_.getTarget(rate_type, group_name_temp);
if (gr_target_opt) { if (gr_target_opt) {
double gr_target_temp = *gr_target_opt; double gr_target_temp = *gr_target_opt;
@ -1346,20 +1356,20 @@ GasLiftSingleWellGeneric::updateGroupRates_(const LimitedRates& rates,
} }
GasLiftSingleWellGeneric::LimitedRates GasLiftSingleWellGeneric::LimitedRates
GasLiftSingleWellGeneric::updateRatesToGroupLimits_(const BasicRates& old_rates, const LimitedRates& rates) const GasLiftSingleWellGeneric::updateRatesToGroupLimits_(const BasicRates& old_rates, const LimitedRates& rates, const std::string& gr_name) const
{ {
LimitedRates new_rates = rates; LimitedRates new_rates = rates;
auto [new_oil_rate, oil_is_limited] = getOilRateWithGroupLimit_(new_rates.oil, old_rates.oil); auto [new_oil_rate, oil_is_limited] = getOilRateWithGroupLimit_(new_rates.oil, old_rates.oil, gr_name);
if (oil_is_limited) { if (oil_is_limited) {
new_rates.oil_limiting_target = Rate::oil; new_rates.oil_limiting_target = Rate::oil;
} }
auto [new_gas_rate, gas_is_limited] = getGasRateWithGroupLimit_(new_rates.gas, old_rates.gas); auto [new_gas_rate, gas_is_limited] = getGasRateWithGroupLimit_(new_rates.gas, old_rates.gas, gr_name);
auto [new_water_rate, water_is_limited] = getWaterRateWithGroupLimit_(new_rates.water, old_rates.water); auto [new_water_rate, water_is_limited] = getWaterRateWithGroupLimit_(new_rates.water, old_rates.water, gr_name);
if (water_is_limited) { if (water_is_limited) {
new_rates.water_limiting_target = Rate::water; new_rates.water_limiting_target = Rate::water;
} }
auto [new_oil_rate2, new_water_rate2, oil_is_limited2, water_is_limited2] auto [new_oil_rate2, new_water_rate2, oil_is_limited2, water_is_limited2]
= getLiquidRateWithGroupLimit_(new_oil_rate, old_rates.oil, new_water_rate, old_rates.water); = getLiquidRateWithGroupLimit_(new_oil_rate, old_rates.oil, new_water_rate, old_rates.water, gr_name);
if (oil_is_limited2) { if (oil_is_limited2) {
new_rates.oil_limiting_target = Rate::liquid; new_rates.oil_limiting_target = Rate::liquid;
} }
@ -1571,10 +1581,12 @@ GasLiftSingleWellGeneric::OptimizeState::checkAlqOutsideLimits(double alq, [[may
} }
bool bool
GasLiftSingleWellGeneric::checkGroupALQrateExceeded(double delta_alq) const GasLiftSingleWellGeneric::checkGroupALQrateExceeded(double delta_alq, const std::string& gr_name_no_check) const
{ {
const auto& pairs = group_info_.getWellGroups(well_name_); const auto& pairs = group_info_.getWellGroups(well_name_);
for (const auto& [group_name, efficiency] : pairs) { for (const auto& [group_name, efficiency] : pairs) {
if (gr_name_no_check == group_name)
continue;
auto max_alq_opt = group_info_.maxAlq(group_name); auto max_alq_opt = group_info_.maxAlq(group_name);
if (max_alq_opt) { if (max_alq_opt) {
double alq = group_info_.alqRate(group_name) + efficiency * delta_alq; double alq = group_info_.alqRate(group_name) + efficiency * delta_alq;

View File

@ -95,7 +95,8 @@ public:
std::optional<GradInfo> calcIncOrDecGradient(double oil_rate, double gas_rate, std::optional<GradInfo> calcIncOrDecGradient(double oil_rate, double gas_rate,
double water_rate, double water_rate,
double alq, bool increase) const; double alq,
const Group& group, bool increase) const;
std::unique_ptr<GasLiftWellState> runOptimize(const int iteration_idx); std::unique_ptr<GasLiftWellState> runOptimize(const int iteration_idx);
@ -239,7 +240,7 @@ protected:
double getBhpWithLimit(); double getBhpWithLimit();
void warn_(std::string msg) {parent.displayWarning_(msg);} void warn_(std::string msg) {parent.displayWarning_(msg);}
}; };
bool checkGroupALQrateExceeded(double delta_alq) const; bool checkGroupALQrateExceeded(double delta_alq, const std::string& gr_name_no_check = "") const;
bool checkGroupTotalRateExceeded(double delta_alq, double delta_gas_rate) const; bool checkGroupTotalRateExceeded(double delta_alq, double delta_gas_rate) const;
std::pair<std::optional<double>, bool> addOrSubtractAlqIncrement_( std::pair<std::optional<double>, bool> addOrSubtractAlqIncrement_(
@ -274,14 +275,14 @@ protected:
std::pair<double, bool> getGasRateWithLimit_( std::pair<double, bool> getGasRateWithLimit_(
const BasicRates& rates) const; const BasicRates& rates) const;
std::pair<double, bool> getGasRateWithGroupLimit_( std::pair<double, bool> getGasRateWithGroupLimit_(
double new_gas_rate, double gas_rate) const; double new_gas_rate, double gas_rate, const std::string& gr_name_no_check) const;
std::pair<std::optional<LimitedRates>,double> getInitialRatesWithLimit_() const; std::pair<std::optional<LimitedRates>,double> getInitialRatesWithLimit_() const;
LimitedRates getLimitedRatesFromRates_(const BasicRates& rates) const; LimitedRates getLimitedRatesFromRates_(const BasicRates& rates) const;
std::tuple<double,double,bool,bool> getLiquidRateWithGroupLimit_( std::tuple<double,double,bool,bool> getLiquidRateWithGroupLimit_(
const double new_oil_rate, const double oil_rate, const double new_oil_rate, const double oil_rate,
const double new_water_rate, const double water_rate) const; const double new_water_rate, const double water_rate, const std::string& gr_name_no_check) const;
std::pair<double, bool> getOilRateWithGroupLimit_( std::pair<double, bool> getOilRateWithGroupLimit_(
double new_oil_rate, double oil_rate) const; double new_oil_rate, double oil_rate, const std::string& gr_name_no_check) const;
std::pair<double, bool> getOilRateWithLimit_(const BasicRates& rates) const; std::pair<double, bool> getOilRateWithLimit_(const BasicRates& rates) const;
std::pair<double, std::optional<Rate>> getOilRateWithLimit2_( std::pair<double, std::optional<Rate>> getOilRateWithLimit2_(
const BasicRates& rates) const; const BasicRates& rates) const;
@ -290,9 +291,9 @@ protected:
std::pair<double, std::optional<Rate>> getRateWithLimit_( std::pair<double, std::optional<Rate>> getRateWithLimit_(
Rate rate_type, const BasicRates& rates) const; Rate rate_type, const BasicRates& rates) const;
std::tuple<double, const std::string*, double> getRateWithGroupLimit_( std::tuple<double, const std::string*, double> getRateWithGroupLimit_(
Rate rate_type, const double new_rate, const double old_rate) const; Rate rate_type, const double new_rate, const double old_rate, const std::string& gr_name_no_check) const;
std::pair<double, bool> getWaterRateWithGroupLimit_( std::pair<double, bool> getWaterRateWithGroupLimit_(
double new_water_rate, double water_rate) const; double new_water_rate, double water_rate, const std::string& gr_name_no_check) const;
std::pair<double, bool> getWaterRateWithLimit_(const BasicRates& rates) const; std::pair<double, bool> getWaterRateWithLimit_(const BasicRates& rates) const;
std::pair<double, std::optional<Rate>> getWaterRateWithLimit2_( std::pair<double, std::optional<Rate>> getWaterRateWithLimit2_(
const BasicRates& rates) const; const BasicRates& rates) const;
@ -323,7 +324,7 @@ protected:
const LimitedRates& new_rates, const LimitedRates& new_rates,
double delta_alq) const; double delta_alq) const;
LimitedRates updateRatesToGroupLimits_( LimitedRates updateRatesToGroupLimits_(
const BasicRates& rates, const LimitedRates& new_rates) const; const BasicRates& rates, const LimitedRates& new_rates, const std::string& gr_name = "") const;
void updateWellStateAlqFixedValue_(const GasLiftOpt::Well& well); void updateWellStateAlqFixedValue_(const GasLiftOpt::Well& well);
bool useFixedAlq_(const GasLiftOpt::Well& well); bool useFixedAlq_(const GasLiftOpt::Well& well);
void debugInfoGroupRatesExceedTarget( void debugInfoGroupRatesExceedTarget(

View File

@ -132,7 +132,7 @@ addOrRemoveALQincrement_(GradMap &grad_map, const std::string& well_name, bool a
std::optional<GasLiftStage2::GradInfo> std::optional<GasLiftStage2::GradInfo>
GasLiftStage2:: GasLiftStage2::
calcIncOrDecGrad_( calcIncOrDecGrad_(
const std::string well_name, const GasLiftSingleWell &gs_well, bool increase) const std::string well_name, const GasLiftSingleWell &gs_well, const Group& group, bool increase)
{ {
// only applies to wells in the well_state_map (i.e. wells on this rank) // only applies to wells in the well_state_map (i.e. wells on this rank)
@ -158,7 +158,7 @@ calcIncOrDecGrad_(
else { else {
auto [oil_rate, gas_rate] = state.getRates(); auto [oil_rate, gas_rate] = state.getRates();
auto alq = state.alq(); auto alq = state.alq();
auto grad = gs_well.calcIncOrDecGradient(oil_rate, gas_rate, state.waterRate(), alq, increase); auto grad = gs_well.calcIncOrDecGradient(oil_rate, gas_rate, state.waterRate(), alq, group, increase);
if (grad) { if (grad) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"well {} : adding {} gradient = {}", "well {} : adding {} gradient = {}",
@ -582,7 +582,7 @@ optimizeGroupsRecursive_(const Group &group)
void void
GasLiftStage2:: GasLiftStage2::
recalculateGradientAndUpdateData_( recalculateGradientAndUpdateData_(
GradPairItr &grad_itr, bool increase, GradPairItr &grad_itr, const Group& group, bool increase,
//incremental and decremental gradients, if 'grads' are incremental, then //incremental and decremental gradients, if 'grads' are incremental, then
// 'other_grads' are decremental, or conversely, if 'grads' are decremental, then // 'other_grads' are decremental, or conversely, if 'grads' are decremental, then
@ -598,7 +598,7 @@ recalculateGradientAndUpdateData_(
// the grads and other grads are synchronized later // the grads and other grads are synchronized later
if(this->stage1_wells_.count(name) > 0) { if(this->stage1_wells_.count(name) > 0) {
GasLiftSingleWell &gs_well = *(this->stage1_wells_.at(name).get()); GasLiftSingleWell &gs_well = *(this->stage1_wells_.at(name).get());
auto grad = calcIncOrDecGrad_(name, gs_well, increase); auto grad = calcIncOrDecGrad_(name, gs_well, group, increase);
if (grad) { if (grad) {
grad_itr->second = grad->grad; grad_itr->second = grad->grad;
old_grad = updateGrad_(name, *grad, increase); old_grad = updateGrad_(name, *grad, increase);
@ -785,7 +785,7 @@ removeSurplusALQ_(const Group &group,
state.updateRates(well_name); state.updateRates(well_name);
state.addOrRemoveALQincrement( this->dec_grads_, well_name, /*add=*/false); state.addOrRemoveALQincrement( this->dec_grads_, well_name, /*add=*/false);
recalculateGradientAndUpdateData_( recalculateGradientAndUpdateData_(
dec_grad_itr, /*increase=*/false, dec_grads, inc_grads); dec_grad_itr, group, /*increase=*/false, dec_grads, inc_grads);
// The dec_grads and inc_grads needs to be syncronized across ranks // The dec_grads and inc_grads needs to be syncronized across ranks
mpiSyncGlobalGradVector_(dec_grads); mpiSyncGlobalGradVector_(dec_grads);
@ -892,12 +892,12 @@ calculateEcoGradients(std::vector<GasLiftSingleWell *> &wells,
for (auto well_ptr : wells) { for (auto well_ptr : wells) {
const auto &gs_well = *well_ptr; // gs = GasLiftSingleWell const auto &gs_well = *well_ptr; // gs = GasLiftSingleWell
const auto &name = gs_well.name(); const auto &name = gs_well.name();
auto inc_grad = this->parent.calcIncOrDecGrad_(name, gs_well, /*increase=*/true); auto inc_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group, /*increase=*/true);
if (inc_grad) { if (inc_grad) {
inc_grads.emplace_back(std::make_pair(name, inc_grad->grad)); inc_grads.emplace_back(std::make_pair(name, inc_grad->grad));
this->parent.saveIncGrad_(name, *inc_grad); this->parent.saveIncGrad_(name, *inc_grad);
} }
auto dec_grad = this->parent.calcIncOrDecGrad_(name, gs_well, /*increase=*/false); auto dec_grad = this->parent.calcIncOrDecGrad_(name, gs_well, group, /*increase=*/false);
if (dec_grad) { if (dec_grad) {
dec_grads.emplace_back(std::make_pair(name, dec_grad->grad)); dec_grads.emplace_back(std::make_pair(name, dec_grad->grad));
this->parent.saveDecGrad_(name, *dec_grad); this->parent.saveDecGrad_(name, *dec_grad);
@ -984,9 +984,9 @@ recalculateGradients(
GradPairItr &min_dec_grad_itr, GradPairItr &max_inc_grad_itr) GradPairItr &min_dec_grad_itr, GradPairItr &max_inc_grad_itr)
{ {
this->parent.recalculateGradientAndUpdateData_( this->parent.recalculateGradientAndUpdateData_(
max_inc_grad_itr, /*increase=*/true, inc_grads, dec_grads); max_inc_grad_itr, this->group, /*increase=*/true, inc_grads, dec_grads);
this->parent.recalculateGradientAndUpdateData_( this->parent.recalculateGradientAndUpdateData_(
min_dec_grad_itr, /*increase=*/false, dec_grads, inc_grads); min_dec_grad_itr, this->group, /*increase=*/false, dec_grads, inc_grads);
// The dec_grads and inc_grads needs to be syncronized across ranks // The dec_grads and inc_grads needs to be syncronized across ranks
this->parent.mpiSyncGlobalGradVector_(dec_grads); this->parent.mpiSyncGlobalGradVector_(dec_grads);

View File

@ -78,7 +78,7 @@ protected:
void addOrRemoveALQincrement_( void addOrRemoveALQincrement_(
GradMap& grad_map, const std::string& well_name, bool add); GradMap& grad_map, const std::string& well_name, bool add);
std::optional<GradInfo> calcIncOrDecGrad_( std::optional<GradInfo> calcIncOrDecGrad_(
const std::string name, const GasLiftSingleWell& gs_well, bool increase); const std::string name, const GasLiftSingleWell& gs_well, const Group& group, bool increase);
bool checkRateAlreadyLimited_(GasLiftWellState& state, bool increase); bool checkRateAlreadyLimited_(GasLiftWellState& state, bool increase);
GradInfo deleteDecGradItem_(const std::string& name); GradInfo deleteDecGradItem_(const std::string& name);
GradInfo deleteIncGradItem_(const std::string& name); GradInfo deleteIncGradItem_(const std::string& name);
@ -102,7 +102,7 @@ protected:
void optimizeGroup_(const Group& group); void optimizeGroup_(const Group& group);
void optimizeGroupsRecursive_(const Group& group); void optimizeGroupsRecursive_(const Group& group);
void recalculateGradientAndUpdateData_( void recalculateGradientAndUpdateData_(
GradPairItr& grad_itr, bool increase, GradPairItr& grad_itr, const Group& group, bool increase,
std::vector<GradPair>& grads, std::vector<GradPair>& other_grads); std::vector<GradPair>& grads, std::vector<GradPair>& other_grads);
void redistributeALQ_( void redistributeALQ_(
std::vector<GasLiftSingleWell *>& wells, const Group& group, std::vector<GasLiftSingleWell *>& wells, const Group& group,