mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Limit the other rates when a rate is limited
This commit is contained in:
parent
b42537155e
commit
6a30966500
@ -532,16 +532,21 @@ getProducerWellRates_(const Well* well, int well_index)
|
|||||||
|
|
||||||
const auto controls = well->productionControls(this->summary_state_);
|
const auto controls = well->productionControls(this->summary_state_);
|
||||||
Scalar oil_rate = oil_pot;
|
Scalar oil_rate = oil_pot;
|
||||||
if (controls.hasControl(Well::ProducerCMode::ORAT)) {
|
Scalar water_rate = water_pot;
|
||||||
oil_rate = std::min(static_cast<Scalar>(controls.oil_rate), oil_rate);
|
|
||||||
}
|
|
||||||
Scalar gas_rate = gas_pot;
|
Scalar gas_rate = gas_pot;
|
||||||
|
|
||||||
|
if (controls.hasControl(Well::ProducerCMode::ORAT) && oil_rate > static_cast<Scalar>(controls.oil_rate)) {
|
||||||
|
water_rate *= (static_cast<Scalar>(controls.oil_rate) / oil_rate);
|
||||||
|
oil_rate = static_cast<Scalar>(controls.oil_rate);
|
||||||
|
}
|
||||||
|
|
||||||
if (controls.hasControl(Well::ProducerCMode::GRAT)) {
|
if (controls.hasControl(Well::ProducerCMode::GRAT)) {
|
||||||
gas_rate = std::min(static_cast<Scalar>(controls.gas_rate), gas_rate);
|
gas_rate = std::min(static_cast<Scalar>(controls.gas_rate), gas_rate);
|
||||||
}
|
}
|
||||||
Scalar water_rate = water_pot;
|
|
||||||
if (controls.hasControl(Well::ProducerCMode::WRAT)) {
|
if (controls.hasControl(Well::ProducerCMode::WRAT) && water_rate > static_cast<Scalar>(controls.water_rate)) {
|
||||||
water_rate = std::min(static_cast<Scalar>(controls.water_rate), water_rate);
|
oil_rate *= (static_cast<Scalar>(controls.water_rate) / water_rate);
|
||||||
|
water_rate = static_cast<Scalar>(controls.water_rate);
|
||||||
}
|
}
|
||||||
if (controls.hasControl(Well::ProducerCMode::LRAT)) {
|
if (controls.hasControl(Well::ProducerCMode::LRAT)) {
|
||||||
Scalar liquid_rate = oil_rate + water_rate;
|
Scalar liquid_rate = oil_rate + water_rate;
|
||||||
@ -650,12 +655,16 @@ initializeGroupRatesRecursive_(const Group& group)
|
|||||||
group.name(), oil_rate, gas_rate, water_rate, alq);
|
group.name(), oil_rate, gas_rate, water_rate, alq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oil_target)
|
if (oil_target && oil_rate > *oil_target) {
|
||||||
oil_rate = std::min(oil_rate, *oil_target);
|
water_rate *= (*oil_target/oil_rate);
|
||||||
if (gas_target)
|
oil_rate = *oil_target;
|
||||||
gas_rate = std::min(gas_rate, *gas_target);
|
}
|
||||||
if (water_target)
|
if (gas_target && gas_rate > *gas_target)
|
||||||
water_rate = std::min(water_rate, *water_target);
|
gas_rate = *gas_target;
|
||||||
|
if (water_target && water_rate > *water_target) {
|
||||||
|
oil_rate *= (*water_target/water_rate);
|
||||||
|
water_rate = *water_target;
|
||||||
|
}
|
||||||
if (liquid_target) {
|
if (liquid_target) {
|
||||||
Scalar liquid_rate = oil_rate + water_rate;
|
Scalar liquid_rate = oil_rate + water_rate;
|
||||||
Scalar liquid_rate_limited = *liquid_target;
|
Scalar liquid_rate_limited = *liquid_target;
|
||||||
|
@ -666,6 +666,13 @@ getRateWithLimit_(Rate rate_type, const BasicRates& rates) const
|
|||||||
// for why the rate was limited.
|
// for why the rate was limited.
|
||||||
std::optional<Rate> target_type;
|
std::optional<Rate> target_type;
|
||||||
|
|
||||||
|
Scalar rate2;
|
||||||
|
if (rate_type == Rate::oil) {
|
||||||
|
rate2 = getRate_(Rate::water, rates);
|
||||||
|
} else {
|
||||||
|
rate2 = getRate_(Rate::oil, rates);
|
||||||
|
}
|
||||||
|
|
||||||
if (hasProductionControl_(rate_type)) {
|
if (hasProductionControl_(rate_type)) {
|
||||||
auto target = getProductionTarget_(rate_type);
|
auto target = getProductionTarget_(rate_type);
|
||||||
if (new_rate > target) {
|
if (new_rate > target) {
|
||||||
@ -675,42 +682,73 @@ getRateWithLimit_(Rate rate_type, const BasicRates& rates) const
|
|||||||
new_rate,
|
new_rate,
|
||||||
target);
|
target);
|
||||||
displayDebugMessage_(msg);
|
displayDebugMessage_(msg);
|
||||||
|
rate2 *= target/new_rate;
|
||||||
new_rate = target;
|
new_rate = target;
|
||||||
target_type = rate_type;
|
target_type = rate_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (((rate_type == Rate::oil) || (rate_type == Rate::water)) && hasProductionControl_(Rate::liquid)) {
|
if (((rate_type == Rate::oil) || (rate_type == Rate::water))) {
|
||||||
Scalar rate2;
|
|
||||||
if (rate_type == Rate::oil) {
|
if (rate_type == Rate::oil) {
|
||||||
rate2 = getRate_(Rate::water, rates);
|
if(hasProductionControl_(Rate::water)) {
|
||||||
|
auto water_target = getProductionTarget_(Rate::water);
|
||||||
|
if (rate2 > water_target) {
|
||||||
|
new_rate *= (water_target / rate2);
|
||||||
|
target_type = Rate::water;
|
||||||
|
rate2 = water_target;
|
||||||
|
const std::string msg = fmt::format("limiting {} rate to {} due to WRAT target: "
|
||||||
|
"computed WRAT: {}, target WRAT: {}",
|
||||||
|
GasLiftGroupInfo<Scalar>::rateToString(rate_type),
|
||||||
|
new_rate,
|
||||||
|
rate2,
|
||||||
|
water_target);
|
||||||
|
displayDebugMessage_(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
rate2 = getRate_(Rate::oil, rates);
|
if(hasProductionControl_(Rate::oil)) {
|
||||||
|
auto oil_target = getProductionTarget_(Rate::oil);
|
||||||
|
if (rate2 > oil_target) {
|
||||||
|
new_rate *= (oil_target / rate2);
|
||||||
|
target_type = Rate::oil;
|
||||||
|
rate2 = oil_target;
|
||||||
|
const std::string msg = fmt::format("limiting {} rate to {} due to ORAT target: "
|
||||||
|
"computed ORAT: {}, target ORAT: {}",
|
||||||
|
GasLiftGroupInfo<Scalar>::rateToString(rate_type),
|
||||||
|
new_rate,
|
||||||
|
rate2,
|
||||||
|
oil_target);
|
||||||
|
displayDebugMessage_(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Note: Since "new_rate" was first updated for ORAT or WRAT, see first "if"
|
|
||||||
// statement in the method, the rate is limited due to LRAT only if
|
|
||||||
// it becomes less than the rate limited by a WRAT or ORAT target..
|
|
||||||
Scalar liq_rate = new_rate + rate2;
|
|
||||||
|
|
||||||
auto liq_target = getProductionTarget_(Rate::liquid);
|
if(hasProductionControl_(Rate::liquid)) {
|
||||||
if (liq_rate > liq_target) {
|
// Note: Since "new_rate" was first updated for ORAT or WRAT, see first "if"
|
||||||
Scalar fraction = new_rate / liq_rate;
|
// statement in the method, the rate is limited due to LRAT only if
|
||||||
// NOTE: since
|
// it becomes less than the rate limited by a WRAT or ORAT target..
|
||||||
// fraction * liq_rate = new_rate,
|
Scalar liq_rate = new_rate + rate2;
|
||||||
// we must have
|
|
||||||
// fraction * liq_target < new_rate
|
auto liq_target = getProductionTarget_(Rate::liquid);
|
||||||
// since
|
if (liq_rate > liq_target) {
|
||||||
// liq_target < liq_rate
|
Scalar fraction = new_rate / liq_rate;
|
||||||
// therefore new_rate will become less than it original was and
|
// NOTE: since
|
||||||
// limited = true.
|
// fraction * liq_rate = new_rate,
|
||||||
new_rate = fraction * liq_target;
|
// we must have
|
||||||
target_type = Rate::liquid;
|
// fraction * liq_target < new_rate
|
||||||
const std::string msg = fmt::format("limiting {} rate to {} due to LRAT target: "
|
// since
|
||||||
"computed LRAT: {}, target LRAT: {}",
|
// liq_target < liq_rate
|
||||||
GasLiftGroupInfo<Scalar>::rateToString(rate_type),
|
// therefore new_rate will become less than it original was and
|
||||||
new_rate,
|
// limited = true.
|
||||||
liq_rate,
|
new_rate = fraction * liq_target;
|
||||||
liq_target);
|
target_type = Rate::liquid;
|
||||||
displayDebugMessage_(msg);
|
const std::string msg = fmt::format("limiting {} rate to {} due to LRAT target: "
|
||||||
|
"computed LRAT: {}, target LRAT: {}",
|
||||||
|
GasLiftGroupInfo<Scalar>::rateToString(rate_type),
|
||||||
|
new_rate,
|
||||||
|
liq_rate,
|
||||||
|
liq_target);
|
||||||
|
displayDebugMessage_(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Also check RESV target?
|
// TODO: Also check RESV target?
|
||||||
@ -768,7 +806,7 @@ getLiquidRateWithGroupLimit_(const Scalar new_oil_rate,
|
|||||||
= getRateWithGroupLimit_(Rate::liquid, new_liquid_rate, liquid_rate, gr_name_dont_limit);
|
= getRateWithGroupLimit_(Rate::liquid, new_liquid_rate, liquid_rate, gr_name_dont_limit);
|
||||||
bool limited = group_name != nullptr;
|
bool limited = group_name != nullptr;
|
||||||
if (limited) {
|
if (limited) {
|
||||||
Scalar oil_fraction = new_oil_rate / new_liquid_rate;
|
Scalar oil_fraction = oil_rate / liquid_rate;
|
||||||
Scalar delta_liquid = liquid_rate_limited - liquid_rate;
|
Scalar delta_liquid = liquid_rate_limited - liquid_rate;
|
||||||
auto limited_oil_rate = oil_rate + oil_fraction * delta_liquid;
|
auto limited_oil_rate = oil_rate + oil_fraction * delta_liquid;
|
||||||
auto limited_water_rate = water_rate + (1.0 - oil_fraction) * delta_liquid;
|
auto limited_water_rate = water_rate + (1.0 - oil_fraction) * delta_liquid;
|
||||||
@ -862,6 +900,7 @@ getInitialRatesWithLimit_() const
|
|||||||
auto temp_rates = getLimitedRatesFromRates_(*rates);
|
auto temp_rates = getLimitedRatesFromRates_(*rates);
|
||||||
BasicRates old_rates = getWellStateRates_();
|
BasicRates old_rates = getWellStateRates_();
|
||||||
limited_rates = updateRatesToGroupLimits_(old_rates, temp_rates);
|
limited_rates = updateRatesToGroupLimits_(old_rates, temp_rates);
|
||||||
|
|
||||||
initial_alq = alq;
|
initial_alq = alq;
|
||||||
}
|
}
|
||||||
return {limited_rates, initial_alq};
|
return {limited_rates, initial_alq};
|
||||||
@ -873,9 +912,10 @@ GasLiftSingleWellGeneric<Scalar>::
|
|||||||
getLimitedRatesFromRates_(const BasicRates& rates) const
|
getLimitedRatesFromRates_(const BasicRates& rates) const
|
||||||
{
|
{
|
||||||
auto [oil_rate, oil_limiting_target] = getOilRateWithLimit2_(rates);
|
auto [oil_rate, oil_limiting_target] = getOilRateWithLimit2_(rates);
|
||||||
|
bool oil_is_limited = oil_limiting_target.has_value();
|
||||||
auto [gas_rate, gas_is_limited] = getGasRateWithLimit_(rates);
|
auto [gas_rate, gas_is_limited] = getGasRateWithLimit_(rates);
|
||||||
auto [water_rate, water_limiting_target] = getWaterRateWithLimit2_(rates);
|
auto [water_rate, water_limiting_target] = getWaterRateWithLimit2_(rates);
|
||||||
bool oil_is_limited = oil_limiting_target.has_value();
|
|
||||||
bool water_is_limited = water_limiting_target.has_value();
|
bool water_is_limited = water_limiting_target.has_value();
|
||||||
return LimitedRates {oil_rate,
|
return LimitedRates {oil_rate,
|
||||||
gas_rate,
|
gas_rate,
|
||||||
@ -1447,13 +1487,16 @@ updateRatesToGroupLimits_(const BasicRates& old_rates,
|
|||||||
{
|
{
|
||||||
LimitedRates new_rates = rates;
|
LimitedRates new_rates = rates;
|
||||||
auto [new_oil_rate, oil_is_limited] = getOilRateWithGroupLimit_(new_rates.oil, old_rates.oil, gr_name);
|
auto [new_oil_rate, oil_is_limited] = getOilRateWithGroupLimit_(new_rates.oil, old_rates.oil, gr_name);
|
||||||
|
auto mod_water_rate = new_rates.water;
|
||||||
if (oil_is_limited) {
|
if (oil_is_limited) {
|
||||||
new_rates.oil_limiting_target = Rate::oil;
|
new_rates.oil_limiting_target = Rate::oil;
|
||||||
|
mod_water_rate *= (new_oil_rate / new_rates.oil);
|
||||||
}
|
}
|
||||||
auto [new_gas_rate, gas_is_limited] = getGasRateWithGroupLimit_(new_rates.gas, old_rates.gas, gr_name);
|
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, gr_name);
|
auto [new_water_rate, water_is_limited] = getWaterRateWithGroupLimit_(mod_water_rate, 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;
|
||||||
|
new_oil_rate *= (new_water_rate / new_rates.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, gr_name);
|
= getLiquidRateWithGroupLimit_(new_oil_rate, old_rates.oil, new_water_rate, old_rates.water, gr_name);
|
||||||
|
Loading…
Reference in New Issue
Block a user