Save guiderate injection settings for group injection

This commit is contained in:
Joakim Hove 2021-12-08 13:32:33 +01:00
parent 0abdac2db6
commit ad420a2b02
5 changed files with 47 additions and 16 deletions

View File

@ -48,10 +48,12 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
waterResRateLimit = 16, // Group's water reservoir volume injection rate target/limit waterResRateLimit = 16, // Group's water reservoir volume injection rate target/limit
waterReinjectionLimit = 17, // Group's water reinjection fraction target/limit waterReinjectionLimit = 17, // Group's water reinjection fraction target/limit
waterVoidageLimit = 18, // Group's water voidage injection fraction target/limit waterVoidageLimit = 18, // Group's water voidage injection fraction target/limit
waterGuideRate = 19,
gasSurfRateLimit = 20, // Group's gas surface volume injection rate target/limit gasSurfRateLimit = 20, // Group's gas surface volume injection rate target/limit
gasResRateLimit = 21, // Group's gas reservoir volume injection rate target/limit gasResRateLimit = 21, // Group's gas reservoir volume injection rate target/limit
gasReinjectionLimit = 22, // Group's gas reinjection fraction target/limit gasReinjectionLimit = 22, // Group's gas reinjection fraction target/limit
gasVoidageLimit = 23, // Group's gas voidage injection fraction target/limit gasVoidageLimit = 23, // Group's gas voidage injection fraction target/limit
gasGuideRate = 24,
}; };
} // SGroup } // SGroup
@ -69,9 +71,11 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
WInjActiveCMode = 16, WInjActiveCMode = 16,
WInjHighLevCtrl = 17, WInjHighLevCtrl = 17,
GConInjeWInjCMode = 19, GConInjeWInjCMode = 19,
GConInjeWaterGuideRateMode = 20,
GInjActiveCMode = 21, GInjActiveCMode = 21,
GInjHighLevCtrl = 22, GInjHighLevCtrl = 22,
GConInjeGInjCMode = 24, GConInjeGInjCMode = 24,
GConInjeGasGuideRateMode = 25,
GroupType = 26, GroupType = 26,
GroupLevel = 27, GroupLevel = 27,
ParentGroup = 28, ParentGroup = 28,

View File

