scale well rates after group switching

This commit is contained in:
Tor Harald Sandve 2021-06-09 15:15:12 +02:00
parent 2dae87fb74
commit b2341a84d6
4 changed files with 142 additions and 27 deletions

View File

@ -398,15 +398,15 @@ checkGroupConstraints(const Group& group,
if (!group.hasInjectionControl(phase)) { if (!group.hasInjectionControl(phase)) {
continue; continue;
} }
Group::InjectionCMode newControl = checkGroupInjectionConstraints(group, reportStepIdx, phase); const auto& check = checkGroupInjectionConstraints(group, reportStepIdx, phase);
if (newControl != Group::InjectionCMode::NONE) { if (check.first != Group::InjectionCMode::NONE) {
return true; return true;
} }
} }
} }
if (group.isProductionGroup()) { if (group.isProductionGroup()) {
Group::ProductionCMode newControl = checkGroupProductionConstraints(group, reportStepIdx, deferred_logger); const auto& check = checkGroupProductionConstraints(group, reportStepIdx, deferred_logger);
if (newControl != Group::ProductionCMode::NONE) if (check.first != Group::ProductionCMode::NONE)
{ {
return true; return true;
} }
@ -420,7 +420,7 @@ checkGroupConstraints(const Group& group,
return violated; return violated;
} }
Group::InjectionCMode std::pair<Group::InjectionCMode, double>
BlackoilWellModelGeneric:: BlackoilWellModelGeneric::
checkGroupInjectionConstraints(const Group& group, checkGroupInjectionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
@ -452,7 +452,10 @@ checkGroupInjectionConstraints(const Group& group,
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.surface_max_rate < current_rate) { if (controls.surface_max_rate < current_rate) {
return Group::InjectionCMode::RATE; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.surface_max_rate / current_rate;
return std::make_pair(Group::InjectionCMode::RATE, scale);
} }
} }
} }
@ -466,7 +469,10 @@ checkGroupInjectionConstraints(const Group& group,
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.resv_max_rate < current_rate) { if (controls.resv_max_rate < current_rate) {
return Group::InjectionCMode::RESV; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.resv_max_rate / current_rate;
return std::make_pair(Group::InjectionCMode::RESV, scale);
} }
} }
} }
@ -488,7 +494,10 @@ checkGroupInjectionConstraints(const Group& group,
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.target_reinj_fraction*production_Rate < current_rate) { if (controls.target_reinj_fraction*production_Rate < current_rate) {
return Group::InjectionCMode::REIN; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.target_reinj_fraction*production_Rate / current_rate;
return std::make_pair(Group::InjectionCMode::REIN, scale);
} }
} }
} }
@ -514,14 +523,17 @@ checkGroupInjectionConstraints(const Group& group,
total_rate = comm_.sum(total_rate); total_rate = comm_.sum(total_rate);
if (controls.target_void_fraction*voidage_rate < total_rate) { if (controls.target_void_fraction*voidage_rate < total_rate) {
return Group::InjectionCMode::VREP; double scale = 1.0;
if (total_rate > 1e-12)
scale = controls.target_void_fraction*voidage_rate / total_rate;
return std::make_pair(Group::InjectionCMode::VREP, scale);
} }
} }
} }
return Group::InjectionCMode::NONE; return std::make_pair(Group::InjectionCMode::NONE, 1.0);
} }
Group::ProductionCMode std::pair<Group::ProductionCMode, double>
BlackoilWellModelGeneric:: BlackoilWellModelGeneric::
checkGroupProductionConstraints(const Group& group, checkGroupProductionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
@ -543,7 +555,10 @@ checkGroupProductionConstraints(const Group& group,
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.oil_target < current_rate ) { if (controls.oil_target < current_rate ) {
return Group::ProductionCMode::ORAT; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.oil_target / current_rate;
return std::make_pair(Group::ProductionCMode::ORAT, scale);
} }
} }
} }
@ -560,7 +575,10 @@ checkGroupProductionConstraints(const Group& group,
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.water_target < current_rate ) { if (controls.water_target < current_rate ) {
return Group::ProductionCMode::WRAT; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.water_target / current_rate;
return std::make_pair(Group::ProductionCMode::WRAT, scale);
} }
} }
} }
@ -574,7 +592,10 @@ checkGroupProductionConstraints(const Group& group,
// sum over all nodes // sum over all nodes
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.gas_target < current_rate ) { if (controls.gas_target < current_rate ) {
return Group::ProductionCMode::GRAT; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.gas_target / current_rate;
return std::make_pair(Group::ProductionCMode::GRAT, scale);
} }
} }
} }
@ -590,7 +611,10 @@ checkGroupProductionConstraints(const Group& group,
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.liquid_target < current_rate ) { if (controls.liquid_target < current_rate ) {
return Group::ProductionCMode::LRAT; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.liquid_target / current_rate;
return std::make_pair(Group::ProductionCMode::LRAT, scale);
} }
} }
} }
@ -612,7 +636,10 @@ checkGroupProductionConstraints(const Group& group,
current_rate = comm_.sum(current_rate); current_rate = comm_.sum(current_rate);
if (controls.resv_target < current_rate ) { if (controls.resv_target < current_rate ) {
return Group::ProductionCMode::RESV; double scale = 1.0;
if (current_rate > 1e-12)
scale = controls.resv_target / current_rate;
return std::make_pair(Group::ProductionCMode::RESV, scale);
} }
} }
} }
@ -620,7 +647,7 @@ checkGroupProductionConstraints(const Group& group,
{ {
OPM_DEFLOG_THROW(std::runtime_error, "Group " + group.name() + "PRBL control for production groups not implemented", deferred_logger); OPM_DEFLOG_THROW(std::runtime_error, "Group " + group.name() + "PRBL control for production groups not implemented", deferred_logger);
} }
return Group::ProductionCMode::NONE; return std::make_pair(Group::ProductionCMode::NONE, 1.0);
} }
void void
@ -808,6 +835,7 @@ checkGroupHigherConstraints(const Group& group,
if (changed.first) { if (changed.first) {
switched_groups.insert(group.name()); switched_groups.insert(group.name());
actionOnBrokenConstraints(group, Group::InjectionCMode::FLD, phase, deferred_logger); actionOnBrokenConstraints(group, Group::InjectionCMode::FLD, phase, deferred_logger);
WellGroupHelpers::updateWellRatesFromGroupTargetScale(changed.second, group, schedule(), reportStepIdx, /* isInjector */ true, this->groupState(), this->wellState());
} }
} }
} }
@ -845,6 +873,7 @@ checkGroupHigherConstraints(const Group& group,
switched_groups.insert(group.name()); switched_groups.insert(group.name());
const auto exceed_action = group.productionControls(summaryState_).exceed_action; const auto exceed_action = group.productionControls(summaryState_).exceed_action;
actionOnBrokenConstraints(group, exceed_action, Group::ProductionCMode::FLD, deferred_logger); actionOnBrokenConstraints(group, exceed_action, Group::ProductionCMode::FLD, deferred_logger);
WellGroupHelpers::updateWellRatesFromGroupTargetScale(changed.second, group, schedule(), reportStepIdx, /* isInjector */ false, this->groupState(), this->wellState());
} }
} }
} }
@ -870,21 +899,23 @@ updateGroupIndividualControl(const Group& group,
if (!group.hasInjectionControl(phase)) { if (!group.hasInjectionControl(phase)) {
continue; continue;
} }
Group::InjectionCMode newControl = checkGroupInjectionConstraints(group, reportStepIdx, phase); const auto& changed = checkGroupInjectionConstraints(group, reportStepIdx, phase);
if (newControl != Group::InjectionCMode::NONE) if (changed.first != Group::InjectionCMode::NONE)
{ {
switched_groups.insert(group.name()); switched_groups.insert(group.name());
actionOnBrokenConstraints(group, newControl, phase, deferred_logger); actionOnBrokenConstraints(group, changed.first, phase, deferred_logger);
WellGroupHelpers::updateWellRatesFromGroupTargetScale(changed.second, group, schedule(), reportStepIdx, /* isInjector */ false, this->groupState(), this->wellState());
} }
} }
} }
if (!skip && group.isProductionGroup()) { if (!skip && group.isProductionGroup()) {
Group::ProductionCMode newControl = checkGroupProductionConstraints(group, reportStepIdx, deferred_logger); const auto& changed = checkGroupProductionConstraints(group, reportStepIdx, deferred_logger);
const auto controls = group.productionControls(summaryState_); const auto controls = group.productionControls(summaryState_);
if (newControl != Group::ProductionCMode::NONE) if (changed.first != Group::ProductionCMode::NONE)
{ {
switched_groups.insert(group.name()); switched_groups.insert(group.name());
actionOnBrokenConstraints(group, controls.exceed_action, newControl, deferred_logger); actionOnBrokenConstraints(group, controls.exceed_action, changed.first, deferred_logger);
WellGroupHelpers::updateWellRatesFromGroupTargetScale(changed.second, group, schedule(), reportStepIdx, /* isInjector */ false, this->groupState(), this->wellState());
} }
} }

