Limit well rates to honor group rates

If a well is under a group that is limited by a target, it should use as little gaslift as possible.
The reduction algorithm will reduce the gaslift of the well as long as the groups potential is above the groups target.
This commit is contained in:
Tor Harald Sandve 2022-02-01 12:55:04 +01:00
parent 29ec104bb6
commit 009134d037
5 changed files with 68 additions and 23 deletions

View File

@ -387,18 +387,18 @@ getProducerWellRates_(int well_index)
{ {
const auto& pu = this->phase_usage_; const auto& pu = this->phase_usage_;
const auto& ws= this->well_state_.well(well_index); const auto& ws= this->well_state_.well(well_index);
const auto& wrate = ws.surface_rates; const auto& wrate = ws.well_potentials;
const auto oil_rate = pu.phase_used[Oil] const auto oil_rate = pu.phase_used[Oil]
? -wrate[pu.phase_pos[Oil]] ? wrate[pu.phase_pos[Oil]]
: 0.0; : 0.0;
const auto gas_rate = pu.phase_used[Gas] const auto gas_rate = pu.phase_used[Gas]
? -wrate[pu.phase_pos[Gas]] ? wrate[pu.phase_pos[Gas]]
: 0.0; : 0.0;
const auto water_rate = pu.phase_used[Water] const auto water_rate = pu.phase_used[Water]
? -wrate[pu.phase_pos[Water]] ? wrate[pu.phase_pos[Water]]
: 0.0; : 0.0;
return {oil_rate, gas_rate, water_rate}; return {oil_rate, gas_rate, water_rate};

View File

@ -43,10 +43,11 @@ GasLiftSingleWellGeneric::GasLiftSingleWellGeneric(
const GroupState& group_state, const GroupState& group_state,
const Well& ecl_well, const Well& ecl_well,
const SummaryState& summary_state, const SummaryState& summary_state,
GasLiftGroupInfo &group_info, GasLiftGroupInfo& group_info,
const PhaseUsage& phase_usage,
const Schedule& schedule, const Schedule& schedule,
const int report_step_idx, const int report_step_idx,
GLiftSyncGroups &sync_groups, GLiftSyncGroups& sync_groups,
bool glift_debug bool glift_debug
) : ) :
GasLiftCommon(well_state, deferred_logger, glift_debug) GasLiftCommon(well_state, deferred_logger, glift_debug)
@ -54,6 +55,7 @@ GasLiftSingleWellGeneric::GasLiftSingleWellGeneric(
, ecl_well_{ecl_well} , ecl_well_{ecl_well}
, summary_state_{summary_state} , summary_state_{summary_state}
, group_info_{group_info} , group_info_{group_info}
, phase_usage_{phase_usage}
, sync_groups_{sync_groups} , sync_groups_{sync_groups}
, controls_{ecl_well_.productionControls(summary_state_)} , controls_{ecl_well_.productionControls(summary_state_)}
, num_phases_{well_state_.numPhases()} , num_phases_{well_state_.numPhases()}
@ -738,8 +740,16 @@ getRateWithGroupLimit_(
double gr_rate_temp = double gr_rate_temp =
this->group_info_.getRate(rate_type, group_name_temp); this->group_info_.getRate(rate_type, group_name_temp);
if (gr_rate_temp > gr_target_temp) { if (gr_rate_temp > gr_target_temp) {
warnGroupInfoGroupRatesExceedTarget( if (this->debug) {
rate_type, group_name_temp, gr_rate_temp, gr_target_temp); debugInfoGroupRatesExceedTarget(
rate_type, group_name_temp, gr_rate_temp, gr_target_temp);
}
group_name = &group_name_temp;
efficiency = efficiency_temp;
limited_rate = old_rate;
gr_target = gr_target_temp;
new_gr_rate = gr_rate_temp;
break;
} }
double new_gr_rate_temp = gr_rate_temp + efficiency_temp * delta_rate; double new_gr_rate_temp = gr_rate_temp + efficiency_temp * delta_rate;
if (new_gr_rate_temp > gr_target_temp) { if (new_gr_rate_temp > gr_target_temp) {
@ -782,7 +792,9 @@ getInitialRatesWithLimit_() const
displayDebugMessage_( displayDebugMessage_(
"Maybe limiting initial rates before optimize loop.."); "Maybe limiting initial rates before optimize loop..");
} }
limited_rates = getLimitedRatesFromRates_(*rates); auto temp_rates = getLimitedRatesFromRates_(*rates);
BasicRates old_rates = getWellStateRates_();
limited_rates = updateRatesToGroupLimits_(old_rates, temp_rates);
} }
return limited_rates; return limited_rates;
} }
@ -802,6 +814,35 @@ getLimitedRatesFromRates_(const BasicRates& rates) const
oil_limiting_target, water_limiting_target}; oil_limiting_target, water_limiting_target};
} }
GasLiftSingleWellGeneric::BasicRates
GasLiftSingleWellGeneric::
getWellStateRates_() const
{
const int well_index = this->well_state_.index(this->well_name_).value();
const auto& pu = this->phase_usage_;
const auto& ws= this->well_state_.well(well_index);
const auto& wrate = ws.well_potentials;
const auto oil_rate = pu.phase_used[Oil]
? wrate[pu.phase_pos[Oil]]
: 0.0;
const auto gas_rate = pu.phase_used[Gas]
? wrate[pu.phase_pos[Gas]]
: 0.0;
const auto water_rate = pu.phase_used[Water]
? wrate[pu.phase_pos[Water]]
: 0.0;
if (this->debug) {
const std::string msg = fmt::format("Initial surface rates: oil : {}, "
"gas : {}, water : {}", oil_rate, gas_rate, water_rate);
displayDebugMessage_(msg);
}
return BasicRates{oil_rate, water_rate, gas_rate, /*bhp_is_limited=*/false};
}
bool bool
GasLiftSingleWellGeneric:: GasLiftSingleWellGeneric::
hasProductionControl_(Rate rate) const hasProductionControl_(Rate rate) const
@ -1247,7 +1288,7 @@ updateGroupRates_(
GasLiftSingleWellGeneric::LimitedRates GasLiftSingleWellGeneric::LimitedRates
GasLiftSingleWellGeneric:: GasLiftSingleWellGeneric::
updateRatesToGroupLimits_( updateRatesToGroupLimits_(
const LimitedRates& old_rates, const LimitedRates& rates) const const BasicRates& old_rates, const LimitedRates& rates) const
{ {
LimitedRates new_rates = rates; LimitedRates new_rates = rates;
auto [new_oil_rate, oil_is_limited] = getOilRateWithGroupLimit_( auto [new_oil_rate, oil_is_limited] = getOilRateWithGroupLimit_(
@ -1340,14 +1381,13 @@ useFixedAlq_(const GasLiftOpt::Well& well)
void void
GasLiftSingleWellGeneric:: GasLiftSingleWellGeneric::
warnGroupInfoGroupRatesExceedTarget( debugInfoGroupRatesExceedTarget(
Rate rate_type, const std::string& gr_name, double rate, double target) const Rate rate_type, const std::string& gr_name, double rate, double target) const
{ {
double fraction = 100.0*std::fabs(rate-target)/target; const std::string msg = fmt::format("{} rate for group {} exceeds target: "
const std::string msg = fmt::format("Warning: {} rate for group {} exceeds target: " "rate = {}, target = {}, the old rate is kept.",
"rate = {}, target = {}, relative overrun = {}%",
GasLiftGroupInfo::rateToString(rate_type), GasLiftGroupInfo::rateToString(rate_type),
gr_name, rate, target, fraction); gr_name, rate, target);
displayDebugMessage_(msg); displayDebugMessage_(msg);
} }

View File

@ -95,15 +95,16 @@ public:
protected: protected:
GasLiftSingleWellGeneric( GasLiftSingleWellGeneric(
DeferredLogger &deferred_logger, DeferredLogger& deferred_logger,
WellState &well_state, WellState& well_state,
const GroupState& group_state, const GroupState& group_state,
const Well& ecl_well, const Well& ecl_well,
const SummaryState& summary_state, const SummaryState& summary_state,
GasLiftGroupInfo &group_info, GasLiftGroupInfo& group_info,
const PhaseUsage& phase_usage,
const Schedule& schedule, const Schedule& schedule,
const int report_step_idx, const int report_step_idx,
GLiftSyncGroups &sync_groups, GLiftSyncGroups& sync_groups,
bool glift_debug bool glift_debug
); );
@ -249,6 +250,7 @@ protected:
double oil_rate, double new_oil_rate, double oil_rate, double new_oil_rate,
double gas_rate, double new_gas_rate, double gas_rate, double new_gas_rate,
bool increase) const; bool increase) const;
void debugPrintWellStateRates() const;
void debugShowAlqIncreaseDecreaseCounts_(); void debugShowAlqIncreaseDecreaseCounts_();
void debugShowBhpAlqTable_(); void debugShowBhpAlqTable_();
void debugShowLimitingTargets_(const LimitedRates& rates) const; void debugShowLimitingTargets_(const LimitedRates& rates) const;
@ -282,6 +284,7 @@ protected:
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;
BasicRates getWellStateRates_() const;
bool hasProductionControl_(Rate rate) const; bool hasProductionControl_(Rate rate) const;
std::pair<LimitedRates, double> increaseALQtoPositiveOilRate_( std::pair<LimitedRates, double> increaseALQtoPositiveOilRate_(
double alq, const LimitedRates& orig_rates) const; double alq, const LimitedRates& orig_rates) const;
@ -306,10 +309,10 @@ protected:
const LimitedRates& new_rates, const LimitedRates& new_rates,
double delta_alq) const; double delta_alq) const;
LimitedRates updateRatesToGroupLimits_( LimitedRates updateRatesToGroupLimits_(
const LimitedRates& rates, const LimitedRates& new_rates) const; const BasicRates& rates, const LimitedRates& new_rates) 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 warnGroupInfoGroupRatesExceedTarget( void debugInfoGroupRatesExceedTarget(
Rate rate_type, const std::string& gr_name, double rate, double target) const; Rate rate_type, const std::string& gr_name, double rate, double target) const;
void warnMaxIterationsExceeded_(); void warnMaxIterationsExceeded_();
@ -317,6 +320,7 @@ protected:
const Well& ecl_well_; const Well& ecl_well_;
const SummaryState& summary_state_; const SummaryState& summary_state_;
GasLiftGroupInfo& group_info_; GasLiftGroupInfo& group_info_;
const PhaseUsage& phase_usage_;
GLiftSyncGroups& sync_groups_; GLiftSyncGroups& sync_groups_;
const Well::ProductionControls controls_; const Well::ProductionControls controls_;

View File

@ -40,6 +40,7 @@ GasLiftSingleWell(const StdWell &std_well,
std_well.wellEcl(), std_well.wellEcl(),
summary_state, summary_state,
group_info, group_info,
std_well.phaseUsage(),
ebos_simulator.vanguard().schedule(), ebos_simulator.vanguard().schedule(),
ebos_simulator.episodeIndex(), ebos_simulator.episodeIndex(),
sync_groups, sync_groups,

View File

@ -408,8 +408,8 @@ getStdWellRates_(const WellInterfaceGeneric &well)
const int well_index = well.indexOfWell(); const int well_index = well.indexOfWell();
const auto& ws = this->well_state_.well(well_index); const auto& ws = this->well_state_.well(well_index);
const auto& pu = well.phaseUsage(); const auto& pu = well.phaseUsage();
auto oil_rate = -ws.surface_rates[pu.phase_pos[Oil]]; auto oil_rate = ws.well_potentials[pu.phase_pos[Oil]];
auto gas_rate = -ws.surface_rates[pu.phase_pos[Gas]]; auto gas_rate = ws.well_potentials[pu.phase_pos[Gas]];
return {oil_rate, gas_rate}; return {oil_rate, gas_rate};
} }