added: support a scaling factor for well efficiency

This commit is contained in:
Arne Morten Kvarving 2024-12-11 12:21:18 +01:00
parent 3661501121
commit 82a9698d27
12 changed files with 45 additions and 21 deletions

View File

@ -1575,7 +1575,8 @@ calculateEfficiencyFactors(const int reportStepIdx)
{ {
for (auto& well : well_container_generic_) { for (auto& well : well_container_generic_) {
const Well& wellEcl = well->wellEcl(); const Well& wellEcl = well->wellEcl();
Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor(); Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor() *
wellState()[well->name()].efficiency_scaling_factor;
WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(), WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(),
reportStepIdx), reportStepIdx),
schedule(), schedule(),

View File

@ -648,7 +648,8 @@ namespace Opm {
// some preparation before the well can be used // some preparation before the well can be used
well->init(&this->phase_usage_, depth_, gravity_, B_avg_, true); well->init(&this->phase_usage_, depth_, gravity_, B_avg_, true);
Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor(); Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor() *
this->wellState()[well_name].efficiency_scaling_factor;
WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(), WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(),
timeStepIdx), timeStepIdx),
this->schedule(), this->schedule(),

View File

@ -584,7 +584,8 @@ initializeGroupRatesRecursive_(const Group& group)
if (well->isProducer()) { if (well->isProducer()) {
auto [sw_oil_rate, sw_gas_rate, sw_water_rate, sw_oil_pot, sw_gas_pot, sw_water_pot] = getProducerWellRates_(well, 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); auto sw_alq = this->well_state_.getALQ(well_name);
Scalar factor = well->getEfficiencyFactor(); const Scalar factor = well->getEfficiencyFactor() *
this->well_state_[well_name].efficiency_scaling_factor;
oil_rate += (factor * sw_oil_rate); oil_rate += (factor * sw_oil_rate);
gas_rate += (factor * sw_gas_rate); gas_rate += (factor * sw_gas_rate);
water_rate += (factor * sw_water_rate); water_rate += (factor * sw_water_rate);
@ -705,7 +706,8 @@ initializeWell2GroupMapRecursive_(const Group& group,
if (checkDoGasLift) { if (checkDoGasLift) {
const auto &well = this->schedule_.getWell( const auto &well = this->schedule_.getWell(
well_name, this->report_step_idx_); well_name, this->report_step_idx_);
Scalar wfac = well.getEfficiencyFactor(); const Scalar wfac = well.getEfficiencyFactor() *
this->well_state_[well_name].efficiency_scaling_factor;
auto [itr, success] = this->well_group_map_.insert( auto [itr, success] = this->well_group_map_.insert(
{well_name, /*empty vector*/ {}}); {well_name, /*empty vector*/ {}});
assert(success); assert(success);

View File

@ -658,13 +658,13 @@ removeSurplusALQ_(const Group& group,
alq, max_glift_str); alq, max_glift_str);
displayDebugMessage_(msg); displayDebugMessage_(msg);
} }
SurplusState state {*this, group, oil_rate, gas_rate, water_rate, alq, SurplusState state {*this, group, this->well_state_, oil_rate, gas_rate, water_rate, alq,
static_cast<Scalar>(min_eco_grad), static_cast<Scalar>(min_eco_grad),
static_cast<Scalar>(controls.oil_target), static_cast<Scalar>(controls.oil_target),
static_cast<Scalar>(controls.gas_target), static_cast<Scalar>(controls.gas_target),
static_cast<Scalar>(controls.water_target), static_cast<Scalar>(controls.water_target),
static_cast<Scalar>(controls.liquid_target), static_cast<Scalar>(controls.liquid_target),
max_glift, max_totalgas }; max_glift, max_totalgas};
while (!stop_iteration) { while (!stop_iteration) {
if (dec_grads.size() >= 2) { if (dec_grads.size() >= 2) {
@ -831,7 +831,8 @@ computeDelta(const std::string& well_name, bool add)
// only get deltas for wells owned by this rank // only get deltas for wells owned by this rank
if (this->well_state_.wellIsOwned(well.indexOfWell(), well_name)) { if (this->well_state_.wellIsOwned(well.indexOfWell(), well_name)) {
const auto& well_ecl = well.wellEcl(); const auto& well_ecl = well.wellEcl();
Scalar factor = well_ecl.getEfficiencyFactor(); Scalar factor = well_ecl.getEfficiencyFactor() *
this->well_state_[well_name].efficiency_scaling_factor;
auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta; auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
delta_oil = factor * (gi.new_oil_rate - state.oilRate()); delta_oil = factor * (gi.new_oil_rate - state.oilRate());
delta_gas = factor * (gi.new_gas_rate - state.gasRate()); delta_gas = factor * (gi.new_gas_rate - state.gasRate());
@ -1081,7 +1082,7 @@ checkGasTarget(Scalar delta_gas)
// the change in gas rate is added to the gas rate to make sure the // the change in gas rate is added to the gas rate to make sure the
// group still can produce its target // group still can produce its target
// i.e. we want to find the solution that optimize gas lift while still // i.e. we want to find the solution that optimize gas lift while still
// producing the given group limit // producing the given group limit
if (this->gas_target < (this->gas_rate + delta_gas) ) { if (this->gas_target < (this->gas_rate + delta_gas) ) {
if (this->parent.debug) { if (this->parent.debug) {
const std::string msg = fmt::format("group: {} : " const std::string msg = fmt::format("group: {} : "
@ -1177,7 +1178,8 @@ computeDelta(const std::string& well_name)
// only get deltas for wells owned by this rank // only get deltas for wells owned by this rank
if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) { if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) {
const auto& well_ecl = well.wellEcl(); const auto& well_ecl = well.wellEcl();
Scalar factor = well_ecl.getEfficiencyFactor(); Scalar factor = well_ecl.getEfficiencyFactor() *
this->well_state[well_name].efficiency_scaling_factor;
auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta; auto& [delta_oil, delta_gas, delta_water, delta_alq] = delta;
delta_oil = factor * (gi.new_oil_rate - state.oilRate()); delta_oil = factor * (gi.new_oil_rate - state.oilRate());
delta_gas = factor * (gi.new_gas_rate - state.gasRate()); delta_gas = factor * (gi.new_gas_rate - state.gasRate());

View File

@ -209,6 +209,7 @@ protected:
{ {
SurplusState(GasLiftStage2& parent_, SurplusState(GasLiftStage2& parent_,
const Group& group_, const Group& group_,
const WellState<Scalar>& well_state_,
Scalar oil_rate_, Scalar oil_rate_,
Scalar gas_rate_, Scalar gas_rate_,
Scalar water_rate_, Scalar water_rate_,
@ -222,6 +223,7 @@ protected:
std::optional<Scalar> max_total_gas_) std::optional<Scalar> max_total_gas_)
: parent{parent_} : parent{parent_}
, group{group_} , group{group_}
, well_state(well_state_)
, oil_rate{oil_rate_} , oil_rate{oil_rate_}
, gas_rate{gas_rate_} , gas_rate{gas_rate_}
, water_rate{water_rate_} , water_rate{water_rate_}
@ -238,6 +240,7 @@ protected:
GasLiftStage2 &parent; GasLiftStage2 &parent;
const Group &group; const Group &group;
const WellState<Scalar>& well_state;
Scalar oil_rate; Scalar oil_rate;
Scalar gas_rate; Scalar gas_rate;
Scalar water_rate; Scalar water_rate;

View File

@ -60,6 +60,7 @@ public:
serializer(bhp); serializer(bhp);
serializer(thp); serializer(thp);
serializer(temperature); serializer(temperature);
serializer(efficiency_scaling_factor);
serializer(phase_mixing_rates); serializer(phase_mixing_rates);
serializer(well_potentials); serializer(well_potentials);
serializer(productivity_index); serializer(productivity_index);
@ -88,6 +89,7 @@ public:
Scalar bhp{0}; Scalar bhp{0};
Scalar thp{0}; Scalar thp{0};
Scalar temperature{0}; Scalar temperature{0};
Scalar efficiency_scaling_factor{1.0};
// filtration injection concentration // filtration injection concentration
Scalar filtrate_conc{0}; Scalar filtrate_conc{0};

View File

@ -66,7 +66,8 @@ assembleControlEqProd(const WellState<Scalar>& well_state,
{ {
const auto current = well_state.well(well_.indexOfWell()).production_cmode; const auto current = well_state.well(well_.indexOfWell()).production_cmode;
const auto& pu = well_.phaseUsage(); const auto& pu = well_.phaseUsage();
const Scalar efficiencyFactor = well_.wellEcl().getEfficiencyFactor(); const Scalar efficiencyFactor = well_.wellEcl().getEfficiencyFactor() *
well_state[well_.name()].efficiency_scaling_factor;
switch (current) { switch (current) {
case Well::ProducerCMode::ORAT: { case Well::ProducerCMode::ORAT: {
@ -208,7 +209,8 @@ assembleControlEqInj(const WellState<Scalar>& well_state,
auto current = well_state.well(well_.indexOfWell()).injection_cmode; auto current = well_state.well(well_.indexOfWell()).injection_cmode;
const InjectorType injectorType = controls.injector_type; const InjectorType injectorType = controls.injector_type;
const auto& pu = well_.phaseUsage(); const auto& pu = well_.phaseUsage();
const Scalar efficiencyFactor = well_.wellEcl().getEfficiencyFactor(); const Scalar efficiencyFactor = well_.wellEcl().getEfficiencyFactor() *
well_state[well_.name()].efficiency_scaling_factor;
switch (current) { switch (current) {
case Well::InjectorCMode::RATE: { case Well::InjectorCMode::RATE: {

View File

@ -150,7 +150,8 @@ checkGroupConstraints(WellState<Scalar>& well_state,
// check, skipping over only the single group parent whose // check, skipping over only the single group parent whose
// control is the active one for the well (if any). // control is the active one for the well (if any).
const auto& group = schedule.getGroup(well.groupName(), well_.currentStep()); const auto& group = schedule.getGroup(well.groupName(), well_.currentStep());
const Scalar efficiencyFactor = well.getEfficiencyFactor(); const Scalar efficiencyFactor = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
const std::pair<bool, Scalar> group_constraint = const std::pair<bool, Scalar> group_constraint =
this->checkGroupConstraintsInj(group, well_state, this->checkGroupConstraintsInj(group, well_state,
group_state, efficiencyFactor, group_state, efficiencyFactor,
@ -181,7 +182,8 @@ checkGroupConstraints(WellState<Scalar>& well_state,
// check, skipping over only the single group parent whose // check, skipping over only the single group parent whose
// control is the active one for the well (if any). // control is the active one for the well (if any).
const auto& group = schedule.getGroup(well.groupName(), well_.currentStep()); const auto& group = schedule.getGroup(well.groupName(), well_.currentStep());
const Scalar efficiencyFactor = well.getEfficiencyFactor(); const Scalar efficiencyFactor = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
const std::pair<bool, Scalar> group_constraint = const std::pair<bool, Scalar> group_constraint =
this->checkGroupConstraintsProd(group, well_state, this->checkGroupConstraintsProd(group, well_state,
group_state, efficiencyFactor, group_state, efficiencyFactor,

View File

@ -115,7 +115,8 @@ namespace Opm {
if (wellEcl.getStatus() == Opm::Well::Status::SHUT) if (wellEcl.getStatus() == Opm::Well::Status::SHUT)
continue; continue;
Scalar factor = wellEcl.getEfficiencyFactor(); const Scalar factor = wellEcl.getEfficiencyFactor() *
wellState[wellEcl.name()].efficiency_scaling_factor;
const auto& ws = wellState.well(well_index.value()); const auto& ws = wellState.well(well_index.value());
if (res_rates) { if (res_rates) {
const auto& well_rates = ws.reservoir_rates; const auto& well_rates = ws.reservoir_rates;
@ -265,7 +266,8 @@ sumSolventRates(const Group& group,
continue; continue;
const auto& ws = wellState.well(well_index.value()); const auto& ws = wellState.well(well_index.value());
const Scalar factor = wellEcl.getEfficiencyFactor(); const Scalar factor = wellEcl.getEfficiencyFactor() *
wellState[wellEcl.name()].efficiency_scaling_factor;
if (injector) if (injector)
rate += factor * ws.sum_solvent_rates(); rate += factor * ws.sum_solvent_rates();
else else
@ -455,8 +457,10 @@ updateGroupTargetReduction(const Group& group,
continue; continue;
} }
const Scalar efficiency = wellTmp.getEfficiencyFactor(); const Scalar efficiency = wellTmp.getEfficiencyFactor() *
// add contributino from wells not under group control wellState[wellTmp.name()].efficiency_scaling_factor;
// add contribution from wells not under group control
const auto& ws = wellState.well(well_index.value()); const auto& ws = wellState.well(well_index.value());
if (isInjector) { if (isInjector) {
if (ws.injection_cmode != Well::InjectorCMode::GRUP) if (ws.injection_cmode != Well::InjectorCMode::GRUP)
@ -868,7 +872,8 @@ computeNetworkPressures(const Network::ExtNetwork& network,
// - Making the wells' maximum flows (i.e. not time-averaged by using a efficiency factor) // - Making the wells' maximum flows (i.e. not time-averaged by using a efficiency factor)
// available and using those (for wells with WEFAC(3) true only) when accumulating group // available and using those (for wells with WEFAC(3) true only) when accumulating group
// rates, but ONLY for network calculations. // rates, but ONLY for network calculations.
const Scalar efficiency = well.getEfficiencyFactor(); const Scalar efficiency = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
node_inflows[node][BlackoilPhases::Vapour] += well_state.getALQ(wellname) * efficiency; node_inflows[node][BlackoilPhases::Vapour] += well_state.getALQ(wellname) * efficiency;
} }
} }

View File

@ -318,7 +318,8 @@ zeroGroupRateTarget(const SummaryState& summary_state,
{ {
const auto& well = this->well_ecl_; const auto& well = this->well_ecl_;
const auto& group = schedule.getGroup(well.groupName(), this->currentStep()); const auto& group = schedule.getGroup(well.groupName(), this->currentStep());
const Scalar efficiencyFactor = well.getEfficiencyFactor(); const Scalar efficiencyFactor = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
if (this->isInjector()) { if (this->isInjector()) {
// Check injector under group control // Check injector under group control
const auto& controls = well.injectionControls(summary_state); const auto& controls = well.injectionControls(summary_state);

View File

@ -1240,7 +1240,8 @@ namespace Opm
{ {
assert(well.isAvailableForGroupControl()); assert(well.isAvailableForGroupControl());
const auto& group = schedule.getGroup(well.groupName(), this->currentStep()); const auto& group = schedule.getGroup(well.groupName(), this->currentStep());
const Scalar efficiencyFactor = well.getEfficiencyFactor(); const Scalar efficiencyFactor = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
std::optional<Scalar> target = std::optional<Scalar> target =
this->getGroupInjectionTargetRate(group, this->getGroupInjectionTargetRate(group,
well_state, well_state,
@ -1464,7 +1465,8 @@ namespace Opm
{ {
assert(well.isAvailableForGroupControl()); assert(well.isAvailableForGroupControl());
const auto& group = schedule.getGroup(well.groupName(), this->currentStep()); const auto& group = schedule.getGroup(well.groupName(), this->currentStep());
const Scalar efficiencyFactor = well.getEfficiencyFactor(); const Scalar efficiencyFactor = well.getEfficiencyFactor() *
well_state[well.name()].efficiency_scaling_factor;
Scalar scale = this->getGroupProductionTargetRate(group, Scalar scale = this->getGroupProductionTargetRate(group,
well_state, well_state,
group_state, group_state,

View File

@ -519,6 +519,7 @@ WellState<Scalar>::report(const int* globalCellIdxMap,
well.bhp = ws.bhp; well.bhp = ws.bhp;
well.thp = ws.thp; well.thp = ws.thp;
well.temperature = ws.temperature; well.temperature = ws.temperature;
well.efficiency_scaling_factor = ws.efficiency_scaling_factor;
well.filtrate.rate = ws.sum_filtrate_rate(); well.filtrate.rate = ws.sum_filtrate_rate();
well.filtrate.total = ws.sum_filtrate_total(); well.filtrate.total = ws.sum_filtrate_total();
well.filtrate.concentration = ws.filtrate_conc; well.filtrate.concentration = ws.filtrate_conc;