Merge pull request #4214 from totto82/glift3_fix

Fixes related to gaslift stage 2
This commit is contained in:
Tor Harald Sandve 2022-11-21 14:40:52 +01:00 committed by GitHub
commit 5c26be0c28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 853 additions and 807 deletions

View File

@ -1044,6 +1044,7 @@ BlackoilWellModelGeneric::
gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
GLiftProdWells& prod_wells,
GLiftOptWells& glift_wells,
GasLiftGroupInfo& group_info,
GLiftWellStateMap& glift_well_state_map,
const int episodeIndex)
{
@ -1053,8 +1054,10 @@ gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
summaryState_,
deferred_logger,
this->wellState(),
this->groupState(),
prod_wells,
glift_wells,
group_info,
glift_well_state_map,
this->glift_debug
};

View File

@ -47,6 +47,7 @@ namespace Opm {
class EclipseState;
class GasLiftSingleWellGeneric;
class GasLiftWellState;
class GasLiftGroupInfo;
class Group;
class GuideRateConfig;
class ParallelWellInfo;
@ -305,6 +306,7 @@ protected:
void gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
GLiftProdWells& prod_wells,
GLiftOptWells& glift_wells,
GasLiftGroupInfo& group_info,
GLiftWellStateMap& map,
const int episodeIndex);

View File

