Adjust reduction rate when well control is considered for GRUP

The reduction rate is computed differently for cases without wells under GRUP
For a well to check whether to switch to GRUP it needed to use the reduction rate
that would have been computed if this particular well was under GRUP control
and thus recompute the reduction rate without entering the no-grup path
This commit is contained in:
Tor Harald Sandve 2021-10-25 15:35:30 +02:00 committed by Tor Harald Sandve
parent 4a74fd1282
commit a57374fae9

View File

@ -1182,18 +1182,50 @@ namespace WellGroupHelpers
// Add my reduction back at the level where it is included in the local reduction
if (local_reduction_level == ii )
target += current_rate * efficiencyFactor;
}
if (ii < num_ancestors - 1) {
// Not final level. Add sub-level reduction back, if
// it was nonzero due to having no group-controlled
// wells. Note that we make this call without setting
// the current well to be always included, because we
// want to know the situation that applied to the
// calculation of reductions.
const int num_gr_ctrl = groupControlledWells(schedule, wellState, group_state, reportStepIdx, chain[ii + 1], "", /*is_producer*/true, /*injectionPhaseNotUsed*/Phase::OIL);
if (num_gr_ctrl == 0) {
if (guideRate->has(chain[ii + 1])) {
target += localReduction(chain[ii + 1]);
for (size_t iii = ii + 1; iii < num_ancestors; ++iii) {
// Not final level. Add sub-level reduction back, if
// it was not under individual control and nonzero due to having no group-controlled
// wells. We may need to look several levels down the hierarchy to find groups without
// group control wells
const Group::ProductionCMode& subGroupControl = group_state.production_control(chain[iii]);
const bool individual_control = (subGroupControl != Group::ProductionCMode::FLD
&& subGroupControl != Group::ProductionCMode::NONE);
// The sub group is on individual control. No adjustments needed.
if (individual_control) {
break;
}
// Note that we make this call without setting
// the current well to be always included, because we
// want to know the situation that applied to the
// calculation of reductions.
const int num_gr_ctrl = groupControlledWells(schedule,
wellState,
group_state,
reportStepIdx,
chain[iii],
"",
/*is_producer*/ true,
/*injectionPhaseNotUsed*/ Phase::OIL);
if (num_gr_ctrl == 0) {
// We found a sub wells with no group controlled wells. We now need to adapt the reduction rate
// to reflect what would have happen if the current well under consideration would have been
// under group control. I.e. we first remove the efficient sub_rate from the reduction rate
// (since the reduction rate is removed already from the target we need to add it to the target)
const double sub_efficiency
= schedule.getGroup(chain[iii], reportStepIdx).getGroupEfficiencyFactor();
const double sub_rate = tcalc.calcModeRateFromRates(group_state.production_rates(chain[iii]));
target += sub_efficiency * sub_rate;
// than we remove the local reduction from the target if it does not have a guide rate
if (!guideRate->has(chain[iii])) {
target -= sub_efficiency * localReduction(chain[iii]);
// this local reduction rate may also need adjustments since it may be computed based on the
// assumption that its subgroup dont have a group control wells. I.e we need to move down the
// hierarchy.
} else {
break;
}
}
}
}
@ -1297,7 +1329,6 @@ namespace WellGroupHelpers
local_reduction_level = ii;
}
}
double target = orig_target;
for (size_t ii = 0; ii < num_ancestors; ++ii) {
if ((ii == 0) || guideRate->has(chain[ii], injectionPhase)) {
@ -1309,18 +1340,51 @@ namespace WellGroupHelpers
// Add my reduction back at the level where it is included in the local reduction
if (local_reduction_level == ii )
target += current_rate * efficiencyFactor;
}
if (ii < num_ancestors - 1) {
// Not final level. Add sub-level reduction back, if
// it was nonzero due to having no group-controlled
// wells. Note that we make this call without setting
// the current well to be always included, because we
// want to know the situation that applied to the
// calculation of reductions.
const int num_gr_ctrl = groupControlledWells(schedule, wellState, group_state, reportStepIdx, chain[ii + 1], "", /*is_producer*/false, injectionPhase);
if (num_gr_ctrl == 0) {
if (guideRate->has(chain[ii + 1], injectionPhase)) {
target += localReduction(chain[ii + 1]);
for (size_t iii = ii + 1; iii < num_ancestors; ++iii) {
// Not final level. Add sub-level reduction back, if
// it was not under individual control and nonzero due to having no group-controlled
// wells. We may need to look several levels down the hierarchy to find groups without
// group control wells
const Group::InjectionCMode& subGroupControl = group_state.injection_control(chain[iii], injectionPhase);
const bool individual_control = (subGroupControl != Group::InjectionCMode::FLD
&& subGroupControl != Group::InjectionCMode::NONE);
// The sub group is on individual control. No adjustments needed.
if (individual_control) {
break;
}
// Note that we make this call without setting
// the current well to be always included, because we
// want to know the situation that applied to the
// calculation of reductions.
const int num_gr_ctrl = groupControlledWells(schedule,
wellState,
group_state,
reportStepIdx,
chain[iii],
"",
/*is_producer*/ false,
injectionPhase);
if (num_gr_ctrl == 0) {
// We found a sub wells with no group controlled wells. We now need to adapt the reduction rate
// to reflect what would have happen if the well under consideration would have been
// under group control. I.e. we first remove the efficient sub_rate from the reduction rate
// (since the reduction rate is removed already from the target we need to add it to the target)
const double sub_efficiency
= schedule.getGroup(chain[iii], reportStepIdx).getGroupEfficiencyFactor();
const double sub_rate
= tcalc.calcModeRateFromRates(group_state.injection_surface_rates(chain[iii]));
target += sub_efficiency * sub_rate;
// than we remove the local reduction from the target if it does not have a guide rate
if (!guideRate->has(chain[iii], injectionPhase)) {
target -= sub_efficiency * localReduction(chain[iii]);
// this local reduction rate may also need adjustments since it may be computed based on the
// assumption that its subgroup dont have group control wells. I.e we need to move down the
// hierarchy.
} else {
break;
}
}
}
}