fix WRAT GRAT reduction

This commit is contained in:
Tor Harald Sandve 2021-11-09 13:40:55 +01:00
parent 7728df33bb
commit a765ab213b
2 changed files with 59 additions and 44 deletions

View File

@ -747,17 +747,16 @@ maybeAdjustALQbeforeOptimizeLoop_(
const std::string msg = fmt::format("initial ALQ: {}", alq);
displayDebugMessage_(msg);
}
if (!increase && oil_is_limited) {
// NOTE: Try to decrease ALQ down to a value where the oil target is
if (!increase && ( oil_is_limited || water_is_limited || gas_is_limited)) {
// NOTE: Try to decrease ALQ down to a value where the well target is
// not exceeded.
// NOTE: This may reduce ALQ below the minimum value set in WLIFTOPT
// item 5. However, this is OK since the rate target is met and there
// is no point in using a higher ALQ value then.
std::tie(oil_rate, gas_rate, oil_is_limited, gas_is_limited, alq) =
reduceALQtoOilTarget_(
alq, oil_rate, gas_rate, water_rate, oil_is_limited, gas_is_limited, potentials);
}
else {
std::tie(oil_rate, gas_rate, water_rate, oil_is_limited, gas_is_limited, water_is_limited, alq) =
reduceALQtoWellTarget_(alq, oil_rate, gas_rate, water_rate,
oil_is_limited, gas_is_limited, water_is_limited, potentials);
} else {
if (increase && oil_rate < 0) {
// NOTE: Try to increase ALQ up to a value where oil_rate is positive
std::tie(oil_rate, gas_rate, oil_is_limited, gas_is_limited, alq) =
@ -779,44 +778,25 @@ maybeAdjustALQbeforeOptimizeLoop_(
return std::make_tuple(oil_rate, gas_rate, water_rate, alq, oil_is_limited, gas_is_limited, water_is_limited);
}
std::tuple<double,double,bool,bool,double>
std::tuple<double,double,double, bool, bool,bool,double>
GasLiftSingleWellGeneric::
reduceALQtoOilTarget_(double alq,
reduceALQtoWellTarget_(double alq,
double oil_rate,
double gas_rate,
double water_rate,
bool oil_is_limited,
bool gas_is_limited,
bool water_is_limited,
std::vector<double>& potentials)
{
displayDebugMessage_("Reducing ALQ to meet oil target before iteration starts..");
displayDebugMessage_("Reducing ALQ to meet well target before iteration starts..");
double orig_oil_rate = oil_rate;
double orig_alq = alq;
// NOTE: This method should only be called if oil_is_limited, and hence
// we know that it has oil rate control or liquid control
assert(this->controls_.hasControl(Well::ProducerCMode::ORAT) || this->controls_.hasControl(Well::ProducerCMode::LRAT));
auto oiltarget = this->controls_.oil_rate;
bool stop_iteration = (oiltarget == 0);
bool limiting_orat = false;
// check well targets
bool stop_iteration = false;
auto limiting_control = Well::ProducerCMode::NONE;
double temp_alq = alq;
while(!stop_iteration) {
temp_alq -= this->increment_;
if (temp_alq <= 0) break;
auto bhp_opt = computeBhpAtThpLimit_(temp_alq);
if (!bhp_opt) break;
auto bhp_this = getBhpWithLimit_(*bhp_opt);
computeWellRates_(bhp_this.first, potentials);
oil_rate = -potentials[this->oil_pos_];
if (oil_rate < oiltarget) {
break;
}
alq = temp_alq;
limiting_orat = true;
}
auto liquidtarget = this->controls_.liquid_rate;
stop_iteration = (liquidtarget == 0);
bool limiting_lrat = false;
temp_alq = alq;
while(!stop_iteration) {
temp_alq -= this->increment_;
if (temp_alq <= 0) break;
@ -826,32 +806,67 @@ reduceALQtoOilTarget_(double alq,
computeWellRates_(bhp_this.first, potentials);
oil_rate = -potentials[this->oil_pos_];
water_rate = -potentials[this->water_pos_];
if ( (oil_rate + water_rate) < liquidtarget) {
gas_rate = -potentials[this->gas_pos_];
if (oil_is_limited && this->controls_.hasControl(Well::ProducerCMode::ORAT) && oil_rate < this->controls_.oil_rate) {
limiting_control = Well::ProducerCMode::ORAT;
break;
}
if (oil_is_limited && this->controls_.hasControl(Well::ProducerCMode::LRAT) && (oil_rate + water_rate) < this->controls_.liquid_rate) {
limiting_control = Well::ProducerCMode::LRAT;
break;
}
if (gas_is_limited && gas_rate < this->controls_.gas_rate) {
limiting_control = Well::ProducerCMode::GRAT;
break;
}
if (water_is_limited && water_rate < this->controls_.water_rate) {
limiting_control = Well::ProducerCMode::WRAT;
break;
}
alq = temp_alq;
limiting_lrat = true;
}
std::tie(oil_rate, oil_is_limited) = getOilRateWithLimit_(potentials);
std::tie(gas_rate, gas_is_limited) = getGasRateWithLimit_(potentials);
std::tie(water_rate, water_is_limited) = getWaterRateWithLimit_(potentials);
if (this->debug_) {
assert( alq <= orig_alq );
auto target = limiting_orat ? oiltarget : liquidtarget;
std::string type;
double target = 0.0;
double rate = 0.0;
if (limiting_control == Well::ProducerCMode::ORAT) {
rate = oil_rate;
target = this->controls_.oil_rate;
type = "ORAT";
} else if(limiting_control == Well::ProducerCMode::LRAT) {
rate = oil_rate + water_rate;
target = this->controls_.liquid_rate;
type = "LRAT";
} else if (limiting_control == Well::ProducerCMode::WRAT) {
rate = water_rate;
target = this->controls_.water_rate;
type = "WRAT";
} else if (limiting_control == Well::ProducerCMode::GRAT) {
rate = gas_rate;
target = this->controls_.gas_rate;
type = "GRAT";
}
if (alq < orig_alq) {
// NOTE: ALQ may drop below zero before we are able to meet the target
const std::string msg = fmt::format(
"Reduced (oil_rate, alq) from ({}, {}) to ({}, {}) to meet target "
"at {}. ", orig_oil_rate, orig_alq, oil_rate, alq, target);
"Reduced (rate, alq) from ({}, {}) to ({}, {}) to meet {} target "
"at {}. ", orig_oil_rate, orig_alq, rate, alq, type, target);
displayDebugMessage_(msg);
}
else if (alq == orig_alq) {
// We might not be able to reduce ALQ, for example if ALQ starts out at zero.
const std::string msg = fmt::format("Not able to reduce ALQ {} further. "
"Oil rate is {} and target is {}", orig_alq, oil_rate, target);
" {} is {} and target is {}", orig_alq, type, rate, target);
displayDebugMessage_(msg);
}
}
return std::make_tuple(oil_rate, gas_rate, oil_is_limited, gas_is_limited, alq);
return std::make_tuple(oil_rate, gas_rate, water_rate,
oil_is_limited, gas_is_limited, water_is_limited, alq);
}
// INPUT:

View File

@ -212,9 +212,9 @@ protected:
maybeAdjustALQbeforeOptimizeLoop_(
bool increase, double alq, double oil_rate, double gas_rate, double water_rate,
bool oil_is_limited, bool gas_is_limited, bool water_is_limited, std::vector<double> &potentials);
std::tuple<double,double,bool,bool,double>
reduceALQtoOilTarget_(double alq, double oil_rate, double gas_rate, double water_rate,
bool oil_is_limited, bool gas_is_limited, std::vector<double> &potentials);
std::tuple<double,double,double, bool, bool,bool,double>
reduceALQtoWellTarget_(double alq, double oil_rate, double gas_rate, double water_rate,
bool oil_is_limited, bool gas_is_limited, bool water_is_limited, std::vector<double> &potentials);
std::unique_ptr<GasLiftWellState> runOptimize1_();
std::unique_ptr<GasLiftWellState> runOptimize2_();