@ -986,6 +986,7 @@ namespace Opm {
phase_usage_,
deferred_logger,
this->wellState(),
this->groupState(),
ebosSimulator_.vanguard().grid().comm(),
this->glift_debug
};
@ -993,7 +994,7 @@ namespace Opm {
gasLiftOptimizationStage1(
deferred_logger, prod_wells, glift_wells, group_info, state_map);
gasLiftOptimizationStage2(
deferred_logger, prod_wells, glift_wells, state_map,
deferred_logger, prod_wells, glift_wells, group_info, state_map,
ebosSimulator_.episodeIndex());
if (this->glift_debug) gliftDebugShowALQ(deferred_logger);
num_wells_changed = glift_wells.size();

View File

@ -25,11 +25,13 @@ namespace Opm {
GasLiftCommon::
GasLiftCommon(
WellState &well_state,
const GroupState &group_state,
DeferredLogger &deferred_logger,
const Parallel::Communication& comm,
bool glift_debug
) :
well_state_{well_state},
group_state_{group_state},
deferred_logger_{deferred_logger},
comm_{comm},
debug{glift_debug}

View File

@ -22,6 +22,7 @@
#include <opm/simulators/utils/DeferredLogger.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <string>
#include <fmt/format.h>
@ -36,6 +37,7 @@ public:
protected:
GasLiftCommon(
WellState &well_state,
const GroupState &group_state,
DeferredLogger &deferred_logger,
const Parallel::Communication& comm,
bool debug
@ -51,6 +53,7 @@ protected:
MessageType msg_type = MessageType::INFO) const;
WellState &well_state_;
const GroupState& group_state_;
DeferredLogger &deferred_logger_;
const Parallel::Communication& comm_;
bool debug;

View File

@ -32,10 +32,11 @@ GasLiftGroupInfo(
const PhaseUsage &phase_usage,
DeferredLogger &deferred_logger,
WellState &well_state,
const GroupState &group_state,
const Communication &comm,
bool glift_debug
) :
GasLiftCommon(well_state, deferred_logger, comm, glift_debug)
GasLiftCommon(well_state, group_state, deferred_logger, comm, glift_debug)
, ecl_wells_{ecl_wells}
, schedule_{schedule}
, summary_state_{summary_state}
@ -74,6 +75,28 @@ gasRate(const std::string& group_name) const
return group_rate.gasRate();
}
double
GasLiftGroupInfo::
gasPotential(const std::string& group_name) const
{
auto& group_rate = this->group_rate_map_.at(group_name);
return group_rate.gasPotential();
}
double
GasLiftGroupInfo::
waterPotential(const std::string& group_name) const
{
auto& group_rate = this->group_rate_map_.at(group_name);
return group_rate.waterPotential();
}
double
GasLiftGroupInfo::
oilPotential(const std::string& group_name) const
{
auto& group_rate = this->group_rate_map_.at(group_name);
return group_rate.oilPotential();
}
std::optional<double>
GasLiftGroupInfo::
gasTarget(const std::string& group_name) const
@ -100,6 +123,24 @@ getRate(Rate rate_type, const std::string& group_name) const
throw std::runtime_error("This should not happen");
}
}
double
GasLiftGroupInfo::
getPotential(Rate rate_type, const std::string& group_name) const
{
switch (rate_type) {
case Rate::oil:
return oilPotential(group_name);
case Rate::gas:
return gasPotential(group_name);
case Rate::water:
return waterPotential(group_name);
case Rate::liquid:
return oilPotential(group_name) + waterPotential(group_name);
default:
// Need this to avoid compiler warning : control reaches end of non-void function
throw std::runtime_error("This should not happen");
}
}
std::tuple<double, double, double, double>
GasLiftGroupInfo::
@ -437,36 +478,56 @@ displayDebugMessage_(const std::string &msg, const std::string &well_name)
}
std::tuple<double, double, double>
std::tuple<double, double, double, double, double, double>
GasLiftGroupInfo::
getProducerWellRates_(int well_index)
getProducerWellRates_(const Well* well, int well_index)
{
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]
const auto oil_pot = pu.phase_used[Oil]
? wrate[pu.phase_pos[Oil]]
: 0.0;
const auto gas_rate = pu.phase_used[Gas]
const auto gas_pot = pu.phase_used[Gas]
? wrate[pu.phase_pos[Gas]]
: 0.0;
const auto water_rate = pu.phase_used[Water]
const auto water_pot = pu.phase_used[Water]
? wrate[pu.phase_pos[Water]]
: 0.0;
return {oil_rate, gas_rate, water_rate};
const auto controls = well->productionControls(this->summary_state_);
double oil_rate = oil_pot;
if (controls.hasControl(Well::ProducerCMode::ORAT)) {
oil_rate = std::min(controls.oil_rate, oil_rate);
}
double gas_rate = gas_pot;
if (controls.hasControl(Well::ProducerCMode::GRAT)) {
gas_rate = std::min(controls.gas_rate, gas_rate);
}
double water_rate = water_pot;
if (controls.hasControl(Well::ProducerCMode::WRAT)) {
water_rate = std::min(controls.water_rate, water_rate);
}
if (controls.hasControl(Well::ProducerCMode::LRAT)) {
double liquid_rate = oil_rate + water_rate;
double liquid_rate_lim = std::min(controls.liquid_rate, liquid_rate);
water_rate = water_rate / liquid_rate * liquid_rate_lim;
oil_rate = oil_rate / liquid_rate * liquid_rate_lim;
}
return {oil_rate, gas_rate, water_rate, oil_pot, gas_pot, water_pot};
}
std::tuple<double, double, double, double>
std::tuple<double, double, double, double, double, double, double>
GasLiftGroupInfo::
initializeGroupRatesRecursive_(const Group &group)
{
std::array<double,4> rates{};
std::array<double,7> rates{};
if (this->debug) debugStartInitializeGroup(group.name());
auto& [oil_rate, water_rate, gas_rate, alq] = rates;
auto& [oil_rate, water_rate, gas_rate, oil_potential, water_potential, gas_potential, alq] = rates;
if (group.wellgroup()) {
for (const std::string& well_name : group.wells()) {
// NOTE: we cannot simply use:
@ -481,17 +542,21 @@ initializeGroupRatesRecursive_(const Group &group)
assert(well); // Should never be nullptr
const int index = (itr->second).second;
if (well->isProducer()) {
auto [sw_oil_rate, sw_gas_rate, sw_water_rate] = getProducerWellRates_(index);
auto [sw_oil_rate, sw_gas_rate, sw_water_rate, sw_oil_pot, sw_gas_pot, sw_water_pot] = getProducerWellRates_(well, index);
auto sw_alq = this->well_state_.getALQ(well_name);
double factor = well->getEfficiencyFactor();
oil_rate += (factor * sw_oil_rate);
gas_rate += (factor * sw_gas_rate);
water_rate += (factor * sw_water_rate);
oil_potential += (factor * sw_oil_pot);
gas_potential += (factor * sw_gas_pot);
water_potential += (factor * sw_water_pot);
alq += (factor * sw_alq);
if (this->debug) {
debugDisplayWellContribution_(
group.name(), well_name, factor,
sw_oil_rate, sw_gas_rate, sw_water_rate, sw_alq,
sw_oil_pot, sw_gas_pot, sw_water_pot, sw_alq,
oil_rate, gas_rate, water_rate, alq
);
}
@ -506,12 +571,16 @@ initializeGroupRatesRecursive_(const Group &group)
continue;
const Group& sub_group = this->schedule_.getGroup(
group_name, this->report_step_idx_);
auto [sg_oil_rate, sg_gas_rate, sg_water_rate, sg_alq]
auto [sg_oil_rate, sg_gas_rate, sg_water_rate,
sg_oil_pot, sg_gas_pot, sg_water_pot, sg_alq]
= initializeGroupRatesRecursive_(sub_group);
const auto gefac = sub_group.getGroupEfficiencyFactor();
oil_rate += (gefac * sg_oil_rate);
gas_rate += (gefac * sg_gas_rate);
water_rate += (gefac * sg_water_rate);
oil_potential += (gefac * sg_oil_pot);
gas_potential += (gefac * sg_gas_pot);
water_potential += (gefac * sg_water_pot);
alq += (gefac * sg_alq);
}
}
@ -537,14 +606,29 @@ initializeGroupRatesRecursive_(const Group &group)
}
if (oil_target || liquid_target || water_target || gas_target || max_total_gas || max_alq) {
updateGroupIdxMap_(group.name());
if(oil_target)
oil_rate = std::min(oil_rate, *oil_target);
if(gas_target)
gas_rate = std::min(gas_rate, *gas_target);
if(water_target)
water_rate = std::min(water_rate, *water_target);
if(liquid_target) {
double liquid_rate = oil_rate + water_rate;
double liquid_rate_limited = std::min(liquid_rate, *liquid_target);
oil_rate = oil_rate / liquid_rate * liquid_rate_limited;
water_rate = water_rate / liquid_rate * liquid_rate_limited;
}
this->group_rate_map_.try_emplace(group.name(),
oil_rate, gas_rate, water_rate, alq, oil_target, gas_target, water_target, liquid_target, max_total_gas, max_alq);
oil_rate, gas_rate, water_rate, alq,
oil_potential, gas_potential, water_potential,
oil_target, gas_target, water_target, liquid_target, max_total_gas, max_alq);
if (this->debug) {
debugDisplayUpdatedGroupRates(
group.name(), oil_rate, gas_rate, water_rate, alq);
}
}
return std::make_tuple(oil_rate, gas_rate, water_rate, alq);
return std::make_tuple(oil_rate, gas_rate, water_rate, oil_potential, gas_potential, water_potential, alq);
}
void

View File

