2019-08-07 07:13:11 -05:00
|
|
|
/*
|
|
|
|
Copyright 2019 Norce.
|
|
|
|
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef OPM_WELLGROUPHELPERS_HEADER_INCLUDED
|
|
|
|
#define OPM_WELLGROUPHELPERS_HEADER_INCLUDED
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace Opm {
|
|
|
|
|
|
|
|
|
|
|
|
namespace wellGroupHelpers
|
|
|
|
{
|
|
|
|
|
|
|
|
inline void setCmodeGroup(const Group2& group, const Schedule& schedule, const SummaryState& summaryState, const int reportStepIdx, WellStateFullyImplicitBlackoil& wellState) {
|
|
|
|
|
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
setCmodeGroup( schedule.getGroup2(groupName, reportStepIdx), schedule, summaryState, reportStepIdx, wellState);
|
|
|
|
}
|
|
|
|
|
|
|
|
// use FLD as default control
|
|
|
|
wellState.setCurrentInjectionGroupControl(group.name(), Group2::InjectionCMode::FLD);
|
|
|
|
wellState.setCurrentProductionGroupControl(group.name(), Group2::ProductionCMode::FLD);
|
|
|
|
|
|
|
|
if (group.isInjectionGroup()) {
|
|
|
|
const auto controls = group.injectionControls(summaryState);
|
|
|
|
wellState.setCurrentInjectionGroupControl(group.name(), controls.cmode);
|
|
|
|
}
|
|
|
|
if (group.isProductionGroup()) {
|
|
|
|
const auto controls = group.productionControls(summaryState);
|
|
|
|
wellState.setCurrentProductionGroupControl(group.name(), controls.cmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline void accumulateGroupEfficiencyFactor(const Group2& group, const Schedule& schedule, const int reportStepIdx, double& factor) {
|
|
|
|
factor *= group.getGroupEfficiencyFactor();
|
|
|
|
if (group.parent() != "FIELD")
|
|
|
|
accumulateGroupEfficiencyFactor(schedule.getGroup2(group.parent(), reportStepIdx), schedule, reportStepIdx, factor);
|
|
|
|
}
|
|
|
|
|
2019-10-16 08:27:40 -05:00
|
|
|
inline void setGroupControl(const Group2& group, const Schedule& schedule, const int reportStepIdx, const bool injector, WellStateFullyImplicitBlackoil& wellState, std::ostringstream& ss) {
|
2019-08-07 07:13:11 -05:00
|
|
|
|
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
2019-10-16 08:27:40 -05:00
|
|
|
setGroupControl(groupTmp, schedule, reportStepIdx, injector, wellState, ss);
|
2019-09-30 05:49:36 -05:00
|
|
|
if (injector)
|
|
|
|
wellState.setCurrentInjectionGroupControl(groupName, Group2::InjectionCMode::FLD);
|
|
|
|
else
|
|
|
|
wellState.setCurrentProductionGroupControl(groupName, Group2::ProductionCMode::FLD);
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
2019-09-30 05:49:36 -05:00
|
|
|
|
2019-08-07 07:13:11 -05:00
|
|
|
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
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int well_index = it->second[0];
|
|
|
|
const auto& wellEcl = schedule.getWell2(wellName, reportStepIdx);
|
2019-09-30 05:49:36 -05:00
|
|
|
|
|
|
|
if (wellEcl.getStatus() == Well2::Status::SHUT)
|
2019-08-07 07:13:11 -05:00
|
|
|
continue;
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
if (!wellEcl.isAvailableForGroupControl())
|
|
|
|
continue;
|
|
|
|
|
2019-10-16 08:27:40 -05:00
|
|
|
if (wellEcl.isProducer() && !injector) {
|
|
|
|
if (wellState.currentProductionControls()[well_index] != Well2::ProducerCMode::GRUP) {
|
|
|
|
wellState.currentProductionControls()[well_index] = Well2::ProducerCMode::GRUP;
|
|
|
|
ss <<"\n Producer " << wellName << " switches to GRUP control limit";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wellEcl.isInjector() && injector) {
|
|
|
|
if (wellState.currentInjectionControls()[well_index] != Well2::InjectorCMode::GRUP) {
|
|
|
|
wellState.currentInjectionControls()[well_index] = Well2::InjectorCMode::GRUP;
|
|
|
|
ss <<"\n Injector " << wellName << " switches to GRUP control limit";
|
|
|
|
}
|
|
|
|
}
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
inline void computeGroupTargetReduction(const Group2& group, const WellStateFullyImplicitBlackoil& wellState, const Schedule& schedule, const int reportStepIdx, const int phasePos, const bool isInjector, double& groupTargetReduction )
|
|
|
|
{
|
|
|
|
|
2019-08-07 07:13:11 -05:00
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
2019-09-30 05:49:36 -05:00
|
|
|
computeGroupTargetReduction(groupTmp, wellState, schedule, reportStepIdx, phasePos, isInjector, groupTargetReduction);
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
for (const std::string& wellName : group.wells()) {
|
2019-09-30 05:49:36 -05:00
|
|
|
const auto& wellTmp = schedule.getWell2(wellName, reportStepIdx);
|
2019-08-07 07:13:11 -05:00
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
if (wellTmp.isProducer() && isInjector)
|
|
|
|
continue;
|
2019-08-07 07:13:11 -05:00
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
if (wellTmp.isInjector() && !isInjector)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (wellTmp.getStatus() == Well2::Status::SHUT)
|
2019-08-07 07:13:11 -05:00
|
|
|
continue;
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
const auto& end = wellState.wellMap().end();
|
|
|
|
const auto& it = wellState.wellMap().find( wellName );
|
|
|
|
if (it == end) // the well is not found
|
|
|
|
continue;
|
2019-08-07 07:13:11 -05:00
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
int well_index = it->second[0];
|
2019-08-07 07:13:11 -05:00
|
|
|
const auto wellrate_index = well_index * wellState.numPhases();
|
2019-09-30 05:49:36 -05:00
|
|
|
// add contributino from wells not under group control
|
|
|
|
if (isInjector) {
|
|
|
|
if (wellState.currentInjectionControls()[well_index] != Well2::InjectorCMode::GRUP)
|
|
|
|
groupTargetReduction += wellState.wellRates()[wellrate_index + phasePos];
|
|
|
|
} else {
|
|
|
|
if (wellState.currentProductionControls()[well_index] != Well2::ProducerCMode::GRUP)
|
|
|
|
groupTargetReduction -= wellState.wellRates()[wellrate_index + phasePos];
|
|
|
|
}
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
inline double sumWellPhaseRates(const std::vector<double>& rates, const Group2& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const int phasePos,
|
|
|
|
const bool injector) {
|
|
|
|
|
|
|
|
double rate = 0.0;
|
2019-08-07 07:13:11 -05:00
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
2019-09-30 05:49:36 -05:00
|
|
|
rate += groupTmp.getGroupEfficiencyFactor()*sumWellPhaseRates(rates, groupTmp, schedule, wellState, reportStepIdx, phasePos, injector);
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
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
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int well_index = it->second[0];
|
2019-09-30 05:49:36 -05:00
|
|
|
|
2019-08-07 07:13:11 -05:00
|
|
|
const auto& wellEcl = schedule.getWell2(wellName, reportStepIdx);
|
2019-09-30 05:49:36 -05:00
|
|
|
//only count producers or injectors
|
|
|
|
if ( (wellEcl.isProducer() && injector) || (wellEcl.isInjector() && !injector))
|
2019-08-07 07:13:11 -05:00
|
|
|
continue;
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
if (wellEcl.getStatus() == Well2::Status::SHUT)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
double factor = wellEcl.getEfficiencyFactor();
|
|
|
|
const auto wellrate_index = well_index * wellState.numPhases();
|
|
|
|
if (injector)
|
|
|
|
rate += factor * rates[ wellrate_index + phasePos];
|
|
|
|
else
|
|
|
|
rate -= factor * rates[ wellrate_index + phasePos];
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
2019-09-30 05:49:36 -05:00
|
|
|
return rate;
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
inline double sumWellRates(const Group2& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const int phasePos, const bool injector) {
|
|
|
|
return sumWellPhaseRates(wellState.wellRates(), group, schedule, wellState, reportStepIdx, phasePos, injector);
|
|
|
|
}
|
2019-08-07 07:13:11 -05:00
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
inline double sumWellResRates(const Group2& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const int phasePos, const bool injector) {
|
|
|
|
return sumWellPhaseRates(wellState.wellReservoirRates(), group, schedule, wellState, reportStepIdx, phasePos, injector);
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
|
2019-09-23 08:15:55 -05:00
|
|
|
inline double sumSolventRates(const Group2& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const bool injector) {
|
|
|
|
|
|
|
|
double rate = 0.0;
|
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
|
|
|
rate += groupTmp.getGroupEfficiencyFactor()*sumSolventRates(groupTmp, schedule, wellState, reportStepIdx, 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
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int well_index = it->second[0];
|
|
|
|
|
|
|
|
const auto& wellEcl = schedule.getWell2(wellName, reportStepIdx);
|
|
|
|
//only count producers or injectors
|
|
|
|
if ( (wellEcl.isProducer() && injector) || (wellEcl.isInjector() && !injector))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (wellEcl.getStatus() == Well2::Status::SHUT)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
double factor = wellEcl.getEfficiencyFactor();
|
|
|
|
if (injector)
|
|
|
|
rate += factor * wellState.solventWellRate(well_index);
|
|
|
|
else
|
|
|
|
rate -= factor * wellState.solventWellRate(well_index);
|
|
|
|
}
|
|
|
|
return rate;
|
|
|
|
}
|
|
|
|
|
2019-11-05 08:12:01 -06:00
|
|
|
inline void updateGroupTargetReduction(const Group2& group, const Schedule& schedule, const int reportStepIdx, const bool isInjector, WellStateFullyImplicitBlackoil& wellState, std::vector<double>& groupTargetReduction)
|
|
|
|
{
|
|
|
|
const int np = wellState.numPhases();
|
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
std::vector<double> thisGroupTargetReduction(np, 0.0);
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
|
|
|
updateGroupTargetReduction(groupTmp, schedule, reportStepIdx, isInjector, wellState, thisGroupTargetReduction);
|
|
|
|
|
|
|
|
// accumulate group contribution from sub group
|
|
|
|
if (isInjector) {
|
|
|
|
const Group2::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(groupName);
|
|
|
|
if (currentGroupControl != Group2::InjectionCMode::FLD) {
|
|
|
|
for (int phase = 0; phase < np; phase++) {
|
|
|
|
groupTargetReduction[phase] += sumWellRates(group, schedule, wellState, reportStepIdx, phase, isInjector);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const Group2::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName);
|
|
|
|
if (currentGroupControl != Group2::ProductionCMode::FLD) {
|
|
|
|
for (int phase = 0; phase < np; phase++) {
|
|
|
|
groupTargetReduction[phase] += sumWellRates(group, schedule, wellState, reportStepIdx, phase, isInjector);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// or accumulate directly from the wells if controled from its parents
|
|
|
|
for (int phase = 0; phase < np; phase++) {
|
|
|
|
groupTargetReduction[phase] += thisGroupTargetReduction[phase];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//std::vector<double> groupTargetReduction(np, 0.0);
|
|
|
|
for (const std::string& wellName : group.wells()) {
|
|
|
|
const auto& wellTmp = schedule.getWell2(wellName, reportStepIdx);
|
|
|
|
|
|
|
|
if (wellTmp.isProducer() && isInjector)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (wellTmp.isInjector() && !isInjector)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (wellTmp.getStatus() == Well2::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];
|
|
|
|
const auto wellrate_index = well_index * wellState.numPhases();
|
|
|
|
// add contributino from wells not under group control
|
|
|
|
if (isInjector) {
|
|
|
|
if (wellState.currentInjectionControls()[well_index] != Well2::InjectorCMode::GRUP)
|
|
|
|
for (int phase = 0; phase < np; phase++) {
|
|
|
|
groupTargetReduction[phase] += wellState.wellRates()[wellrate_index + phase];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (wellState.currentProductionControls()[well_index] != Well2::ProducerCMode::GRUP)
|
|
|
|
for (int phase = 0; phase < np; phase++) {
|
|
|
|
groupTargetReduction[phase] -= wellState.wellRates()[wellrate_index + phase];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isInjector)
|
|
|
|
wellState.setCurrentInjectionGroupReductionRates(group.name(), groupTargetReduction);
|
|
|
|
else
|
|
|
|
wellState.setCurrentProductionGroupReductionRates(group.name(), groupTargetReduction);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-08-07 07:13:11 -05:00
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
inline void updateGuideRateForGroups(const Group2& group, const Schedule& schedule, const PhaseUsage& pu, const int reportStepIdx, const double& simTime, GuideRate* guideRate, WellStateFullyImplicitBlackoil& wellState) {
|
2019-08-07 07:13:11 -05:00
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
2019-09-30 05:49:36 -05:00
|
|
|
updateGuideRateForGroups(groupTmp, schedule, pu, reportStepIdx, simTime, guideRate, wellState);
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
2019-09-30 05:49:36 -05:00
|
|
|
bool isInjector = group.isInjectionGroup();
|
|
|
|
bool isProducer = group.isProductionGroup();
|
|
|
|
|
|
|
|
if (!isInjector && !isProducer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
double oilPot = 0.0;
|
|
|
|
if (pu.phase_used[BlackoilPhases::Liquid])
|
|
|
|
oilPot = sumWellPhaseRates(wellState.wellPotentials(), group, schedule, wellState, reportStepIdx, pu.phase_pos[BlackoilPhases::Liquid], isInjector);
|
|
|
|
|
|
|
|
double gasPot = 0.0;
|
|
|
|
if (pu.phase_used[BlackoilPhases::Vapour])
|
|
|
|
gasPot = sumWellPhaseRates(wellState.wellPotentials(), group, schedule, wellState, reportStepIdx, pu.phase_pos[BlackoilPhases::Vapour], isInjector);
|
|
|
|
|
|
|
|
double waterPot = 0.0;
|
|
|
|
if (pu.phase_used[BlackoilPhases::Aqua])
|
|
|
|
waterPot = sumWellPhaseRates(wellState.wellPotentials(), group, schedule, wellState, reportStepIdx, pu.phase_pos[BlackoilPhases::Aqua], isInjector);
|
|
|
|
|
|
|
|
guideRate->compute(group.name(), reportStepIdx, simTime, oilPot, gasPot, waterPot);
|
|
|
|
}
|
|
|
|
|
2019-11-05 08:12:01 -06:00
|
|
|
inline void updateVREPForGroups(const Group2& group, const Schedule& schedule, const int reportStepIdx, WellStateFullyImplicitBlackoil& wellState, double& resv) {
|
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
|
|
|
double thisResv = 0.0;
|
|
|
|
updateVREPForGroups(groupTmp, schedule, reportStepIdx, wellState, thisResv);
|
|
|
|
resv += thisResv;
|
|
|
|
}
|
|
|
|
const int np = wellState.numPhases();
|
|
|
|
for (int phase = 0; phase < np; ++phase) {
|
|
|
|
resv += sumWellPhaseRates(wellState.wellReservoirRates(), group, schedule, wellState, reportStepIdx, phase, /*isInjector*/ false);
|
|
|
|
}
|
|
|
|
|
|
|
|
wellState.setCurrentInjectionVREPRates(group.name(), resv);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void updateREINForGroups(const Group2& group, const Schedule& schedule, const int reportStepIdx, WellStateFullyImplicitBlackoil& wellState, std::vector<double>& rein) {
|
|
|
|
const int np = wellState.numPhases();
|
|
|
|
for (const std::string& groupName : group.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
|
|
|
std::vector<double> thisRein(np, 0.0);
|
|
|
|
updateREINForGroups(groupTmp, schedule, reportStepIdx, wellState, thisRein);
|
|
|
|
for (int phase = 0; phase < np; ++phase) {
|
|
|
|
rein[phase] = thisRein[phase];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int phase = 0; phase < np; ++phase) {
|
|
|
|
rein[phase] = sumWellPhaseRates(wellState.wellRates(), group, schedule, wellState, reportStepIdx, phase, /*isInjector*/ false);
|
|
|
|
}
|
|
|
|
wellState.setCurrentInjectionREINRates(group.name(), rein);
|
|
|
|
}
|
|
|
|
|
2019-10-17 05:40:14 -05:00
|
|
|
inline double wellFractionFromGuideRates(const Well2& well, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const GuideRate* guideRate, const Well2::GuideRateTarget& wellTarget, const bool isInjector) {
|
2019-09-30 05:49:36 -05:00
|
|
|
double groupTotalGuideRate = 0.0;
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(well.groupName(), reportStepIdx);
|
|
|
|
for (const std::string& wellName : groupTmp.wells()) {
|
2019-08-07 07:13:11 -05:00
|
|
|
const auto& wellTmp = schedule.getWell2(wellName, reportStepIdx);
|
|
|
|
|
|
|
|
if (wellTmp.isProducer() && isInjector)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (wellTmp.isInjector() && !isInjector)
|
|
|
|
continue;
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
if (wellTmp.getStatus() == Well2::Status::SHUT)
|
|
|
|
continue;
|
2019-08-07 07:13:11 -05:00
|
|
|
|
2019-10-17 05:40:14 -05:00
|
|
|
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];
|
|
|
|
|
|
|
|
// only count wells under group control
|
|
|
|
if (isInjector) {
|
|
|
|
if (wellState.currentInjectionControls()[well_index] != Well2::InjectorCMode::GRUP)
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if (wellState.currentProductionControls()[well_index] != Well2::ProducerCMode::GRUP)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
groupTotalGuideRate += guideRate->get(wellName, wellTarget);
|
|
|
|
}
|
2019-09-30 08:26:47 -05:00
|
|
|
|
|
|
|
if (groupTotalGuideRate == 0.0)
|
|
|
|
return 0.0;
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
double wellGuideRate = guideRate->get(well.name(), wellTarget);
|
|
|
|
return wellGuideRate / groupTotalGuideRate;
|
|
|
|
}
|
|
|
|
|
2019-10-17 05:40:14 -05:00
|
|
|
inline double groupFractionFromGuideRates(const Group2& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const GuideRate* guideRate, const Group2::GuideRateTarget& groupTarget, const bool isInjector) {
|
2019-09-30 05:49:36 -05:00
|
|
|
double groupTotalGuideRate = 0.0;
|
|
|
|
const Group2& groupParent = schedule.getGroup2(group.parent(), reportStepIdx);
|
|
|
|
for (const std::string& groupName : groupParent.groups()) {
|
|
|
|
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
|
|
|
|
|
2019-10-17 05:40:14 -05:00
|
|
|
// only count group under group control from its parent
|
|
|
|
if (isInjector) {
|
2019-11-05 08:13:47 -06:00
|
|
|
const Group2::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(groupName);
|
2019-10-17 05:40:14 -05:00
|
|
|
if (currentGroupControl != Group2::InjectionCMode::FLD)
|
|
|
|
continue;
|
|
|
|
} else {
|
2019-11-05 08:13:47 -06:00
|
|
|
const Group2::ProductionCMode& currentGroupControl = wellState.currentProductionGroupControl(groupName);
|
2019-10-17 05:40:14 -05:00
|
|
|
if (currentGroupControl != Group2::ProductionCMode::FLD)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
if ( (groupTmp.isProductionGroup() && !isInjector) ||
|
|
|
|
(groupTmp.isInjectionGroup() && isInjector) )
|
|
|
|
{
|
|
|
|
groupTotalGuideRate += guideRate->get(groupName, groupTarget);
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
}
|
2019-09-30 08:26:47 -05:00
|
|
|
if (groupTotalGuideRate == 0.0)
|
2019-11-05 08:13:47 -06:00
|
|
|
return 1.0;
|
2019-09-30 08:26:47 -05:00
|
|
|
|
2019-09-30 05:49:36 -05:00
|
|
|
double groupGuideRate = guideRate->get(group.name(), groupTarget);
|
|
|
|
return groupGuideRate / groupTotalGuideRate;
|
2019-08-07 07:13:11 -05:00
|
|
|
}
|
|
|
|
|
2019-11-05 08:13:47 -06:00
|
|
|
inline void accumulateGroupFractions(const std::string& groupName, const std::string& controlGroupName, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState,const int reportStepIdx, const GuideRate* guideRate, const Group2::GuideRateTarget& groupTarget, const bool isInjector, double& fraction) {
|
2019-09-30 05:49:36 -05:00
|
|
|
|
|
|
|
const Group2& group = schedule.getGroup2(groupName, reportStepIdx);
|
|
|
|
if (groupName != controlGroupName) {
|
2019-10-17 05:40:14 -05:00
|
|
|
fraction *= groupFractionFromGuideRates(group, schedule, wellState, reportStepIdx, guideRate, groupTarget, isInjector);
|
|
|
|
accumulateGroupFractions(group.parent(), controlGroupName, schedule, wellState, reportStepIdx, guideRate, groupTarget, isInjector, fraction);
|
2019-09-30 05:49:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-08-07 07:13:11 -05:00
|
|
|
|
|
|
|
} // namespace wellGroupHelpers
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|