View File

@ -286,10 +286,10 @@ protected:
const int reportStepIdx, const int reportStepIdx,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
Group::InjectionCMode checkGroupInjectionConstraints(const Group& group, std::pair<Group::InjectionCMode, double> checkGroupInjectionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
const Phase& phase) const; const Phase& phase) const;
Group::ProductionCMode checkGroupProductionConstraints(const Group& group, std::pair<Group::ProductionCMode, double> checkGroupProductionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;

View File

@ -423,6 +423,76 @@ namespace WellGroupHelpers
group_state.update_production_reduction_rates(group.name(), groupTargetReduction); group_state.update_production_reduction_rates(group.name(), groupTargetReduction);
} }
void updateWellRatesFromGroupTargetScale(const double scale,
const Group& group,
const Schedule& schedule,
const int reportStepIdx,
bool isInjector,
const GroupState& group_state,
WellState& wellState) {
for (const std::string& groupName : group.groups()) {
bool individual_control = false;
if (isInjector) {
const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS};
for (Phase phase : all) {
const Group::InjectionCMode& currentGroupControl
= group_state.injection_control(groupName, phase);
individual_control = individual_control || (currentGroupControl != Group::InjectionCMode::FLD
&& currentGroupControl != Group::InjectionCMode::NONE);
}
} else {
const Group::ProductionCMode& currentGroupControl = group_state.production_control(groupName);
individual_control = (currentGroupControl != Group::ProductionCMode::FLD
&& currentGroupControl != Group::ProductionCMode::NONE);
}
if (!individual_control) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateWellRatesFromGroupTargetScale(scale, groupTmp, schedule, reportStepIdx, isInjector, group_state, wellState);
}
}
const int np = wellState.numPhases();
for (const std::string& wellName : group.wells()) {
const auto& wellTmp = schedule.getWell(wellName, reportStepIdx);
if (wellTmp.isProducer() && isInjector)
continue;
if (wellTmp.isInjector() && !isInjector)
continue;
if (wellTmp.getStatus() == Well::Status::SHUT)
continue;
const auto& end = wellState.wellMap().end();
const auto& it = wellState.wellMap().find(wellName);
if (it == end) // the well is not found
continue;
int well_index = it->second[0];
if (! wellState.wellIsOwned(well_index, wellName) ) // Only sum once
{
continue;
}
// scale rates
if (isInjector) {
if (wellState.currentInjectionControl(well_index) == Well::InjectorCMode::GRUP)
for (int phase = 0; phase < np; phase++) {
wellState.wellRates(well_index)[phase] *= scale;
}
} else {
if (wellState.currentProductionControl(well_index) == Well::ProducerCMode::GRUP)
for (int phase = 0; phase < np; phase++) {
wellState.wellRates(well_index)[phase] *= scale;
}
}
}
}
void updateVREPForGroups(const Group& group, void updateVREPForGroups(const Group& group,
const Schedule& schedule, const Schedule& schedule,
@ -1100,7 +1170,10 @@ namespace WellGroupHelpers
} }
// Avoid negative target rates comming from too large local reductions. // Avoid negative target rates comming from too large local reductions.
const double target_rate = std::max(1e-12, target / efficiencyFactorInclGroup); const double target_rate = std::max(1e-12, target / efficiencyFactorInclGroup);
return std::make_pair(current_rate > target_rate, target_rate / current_rate); double scale = 1.0;
if (current_rate > 1e-12)
scale = target_rate / current_rate;
return std::make_pair(current_rate > target_rate, scale);
} }
std::pair<bool, double> checkGroupConstraintsInj(const std::string& name, std::pair<bool, double> checkGroupConstraintsInj(const std::string& name,
@ -1224,7 +1297,10 @@ namespace WellGroupHelpers
} }
// Avoid negative target rates comming from too large local reductions. // Avoid negative target rates comming from too large local reductions.
const double target_rate = std::max(1e-12, target / efficiencyFactorInclGroup); const double target_rate = std::max(1e-12, target / efficiencyFactorInclGroup);
return std::make_pair(current_rate > target_rate, target_rate / current_rate); double scale = 1.0;
if (current_rate > 1e-12)
scale = target_rate / current_rate;
return std::make_pair(current_rate > target_rate, scale);
} }
template <class Comm> template <class Comm>

View File

@ -158,6 +158,14 @@ namespace WellGroupHelpers
WellState& wellState, WellState& wellState,
GroupState& group_state); GroupState& group_state);
void updateWellRatesFromGroupTargetScale(const double scale,
const Group& group,
const Schedule& schedule,
const int reportStepIdx,
bool isInjector,
const GroupState& group_state,
WellState& wellState);
void updateREINForGroups(const Group& group, void updateREINForGroups(const Group& group,
const Schedule& schedule, const Schedule& schedule,
const int reportStepIdx, const int reportStepIdx,