diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 5552d4695..b051a5e2e 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -785,6 +785,8 @@ namespace Opm { calculateExplicitQuantities(local_deferredLogger); prepareTimeStep(local_deferredLogger); } + updateWellControls(local_deferredLogger, true); + // only check group controls for iterationIdx smaller then nupcol const int reportStepIdx = ebosSimulator_.episodeIndex(); const int nupcol = schedule().getNupcol(reportStepIdx); @@ -792,13 +794,14 @@ namespace Opm { const Group2& fieldGroup = schedule().getGroup2("FIELD", reportStepIdx); std::vector groupTargetReduction(numPhases(), 0.0); wellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, well_state_, groupTargetReduction); + std::vector groupTargetReductionInj(numPhases(), 0.0); + wellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, well_state_, groupTargetReductionInj); std::vector rein(numPhases(), 0.0); wellGroupHelpers::updateREINForGroups(fieldGroup, schedule(), reportStepIdx, well_state_, rein); double resv = 0.0; wellGroupHelpers::updateVREPForGroups(fieldGroup, schedule(), reportStepIdx, well_state_, resv); } - updateWellControls(local_deferredLogger, true); // Set the well primary variables based on the value of well solutions initPrimaryVariablesEvaluation(); @@ -1684,16 +1687,18 @@ namespace Opm { } } if (group.has_control(Group2::InjectionCMode::VREP)) { - double voidage_Rate = 0.0; + double voidage_rate = 0.0; const Group2& groupVoidage = schedule().getGroup2(controls.voidage_group, reportStepIdx); - voidage_Rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], false); - voidage_Rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], false); - voidage_Rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Vapour], false); + voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], false); + voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], false); + voidage_rate += wellGroupHelpers::sumWellResRates(groupVoidage, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Vapour], false); - double current_rate = 0.0; - current_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phasePos, /*isInjector*/true); + double total_rate = 0.0; + total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Aqua], true); + total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Liquid], true); + total_rate += wellGroupHelpers::sumWellResRates(group, schedule(), well_state, reportStepIdx, phase_usage_.phase_pos[BlackoilPhases::Vapour], true); - if (controls.target_void_fraction*voidage_Rate < current_rate) { + if (controls.target_void_fraction*voidage_rate < total_rate) { actionOnBrokenConstraints(group, Group2::InjectionCMode::VREP, reportStepIdx, deferred_logger); } } diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index fccf0017e..b945c5056 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -1005,8 +1005,8 @@ namespace Opm throw("Expected WATER, OIL or GAS as type for injectors " + well.name()); } - const std::vector& groupTargetReductions = well_state.currentProductionGroupReductionRates(group.name()); - double groupTargetReduction = groupTargetReductions[phasePos]; + const std::vector& groupInjectionReductions = well_state.currentInjectionGroupReductionRates(group.name()); + double groupTargetReduction = groupInjectionReductions[phasePos]; double fraction = wellGroupHelpers::wellFractionFromGuideRates(well, schedule, well_state, current_step_, Base::guide_rate_, wellTarget, /*isInjector*/true); wellGroupHelpers::accumulateGroupFractions(well.groupName(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, groupTarget, /*isInjector*/true, fraction); @@ -1045,7 +1045,22 @@ namespace Opm Base::rateConverter_.calcCoeff(/*fipreg*/ 0, Base::pvtRegionIdx_, convert_coeff); double coeff = convert_coeff[phasePos]; double voidageRate = well_state.currentInjectionVREPRates(groupcontrols.voidage_group); + + double injReduction = 0.0; + + if (groupcontrols.phase != Phase::WATER) + injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Aqua]]*convert_coeff[pu.phase_pos[BlackoilPhases::Aqua]]; + + if (groupcontrols.phase != Phase::OIL) + injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Liquid]]*convert_coeff[pu.phase_pos[BlackoilPhases::Liquid]]; + + if (groupcontrols.phase != Phase::GAS) + injReduction += groupInjectionReductions[pu.phase_pos[BlackoilPhases::Vapour]]*convert_coeff[pu.phase_pos[BlackoilPhases::Vapour]]; + + voidageRate -= injReduction; + voidageRate /= efficiencyFactor; + double target = std::max(0.0, ( groupcontrols.target_void_fraction*voidageRate/coeff - groupTargetReduction)); control_eq = getWQTotal() - fraction * target; break; diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index 494295ced..27d140a9b 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -94,6 +94,10 @@ namespace Opm { } if (wellEcl.isInjector() && injector) { + // only switch if the well phase is the same as the group phase + if (group.injection_phase() != wellEcl.getPreferredPhase()) + continue; + if (wellState.currentInjectionControls()[well_index] != Well2::InjectorCMode::GRUP) { wellState.currentInjectionControls()[well_index] = Well2::InjectorCMode::GRUP; ss <<"\n Injector " << wellName << " switches to GRUP control limit";