From c1748604f0e4fb71a95b4ef8e1c140d8cbcf5696 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Mon, 13 Jan 2020 11:03:35 +0100 Subject: [PATCH 1/2] Fix REIN for multi level groups by passing the top phase --- .../wells/BlackoilWellModel_impl.hpp | 8 ++++-- opm/simulators/wells/WellGroupHelpers.hpp | 28 ++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index e43506351..4569e5281 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -1954,7 +1954,9 @@ namespace Opm { well_state.setCurrentProductionGroupControl(group.name(), newControl); ss << "Switching control mode for group "<< group.name() << " to " << Group::ProductionCMode2String(newControl); } - wellGroupHelpers::setGroupControl(group, schedule(), reportStepIdx, false, well_state, ss); + // Pass a dummy phase for producer groups. The topPhase is only relevant for injector groups + const Phase topPhase = Phase::WATER; + wellGroupHelpers::setGroupControl(group, schedule(), topPhase, reportStepIdx, false, well_state, ss); break; } default: @@ -1991,7 +1993,9 @@ namespace Opm { } well_state.setCurrentInjectionGroupControl(group.name(), newControl); } - wellGroupHelpers::setGroupControl(group, schedule(), reportStepIdx, /*isInjector*/true, well_state, ss); + const auto& summaryState = ebosSimulator_.vanguard().summaryState(); + const Phase& topPhase = group.injectionControls(summaryState).phase; + wellGroupHelpers::setGroupControl(group, schedule(), topPhase, reportStepIdx, /*isInjector*/true, well_state, ss); if (!ss.str().empty()) deferred_logger.info(ss.str()); diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index 3bba204f5..9bebb6ab0 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -29,15 +29,17 @@ namespace Opm { namespace wellGroupHelpers { - inline void setGroupControl(const Group& group, const Schedule& schedule, const int reportStepIdx, const bool injector, WellStateFullyImplicitBlackoil& wellState, std::ostringstream& ss) { + inline void setGroupControl(const Group& group, const Schedule& schedule, const Phase& topPhase, const int reportStepIdx, const bool injector, WellStateFullyImplicitBlackoil& wellState, std::ostringstream& ss) { for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - setGroupControl(groupTmp, schedule, reportStepIdx, injector, wellState, ss); - if (injector) - wellState.setCurrentInjectionGroupControl(groupName, Group::InjectionCMode::FLD); - else + setGroupControl(groupTmp, schedule, topPhase, reportStepIdx, injector, wellState, ss); + if (injector) { + if (groupTmp.injection_phase() == topPhase || wellState.currentInjectionGroupControl(groupName) == Group::InjectionCMode::NONE) // only switch sub groups with same face or NONE + wellState.setCurrentInjectionGroupControl(groupName, Group::InjectionCMode::FLD); + } else { wellState.setCurrentProductionGroupControl(groupName, Group::ProductionCMode::FLD); + } } const auto& end = wellState.wellMap().end(); @@ -64,9 +66,21 @@ 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()) + // Get the current controls. + const Well::InjectorType& injectorType = wellEcl.getInjectionProperties().injectorType; + + if (injectorType == Well::InjectorType::WATER && topPhase != Phase::WATER) continue; + if (injectorType == Well::InjectorType::OIL && topPhase != Phase::OIL) + continue; + + if (injectorType == Well::InjectorType::GAS && topPhase != Phase::GAS) + continue; + + if (injectorType == Well::InjectorType::MULTI) + throw("Expected WATER, OIL or GAS as type for injectors " + wellEcl.name()); + if (wellState.currentInjectionControls()[well_index] != Well::InjectorCMode::GRUP) { wellState.currentInjectionControls()[well_index] = Well::InjectorCMode::GRUP; ss <<"\n Injector " << wellName << " switches to GRUP control limit"; @@ -102,7 +116,7 @@ namespace Opm { if (schedule.gConSale(reportStepIdx).has(group.name())) { wellState.setCurrentInjectionGroupControl(group.name(), Group::InjectionCMode::SALE); std::ostringstream ss; - setGroupControl(group, schedule, reportStepIdx, /*injector*/true, wellState, ss); + setGroupControl(group, schedule, Phase::GAS, reportStepIdx, /*injector*/true, wellState, ss); } } From 6e0f26f488930a0408ab3e24612529e5f68a3f49 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Mon, 20 Jan 2020 09:14:19 +0100 Subject: [PATCH 2/2] fix typos --- opm/simulators/wells/BlackoilWellModel_impl.hpp | 10 +++++----- opm/simulators/wells/WellGroupHelpers.hpp | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 4569e5281..9e8b1cc19 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -1954,9 +1954,9 @@ namespace Opm { well_state.setCurrentProductionGroupControl(group.name(), newControl); ss << "Switching control mode for group "<< group.name() << " to " << Group::ProductionCMode2String(newControl); } - // Pass a dummy phase for producer groups. The topPhase is only relevant for injector groups - const Phase topPhase = Phase::WATER; - wellGroupHelpers::setGroupControl(group, schedule(), topPhase, reportStepIdx, false, well_state, ss); + // Pass a dummy phase for producer groups. The topUpPhase is only relevant for injector groups + const Phase topUpPhase = Phase::WATER; + wellGroupHelpers::setGroupControl(group, schedule(), topUpPhase, reportStepIdx, false, well_state, ss); break; } default: @@ -1994,8 +1994,8 @@ namespace Opm { well_state.setCurrentInjectionGroupControl(group.name(), newControl); } const auto& summaryState = ebosSimulator_.vanguard().summaryState(); - const Phase& topPhase = group.injectionControls(summaryState).phase; - wellGroupHelpers::setGroupControl(group, schedule(), topPhase, reportStepIdx, /*isInjector*/true, well_state, ss); + const Phase& topUpPhase = group.injectionControls(summaryState).phase; + wellGroupHelpers::setGroupControl(group, schedule(), topUpPhase, reportStepIdx, /*isInjector*/true, well_state, ss); if (!ss.str().empty()) deferred_logger.info(ss.str()); diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index 9bebb6ab0..2e4457e3f 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -29,13 +29,13 @@ namespace Opm { namespace wellGroupHelpers { - inline void setGroupControl(const Group& group, const Schedule& schedule, const Phase& topPhase, const int reportStepIdx, const bool injector, WellStateFullyImplicitBlackoil& wellState, std::ostringstream& ss) { + inline void setGroupControl(const Group& group, const Schedule& schedule, const Phase& topUpPhase, const int reportStepIdx, const bool injector, WellStateFullyImplicitBlackoil& wellState, std::ostringstream& ss) { for (const std::string& groupName : group.groups()) { const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx); - setGroupControl(groupTmp, schedule, topPhase, reportStepIdx, injector, wellState, ss); + setGroupControl(groupTmp, schedule, topUpPhase, reportStepIdx, injector, wellState, ss); if (injector) { - if (groupTmp.injection_phase() == topPhase || wellState.currentInjectionGroupControl(groupName) == Group::InjectionCMode::NONE) // only switch sub groups with same face or NONE + if (groupTmp.injection_phase() == topUpPhase || wellState.currentInjectionGroupControl(groupName) == Group::InjectionCMode::NONE) // only switch sub groups with same phase or NONE wellState.setCurrentInjectionGroupControl(groupName, Group::InjectionCMode::FLD); } else { wellState.setCurrentProductionGroupControl(groupName, Group::ProductionCMode::FLD); @@ -69,13 +69,13 @@ namespace Opm { // Get the current controls. const Well::InjectorType& injectorType = wellEcl.getInjectionProperties().injectorType; - if (injectorType == Well::InjectorType::WATER && topPhase != Phase::WATER) + if (injectorType == Well::InjectorType::WATER && topUpPhase != Phase::WATER) continue; - if (injectorType == Well::InjectorType::OIL && topPhase != Phase::OIL) + if (injectorType == Well::InjectorType::OIL && topUpPhase != Phase::OIL) continue; - if (injectorType == Well::InjectorType::GAS && topPhase != Phase::GAS) + if (injectorType == Well::InjectorType::GAS && topUpPhase != Phase::GAS) continue; if (injectorType == Well::InjectorType::MULTI)