@ -33,6 +33,7 @@
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/simulators/wells/GasLiftCommon.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <opm/simulators/utils/DeferredLogger.hpp>
#include <algorithm>
@ -81,6 +82,7 @@ public:
const PhaseUsage& phase_usage,
DeferredLogger& deferred_logger,
WellState& well_state,
const GroupState& group_state,
const Parallel::Communication& comm,
bool glift_debug
);
@ -89,8 +91,12 @@ public:
double alqRate(const std::string& group_name);
double gasRate(const std::string& group_name) const;
double gasPotential(const std::string& group_name) const;
double waterPotential(const std::string& group_name) const;
double oilPotential(const std::string& group_name) const;
int getGroupIdx(const std::string& group_name);
double getRate(Rate rate_type, const std::string& group_name) const;
double getPotential(Rate rate_type, const std::string& group_name) const;
std::tuple<double,double,double,double> getRates(const int group_idx) const;
std::optional<double> gasTarget(const std::string& group_name) const;
std::optional<double> getTarget(
@ -128,8 +134,9 @@ protected:
void debugStartInitializeGroup(const std::string& name) const;
void displayDebugMessage_(const std::string& msg) const override;
void displayDebugMessage_(const std::string& msg, const std::string& well_name);
std::tuple<double, double, double> getProducerWellRates_(const int index);
std::tuple<double, double, double, double>
std::tuple<double, double, double, double, double, double>
getProducerWellRates_(const Well* well, const int index);
std::tuple<double, double, double, double, double, double, double>
initializeGroupRatesRecursive_(const Group &group);
void initializeWell2GroupMapRecursive_(
const Group& group, std::vector<std::string>& group_names,
@ -140,6 +147,7 @@ protected:
class GroupRates {
public:
GroupRates( double oil_rate, double gas_rate, double water_rate, double alq,
double oil_potential, double gas_potential, double water_potential,
std::optional<double> oil_target,
std::optional<double> gas_target,
std::optional<double> water_target,
@ -151,6 +159,9 @@ protected:
gas_rate_{gas_rate},
water_rate_{water_rate},
alq_{alq},
oil_potential_{oil_potential},
gas_potential_{gas_potential},
water_potential_{water_potential},
oil_target_{oil_target},
gas_target_{gas_target},
water_target_{water_target},
@ -175,6 +186,9 @@ protected:
double oilRate() const { return oil_rate_; }
std::optional<double> oilTarget() const { return oil_target_; }
std::optional<double> liquidTarget() const { return liquid_target_; }
double oilPotential() const { return oil_potential_; }
double gasPotential() const { return gas_potential_; }
double waterPotential() const { return water_potential_; }
void update(double delta_oil, double delta_gas, double delta_water, double delta_alq)
{
@ -182,12 +196,17 @@ 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_;
double gas_rate_;
double water_rate_;
double alq_;
double oil_potential_;
double gas_potential_;
double water_potential_;
std::optional<double> oil_target_;
std::optional<double> gas_target_;
std::optional<double> water_target_;

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/simulators/wells/GasLiftGroupInfo.hpp>
#include <opm/simulators/wells/GasLiftCommon.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <functional>
#include <optional>
@ -93,7 +94,10 @@ public:
const std::string& name() const { return well_name_; }
std::optional<GradInfo> calcIncOrDecGradient(double oil_rate, double gas_rate,
double alq, bool increase) const;
double water_rate,
double alq,
const std::string& gr_name_dont_limit,
bool increase) const;
std::unique_ptr<GasLiftWellState> runOptimize(const int iteration_idx);
@ -237,7 +241,7 @@ protected:
double getBhpWithLimit();
void warn_(std::string msg) {parent.displayWarning_(msg);}
};
bool checkGroupALQrateExceeded(double delta_alq) 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<std::optional<double>, bool> addOrSubtractAlqIncrement_(
@ -272,14 +276,14 @@ protected:
std::pair<double, bool> getGasRateWithLimit_(
const BasicRates& rates) const;
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_dont_limit) const;
std::pair<std::optional<LimitedRates>,double> getInitialRatesWithLimit_() const;
LimitedRates getLimitedRatesFromRates_(const BasicRates& rates) const;
std::tuple<double,double,bool,bool> getLiquidRateWithGroupLimit_(
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_dont_limit) const;
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_dont_limit) const;
std::pair<double, bool> getOilRateWithLimit_(const BasicRates& rates) const;
std::pair<double, std::optional<Rate>> getOilRateWithLimit2_(
const BasicRates& rates) const;
@ -288,9 +292,9 @@ protected:
std::pair<double, std::optional<Rate>> getRateWithLimit_(
Rate rate_type, const BasicRates& rates) const;
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_dont_limit) const;
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_dont_limit) const;
std::pair<double, bool> getWaterRateWithLimit_(const BasicRates& rates) const;
std::pair<double, std::optional<Rate>> getWaterRateWithLimit2_(
const BasicRates& rates) const;
@ -321,14 +325,13 @@ protected:
const LimitedRates& new_rates,
double delta_alq) const;
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);
bool useFixedAlq_(const GasLiftOpt::Well& well);
void debugInfoGroupRatesExceedTarget(
Rate rate_type, const std::string& gr_name, double rate, double target) const;
void warnMaxIterationsExceeded_();
const GroupState& group_state_;
const Well& ecl_well_;
const SummaryState& summary_state_;
GasLiftGroupInfo& group_info_;

View File

