From 92ee56c3b31cf589d50c0951040aa3ea58be35a9 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Mon, 23 Mar 2020 16:14:31 +0100 Subject: [PATCH] scale guiderate by current well rate --- .../wells/MultisegmentWell_impl.hpp | 8 +- opm/simulators/wells/StandardWell_impl.hpp | 12 +-- opm/simulators/wells/WellGroupHelpers.hpp | 90 ++++++++++++++----- 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/opm/simulators/wells/MultisegmentWell_impl.hpp b/opm/simulators/wells/MultisegmentWell_impl.hpp index 2b3080059..15bba590f 100644 --- a/opm/simulators/wells/MultisegmentWell_impl.hpp +++ b/opm/simulators/wells/MultisegmentWell_impl.hpp @@ -2332,7 +2332,7 @@ namespace Opm case Group::ProductionCMode::ORAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Oil]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::OIL)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::OIL), pu); const double rate_target = std::max(0.0, groupcontrols.oil_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); @@ -2343,7 +2343,7 @@ namespace Opm case Group::ProductionCMode::WRAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Water]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::WAT)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::WAT), pu); const double rate_target = std::max(0.0, groupcontrols.gas_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); @@ -2354,7 +2354,7 @@ namespace Opm case Group::ProductionCMode::GRAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Gas]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::GAS)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::GAS), pu); const double rate_target = std::max(0.0, groupcontrols.gas_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::gasCompIdx)); @@ -2365,7 +2365,7 @@ namespace Opm case Group::ProductionCMode::LRAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Oil]] + groupTargetReductions[pu.phase_pos[Water]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::LIQ)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::LIQ), pu); const double rate_target = std::max(0.0, groupcontrols.liquid_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); EvalWell rate = -getSegmentRate(0, Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx)) diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index d536a4b54..3b3172268 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -1178,7 +1178,7 @@ namespace Opm // If we are here, we are at the topmost group to be visited in the recursion. // This is the group containing the control we will check against. wellGroupHelpers::TargetCalculator tcalc(currentGroupControl, pu, Base::rateConverter_, Base::pvtRegionIdx_); - wellGroupHelpers::FractionCalculator fcalc(schedule, well_state, current_step_, Base::guide_rate_, tcalc.guideTargetMode()); + wellGroupHelpers::FractionCalculator fcalc(schedule, well_state, current_step_, Base::guide_rate_, tcalc.guideTargetMode(), pu); auto localFraction = [&](const std::string& child) { return fcalc.localFraction(child, ""); @@ -1238,7 +1238,7 @@ namespace Opm case Group::ProductionCMode::ORAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Oil]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::OIL)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::OIL), pu); const double rate_target = std::max(0.0, groupcontrols.oil_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); @@ -1249,7 +1249,7 @@ namespace Opm case Group::ProductionCMode::WRAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Water]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::WAT)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::WAT), pu); const double rate_target = std::max(0.0, groupcontrols.water_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); @@ -1260,7 +1260,7 @@ namespace Opm case Group::ProductionCMode::GRAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Gas]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::GAS)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::GAS), pu); const double rate_target = std::max(0.0, groupcontrols.gas_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::gasCompIdx)); @@ -1271,7 +1271,7 @@ namespace Opm case Group::ProductionCMode::LRAT: { double groupTargetReduction = groupTargetReductions[pu.phase_pos[Oil]] + groupTargetReductions[pu.phase_pos[Water]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::LIQ)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::LIQ), pu); const double rate_target = std::max(0.0, groupcontrols.liquid_target - groupTargetReduction) / efficiencyFactor; assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); @@ -1292,7 +1292,7 @@ namespace Opm + groupTargetReductions[pu.phase_pos[Gas]] + groupTargetReductions[pu.phase_pos[Water]]; - double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::RES)); + double fraction = wellGroupHelpers::fractionFromGuideRates(well.name(), group.name(), schedule, well_state, current_step_, Base::guide_rate_, GuideRateModel::convert_target(Well::GuideRateTarget::RES), pu); EvalWell total_rate(numWellEq_ + numEq, 0.); // reservoir rate std::vector convert_coeff(number_of_phases_, 1.0); diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index 49f90d551..8e2ed17a2 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -420,6 +420,29 @@ namespace Opm { wellState.setCurrentInjectionREINRates(group.name(), rein); } + inline GuideRate::RateVector getRateVector(const WellState& well_state, const PhaseUsage& pu, const std::string& name) { + + const auto& end = well_state.wellMap().end(); + const auto& it = well_state.wellMap().find( name); + if (it == end) // the well is not found + assert(false); + + int well_index = it->second[0]; + int np = well_state.numPhases(); + double oilRate = 0.0; + if (pu.phase_used[BlackoilPhases::Liquid]) + oilRate = well_state.wellRates()[ well_index*np + pu.phase_pos[BlackoilPhases::Liquid]]; + + double gasRate = 0.0; + if (pu.phase_used[BlackoilPhases::Vapour]) + gasRate = well_state.wellRates()[ well_index*np + pu.phase_pos[BlackoilPhases::Vapour]]; + + double waterRate = 0.0; + if (pu.phase_used[BlackoilPhases::Aqua]) + waterRate = well_state.wellRates()[well_index*np + pu.phase_pos[BlackoilPhases::Aqua]]; + + return GuideRate::RateVector{oilRate, gasRate, waterRate}; + } inline double getGuideRate(const std::string& name, @@ -427,10 +450,11 @@ namespace Opm { const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const GuideRate* guideRate, - const GuideRateModel::Target target) + const GuideRateModel::Target target, + const PhaseUsage& pu) { if (schedule.hasWell(name, reportStepIdx) || guideRate->has(name)) { - return guideRate->get(name, target); + return guideRate->get(name, target, getRateVector(wellState, pu, name)); } double totalGuideRate = 0.0; @@ -440,7 +464,7 @@ namespace Opm { const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName); if (currentGroupControl == Group::ProductionCMode::FLD || currentGroupControl == Group::ProductionCMode::NONE) { // accumulate from sub wells/groups - totalGuideRate += getGuideRate(groupName, schedule, wellState, reportStepIdx, guideRate, target); + totalGuideRate += getGuideRate(groupName, schedule, wellState, reportStepIdx, guideRate, target, pu); } } @@ -457,7 +481,7 @@ namespace Opm { if (!wellState.isProductionGrup(wellName)) continue; - totalGuideRate += guideRate->get(wellName, target); + totalGuideRate += guideRate->get(wellName, target, getRateVector(wellState, pu, wellName)); } return totalGuideRate; } @@ -469,10 +493,11 @@ namespace Opm { const int reportStepIdx, const GuideRate* guideRate, const GuideRateModel::Target target, - const Phase& injectionPhase) + const Phase& injectionPhase, + const PhaseUsage& pu) { if (schedule.hasWell(name, reportStepIdx)) { - return guideRate->get(name, target); + return guideRate->get(name, target, getRateVector(wellState, pu, name)); } double totalGuideRate = 0.0; @@ -482,7 +507,7 @@ namespace Opm { const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(injectionPhase, groupName); if (currentGroupControl == Group::InjectionCMode::FLD || currentGroupControl == Group::InjectionCMode::NONE) { // accumulate from sub wells/groups - totalGuideRate += getGuideRateInj(groupName, schedule, wellState, reportStepIdx, guideRate, target, injectionPhase); + totalGuideRate += getGuideRateInj(groupName, schedule, wellState, reportStepIdx, guideRate, target, injectionPhase, pu); } } @@ -499,7 +524,7 @@ namespace Opm { if (!wellState.isInjectionGrup(wellName)) continue; - totalGuideRate += guideRate->get(wellName, target); + totalGuideRate += guideRate->get(wellName, target, getRateVector(wellState, pu, wellName)); } return totalGuideRate; } @@ -540,12 +565,14 @@ namespace Opm { const WellStateFullyImplicitBlackoil& well_state, const int report_step, const GuideRate* guide_rate, - const GuideRateModel::Target target) + const GuideRateModel::Target target, + const PhaseUsage& pu) : schedule_(schedule) , well_state_(well_state) , report_step_(report_step) , guide_rate_(guide_rate) , target_(target) + , pu_(pu) { } double fraction(const std::string& name, @@ -604,11 +631,11 @@ namespace Opm { double guideRate(const std::string& name, const std::string& always_included_child) { if (schedule_.hasWell(name, report_step_)) { - return guide_rate_->get(name, target_); + return guide_rate_->get(name, target_, getRateVector(well_state_, pu_, name)); } else { if (groupControlledWells(name, always_included_child) > 0) { if (guide_rate_->has(name)) { - return guide_rate_->get(name, target_); + return guide_rate_->get(name, target_, getGroupRateVector(name)); } else { // We are a group, with default guide rate. // Compute guide rate by accumulating our children's guide rates. @@ -647,11 +674,33 @@ namespace Opm { */ return ::Opm::wellGroupHelpers::groupControlledWells(schedule_, well_state_, report_step_, group_name, always_included_child); } + + inline GuideRate::RateVector getGroupRateVector(const std::string& group_name) { + +#warning Does not work in parallell + const Group& group = schedule_.getGroup(group_name, report_step_); + double oilRate = 0.0; + if (pu_.phase_used[BlackoilPhases::Liquid]) + oilRate = sumWellPhaseRates(well_state_.wellRates(), group, schedule_, well_state_, report_step_, pu_.phase_pos[BlackoilPhases::Liquid], /*isInjector*/ false); + + double gasRate = 0.0; + if (pu_.phase_used[BlackoilPhases::Vapour]) + gasRate = sumWellPhaseRates(well_state_.wellRates(), group, schedule_, well_state_, report_step_, pu_.phase_pos[BlackoilPhases::Vapour], /*isInjector*/ false); + + double waterRate = 0.0; + if (pu_.phase_used[BlackoilPhases::Aqua]) + waterRate = sumWellPhaseRates(well_state_.wellRates(), group, schedule_, well_state_, report_step_, pu_.phase_pos[BlackoilPhases::Aqua], /*isInjector*/ false); + + return GuideRate::RateVector{oilRate, gasRate, waterRate}; + } + + const Schedule& schedule_; const WellStateFullyImplicitBlackoil& well_state_; int report_step_; const GuideRate* guide_rate_; GuideRateModel::Target target_; + PhaseUsage pu_; }; @@ -662,9 +711,10 @@ namespace Opm { const int reportStepIdx, const GuideRate* guideRate, const GuideRateModel::Target target, + const PhaseUsage& pu, const bool alwaysIncludeThis = false) { - FractionCalculator calc(schedule, wellState, reportStepIdx, guideRate, target); + FractionCalculator calc(schedule, wellState, reportStepIdx, guideRate, target, pu); return calc.fraction(name, controlGroupName, alwaysIncludeThis); } @@ -679,8 +729,8 @@ namespace Opm { const Phase& injectionPhase, const bool alwaysIncludeThis = false) { - double thisGuideRate = getGuideRateInj(name, schedule, wellState, reportStepIdx, guideRate, target, injectionPhase); - double controlGroupGuideRate = getGuideRateInj(controlGroupName, schedule, wellState, reportStepIdx, guideRate, target, injectionPhase); + double thisGuideRate = getGuideRateInj(name, schedule, wellState, reportStepIdx, guideRate, target, injectionPhase, pu); + double controlGroupGuideRate = getGuideRateInj(controlGroupName, schedule, wellState, reportStepIdx, guideRate, target, injectionPhase, pu); if (alwaysIncludeThis) controlGroupGuideRate += thisGuideRate; @@ -900,11 +950,11 @@ namespace Opm { x = 0.0; return x; } - template <> - static double zero() - { - return 0.0; - } + //template <> + //static double zero() + //{ + // return 0.0; + //} template auto calcModeRateFromRates(const RateVec& rates) const { @@ -1085,7 +1135,7 @@ namespace Opm { // If we are here, we are at the topmost group to be visited in the recursion. // This is the group containing the control we will check against. TargetCalculator tcalc(currentGroupControl, pu, rateConverter, pvtRegionIdx); - FractionCalculator fcalc(schedule, wellState, reportStepIdx, guideRate, tcalc.guideTargetMode()); + FractionCalculator fcalc(schedule, wellState, reportStepIdx, guideRate, tcalc.guideTargetMode(), pu); auto localFraction = [&](const std::string& child) { return fcalc.localFraction(child, name);