@ -125,6 +125,7 @@ enum class GuideRateInjTarget {
}; };
static GuideRateInjTarget GuideRateInjTargetFromString( const std::string& stringValue ); static GuideRateInjTarget GuideRateInjTargetFromString( const std::string& stringValue );
static GuideRateInjTarget GuideRateInjTargetFromInt(int ecl_id); static GuideRateInjTarget GuideRateInjTargetFromInt(int ecl_id);
static int GuideRateInjTargetToInt(GuideRateInjTarget target);
struct GroupInjectionProperties { struct GroupInjectionProperties {

View File

@ -483,17 +483,18 @@ void productionGroup(const Opm::Schedule& sched,
} }
} }
std::tuple<int, int, int> injectionGroup(const Opm::Schedule& sched, std::tuple<int, int, int, int> injectionGroup(const Opm::Schedule& sched,
const Opm::Group& group, const Opm::Group& group,
const std::size_t simStep, const std::size_t simStep,
const Opm::SummaryState& sumState, const Opm::SummaryState& sumState,
const Opm::Phase phase) const Opm::Phase phase)
{ {
const bool is_field = group.name() == "FIELD"; const bool is_field = group.name() == "FIELD";
auto group_parent_list = groupParentSeqIndex(sched, group, simStep); auto group_parent_list = groupParentSeqIndex(sched, group, simStep);
int high_level_ctrl = 0; int high_level_ctrl = 0;
int current_cmode = 0; int current_cmode = 0;
int gconinje_cmode = 0; int gconinje_cmode = 0;
int guide_rate_def = 0;
const std::string field_key = (phase == Opm::Phase::WATER) ? "FMCTW" : "FMCTG"; const std::string field_key = (phase == Opm::Phase::WATER) ? "FMCTW" : "FMCTG";
const std::string group_key = (phase == Opm::Phase::WATER) ? "GMCTW" : "GMCTG"; const std::string group_key = (phase == Opm::Phase::WATER) ? "GMCTW" : "GMCTG";
@ -502,13 +503,13 @@ std::tuple<int, int, int> injectionGroup(const Opm::Schedule& sched,
if (group.hasInjectionControl(phase)) { if (group.hasInjectionControl(phase)) {
const auto& injection_controls = group.injectionControls(phase, sumState); 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<int>(sumState.get(field_key, -1)) : static_cast<int>(sumState.get_group_var(group.name(), group_key, -1)); const auto& cur_inj_ctrl = group.name() == "FIELD" ? static_cast<int>(sumState.get(field_key, -1)) : static_cast<int>(sumState.get_group_var(group.name(), group_key, -1));
Opm::Group::InjectionCMode active_cmode = Opm::Group::InjectionCModeFromInt(cur_inj_ctrl); Opm::Group::InjectionCMode active_cmode = Opm::Group::InjectionCModeFromInt(cur_inj_ctrl);
const auto& deck_cmode = (group.hasInjectionControl(phase)) const auto& deck_cmode = (group.hasInjectionControl(phase))
? injection_controls.cmode : Opm::Group::InjectionCMode::NONE; ? injection_controls.cmode : Opm::Group::InjectionCMode::NONE;
const auto& cgroup = injectionControlGroup(sched, sumState, group, group_key, field_key, simStep); const auto& cgroup = injectionControlGroup(sched, sumState, group, group_key, field_key, simStep);
const auto& group_control_available = group.injectionGroupControlAvailable(phase); const auto& group_control_available = group.injectionGroupControlAvailable(phase);
const auto& deck_guide_rate_def = injection_controls.guide_rate_def;
// group is available for higher level control, but is currently constrained by own limits // group is available for higher level control, but is currently constrained by own limits
high_level_ctrl = -1; high_level_ctrl = -1;
@ -523,7 +524,7 @@ std::tuple<int, int, int> injectionGroup(const Opm::Schedule& sched,
if ((deck_cmode != Opm::Group::InjectionCMode::FLD) && (deck_cmode != Opm::Group::InjectionCMode::NONE)) { if ((deck_cmode != Opm::Group::InjectionCMode::FLD) && (deck_cmode != Opm::Group::InjectionCMode::NONE)) {
high_level_ctrl = cgroup->insert_index(); high_level_ctrl = cgroup->insert_index();
} else { } else {
if (guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) { if (deck_guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) {
if (deck_cmode == Opm::Group::InjectionCMode::FLD) { if (deck_cmode == Opm::Group::InjectionCMode::FLD) {
high_level_ctrl = 1; high_level_ctrl = 1;
} else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) { } else if ((deck_cmode == Opm::Group::InjectionCMode::NONE) && group_control_available) {
@ -539,7 +540,7 @@ std::tuple<int, int, int> injectionGroup(const Opm::Schedule& sched,
} }
} }
} else { } else {
if ((active_cmode == Opm::Group::InjectionCMode::NONE) && (guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE)) { if ((active_cmode == Opm::Group::InjectionCMode::NONE) && (deck_guide_rate_def == Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE)) {
//group is directly under higher level controlGroup //group is directly under higher level controlGroup
if (deck_cmode == Opm::Group::InjectionCMode::FLD) { if (deck_cmode == Opm::Group::InjectionCMode::FLD) {
high_level_ctrl = 1; high_level_ctrl = 1;
@ -549,10 +550,11 @@ std::tuple<int, int, int> injectionGroup(const Opm::Schedule& sched,
} }
} }
guide_rate_def = Opm::Group::GuideRateInjTargetToInt(deck_guide_rate_def);
gconinje_cmode = Opm::Group::InjectionCMode2Int(deck_cmode); gconinje_cmode = Opm::Group::InjectionCMode2Int(deck_cmode);
if (cgroup && (cgroup->name() != group.name()) && (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<int>(sumState.get(field_key, 0)) : static_cast<int>(sumState.get_group_var(cgroup->name(), group_key, 0)); auto cgroup_control = (cgroup->name() == "FIELD") ? static_cast<int>(sumState.get(field_key, 0)) : static_cast<int>(sumState.get_group_var(cgroup->name(), group_key, 0));
current_cmode = (guide_rate_def != Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) ? cgroup_control : 0; current_cmode = (deck_guide_rate_def != Opm::Group::GuideRateInjTarget::NO_GUIDE_RATE) ? cgroup_control : 0;
} else { } else {
current_cmode = cur_inj_ctrl; current_cmode = cur_inj_ctrl;
} }
@ -565,7 +567,7 @@ std::tuple<int, int, int> injectionGroup(const Opm::Schedule& sched,
// special treatment of group "FIELD" // special treatment of group "FIELD"
if (is_field) high_level_ctrl = 0; if (is_field) high_level_ctrl = 0;
return {high_level_ctrl, current_cmode, gconinje_cmode}; return {high_level_ctrl, current_cmode, gconinje_cmode, guide_rate_def};
} }
@ -602,16 +604,20 @@ void injectionGroup(const Opm::Schedule& sched,
} }
{ {
auto [high_level_ctrl, active_cmode, gconinje_cmode] = injectionGroup(sched, group, simStep, sumState, Opm::Phase::WATER); if (group.hasInjectionControl(Opm::Phase::WATER)) {
iGrp[nwgmax + IGroup::WInjHighLevCtrl] = high_level_ctrl; auto [high_level_ctrl, active_cmode, gconinje_cmode, guide_rate_def] = injectionGroup(sched, group, simStep, sumState, Opm::Phase::WATER);
iGrp[nwgmax + IGroup::WInjActiveCMode] = active_cmode; iGrp[nwgmax + IGroup::WInjHighLevCtrl] = high_level_ctrl;
iGrp[nwgmax + IGroup::GConInjeWInjCMode] = gconinje_cmode; iGrp[nwgmax + IGroup::WInjActiveCMode] = active_cmode;
iGrp[nwgmax + IGroup::GConInjeWInjCMode] = gconinje_cmode;
iGrp[nwgmax + IGroup::GConInjeWaterGuideRateMode] = guide_rate_def;
}
} }
{ {
auto [high_level_ctrl, active_cmode, gconinje_cmode] = injectionGroup(sched, group, simStep, sumState, Opm::Phase::GAS); auto [high_level_ctrl, active_cmode, gconinje_cmode, guide_rate_def] = injectionGroup(sched, group, simStep, sumState, Opm::Phase::GAS);
iGrp[nwgmax + IGroup::GInjHighLevCtrl] = high_level_ctrl; iGrp[nwgmax + IGroup::GInjHighLevCtrl] = high_level_ctrl;
iGrp[nwgmax + IGroup::GInjActiveCMode] = active_cmode; iGrp[nwgmax + IGroup::GInjActiveCMode] = active_cmode;
iGrp[nwgmax + IGroup::GConInjeGInjCMode] = gconinje_cmode; iGrp[nwgmax + IGroup::GConInjeGInjCMode] = gconinje_cmode;
iGrp[nwgmax + IGroup::GConInjeGasGuideRateMode] = guide_rate_def;
} }
} }
@ -877,6 +883,8 @@ void staticContrib(const Opm::Group& group,
sGrp[Isi::gasVoidageLimit] = inj_cntl.target_void_fraction; sGrp[Isi::gasVoidageLimit] = inj_cntl.target_void_fraction;
sGrp[68] = sGrp[Isi::gasVoidageLimit]; sGrp[68] = sGrp[Isi::gasVoidageLimit];
} }
sGrp[Isi::waterGuideRate] = inj_cntl.guide_rate;
} }
if (group.hasInjectionControl(Opm::Phase::WATER)) { if (group.hasInjectionControl(Opm::Phase::WATER)) {
@ -897,6 +905,8 @@ void staticContrib(const Opm::Group& group,
sGrp[Isi::waterVoidageLimit] = inj_cntl.target_void_fraction; sGrp[Isi::waterVoidageLimit] = inj_cntl.target_void_fraction;
sGrp[64] = sGrp[Isi::waterVoidageLimit]; sGrp[64] = sGrp[Isi::waterVoidageLimit];
} }
sGrp[Isi::waterGuideRate] = inj_cntl.guide_rate;
} }
if (group.hasInjectionControl(Opm::Phase::OIL)) { if (group.hasInjectionControl(Opm::Phase::OIL)) {

View File

@ -1119,6 +1119,22 @@ Group::GuideRateInjTarget Group::GuideRateInjTargetFromString( const std::string
return GuideRateInjTarget::NO_GUIDE_RATE; return GuideRateInjTarget::NO_GUIDE_RATE;
} }
int Group::GuideRateInjTargetToInt(GuideRateInjTarget target) {
switch (target) {
case GuideRateInjTarget::RATE:
return 1;
case GuideRateInjTarget::RESV:
return 2;
case GuideRateInjTarget::VOID:
return 3;
case GuideRateInjTarget::NETV:
return 4;
default:
return 0;
}
}
Group::GuideRateProdTarget Group::GuideRateProdTargetFromString( const std::string& stringValue ) { Group::GuideRateProdTarget Group::GuideRateProdTargetFromString( const std::string& stringValue ) {
if (stringValue == "OIL") if (stringValue == "OIL")
return GuideRateProdTarget::OIL; return GuideRateProdTarget::OIL;

View File

@ -809,7 +809,7 @@ BOOST_AUTO_TEST_CASE (Declared_Group_Data_2)
const auto& iGrp = agrpd.getIGroup(); const auto& iGrp = agrpd.getIGroup();
BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 5] , 2); // group available for higher level production control BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 5] , 2); // group available for higher level production control
BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 17] , 1); // group available for higher level water injection control BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 17] , 0); // group available for higher level water injection control
BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 22] , -1); // group available for higher level gas injection control BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 22] , -1); // group available for higher level gas injection control
BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 39] , 3); // groups sequence number in the external networt defined BOOST_CHECK_EQUAL(iGrp[start + nwgmax + 39] , 3); // groups sequence number in the external networt defined