@ -28,7 +28,7 @@
#include <opm/simulators/wells/GasLiftWellState.hpp>
#include <opm/simulators/wells/WellInterfaceGeneric.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/GasLiftGroupInfo.hpp>
#include <cmath>
#include <optional>
#include <string>
@ -44,14 +44,17 @@ GasLiftStage2::GasLiftStage2(
const SummaryState& summary_state,
DeferredLogger &deferred_logger,
WellState &well_state,
const GroupState &group_state,
GLiftProdWells &prod_wells,
GLiftOptWells &glift_wells,
GasLiftGroupInfo& group_info,
GLiftWellStateMap &state_map,
bool glift_debug
) :
GasLiftCommon(well_state, deferred_logger, comm, glift_debug)
GasLiftCommon(well_state, group_state, deferred_logger, comm, glift_debug)
, prod_wells_{prod_wells}
, stage1_wells_{glift_wells}
, group_info_{group_info}
, well_state_map_{state_map}
, report_step_idx_{report_step_idx}
, summary_state_{summary_state}
@ -114,24 +117,25 @@ addOrRemoveALQincrement_(GradMap &grad_map, const std::string& well_name, bool a
}
state.update(gi.new_oil_rate, gi.oil_is_limited,
gi.new_gas_rate, gi.gas_is_limited,
gi.alq, gi.alq_is_limited, gi.new_water_rate, add);
this->well_state_.setALQ(well_name, gi.alq);
const auto& pu = this->well_state_.phaseUsage();
std::vector<double> well_pot(pu.num_phases, 0.0);
if(pu.phase_used[BlackoilPhases::PhaseIndex::Liquid])
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Liquid]] = gi.new_oil_rate;
if(pu.phase_used[BlackoilPhases::PhaseIndex::Aqua])
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Aqua]] = gi.new_water_rate;
if(pu.phase_used[BlackoilPhases::PhaseIndex::Vapour])
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Vapour]] = gi.new_gas_rate;
gi.alq, gi.alq_is_limited, gi.new_water_rate, gi.water_is_limited, add);
this->well_state_[well_name].well_potentials = well_pot;
this->well_state_.setALQ(well_name, gi.alq);
const auto& pu = this->well_state_.phaseUsage();
std::vector<double> well_pot(pu.num_phases, 0.0);
if(pu.phase_used[BlackoilPhases::PhaseIndex::Liquid])
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Liquid]] = gi.new_oil_rate;
if(pu.phase_used[BlackoilPhases::PhaseIndex::Aqua])
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Aqua]] = gi.new_water_rate;
if(pu.phase_used[BlackoilPhases::PhaseIndex::Vapour])
well_pot[pu.phase_pos[BlackoilPhases::PhaseIndex::Vapour]] = gi.new_gas_rate;
this->well_state_[well_name].well_potentials = well_pot;
}
std::optional<GasLiftStage2::GradInfo>
GasLiftStage2::
calcIncOrDecGrad_(
const std::string well_name, const GasLiftSingleWell &gs_well, 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)
@ -157,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, alq, 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 = {}",
@ -191,7 +195,7 @@ checkRateAlreadyLimited_(GasLiftWellState &state, bool increase)
if (increase) do_check = true;
}
if (do_check) {
if (state.gasIsLimited() || state.oilIsLimited() || state.alqIsLimited()) {
if (state.gasIsLimited() || state.oilIsLimited() || state.alqIsLimited() || state.waterIsLimited()) {
const std::string msg = fmt::format(
"{} gradient : skipping since {} was limited in previous step",
(increase ? "incremental" : "decremental"),
@ -272,152 +276,34 @@ displayDebugMessage_(const std::string &msg, const std::string &group_name)
}
}
std::tuple<double, double, double>
std::tuple<double, double, double, double>
GasLiftStage2::
getCurrentGroupRates_(const Group &group)
{
auto rates = getCurrentGroupRatesRecursive_(group);
this->comm_.sum(rates.data(), rates.size());
auto [oil_rate, gas_rate, alq] = rates;
if (this->debug) {
const std::string msg = fmt::format(
"Current group rates for {} : oil: {}, gas: {}, alq: {}",
group.name(), oil_rate, gas_rate, alq);
displayDebugMessageOnRank0_(msg);
}
return {oil_rate, gas_rate, alq};
return {this->group_info_.oilRate(group.name()),
this->group_info_.gasRate(group.name()),
this->group_info_.waterRate(group.name()),
this->group_info_.alqRate(group.name())};
}
std::array <double, 3>
GasLiftStage2::
getCurrentGroupRatesRecursive_(const Group &group)
std::optional<double>
GasLiftStage2::getGroupMaxALQ_(const Group &group)
{
double oil_rate = 0.0;
double gas_rate = 0.0;
double alq = 0.0;
// NOTE: A group can either contain wells or groups, but not both
if (group.wellgroup()) {
for (const std::string& well_name : group.wells()) {
auto [sw_oil_rate, sw_gas_rate, sw_alq] =
getCurrentWellRates_(well_name, group.name());
oil_rate += sw_oil_rate;
gas_rate += sw_gas_rate;
alq += sw_alq;
}
if (this->glo_.has_group(group.name())) {
const auto &gl_group = this->glo_.group(group.name());
return gl_group.max_lift_gas();
}
else {
for (const std::string& group_name : group.groups()) {
if(this->schedule_.back().groups.has(group_name)) {
const Group& sub_group =
this->schedule_.getGroup(group_name, this->report_step_idx_);
// If groups have efficiency factors to model
// synchronized downtime of their subordinate wells
// (see keyword GEFAC), their lift gas injection rates
// are multiplied by their efficiency factors when
// they are added to the lift gas supply rate of the
// parent group.
const auto gefac = sub_group.getGroupEfficiencyFactor();
auto rates = getCurrentGroupRatesRecursive_(sub_group);
auto [sg_oil_rate, sg_gas_rate, sg_alq] = rates;
oil_rate += (gefac * sg_oil_rate);
gas_rate += (gefac * sg_gas_rate);
alq += (gefac * sg_alq);
}
}
}
return {oil_rate, gas_rate, alq};
return std::nullopt; // If GLIFTOPT is missing from schedule, assume unlimited alq
}
std::tuple<double, double, double>
GasLiftStage2::
getCurrentWellRates_(const std::string &well_name, const std::string &group_name)
std::optional<double>
GasLiftStage2::getGroupMaxTotalGas_(const Group &group)
{
double oil_rate, gas_rate, alq;
bool success = false;
const WellInterfaceGeneric *well_ptr = nullptr;
std::string debug_info;
if (this->stage1_wells_.count(well_name) == 1) {
GasLiftSingleWell &gs_well = *(this->stage1_wells_.at(well_name).get());
const WellInterfaceGeneric &well = gs_well.getWell();
well_ptr = &well;
GasLiftWellState &state = *(this->well_state_map_.at(well_name).get());
std::tie(oil_rate, gas_rate) = state.getRates();
success = true;
if ( this->debug) debug_info = "(A)";
if (this->glo_.has_group(group.name())) {
const auto &gl_group = this->glo_.group(group.name());
return gl_group.max_total_gas();
}
else if (this->prod_wells_.count(well_name) == 1) {
well_ptr = this->prod_wells_.at(well_name);
std::tie(oil_rate, gas_rate) = getWellRates_(*well_ptr);
success = true;
if ( this->debug) debug_info = "(B)";
}
if (well_ptr) {
// we only want rates from wells owned by the rank
if (!well_state_.wellIsOwned(well_ptr->indexOfWell(), well_name)) {
success = false;
}
}
if (success) {
assert(well_ptr);
assert(well_ptr->isProducer());
alq = this->well_state_.getALQ(well_name);
if (this->debug) {
const std::string msg = fmt::format(
"Rates {} for well {} : oil: {}, gas: {}, alq: {}",
debug_info, well_name, oil_rate, gas_rate, alq);
displayDebugMessage_(msg, group_name);
}
// If wells have efficiency factors to take account of regular
// downtime (see keyword WEFAC), their lift gas injection
// rates are multiplied by their efficiency factors when they
// are added to the group lift gas supply rate. This is
// consistent with the summation of flow rates for wells with
// downtime, and preserves the ratio of production rate to
// lift gas injection rate.
const auto &well_ecl = well_ptr->wellEcl();
double factor = well_ecl.getEfficiencyFactor();
oil_rate *= factor;
gas_rate *= factor;
alq *= factor;
if (this->debug && (factor != 1)) {
const std::string msg = fmt::format(
"Well {} : efficiency factor {}. New rates : oil: {}, gas: {}, alq: {}",
well_name, factor, oil_rate, gas_rate, alq);
displayDebugMessage_(msg, group_name);
}
}
else {
// NOTE: This happens for wells that are not producers, or not active.
if (this->debug) {
const std::string msg = fmt::format("Could not determine current rates for "
"well {}: (not active or injector)", well_name);
displayDebugMessage_(msg, group_name);
}
oil_rate = 0.0; gas_rate = 0.0; alq = 0.0;
}
return std::make_tuple(oil_rate, gas_rate, alq);
}
std::pair<double, double>
GasLiftStage2::
getWellRates_(const WellInterfaceGeneric &well)
{
const int well_index = well.indexOfWell();
const auto& ws = this->well_state_.well(well_index);
const auto& pu = well.phaseUsage();
auto oil_rate = ws.well_potentials[pu.phase_pos[Oil]];
double gas_rate = 0.0;
// See comment for setupPhaseVariables_() in GasLiftSingleWell_impl.hpp
// about the two-phase oil-water case.
if (pu.phase_used[BlackoilPhases::Vapour]) {
gas_rate = ws.well_potentials[pu.phase_pos[Gas]];
}
return {oil_rate, gas_rate};
return std::nullopt; // If GLIFTOPT is missing from schedule, assume unlimited alq
}
// Find all subordinate wells of a given group.
@ -517,13 +403,16 @@ void
GasLiftStage2::
optimizeGroup_(const Group &group)
{
const auto &gl_group = this->glo_.group(group.name());
const auto &max_glift = gl_group.max_lift_gas();
const auto &max_total_gas = gl_group.max_total_gas();
if (group.has_control(Group::ProductionCMode::ORAT)
|| max_glift || max_total_gas)
const auto& group_name = group.name();
const auto prod_control = this->group_state_.production_control(group_name);
//if (group.has_control(Group::ProductionCMode::ORAT) || group.has_control(Group::ProductionCMode::LRAT)
// || max_glift || max_total_gas)
// NOTE: it only makes sense to try to optimize the distribution of the gaslift if the amount
// of gaslift is constrained either by the maximum allowed gaslift or total gas
// or the group is under individual control
if ((prod_control != Group::ProductionCMode::NONE) && (prod_control != Group::ProductionCMode::FLD))
{
displayDebugMessage_("optimizing", group.name());
displayDebugMessage_("optimizing", group_name);
auto wells = getGroupGliftWells_(group);
std::vector<GradPair> inc_grads;
std::vector<GradPair> dec_grads;
@ -531,7 +420,7 @@ optimizeGroup_(const Group &group)
removeSurplusALQ_(group, inc_grads, dec_grads);
}
else {
displayDebugMessage_("skipping", group.name());
displayDebugMessage_("skipping", group_name);
}
}
@ -546,22 +435,13 @@ optimizeGroupsRecursive_(const Group &group)
group_name, this->report_step_idx_);
optimizeGroupsRecursive_(sub_group);
}
// TODO: should we also optimize groups that do not have GLIFTOPT defined?
// (i.e. glo_.has_group(name) returns false)
// IF GLIFTOPT is not specified for the group or if item 2 of GLIFTOPT
// is defaulted, there is no maximum lift gas supply for the group.
// But even if there is no limit on the liftgas supply it can still
// be desireable to use as little ALQ as possible to achieve a
// group oil rate limit or gas rate limit.
if (this->glo_.has_group(group.name())) // only optimize if GLIFTOPT is given
optimizeGroup_(group);
optimizeGroup_(group);
}
void
GasLiftStage2::
recalculateGradientAndUpdateData_(
GradPairItr &grad_itr, 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
@ -577,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, 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);
@ -718,11 +598,11 @@ removeSurplusALQ_(const Group &group,
return;
}
assert(!dec_grads.empty());
const auto &gl_group = this->glo_.group(group.name());
const auto &max_glift = gl_group.max_lift_gas();
const auto max_glift = getGroupMaxALQ_(group);
const auto max_totalgas = getGroupMaxTotalGas_(group);
const auto controls = group.productionControls(this->summary_state_);
//const auto &max_total_gas = gl_group.max_total_gas();
auto [oil_rate, gas_rate, alq] = getCurrentGroupRates_(group);
auto [oil_rate, gas_rate, water_rate, alq] = getCurrentGroupRates_(group);
auto min_eco_grad = this->glo_.min_eco_gradient();
bool stop_iteration = false;
if (this->debug) {
@ -730,12 +610,15 @@ removeSurplusALQ_(const Group &group,
if (max_glift) max_glift_str = fmt::format("{}", *max_glift);
const std::string msg = fmt::format("Starting iteration for group: {}. "
"oil_rate = {}, oil_target = {}, gas_rate = {}, gas_target = {}, "
"alq = {}, max_alq = {}", group.name(), oil_rate, controls.oil_target,
gas_rate, controls.gas_target, alq, max_glift_str);
"water_rate = {}, liquid_target = {}, alq = {}, max_alq = {}",
group.name(), oil_rate, controls.oil_target,
gas_rate, controls.gas_target, water_rate, controls.liquid_target,
alq, max_glift_str);
displayDebugMessage_(msg);
}
SurplusState state {*this, group, oil_rate, gas_rate, alq,
min_eco_grad, controls.oil_target, controls.gas_target, max_glift };
SurplusState state {*this, group, oil_rate, gas_rate, water_rate, alq,
min_eco_grad, controls.oil_target, controls.gas_target, controls.water_target,
controls.liquid_target, max_glift, max_totalgas };
while (!stop_iteration) {
if (dec_grads.size() >= 2) {
@ -745,7 +628,12 @@ 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() || state.checkGasTarget() || state.checkALQlimit()) {
const auto delta = state.computeDelta(well_name);
const auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
if (state.checkOilTarget(delta_oil) || state.checkGasTarget(delta_gas)
|| state.checkLiquidTarget(delta_oil + delta_water) || state.checkWaterTarget(delta_water)
|| state.checkALQlimit(delta_alq, delta_gas))
{
remove = true;
}
else {
@ -757,10 +645,14 @@ removeSurplusALQ_(const Group &group,
if (state.checkEcoGradient(well_name, eco_grad)) remove = true;
}
if (remove) {
state.updateRates(well_name);
state.updateRates(delta);
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, /*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);
@ -777,11 +669,11 @@ removeSurplusALQ_(const Group &group,
}
if (state.it >= 1) {
if (this->debug) {
auto [oil_rate2, gas_rate2, alq2] = getCurrentGroupRates_(group);
auto [oil_rate2, gas_rate2, water_rate2, alq2] = getCurrentGroupRates_(group);
const std::string msg = fmt::format(
"Finished after {} iterations for group: {}."
" oil_rate = {}, gas_rate = {}, alq = {}", state.it,
group.name(), oil_rate2, gas_rate2, alq2);
" oil_rate = {}, gas_rate = {}, water_rate = {}, alq = {}", state.it,
group.name(), oil_rate2, gas_rate2, water_rate2, alq2);
displayDebugMessage_(msg);
}
}
@ -867,12 +759,12 @@ calculateEcoGradients(std::vector<GasLiftSingleWell *> &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, /*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, /*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);
@ -959,9 +851,9 @@ recalculateGradients(
GradPairItr &min_dec_grad_itr, GradPairItr &max_inc_grad_itr)
{
this->parent.recalculateGradientAndUpdateData_(
max_inc_grad_itr, /*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, /*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);
@ -1021,13 +913,11 @@ addOrRemoveALQincrement(GradMap &grad_map, const std::string& well_name, bool ad
bool
GasLiftStage2::SurplusState::
checkALQlimit()
checkALQlimit(double delta_alq, double delta_gas)
{
if (this->max_glift) {
double max_alq = *(this->max_glift);
double increment = this->parent.glo_.gaslift_increment();
double epsilon = 1e-6 * increment;
if ((max_alq+epsilon) < this->alq ) {
if ((max_alq) < (this->alq + delta_alq) ) {
if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : "
"ALQ rate {} is greater than ALQ limit {}", this->group.name(),
@ -1037,6 +927,19 @@ checkALQlimit()
return true;
}
}
if (this->max_total_gas) {
double max_total = *(this->max_total_gas);
double total_gas_rate = (this->alq + delta_alq + this->gas_rate + delta_gas);
if ((max_total) < total_gas_rate ) {
if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : "
"Total gas rate {} is greater than Total gas limit {}", this->group.name(),
total_gas_rate, max_total);
this->parent.displayDebugMessage_(msg);
}
return true;
}
}
return false;
}
@ -1060,10 +963,10 @@ checkEcoGradient(const std::string &well_name, double eco_grad)
bool
GasLiftStage2::SurplusState::
checkGasTarget()
checkGasTarget(double delta_gas)
{
if (this->group.has_control(Group::ProductionCMode::GRAT)) {
if (this->gas_target < this->gas_rate ) {
if (this->gas_target < (this->gas_rate + delta_gas) ) {
if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : "
"gas rate {} is greater than gas target {}", this->group.name(),
@ -1075,17 +978,19 @@ checkGasTarget()
}
return false;
}
bool
GasLiftStage2::SurplusState::
checkOilTarget()
checkLiquidTarget(double delta_liquid)
{
if (this->group.has_control(Group::ProductionCMode::ORAT)) {
if (this->oil_target < this->oil_rate ) {
if (this->group.has_control(Group::ProductionCMode::LRAT)) {
// the change in liquid rate from the is subtracted from the rate to make sure the
// group still can produce its target
auto liquid_rate = this->oil_rate + this->water_rate + delta_liquid;
if (this->liquid_target < (liquid_rate) ) {
if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : "
"oil rate {} is greater than oil target {}", this->group.name(),
this->oil_rate, this->oil_target);
"liquid rate {} is greater than liquid target {}", this->group.name(),
liquid_rate, this->liquid_target);
this->parent.displayDebugMessage_(msg);
}
return true;
@ -1094,11 +999,49 @@ checkOilTarget()
return false;
}
void
bool
GasLiftStage2::SurplusState::
updateRates(const std::string &well_name)
checkOilTarget(double delta_oil)
{
std::array<double, 3> delta = {0.0,0.0,0.0};
if (this->group.has_control(Group::ProductionCMode::ORAT)) {
// the change in oil rate from 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 + delta_oil) ) {
if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : "
"oil rate {} is greater than oil target {}", this->group.name(),
this->oil_rate - delta_oil, this->oil_target);
this->parent.displayDebugMessage_(msg);
}
return true;
}
}
return false;
}
bool
GasLiftStage2::SurplusState::
checkWaterTarget(double delta_water)
{
if (this->group.has_control(Group::ProductionCMode::WRAT)) {
if (this->water_target < (this->water_rate + delta_water) ) {
if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : "
"water rate {} is greater than oil target {}", this->group.name(),
this->water_rate, this->water_target);
this->parent.displayDebugMessage_(msg);
}
return true;
}
}
return false;
}
std::array<double, 4>
GasLiftStage2::SurplusState::
computeDelta(const std::string &well_name)
{
std::array<double, 4> delta = {0.0, 0.0, 0.0, 0.0};
// compute the delta on wells on own rank
if (this->parent.well_state_map_.count(well_name) > 0) {
const GradInfo &gi = this->parent.dec_grads_.at(well_name);
@ -1109,21 +1052,30 @@ updateRates(const std::string &well_name)
if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) {
const auto &well_ecl = well.wellEcl();
double factor = well_ecl.getEfficiencyFactor();
auto& [delta_oil, delta_gas, delta_alq] = delta;
delta_oil = factor * (gi.new_oil_rate - state.oilRate());
delta_gas = factor * (gi.new_gas_rate - state.gasRate());
delta_alq = factor * (gi.alq - state.alq());
auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
delta_oil = factor * (gi.new_oil_rate - state.oilRate());
delta_gas = factor * (gi.new_gas_rate - state.gasRate());
delta_water = factor * (gi.new_water_rate - state.waterRate());
delta_alq = factor * (gi.alq - state.alq());
}
}
// and communicate the results
this->parent.comm_.sum(delta.data(), delta.size());
// and update
const auto& [delta_oil, delta_gas, delta_alq] = delta;
return delta;
}
void
GasLiftStage2::SurplusState::
updateRates(const std::array<double, 4>& delta)
{
const auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
this->oil_rate += delta_oil;
this->gas_rate += delta_gas;
this->water_rate += delta_water;
this->alq += delta_alq;
}
} // namespace Opm

View File

@ -22,6 +22,7 @@
#include <opm/core/props/BlackoilPhases.hpp>
#include <opm/simulators/wells/GasLiftSingleWellGeneric.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <dune/common/version.hh>
#include <dune/common/parallel/mpihelper.hh>
@ -66,8 +67,10 @@ public:
const SummaryState& summary_state,
DeferredLogger& deferred_logger,
WellState& well_state,
const GroupState& group_state,
GLiftProdWells& prod_wells,
GLiftOptWells& glift_wells,
GasLiftGroupInfo& group_info,
GLiftWellStateMap& state_map,
bool glift_debug
);
@ -76,7 +79,7 @@ protected:
void addOrRemoveALQincrement_(
GradMap& grad_map, const std::string& well_name, bool add);
std::optional<GradInfo> calcIncOrDecGrad_(
const std::string name, const GasLiftSingleWell& gs_well, 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);
@ -86,21 +89,17 @@ protected:
void displayDebugMessage_(const std::string& msg, const std::string& group_name);
void displayWarning_(const std::string& msg, const std::string& group_name);
void displayWarning_(const std::string& msg);
std::tuple<double, double, double> getCurrentGroupRates_(
const Group& group);
std::array<double,3> getCurrentGroupRatesRecursive_(
const Group& group);
std::tuple<double, double, double> getCurrentWellRates_(
const std::string& well_name, const std::string& group_name);
std::tuple<double, double, double, double> getCurrentGroupRates_(const Group& group);
std::optional<double> getGroupMaxALQ_(const Group &group);
std::optional<double> getGroupMaxTotalGas_(const Group &group);
std::vector<GasLiftSingleWell *> getGroupGliftWells_(
const Group& group);
void getGroupGliftWellsRecursive_(
const Group& group, std::vector<GasLiftSingleWell *>& wells);
std::pair<double, double> getWellRates_(const WellInterfaceGeneric& well);
void optimizeGroup_(const Group& group);
void optimizeGroupsRecursive_(const Group& group);
void recalculateGradientAndUpdateData_(
GradPairItr& grad_itr, bool increase,
GradPairItr& grad_itr, const std::string& gr_name_dont_limit, bool increase,
std::vector<GradPair>& grads, std::vector<GradPair>& other_grads);
void redistributeALQ_(
std::vector<GasLiftSingleWell *>& wells, const Group& group,
@ -124,6 +123,7 @@ protected:
GLiftProdWells& prod_wells_;
GLiftOptWells& stage1_wells_;
GasLiftGroupInfo& group_info_;
GLiftWellStateMap& well_state_map_;
int report_step_idx_;
@ -169,38 +169,50 @@ protected:
struct SurplusState {
SurplusState( GasLiftStage2& parent_, const Group& group_,
double oil_rate_, double gas_rate_, double alq_, double min_eco_grad_,
double oil_target_, double gas_target_,
std::optional<double> max_glift_) :
double oil_rate_, double gas_rate_, double water_rate_, double alq_,
double min_eco_grad_,
double oil_target_, double gas_target_, double water_target_, double liquid_target_,
std::optional<double> max_glift_, std::optional<double> max_total_gas_) :
parent{parent_},
group{group_},
oil_rate{oil_rate_},
gas_rate{gas_rate_},
water_rate{water_rate_},
alq{alq_},
min_eco_grad{min_eco_grad_},
oil_target{oil_target_},
gas_target{gas_target_},
water_target(water_target_),
liquid_target{liquid_target_},
max_glift{max_glift_},
max_total_gas{max_total_gas_},
it{0}
{}
GasLiftStage2 &parent;
const Group &group;
double oil_rate;
double gas_rate;
double water_rate;
double alq;
const double min_eco_grad;
const double oil_target;
const double gas_target;
const double water_target;
const double liquid_target;
std::optional<double> max_glift;
std::optional<double> max_total_gas;
int it;
void addOrRemoveALQincrement(
GradMap &grad_map, const std::string& well_name, bool add);
bool checkALQlimit();
bool checkALQlimit(double delta_alq, double delta_gas);
bool checkEcoGradient(const std::string& well_name, double eco_grad);
bool checkGasTarget();
bool checkOilTarget();
void updateRates(const std::string& name);
bool checkGasTarget(double delta_gas);
bool checkLiquidTarget(double delta_liquid);
bool checkOilTarget(double delta_oil);
bool checkWaterTarget(double delta_water);
std::array<double, 4> computeDelta(const std::string& name);
void updateRates(const std::array<double, 4>& delta);
};
};

View File

@ -31,7 +31,7 @@ namespace Opm
//GasLiftWellState() { }
GasLiftWellState(double oil_rate, bool oil_is_limited,
double gas_rate, bool gas_is_limited,
double alq, bool alq_is_limited, double water_rate, std::optional<bool> increase) :
double alq, bool alq_is_limited, double water_rate, bool water_is_limited, std::optional<bool> increase) :
oil_rate_{oil_rate},
oil_is_limited_{oil_is_limited},
gas_rate_{gas_rate},
@ -39,6 +39,7 @@ namespace Opm
alq_{alq},
alq_is_limited_{alq_is_limited},
water_rate_{water_rate},
water_is_limited_{water_is_limited},
increase_{increase}
{}
double alq() const { return alq_; }
@ -51,9 +52,11 @@ namespace Opm
bool oilIsLimited() const { return oil_is_limited_; }
double oilRate() const { return oil_rate_; }
double waterRate() const { return water_rate_; }
bool waterIsLimited() const { return water_is_limited_; }
void update(double oil_rate, bool oil_is_limited,
double gas_rate, bool gas_is_limited,
double alq, bool alq_is_limited, double water_rate,
double water_is_limited,
bool increase)
{
oil_rate_ = oil_rate;
@ -63,6 +66,7 @@ namespace Opm
alq_ = alq;
alq_is_limited_ = alq_is_limited;
water_rate_ = water_rate;
water_is_limited_ = water_is_limited;
increase_ = increase;
}
private:
@ -73,6 +77,7 @@ namespace Opm
double alq_;
bool alq_is_limited_;
double water_rate_;
bool water_is_limited_;
std::optional<bool> increase_;
};

View File

@ -346,7 +346,6 @@ namespace Opm
deferred_logger.debug(msg);
return;
}
std::vector<double> potentials;
try {
computeWellPotentials(simulator, well_state_copy, potentials, deferred_logger);

View File

@ -181,6 +181,7 @@ BOOST_AUTO_TEST_CASE(G1)
well_model.phaseUsage(),
deferred_logger,
well_state,
group_state,
comm,
/*glift_debug=*/false
};