diff --git a/opm/input/eclipse/Schedule/Group/Group.hpp b/opm/input/eclipse/Schedule/Group/Group.hpp index 27a2c047a..ea62c14c6 100644 --- a/opm/input/eclipse/Schedule/Group/Group.hpp +++ b/opm/input/eclipse/Schedule/Group/Group.hpp @@ -174,6 +174,31 @@ struct GroupInjectionProperties { } }; +struct GroupLimitAction +{ + ExceedAction allRates{ExceedAction::NONE}; + ExceedAction water{ExceedAction::NONE}; + ExceedAction gas{ExceedAction::NONE}; + ExceedAction liquid{ExceedAction::NONE}; + + template + void serializeOp(Serializer& serializer) + { + serializer(allRates); + serializer(water); + serializer(gas); + serializer(liquid); + } + + bool operator==(const GroupLimitAction& other) const + { + return (this->allRates == other.allRates) + && (this->water == other.water) + && (this->gas == other.gas) + && (this->liquid == other.liquid); + } +}; + struct InjectionControls { Phase phase; InjectionCMode cmode; @@ -194,7 +219,7 @@ struct GroupProductionProperties { std::string name; ProductionCMode cmode = ProductionCMode::NONE; - ExceedAction exceed_action = ExceedAction::NONE; + GroupLimitAction group_limit_action; UDAValue oil_target; UDAValue water_target; UDAValue gas_target; @@ -216,7 +241,7 @@ struct GroupProductionProperties { { serializer(name); serializer(cmode); - serializer(exceed_action); + serializer(group_limit_action); serializer(oil_target); serializer(water_target); serializer(gas_target); @@ -232,7 +257,7 @@ struct GroupProductionProperties { struct ProductionControls { ProductionCMode cmode; - ExceedAction exceed_action; + GroupLimitAction group_limit_action; double oil_target; double water_target; double gas_target; diff --git a/src/opm/input/eclipse/Schedule/Group/Group.cpp b/src/opm/input/eclipse/Schedule/Group/Group.cpp index a43b8ee3a..99259e121 100644 --- a/src/opm/input/eclipse/Schedule/Group/Group.cpp +++ b/src/opm/input/eclipse/Schedule/Group/Group.cpp @@ -127,18 +127,9 @@ namespace { production.water_target.update(rst_group.water_rate_limit); production.liquid_target.update(rst_group.liquid_rate_limit); production.cmode = Opm::Group::ProductionCModeFromInt(rst_group.prod_cmode); - production.exceed_action = Opm::Group::ExceedActionFromInt(rst_group.exceed_action); + production.group_limit_action.allRates = Opm::Group::ExceedActionFromInt(rst_group.exceed_action); production.guide_rate_def = Opm::Group::GuideRateProdTargetFromInt(rst_group.prod_guide_rate_def); - //TODO allow also for ExceedAction::NONE (item 7 of GCONPROD) - if ((production.cmode == Opm::Group::ProductionCMode::ORAT) || - (production.cmode == Opm::Group::ProductionCMode::WRAT) || - (production.cmode == Opm::Group::ProductionCMode::GRAT) || - (production.cmode == Opm::Group::ProductionCMode::LRAT)) - { - production.exceed_action = Opm::Group::ExceedAction::RATE; - } - production.production_controls = 0; if (active.oil) @@ -499,7 +490,7 @@ Group::GroupProductionProperties Group::GroupProductionProperties::serialization Group::GroupProductionProperties result(UnitSystem(UnitSystem::UnitType::UNIT_TYPE_METRIC), "Group123"); result.name = "Group123"; result.cmode = ProductionCMode::PRBL; - result.exceed_action = ExceedAction::WELL; + result.group_limit_action = {ExceedAction::WELL,ExceedAction::WELL,ExceedAction::WELL,ExceedAction::WELL}; result.oil_target = UDAValue(1.0); result.water_target = UDAValue(2.0); result.gas_target = UDAValue(3.0); @@ -517,7 +508,7 @@ bool Group::GroupProductionProperties::operator==(const GroupProductionPropertie return this->name == other.name && this->cmode == other.cmode && - this->exceed_action == other.exceed_action && + this->group_limit_action == other.group_limit_action && this->oil_target == other.oil_target && this->water_target == other.water_target && this->gas_target == other.gas_target && @@ -760,7 +751,7 @@ Group::ProductionControls Group::productionControls(const SummaryState& st) cons Group::ProductionControls pc; pc.cmode = this->production_properties.cmode; - pc.exceed_action = this->production_properties.exceed_action; + pc.group_limit_action = this->production_properties.group_limit_action; pc.oil_target = UDA::eval_group_uda(this->production_properties.oil_target, this->m_name, st, this->udq_undefined); pc.water_target = UDA::eval_group_uda(this->production_properties.water_target, this->m_name, st, this->udq_undefined); pc.gas_target = UDA::eval_group_uda(this->production_properties.gas_target, this->m_name, st, this->udq_undefined); diff --git a/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp b/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp index e7f59726c..544fdc694 100644 --- a/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp +++ b/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp @@ -526,7 +526,11 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno) this->invalidNamePattern(groupNamePattern, handlerContext); const Group::ProductionCMode controlMode = Group::ProductionCModeFromString(record.getItem("CONTROL_MODE").getTrimmedString(0)); - const Group::ExceedAction exceedAction = Group::ExceedActionFromString(record.getItem("EXCEED_PROC").getTrimmedString(0)); + Group::GroupLimitAction groupLimitAction; + groupLimitAction.allRates = Group::ExceedActionFromString(record.getItem("EXCEED_PROC").getTrimmedString(0)); + groupLimitAction.water = Group::ExceedActionFromString(record.getItem("WATER_EXCEED_PROCEDURE").getTrimmedString(0)); + groupLimitAction.gas = Group::ExceedActionFromString(record.getItem("GAS_EXCEED_PROCEDURE").getTrimmedString(0)); + groupLimitAction.liquid = Group::ExceedActionFromString(record.getItem("LIQUID_EXCEED_PROCEDURE").getTrimmedString(0)); const bool respond_to_parent = DeckItem::to_bool(record.getItem("RESPOND_TO_PARENT").getTrimmedString(0)); @@ -593,73 +597,40 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno) production.guide_rate_def = guide_rate_def; production.resv_target = resv_target; production.available_group_control = availableForGroupControl; + production.group_limit_action = groupLimitAction; - production.exceed_action = exceedAction; production.production_controls = 0; // GCONPROD // 'G1' 'ORAT' 1000 100 200 300 NONE => constraints 100,200,300 should be ignored // // GCONPROD // 'G1' 'ORAT' 1000 100 200 300 RATE => constraints 100,200,300 should be honored - if (production.cmode == Group::ProductionCMode::ORAT){ - production.production_controls += static_cast(Group::ProductionCMode::ORAT); - if (exceedAction == Group::ExceedAction::RATE) { - if (!apply_default_gas_target) - production.production_controls += static_cast(Group::ProductionCMode::GRAT); - if (!apply_default_water_target) - production.production_controls += static_cast(Group::ProductionCMode::WRAT); - if (!apply_default_liquid_target) - production.production_controls += static_cast(Group::ProductionCMode::LRAT); - } + if (production.cmode == Group::ProductionCMode::ORAT || + (groupLimitAction.allRates == Group::ExceedAction::RATE && + !apply_default_oil_target)) { + production.production_controls |= static_cast(Group::ProductionCMode::ORAT); } - else if (production.cmode == Group::ProductionCMode::GRAT){ - production.production_controls += static_cast(Group::ProductionCMode::GRAT); - if (exceedAction == Group::ExceedAction::RATE) { - if (!apply_default_oil_target) - production.production_controls += static_cast(Group::ProductionCMode::ORAT); - if (!apply_default_water_target) - production.production_controls += static_cast(Group::ProductionCMode::WRAT); - if (!apply_default_liquid_target) - production.production_controls += static_cast(Group::ProductionCMode::LRAT); - } + if (production.cmode == Group::ProductionCMode::WRAT || + ((groupLimitAction.allRates == Group::ExceedAction::RATE || + groupLimitAction.water == Group::ExceedAction::RATE) && + !apply_default_water_target)) { + production.production_controls |= static_cast(Group::ProductionCMode::WRAT); } - else if (production.cmode == Group::ProductionCMode::WRAT){ - production.production_controls += static_cast(Group::ProductionCMode::WRAT); - if (exceedAction == Group::ExceedAction::RATE) { - if (!apply_default_oil_target) - production.production_controls += static_cast(Group::ProductionCMode::ORAT); - if (!apply_default_gas_target) - production.production_controls += static_cast(Group::ProductionCMode::GRAT); - if (!apply_default_liquid_target) - production.production_controls += static_cast(Group::ProductionCMode::LRAT); - } + if (production.cmode == Group::ProductionCMode::GRAT || + ((groupLimitAction.allRates == Group::ExceedAction::RATE || + groupLimitAction.gas == Group::ExceedAction::RATE) && + !apply_default_gas_target)) { + production.production_controls |= static_cast(Group::ProductionCMode::GRAT); } - else if (production.cmode == Group::ProductionCMode::LRAT){ - production.production_controls += static_cast(Group::ProductionCMode::LRAT); - if (exceedAction == Group::ExceedAction::RATE) { - if (!apply_default_oil_target) - production.production_controls += static_cast(Group::ProductionCMode::ORAT); - if (!apply_default_gas_target) - production.production_controls += static_cast(Group::ProductionCMode::GRAT); - if (!apply_default_water_target) - production.production_controls += static_cast(Group::ProductionCMode::WRAT); - } - } - else { - if (exceedAction == Group::ExceedAction::RATE) { - if (!apply_default_oil_target) - production.production_controls += static_cast(Group::ProductionCMode::ORAT); - if (!apply_default_water_target) - production.production_controls += static_cast(Group::ProductionCMode::WRAT); - if (!apply_default_gas_target) - production.production_controls += static_cast(Group::ProductionCMode::GRAT); - if (!apply_default_liquid_target) - production.production_controls += static_cast(Group::ProductionCMode::LRAT); - } + if (production.cmode == Group::ProductionCMode::LRAT || + ((groupLimitAction.allRates == Group::ExceedAction::RATE || + groupLimitAction.liquid == Group::ExceedAction::RATE) && + !apply_default_liquid_target)) { + production.production_controls |= static_cast(Group::ProductionCMode::LRAT); } if (!apply_default_resv_target) - production.production_controls += static_cast(Group::ProductionCMode::RESV); + production.production_controls |= static_cast(Group::ProductionCMode::RESV); if (new_group.updateProduction(production)) { auto new_config = this->snapshots.back().guide_rate(); diff --git a/src/opm/output/eclipse/AggregateGroupData.cpp b/src/opm/output/eclipse/AggregateGroupData.cpp index 0c3995d15..41c2004f0 100644 --- a/src/opm/output/eclipse/AggregateGroupData.cpp +++ b/src/opm/output/eclipse/AggregateGroupData.cpp @@ -412,7 +412,7 @@ void productionGroup(const Opm::Schedule& sched, Other reduction options are currently not covered in the code */ - const auto& p_exceed_act = production_controls.exceed_action; + const auto& p_exceed_act = production_controls.group_limit_action.allRates; switch (deck_cmode) { case Opm::Group::ProductionCMode::NONE: iGrp[nwgmax + IGroup::ExceedAction] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 0 : 4; diff --git a/tests/parser/GroupTests.cpp b/tests/parser/GroupTests.cpp index 619153048..08a5b5b8c 100644 --- a/tests/parser/GroupTests.cpp +++ b/tests/parser/GroupTests.cpp @@ -263,7 +263,7 @@ BOOST_AUTO_TEST_CASE(createDeckWithGCONPROD) { / GCONPROD - 'G1' 'ORAT' 10000 3* 'RATE' / + 'G1' 'ORAT' 10000 3* 'RATE' 3* 'RATE' 'NONE' 'RATE'/ 'G2' 'RESV' 10000 3* 'CON' / 'G3' 'ORAT' 10000 3* 1* / /)"; @@ -279,12 +279,14 @@ BOOST_AUTO_TEST_CASE(createDeckWithGCONPROD) { auto ctrl2 = group2.productionControls(st); auto ctrl3 = group3.productionControls(st); - BOOST_CHECK(ctrl1.exceed_action == Group::ExceedAction::RATE); - BOOST_CHECK(ctrl2.exceed_action == Group::ExceedAction::CON); - BOOST_CHECK(ctrl3.exceed_action == Group::ExceedAction::NONE); + BOOST_CHECK(ctrl1.group_limit_action.allRates == Group::ExceedAction::RATE); + BOOST_CHECK(ctrl1.group_limit_action.water == Group::ExceedAction::RATE); + BOOST_CHECK(ctrl1.group_limit_action.gas == Group::ExceedAction::NONE); + BOOST_CHECK(ctrl1.group_limit_action.liquid == Group::ExceedAction::RATE); + BOOST_CHECK(ctrl2.group_limit_action.allRates == Group::ExceedAction::CON); + BOOST_CHECK(ctrl3.group_limit_action.allRates == Group::ExceedAction::NONE); } - BOOST_AUTO_TEST_CASE(TESTGuideRateModel) { Opm::GuideRateModel grc_default; BOOST_CHECK_THROW(Opm::GuideRateModel(0.0,GuideRateModel::Target::OIL, -5,0,0,0,0,0,true,1,true), std::invalid_argument);