From 1ce5c5985199c04bb7ff35e0da1147bb11866d21 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Mon, 1 Mar 2021 10:26:40 +0100 Subject: [PATCH 1/6] Honor GEFAC for top group in get{Injection,Production}Controls. --- opm/simulators/wells/WellInterface_impl.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opm/simulators/wells/WellInterface_impl.hpp b/opm/simulators/wells/WellInterface_impl.hpp index b18042e41..ac90bf640 100644 --- a/opm/simulators/wells/WellInterface_impl.hpp +++ b/opm/simulators/wells/WellInterface_impl.hpp @@ -2220,6 +2220,7 @@ namespace Opm } } + efficiencyFactor *= group.getGroupEfficiencyFactor(); assert(group.hasInjectionControl(injectionPhase)); const auto& groupcontrols = group.injectionControls(injectionPhase, summaryState); @@ -2353,6 +2354,7 @@ namespace Opm } } + efficiencyFactor *= group.getGroupEfficiencyFactor(); const auto& well = well_ecl_; const auto pu = phaseUsage(); From 1d9f13e31059969ea2c2def79884bf78f078048e Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Thu, 25 Feb 2021 21:33:42 +0100 Subject: [PATCH 2/6] Honor GEFAC for the top most group when calculating well phase rates. Previously GEFAC was not applied here. --- opm/simulators/wells/WellGroupHelpers.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index 3b2bf23c5..731894d8c 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -128,10 +128,10 @@ namespace WellGroupHelpers double rate = 0.0; for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - rate += groupTmp.getGroupEfficiencyFactor() - * sumWellPhaseRates(rates, groupTmp, schedule, wellState, reportStepIdx, phasePos, injector); + rate += sumWellPhaseRates(rates, groupTmp, schedule, wellState, reportStepIdx, phasePos, injector); } const auto& end = wellState.wellMap().end(); + for (const std::string& wellName : group.wells()) { const auto& it = wellState.wellMap().find(wellName); if (it == end) // the well is not found @@ -159,7 +159,8 @@ namespace WellGroupHelpers else rate -= factor * rates[wellrate_index + phasePos]; } - return rate; + const auto& gefac = group.getGroupEfficiencyFactor(); + return gefac * rate; } double sumWellRates(const Group& group, From 6e8b1e8d2e66a6ebcdb7cadb9f84b73ccc3116a8 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Mon, 1 Mar 2021 11:00:00 +0100 Subject: [PATCH 3/6] Honor gefac of topmost group in WellHelpers::updateGuideRateForGroups --- opm/simulators/wells/WellGroupHelpers.hpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index db2a6a260..658119f1e 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -110,11 +110,11 @@ namespace WellGroupHelpers for (const std::string& groupName : group.groups()) { std::vector thisPot(np, 0.0); const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); + + // Note that group effiency factors for groupTmp are applied in updateGuideRateForGroups updateGuideRateForGroups( groupTmp, schedule, pu, reportStepIdx, simTime, isInjector, wellState, comm, guideRate, thisPot); - const auto gefac = groupTmp.getGroupEfficiencyFactor(); - // accumulate group contribution from sub group unconditionally if (isInjector) { const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS}; @@ -129,7 +129,7 @@ namespace WellGroupHelpers else continue; - pot[phasePos] += gefac * thisPot[phasePos]; + pot[phasePos] += thisPot[phasePos]; } } else { const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName); @@ -138,7 +138,7 @@ namespace WellGroupHelpers continue; } for (int phase = 0; phase < np; phase++) { - pot[phase] += gefac * thisPot[phase]; + pot[phase] += thisPot[phase]; } } } @@ -173,6 +173,13 @@ namespace WellGroupHelpers } } + // Apply group efficiency factor for this goup + auto gefac = group.getGroupEfficiencyFactor(); + + for (int phase = 0; phase < np; phase++) { + pot[phase] *= gefac; + } + double oilPot = 0.0; if (pu.phase_used[BlackoilPhases::Liquid]) oilPot = pot[pu.phase_pos[BlackoilPhases::Liquid]]; From 39546864ab4709cc4b9aab9d39bae3901c7fb8ec Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Mon, 1 Mar 2021 11:15:24 +0100 Subject: [PATCH 4/6] Honor GEFAC of topmost group when summing solvent rates. --- opm/simulators/wells/WellGroupHelpers.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index 731894d8c..4fa705574 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -194,8 +194,7 @@ namespace WellGroupHelpers double rate = 0.0; for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - rate += groupTmp.getGroupEfficiencyFactor() - * sumSolventRates(groupTmp, schedule, wellState, reportStepIdx, injector); + rate += sumSolventRates(groupTmp, schedule, wellState, reportStepIdx, injector); } const auto& end = wellState.wellMap().end(); for (const std::string& wellName : group.wells()) { @@ -224,7 +223,8 @@ namespace WellGroupHelpers else rate -= factor * wellState.solventWellRate(well_index); } - return rate; + const auto& gefac = group.getGroupEfficiencyFactor(); + return gefac * rate; } void updateGroupTargetReduction(const Group& group, From 0d2b9629b067f05866cf48a617c367ffe6ad2c6e Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Tue, 2 Mar 2021 11:31:04 +0100 Subject: [PATCH 5/6] Document efficiencyFactor in checkGroupConstraints{Inj,Prod} Reading recursion is quite hard and a comment might help others. --- opm/simulators/wells/WellGroupHelpers.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index 4fa705574..b8dd84558 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -1017,6 +1017,9 @@ namespace WellGroupHelpers // will be the name of 'group'. But if we recurse, 'name' and // 'parent' will stay fixed while 'group' will be higher up // in the group tree. + // efficiency factor is the well efficiency factor for the first group the well is + // part of. Later it is the accumulated factor including the group efficiency factor + // of the child of group. const Group::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(injectionPhase, group.name()); @@ -1237,6 +1240,9 @@ namespace WellGroupHelpers // will be the name of 'group'. But if we recurse, 'name' and // 'parent' will stay fixed while 'group' will be higher up // in the group tree. + // efficiencyfactor is the well efficiency factor for the first group the well is + // part of. Later it is the accumulated factor including the group efficiency factor + // of the child of group. const Group::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(group.name()); From d1f65451f17abb0585ae4e79f7a93d90238d8a09 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Tue, 2 Mar 2021 11:32:27 +0100 Subject: [PATCH 6/6] Honor top most group efficiency factor in checkGroupConstraints{Inj,Prod} --- opm/simulators/wells/WellGroupHelpers.cpp | 25 +++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index b8dd84558..24ead3e59 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -1089,13 +1089,15 @@ namespace WellGroupHelpers name, group.name(), schedule, wellState, reportStepIdx, guideRate, target, pu, injectionPhase, true); double target_fraction = 1.0; bool constraint_broken = false; + double efficiencyFactorInclGroup = efficiencyFactor * group.getGroupEfficiencyFactor(); + switch (currentGroupControl) { case Group::InjectionCMode::RATE: { const double current_rate = rates[phasePos]; const double target_rate = fraction * std::max(0.0, - (groupcontrols.surface_max_rate - groupTargetReduction + current_rate * efficiencyFactor)) - / efficiencyFactor; + (groupcontrols.surface_max_rate - groupTargetReduction + current_rate * efficiencyFactorInclGroup)) + / efficiencyFactorInclGroup; if (current_rate > target_rate) { constraint_broken = true; target_fraction = target_rate / current_rate; @@ -1108,8 +1110,8 @@ namespace WellGroupHelpers const double target_rate = fraction * std::max(0.0, (groupcontrols.resv_max_rate / coeff - groupTargetReduction - + current_rate * efficiencyFactor)) - / efficiencyFactor; + + current_rate * efficiencyFactorInclGroup)) + / efficiencyFactorInclGroup; if (current_rate > target_rate) { constraint_broken = true; target_fraction = target_rate / current_rate; @@ -1122,8 +1124,8 @@ namespace WellGroupHelpers const double target_rate = fraction * std::max(0.0, (groupcontrols.target_reinj_fraction * productionRate - groupTargetReduction - + current_rate * efficiencyFactor)) - / efficiencyFactor; + + current_rate * efficiencyFactorInclGroup)) + / efficiencyFactorInclGroup; if (current_rate > target_rate) { constraint_broken = true; target_fraction = target_rate / current_rate; @@ -1149,8 +1151,8 @@ namespace WellGroupHelpers const double current_rate = rates[phasePos]; const double target_rate = fraction - * std::max(0.0, (voidageRate / coeff - groupTargetReduction + current_rate * efficiencyFactor)) - / efficiencyFactor; + * std::max(0.0, (voidageRate / coeff - groupTargetReduction + current_rate * efficiencyFactorInclGroup)) + / efficiencyFactorInclGroup; if (current_rate > target_rate) { constraint_broken = true; target_fraction = target_rate / current_rate; @@ -1169,7 +1171,7 @@ namespace WellGroupHelpers const double current_rate = rates[phasePos]; const double target_rate = fraction - * std::max(0.0, (inj_rate - groupTargetReduction + current_rate * efficiencyFactor)) / efficiencyFactor; + * std::max(0.0, (inj_rate - groupTargetReduction + current_rate * efficiencyFactorInclGroup)) / efficiencyFactorInclGroup; if (current_rate > target_rate) { constraint_broken = true; target_fraction = target_rate / current_rate; @@ -1311,6 +1313,7 @@ namespace WellGroupHelpers } } + double efficiencyFactorInclGroup = efficiencyFactor * group.getGroupEfficiencyFactor(); double target = orig_target; for (size_t ii = 0; ii < num_ancestors; ++ii) { if ((ii == 0) || guideRate->has(chain[ii])) { @@ -1321,7 +1324,7 @@ 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; + target += current_rate * efficiencyFactorInclGroup; } if (ii < num_ancestors - 1) { // Not final level. Add sub-level reduction back, if @@ -1340,7 +1343,7 @@ namespace WellGroupHelpers target *= localFraction(chain[ii + 1]); } // Avoid negative target rates comming from too large local reductions. - const double target_rate = std::max(1e-12, target / efficiencyFactor); + const double target_rate = std::max(1e-12, target / efficiencyFactorInclGroup); return std::make_pair(current_rate > target_rate, target_rate / current_rate); }