diff --git a/src/opm/output/eclipse/AggregateGroupData.cpp b/src/opm/output/eclipse/AggregateGroupData.cpp index 6fc548367..94dafc6f6 100644 --- a/src/opm/output/eclipse/AggregateGroupData.cpp +++ b/src/opm/output/eclipse/AggregateGroupData.cpp @@ -244,16 +244,23 @@ std::optional controlGroup(const Opm::Schedule& sched, const Opm::Group& group, const std::size_t simStep) { auto current = group; - double cur_prod_ctrl = 0.; - while (current.name() != "FIELD") { - current = sched.getGroup(current.parent(), simStep); + bool isField = false; + double cur_prod_ctrl= 0.; + while (!isField) { if (current.name() != "FIELD") { cur_prod_ctrl = sumState.get_group_var(current.name(), "GMCTP", 0); } else { cur_prod_ctrl = sumState.get("FMCTP", 0); } - if (cur_prod_ctrl > 0) + if (cur_prod_ctrl > 0) { return current; + } + if (current.name() != "FIELD") { + current = sched.getGroup(current.parent(), simStep); + } + else { + isField = true; + } } return {}; } @@ -270,13 +277,13 @@ std::optional injectionControlGroup(const Opm::Schedule& sched, // { auto current = group; - double cur_inj_ctrl = 0.; - while (current.name() != "FIELD" ) { - current = sched.getGroup(current.parent(), simStep); - if (current.name() != "FIELD" ) { - cur_inj_ctrl = sumState.get_group_var(current.name(), curGroupInjCtrlKey, 0.); + bool isField = false; + double cur_inj_ctrl = 0.; + while (!isField) { + if (current.name() != "FIELD") { + cur_inj_ctrl = sumState.get_group_var(current.name(), curGroupInjCtrlKey, 0.); } else { - cur_inj_ctrl = sumState.get(curFieldInjCtrlKey, 0); + cur_inj_ctrl = sumState.get(curFieldInjCtrlKey, 0.); } if (cur_inj_ctrl > 0) { return current; @@ -287,6 +294,11 @@ std::optional injectionControlGroup(const Opm::Schedule& sched, << " is not defined for group: " << current.name() << " at timestep: " << simStep << std::endl; } #endif // ENABLE_GCNTL_DEBUG_OUTPUT + if (current.name() != "FIELD") { + current = sched.getGroup(current.parent(), simStep); + } else { + isField = true; + } } return {}; } // namespace @@ -372,7 +384,7 @@ void productionGroup(const Opm::Schedule& sched, const auto& cgroup = controlGroup(sched, sumState, group, simStep); const auto& deck_cmode = group.prod_cmode(); - if (cgroup && (group.getGroupType() != Opm::Group::GroupType::NONE)) { + if (cgroup && (cgroup->name() != group.name()) && (group.getGroupType() != Opm::Group::GroupType::NONE)) { auto cgroup_control = (cgroup->name() == "FIELD") ? static_cast(sumState.get("FMCTP", 0)) : static_cast(sumState.get_group_var(cgroup->name(), "GMCTP", 0)); iGrp[nwgmax + IGroup::ProdActiveCMode] = (prod_guide_rate_def != Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE) ? cgroup_control : 0; @@ -426,7 +438,7 @@ void productionGroup(const Opm::Schedule& sched, break; case Opm::Group::ProductionCMode::FLD: if (cgroup && (prod_guide_rate_def != Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { - iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::Form; + iGrp[nwgmax + IGroup::GuideRateDef] = GuideRateModeFromGuideRateProdTarget(prod_guide_rate_def); } iGrp[nwgmax + IGroup::ExceedAction] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 4 : 4; break; @@ -437,7 +449,7 @@ void productionGroup(const Opm::Schedule& sched, // Start branching for determining iGrp[nwgmax + IGroup::ProdHighLevCtrl] // use default value if group is not available for group control - if (group.getGroupType() == Opm::Group::GroupType::NONE) { + if (group.getGroupType() == Opm::Group::GroupType::NONE || group.getGroupType() == Opm::Group::GroupType::INJECTION) { if (is_field) { iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 0; } else { @@ -447,36 +459,38 @@ void productionGroup(const Opm::Schedule& sched, return; } - if (cgroup && cgroup->name() == "FIELD") - throw std::logic_error("Got cgroup == FIELD - uncertain logic"); - // group is available for higher level control, but is currently constrained by own limits - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = -1; - if ((deck_cmode != Opm::Group::ProductionCMode::FLD) && !group.productionGroupControlAvailable()) { - //group is not free to respond to higher level control) + if (group.name() == "FIELD" ) { iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 0; - } else if (cgroup && ((active_cmode == Opm::Group::ProductionCMode::FLD) || (active_cmode == Opm::Group::ProductionCMode::NONE))) { - //a higher level group control is active constraint - if ((deck_cmode != Opm::Group::ProductionCMode::FLD) && (deck_cmode != Opm::Group::ProductionCMode::NONE)) { - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = cgroup->insert_index(); - } else if ((deck_cmode == Opm::Group::ProductionCMode::FLD) && (prod_guide_rate_def != Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = cgroup->insert_index(); - } else if ((deck_cmode == Opm::Group::ProductionCMode::NONE) && group.productionGroupControlAvailable() && - (prod_guide_rate_def != Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = cgroup->insert_index(); + } else { + // group is available for higher level control, but is currently constrained by own limits + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = -1; + if ((deck_cmode != Opm::Group::ProductionCMode::FLD) && !group.productionGroupControlAvailable()) { + //group is not free to respond to higher level control) + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 0; + } else if (cgroup && ((active_cmode == Opm::Group::ProductionCMode::FLD) || (active_cmode == Opm::Group::ProductionCMode::NONE))) { + //a higher level group control is active constraint + if ((deck_cmode != Opm::Group::ProductionCMode::FLD) && (deck_cmode != Opm::Group::ProductionCMode::NONE)) { + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = cgroup->insert_index(); + } else if ((deck_cmode == Opm::Group::ProductionCMode::FLD) && (prod_guide_rate_def != Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = cgroup->insert_index(); + } else if ((deck_cmode == Opm::Group::ProductionCMode::NONE) && group.productionGroupControlAvailable() && + (prod_guide_rate_def != Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = cgroup->insert_index(); + //group is directly under higher level controlGroup + } else if ((deck_cmode == Opm::Group::ProductionCMode::FLD) && (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; + } else if ((deck_cmode == Opm::Group::ProductionCMode::NONE) && group.productionGroupControlAvailable() && + (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; + } + } else if (!cgroup && active_cmode == Opm::Group::ProductionCMode::NONE) { //group is directly under higher level controlGroup - } else if ((deck_cmode == Opm::Group::ProductionCMode::FLD) && (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; - } else if ((deck_cmode == Opm::Group::ProductionCMode::NONE) && group.productionGroupControlAvailable() && - (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; - } - } else if (!cgroup && active_cmode == Opm::Group::ProductionCMode::NONE) { - //group is directly under higher level controlGroup - if ((deck_cmode == Opm::Group::ProductionCMode::FLD) && (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; - } else if ((deck_cmode == Opm::Group::ProductionCMode::NONE) && group.productionGroupControlAvailable() && - (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { - iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; + if ((deck_cmode == Opm::Group::ProductionCMode::FLD) && (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; + } else if ((deck_cmode == Opm::Group::ProductionCMode::NONE) && group.productionGroupControlAvailable() && + (prod_guide_rate_def == Opm::Group::GuideRateProdTarget::NO_GUIDE_RATE)) { + iGrp[nwgmax + IGroup::ProdHighLevCtrl] = 1; + } } } } @@ -489,7 +503,7 @@ std::tuple injectionGroup(const Opm::Schedule& sched, { const bool is_field = group.name() == "FIELD"; auto group_parent_list = groupParentSeqIndex(sched, group, simStep); - int high_level_ctrl; + int high_level_ctrl = 0; int current_cmode = 0; int gconinje_cmode = 0; @@ -499,66 +513,60 @@ std::tuple injectionGroup(const Opm::Schedule& sched, // WATER INJECTION GROUP CONTROL if (group.hasInjectionControl(phase)) { - if (is_field) { - //set value for the group's availability for higher level control for injection + const auto& injection_controls = group.injectionControls(phase, sumState); + const auto& guide_rate_def = injection_controls.guide_rate_def; + const auto& cur_inj_ctrl = group.name() == "FIELD" ? static_cast(sumState.get(field_key, -1)) : static_cast(sumState.get_group_var(group.name(), group_key, -1)); + Opm::Group::InjectionCMode active_cmode = Opm::Group::InjectionCModeFromInt(cur_inj_ctrl); + const auto& deck_cmode = (group.hasInjectionControl(phase)) + ? injection_controls.cmode : Opm::Group::InjectionCMode::NONE; + const auto& cgroup = injectionControlGroup(sched, sumState, group, group_key, field_key, simStep); + const auto& group_control_available = group.injectionGroupControlAvailable(phase); + + // group is available for higher level control, but is currently constrained by own limits + high_level_ctrl = -1; + if ((deck_cmode != Opm::Group::InjectionCMode::FLD) && !group_control_available) { + //group is not free to respond to higher level control) high_level_ctrl = 0; - } else { + } - const auto& injection_controls = group.injectionControls(phase, sumState); - const auto& guide_rate_def = injection_controls.guide_rate_def; - const auto& cur_inj_ctrl = group.name() == "FIELD" ? static_cast(sumState.get(field_key, -1)) : static_cast(sumState.get_group_var(group.name(), group_key, -1)); - Opm::Group::InjectionCMode active_cmode = Opm::Group::InjectionCModeFromInt(cur_inj_ctrl); - const auto& deck_cmode = (group.hasInjectionControl(phase)) - ? injection_controls.cmode : Opm::Group::InjectionCMode::NONE; - const auto& cgroup = injectionControlGroup(sched, sumState, group, group_key, field_key, simStep); - const auto& group_control_available = group.injectionGroupControlAvailable(phase); - - // group is available for higher level control, but is currently constrained by own limits - high_level_ctrl = -1; - if ((deck_cmode != Opm::Group::InjectionCMode::FLD) && !group_control_available) { - //group is not free to respond to higher level control) - high_level_ctrl = 0; - } - - if (cgroup) { - if ((active_cmode == Opm::Group::InjectionCMode::FLD) || (active_cmode == Opm::Group::InjectionCMode::NONE)) { - //a higher level group control is active constraint - if ((deck_cmode != Opm::Group::InjectionCMode::FLD) && (deck_cmode != Opm::Group::InjectionCMode::NONE)) { - high_level_ctrl = cgroup->insert_index(); + if (cgroup) { + if ((active_cmode == Opm::Group::InjectionCMode::FLD) || (active_cmode == Opm::Group::InjectionCMode::NONE)) { + //a higher level group control is active constraint + if ((deck_cmode != Opm::Group::InjectionCMode::FLD) && (deck_cmode != Opm::Group::InjectionCMode::NONE)) { + high_level_ctrl = cgroup->insert_index(); + } else { + if (guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) { + if (deck_cmode == Opm::Group::InjectionCMode::FLD) { + high_level_ctrl = 1; + } else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) { + high_level_ctrl = 1; + } } else { - if (guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) { - if (deck_cmode == Opm::Group::InjectionCMode::FLD) { - high_level_ctrl = 1; - } else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) { - high_level_ctrl = 1; - } - } else { - if (deck_cmode == Opm::Group::InjectionCMode::FLD) { - high_level_ctrl = cgroup->insert_index(); - } else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) { - high_level_ctrl = cgroup->insert_index(); - } + if (deck_cmode == Opm::Group::InjectionCMode::FLD) { + high_level_ctrl = cgroup->insert_index(); + } else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) { + high_level_ctrl = cgroup->insert_index(); } } } - } else { - if ((active_cmode == Opm::Group::InjectionCMode::NONE) && (guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE)) { - //group is directly under higher level controlGroup - if (deck_cmode == Opm::Group::InjectionCMode::FLD) { - high_level_ctrl = 1; - } else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) { - high_level_ctrl = 1; - } + } + } else { + if ((active_cmode == Opm::Group::InjectionCMode::NONE) && (guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE)) { + //group is directly under higher level controlGroup + if (deck_cmode == Opm::Group::InjectionCMode::FLD) { + high_level_ctrl = 1; + } else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) { + high_level_ctrl = 1; } } + } - gconinje_cmode = Opm::Group::InjectionCMode2Int(deck_cmode); - if (cgroup && (group.getGroupType() != Opm::Group::GroupType::NONE)) { - auto cgroup_control = (cgroup->name() == "FIELD") ? static_cast(sumState.get(field_key, 0)) : static_cast(sumState.get_group_var(cgroup->name(), group_key, 0)); - current_cmode = (guide_rate_def != Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) ? cgroup_control : 0; - } else { - current_cmode = cur_inj_ctrl; - } + gconinje_cmode = Opm::Group::InjectionCMode2Int(deck_cmode); + if (cgroup && (cgroup->name() != group.name()) && (group.getGroupType() != Opm::Group::GroupType::NONE)) { + auto cgroup_control = (cgroup->name() == "FIELD") ? static_cast(sumState.get(field_key, 0)) : static_cast(sumState.get_group_var(cgroup->name(), group_key, 0)); + current_cmode = (guide_rate_def != Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) ? cgroup_control : 0; + } else { + current_cmode = cur_inj_ctrl; } } else { @@ -566,6 +574,9 @@ std::tuple injectionGroup(const Opm::Schedule& sched, high_level_ctrl = (groupCurrentlyInjectionControllable(sched, sumState, group, phase, simStep) ) ? 1 : -1; } + // special treatment of group "FIELD" + if (is_field) high_level_ctrl = 0; + return {high_level_ctrl, current_cmode, gconinje_cmode}; }