Revert "Igrp prod"

This commit is contained in:
Joakim Hove 2020-11-05 11:15:20 +01:00 committed by GitHub
parent f16375f5ee
commit 57566ad768
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 205 additions and 207 deletions

View File

@ -61,8 +61,6 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
WInjCMode = 16, WInjCMode = 16,
GConProdCMode = 10, GConProdCMode = 10,
GInjCMode = 21, GInjCMode = 21,
GroupType = 26,
GroupLevel = 27,
ParentGroup = 28, ParentGroup = 28,
FlowingWells = 33, FlowingWells = 33,
}; };
@ -78,12 +76,6 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
Form = 8, Form = 8,
Comb = 9, Comb = 9,
}; };
enum GroupType : int {
WellGroup = 0,
TreeGroup = 1,
};
} }
} }

View File

@ -58,14 +58,13 @@ public:
int ecl_phase() const; int ecl_phase() const;
Phase preferred_phase() const; Phase preferred_phase() const;
InjectorType injector_type() const; InjectorType injector_type() const;
Phase injection_phase() const;
bool operator==(const WellType& other) const; bool operator==(const WellType& other) const;
template<class Serializer> template<class Serializer>
void serializeOp(Serializer& serializer) void serializeOp(Serializer& serializer)
{ {
serializer(m_producer); serializer(m_producer);
serializer(m_injection_phase); serializer(injection_phase);
serializer(m_welspecs_phase); serializer(m_welspecs_phase);
} }
@ -84,7 +83,7 @@ private:
used when initializing the well equations for a producer. used when initializing the well equations for a producer.
*/ */
Phase m_injection_phase; Phase injection_phase;
Phase m_welspecs_phase; Phase m_welspecs_phase;
}; };

View File

@ -116,72 +116,90 @@ int currentGroupLevel(const Opm::Schedule& sched, const Opm::Group& group, const
} }
} }
void groupProductionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const size_t simStep, bool& controllable) bool groupProductionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const size_t simStep)
{ {
using wellCtrlMode = ::Opm::RestartIO::Helpers::VectorItems::IWell::Value::WellCtrlMode; using wellCtrlMode = ::Opm::RestartIO::Helpers::VectorItems::IWell::Value::WellCtrlMode;
if (controllable) bool controllable = false;
return; if (group.defined( simStep )) {
if (!group.wellgroup()) {
for (const auto& group_name : group.groups()) if(!group.groups().empty()) {
groupProductionControllable(sched, sumState, sched.getGroup(group_name, simStep), simStep, controllable); for (const auto& group_name : group.groups()) {
if (groupProductionControllable(sched, sumState, sched.getGroup(group_name, simStep), simStep)) {
for (const auto& well_name : group.wells()) { controllable = true;
const auto& well = sched.getWell(well_name, simStep); continue;
if (well.isProducer()) { }
int cur_prod_ctrl = 0; }
// Find control mode for well
const std::string sum_key = "WMCTL";
if (sumState.has_well_var(well_name, sum_key)) {
cur_prod_ctrl = static_cast<int>(sumState.get_well_var(well_name, sum_key));
}
if (cur_prod_ctrl == wellCtrlMode::Group) {
controllable = true;
return;
} }
} }
else {
for (const auto& well_name : group.wells()) {
const auto& well = sched.getWell(well_name, simStep);
if (well.isProducer()) {
int cur_prod_ctrl = 0;
// Find control mode for well
std::string well_key_1 = "WMCTL:" + well_name;
if (sumState.has(well_key_1)) {
cur_prod_ctrl = static_cast<int>(sumState.get(well_key_1));
}
if (cur_prod_ctrl == wellCtrlMode::Group) {
controllable = true;
continue;
}
}
}
}
return controllable;
} else {
std::stringstream str;
str << "actual group has not been defined at report time: " << simStep;
throw std::invalid_argument(str.str());
} }
} }
bool groupInjectionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const Opm::Phase& iPhase, const size_t simStep)
bool groupProductionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const size_t simStep) {
bool controllable = false;
groupProductionControllable(sched, sumState, group, simStep, controllable);
return controllable;
}
void groupInjectionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const Opm::Phase& iPhase, const size_t simStep, bool& controllable)
{ {
using wellCtrlMode = ::Opm::RestartIO::Helpers::VectorItems::IWell::Value::WellCtrlMode; using wellCtrlMode = ::Opm::RestartIO::Helpers::VectorItems::IWell::Value::WellCtrlMode;
if (controllable) bool controllable = false;
return; if (group.defined( simStep )) {
if (!group.wellgroup()) {
for (const auto& group_name : group.groups()) if(!group.groups().empty()) {
groupInjectionControllable(sched, sumState, sched.getGroup(group_name, simStep), iPhase, simStep, controllable); for (const auto& group_name : group.groups()) {
if (groupInjectionControllable(sched, sumState, sched.getGroup(group_name, simStep), iPhase, simStep)) {
for (const auto& well_name : group.wells()) { controllable = true;
const auto& well = sched.getWell(well_name, simStep); continue;
if (well.isInjector() && iPhase == well.wellType().injection_phase()) { }
int cur_inj_ctrl = 0; }
// Find control mode for well
const std::string sum_key = "WMCTL";
if (sumState.has_well_var(well_name, sum_key)) {
cur_inj_ctrl = static_cast<int>(sumState.get_well_var(well_name, sum_key));
}
if (cur_inj_ctrl == wellCtrlMode::Group) {
controllable = true;
return;
} }
} }
else {
for (const auto& well_name : group.wells()) {
const auto& well = sched.getWell(well_name, simStep);
if (well.isInjector()) {
if (((iPhase == Opm::Phase::WATER) && (well.injectionControls(sumState).injector_type == Opm::InjectorType::WATER)) ||
((iPhase == Opm::Phase::GAS) && (well.injectionControls(sumState).injector_type == Opm::InjectorType::GAS))
) {
int cur_inj_ctrl = 0;
// Find control mode for well
std::string well_key_1 = "WMCTL:" + well_name;
if (sumState.has(well_key_1)) {
cur_inj_ctrl = static_cast<int>(sumState.get(well_key_1));
}
if (cur_inj_ctrl == wellCtrlMode::Group) {
controllable = true;
continue;
}
}
}
}
}
return controllable;
} else {
std::stringstream str;
str << "actual group has not been defined at report time: " << simStep;
throw std::invalid_argument(str.str());
} }
} }
bool groupInjectionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const Opm::Phase& iPhase, const size_t simStep) {
bool controllable = false;
groupInjectionControllable(sched, sumState, group, iPhase, simStep, controllable);
return controllable;
}
int higherLevelProdControlGroupSeqIndex(const Opm::Schedule& sched, int higherLevelProdControlGroupSeqIndex(const Opm::Schedule& sched,
@ -377,6 +395,20 @@ int higherLevelInjCMode_NotNoneFld_SeqIndex(const Opm::Schedule& sched,
} }
int groupType(const Opm::Group& group) {
if (group.wellgroup())
return 0;
else
return 1;
}
std::size_t groupSize(const Opm::Group& group) {
if (group.wellgroup())
return group.wells().size();
else
return group.groups().size();
}
namespace IGrp { namespace IGrp {
std::size_t entriesPerGroup(const std::vector<int>& inteHead) std::size_t entriesPerGroup(const std::vector<int>& inteHead)
@ -397,40 +429,6 @@ allocate(const std::vector<int>& inteHead)
template <class IGrpArray>
void gconprodCMode(const Opm::Group& group,
const int nwgmax,
IGrpArray& iGrp) {
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
const auto& prod_cmode = group.gconprod_cmode();
switch (prod_cmode) {
case Opm::Group::ProductionCMode::NONE:
iGrp[nwgmax + IGroup::GConProdCMode] = 0;
break;
case Opm::Group::ProductionCMode::ORAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 1;
break;
case Opm::Group::ProductionCMode::WRAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 2;
break;
case Opm::Group::ProductionCMode::GRAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 3;
break;
case Opm::Group::ProductionCMode::LRAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 4;
break;
case Opm::Group::ProductionCMode::RESV:
iGrp[nwgmax + IGroup::GConProdCMode] = 5;
break;
case Opm::Group::ProductionCMode::FLD:
iGrp[nwgmax + IGroup::GConProdCMode] = 0; // need to be checked!!
break;
default:
iGrp[nwgmax + IGroup::GConProdCMode] = 0; // need to be checked!!
}
}
template <class IGrpArray> template <class IGrpArray>
void productionGroup(const Opm::Schedule& sched, void productionGroup(const Opm::Schedule& sched,
@ -443,23 +441,50 @@ void productionGroup(const Opm::Schedule& sched,
{ {
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index; using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
namespace Value = ::Opm::RestartIO::Helpers::VectorItems::IGroup::Value; namespace Value = ::Opm::RestartIO::Helpers::VectorItems::IGroup::Value;
gconprodCMode(group, nwgmax, iGrp); const auto& prod_cmode = group.gconprod_cmode();
if (group.name() == "FIELD") { if (group.name() == "FIELD") {
iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::None; iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::None;
iGrp[nwgmax + 7] = 0; iGrp[nwgmax + 7] = 0;
switch (prod_cmode) {
case Opm::Group::ProductionCMode::NONE:
iGrp[nwgmax + IGroup::GConProdCMode] = 0;
break;
case Opm::Group::ProductionCMode::ORAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 1;
break;
case Opm::Group::ProductionCMode::WRAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 2;
break;
case Opm::Group::ProductionCMode::GRAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 3;
break;
case Opm::Group::ProductionCMode::LRAT:
iGrp[nwgmax + IGroup::GConProdCMode] = 4;
break;
case Opm::Group::ProductionCMode::RESV:
iGrp[nwgmax + IGroup::GConProdCMode] = 5;
break;
case Opm::Group::ProductionCMode::FLD:
iGrp[nwgmax + IGroup::GConProdCMode] = 0;
break;
default:
iGrp[nwgmax + IGroup::GConProdCMode] = 0;
}
return; return;
} }
const auto& production_controls = group.productionControls(sumState);
const auto& prod_guide_rate_def = production_controls.guide_rate_def;
Opm::Group::ProductionCMode active_cmode = Opm::Group::ProductionCMode::NONE;
{
auto cur_prod_ctrl = sumState.get_group_var(group.name(), "GMCTP", -1);
if (cur_prod_ctrl >= 0)
active_cmode = pCtrlToPCmode.at(static_cast<int>(cur_prod_ctrl));
}
const auto& prod_guide_rate_def = group.productionControls(sumState).guide_rate_def;
const auto& p_exceed_act = group.productionControls(sumState).exceed_action;
// Find production control mode for group
const double cur_prod_ctrl = sumState.get_group_var(group.name(), "GMCTP", -1);
Opm::Group::ProductionCMode pctl_mode = Opm::Group::ProductionCMode::NONE;
if (cur_prod_ctrl >= 0) {
const auto it_ctrl = pCtrlToPCmode.find(cur_prod_ctrl);
if (it_ctrl != pCtrlToPCmode.end()) {
pctl_mode = it_ctrl->second;
}
}
#if ENABLE_GCNTL_DEBUG_OUTPUT #if ENABLE_GCNTL_DEBUG_OUTPUT
else { else {
// std::stringstream str; // std::stringstream str;
@ -497,7 +522,6 @@ void productionGroup(const Opm::Schedule& sched,
iGrp[nwgmax + 5] = -1; iGrp[nwgmax + 5] = -1;
const int higher_lev_ctrl = higherLevelProdControlGroupSeqIndex(sched, sumState, group, simStep); const int higher_lev_ctrl = higherLevelProdControlGroupSeqIndex(sched, sumState, group, simStep);
const int higher_lev_ctrl_mode = higherLevelProdControlMode(sched, sumState, group, simStep); const int higher_lev_ctrl_mode = higherLevelProdControlMode(sched, sumState, group, simStep);
const auto& deck_cmode = group.gconprod_cmode();
// Start branching for determining iGrp[nwgmax + 5] // Start branching for determining iGrp[nwgmax + 5]
// use default value if group is not available for group control // use default value if group is not available for group control
if (groupProductionControllable(sched, sumState, group, simStep)) { if (groupProductionControllable(sched, sumState, group, simStep)) {
@ -505,31 +529,31 @@ void productionGroup(const Opm::Schedule& sched,
if (!group.productionGroupControlAvailable() && (higher_lev_ctrl <= 0)) { if (!group.productionGroupControlAvailable() && (higher_lev_ctrl <= 0)) {
// group can respond to higher level control // group can respond to higher level control
iGrp[nwgmax + 5] = 0; iGrp[nwgmax + 5] = 0;
} else if (((active_cmode != Opm::Group::ProductionCMode::NONE)) && (higher_lev_ctrl < 0)) { } else if (((pctl_mode != Opm::Group::ProductionCMode::NONE)) && (higher_lev_ctrl < 0)) {
// group is constrained by its own limits or controls // group is constrained by its own limits or controls
// if (active_cmode != Opm::Group::ProductionCMode::FLD) - need to use this test? - else remove // if (pctl_mode != Opm::Group::ProductionCMode::FLD) - need to use this test? - else remove
iGrp[nwgmax + 5] = -1; // only value that seems to work when no group at higher level has active control iGrp[nwgmax + 5] = -1; // only value that seems to work when no group at higher level has active control
} else if (higher_lev_ctrl > 0) { } else if (higher_lev_ctrl > 0) {
if (((deck_cmode == Opm::Group::ProductionCMode::FLD) || (deck_cmode == Opm::Group::ProductionCMode::NONE)) if (((prod_cmode == Opm::Group::ProductionCMode::FLD) || (prod_cmode == Opm::Group::ProductionCMode::NONE))
&& (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE)) { && (group.productionControls(sumState).guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE)) {
iGrp[nwgmax + 5] = higher_lev_ctrl; iGrp[nwgmax + 5] = higher_lev_ctrl;
} else { } else {
iGrp[nwgmax + 5] = 1; iGrp[nwgmax + 5] = 1;
} }
} else if (higherLevelProdCMode_NotNoneFld(sched, group, simStep)) { } else if (higherLevelProdCMode_NotNoneFld(sched, group, simStep)) {
if (!((deck_cmode == Opm::Group::ProductionCMode::FLD) if (!((prod_cmode == Opm::Group::ProductionCMode::FLD)
|| (deck_cmode == Opm::Group::ProductionCMode::NONE))) { || (prod_cmode == Opm::Group::ProductionCMode::NONE))) {
iGrp[nwgmax + 5] = -1; iGrp[nwgmax + 5] = -1;
} else { } else {
iGrp[nwgmax + 5] = 1; iGrp[nwgmax + 5] = 1;
} }
} else if ((deck_cmode == Opm::Group::ProductionCMode::FLD) } else if ((prod_cmode == Opm::Group::ProductionCMode::FLD)
|| (deck_cmode == Opm::Group::ProductionCMode::NONE)) { || (prod_cmode == Opm::Group::ProductionCMode::NONE)) {
iGrp[nwgmax + 5] = -1; iGrp[nwgmax + 5] = -1;
} else { } else {
iGrp[nwgmax + 5] = -1; iGrp[nwgmax + 5] = -1;
} }
} else if (deck_cmode == Opm::Group::ProductionCMode::NONE) { } else if (prod_cmode == Opm::Group::ProductionCMode::NONE) {
iGrp[nwgmax + 5] = 1; iGrp[nwgmax + 5] = 1;
} }
@ -553,7 +577,7 @@ void productionGroup(const Opm::Schedule& sched,
iGrp[nwgmax + IGroup::ProdActiveCMode] iGrp[nwgmax + IGroup::ProdActiveCMode]
= (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE) ? higher_lev_ctrl_mode : 0; = (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE) ? higher_lev_ctrl_mode : 0;
} else { } else {
switch (active_cmode) { switch (pctl_mode) {
case Opm::Group::ProductionCMode::NONE: case Opm::Group::ProductionCMode::NONE:
iGrp[nwgmax + IGroup::ProdActiveCMode] = 0; iGrp[nwgmax + IGroup::ProdActiveCMode] = 0;
break; break;
@ -582,35 +606,41 @@ void productionGroup(const Opm::Schedule& sched,
iGrp[nwgmax + 9] = iGrp[nwgmax + IGroup::ProdActiveCMode]; iGrp[nwgmax + 9] = iGrp[nwgmax + IGroup::ProdActiveCMode];
iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::None; iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::None;
switch (prod_cmode) {
const auto& p_exceed_act = production_controls.exceed_action;
switch (deck_cmode) {
case Opm::Group::ProductionCMode::NONE: case Opm::Group::ProductionCMode::NONE:
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 0 : 4; iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 0 : 4;
iGrp[nwgmax + IGroup::GConProdCMode] = 0;
break; break;
case Opm::Group::ProductionCMode::ORAT: case Opm::Group::ProductionCMode::ORAT:
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -40000 : 4; iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -40000 : 4;
iGrp[nwgmax + IGroup::GConProdCMode] = 1;
break; break;
case Opm::Group::ProductionCMode::WRAT: case Opm::Group::ProductionCMode::WRAT:
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -4000 : 4; iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -4000 : 4;
iGrp[nwgmax + IGroup::GConProdCMode] = 2;
break; break;
case Opm::Group::ProductionCMode::GRAT: case Opm::Group::ProductionCMode::GRAT:
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -400 : 4; iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -400 : 4;
iGrp[nwgmax + IGroup::GConProdCMode] = 3;
break; break;
case Opm::Group::ProductionCMode::LRAT: case Opm::Group::ProductionCMode::LRAT:
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -40 : 4; iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -40 : 4;
iGrp[nwgmax + IGroup::GConProdCMode] = 4;
break; break;
case Opm::Group::ProductionCMode::RESV: case Opm::Group::ProductionCMode::RESV:
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -4 : 4; // need to be checked iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -4 : 4; // need to be checked
iGrp[nwgmax + IGroup::GConProdCMode] = 5;
break; break;
case Opm::Group::ProductionCMode::FLD: case Opm::Group::ProductionCMode::FLD:
if ((higher_lev_ctrl > 0) && (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE)) { if ((higher_lev_ctrl > 0) && (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE)) {
iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::Form; iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::Form;
} }
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 4 : 4; iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 4 : 4;
iGrp[nwgmax + IGroup::GConProdCMode] = 0; // need to be checked!!
break; break;
default: default:
iGrp[nwgmax + 7] = 0; iGrp[nwgmax + 7] = 0;
iGrp[nwgmax + IGroup::GConProdCMode] = 0; // need to be checked!!
} }
} }
@ -629,7 +659,6 @@ void injectionGroup(const Opm::Schedule& sched,
auto group_parent_list = groupParentSeqIndex(sched, group, simStep); auto group_parent_list = groupParentSeqIndex(sched, group, simStep);
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index; using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
// set "default value" in case a group is only injection group // set "default value" in case a group is only injection group
if (group.isInjectionGroup() && !group.isProductionGroup()) { if (group.isInjectionGroup() && !group.isProductionGroup()) {
iGrp[nwgmax + 5] = 1; iGrp[nwgmax + 5] = 1;
@ -798,67 +827,6 @@ void injectionGroup(const Opm::Schedule& sched,
} }
} }
template <class IGrpArray>
void storeGroupTree(const Opm::Schedule& sched,
const Opm::Group& group,
const int nwgmax,
const int ngmaxz,
const std::size_t simStep,
IGrpArray& iGrp) {
namespace Value = ::Opm::RestartIO::Helpers::VectorItems::IGroup::Value;
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
const bool is_field = group.name() == "FIELD";
// Store index of all child wells or child groups.
if (group.wellgroup()) {
int igrpCount = 0;
for (const auto& well_name : group.wells()) {
const auto& well = sched.getWell(well_name, simStep);
iGrp[igrpCount] = well.seqIndex() + 1;
igrpCount += 1;
}
iGrp[nwgmax] = group.wells().size();
iGrp[nwgmax + IGroup::GroupType] = Value::GroupType::WellGroup;
} else {
int igrpCount = 0;
for (const auto& group_name : group.groups()) {
const auto& child_group = sched.getGroup(group_name, simStep);
iGrp[igrpCount] = child_group.insert_index();
igrpCount += 1;
}
iGrp[nwgmax] = group.groups().size();
iGrp[nwgmax + IGroup::GroupType] = Value::GroupType::TreeGroup;
}
// Store index of parent group
if (is_field)
iGrp[nwgmax + IGroup::ParentGroup] = 0;
else {
const auto& parent_group = sched.getGroup(group.parent(), simStep);
if (parent_group.name() == "FIELD")
iGrp[nwgmax + IGroup::ParentGroup] = ngmaxz;
else
iGrp[nwgmax + IGroup::ParentGroup] = parent_group.insert_index();
}
iGrp[nwgmax + IGroup::GroupLevel] = currentGroupLevel(sched, group, simStep);
}
template <class IGrpArray>
void storeFlowingWells(const Opm::Group& group,
const int nwgmax,
const Opm::SummaryState& sumState,
IGrpArray& iGrp) {
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
const bool is_field = group.name() == "FIELD";
const double g_act_pwells = is_field ? sumState.get("FMWPR", 0) : sumState.get_group_var(group.name(), "GMWPR", 0);
const double g_act_iwells = is_field ? sumState.get("FMWIN", 0) : sumState.get_group_var(group.name(), "GMWIN", 0);
iGrp[nwgmax + IGroup::FlowingWells] = static_cast<int>(g_act_pwells) + static_cast<int>(g_act_iwells);
}
template <class IGrpArray> template <class IGrpArray>
void staticContrib(const Opm::Schedule& sched, void staticContrib(const Opm::Schedule& sched,
@ -871,22 +839,54 @@ void staticContrib(const Opm::Schedule& sched,
const std::map<Opm::Group::InjectionCMode, int>& cmodeToNum, const std::map<Opm::Group::InjectionCMode, int>& cmodeToNum,
IGrpArray& iGrp) IGrpArray& iGrp)
{ {
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
const bool is_field = group.name() == "FIELD"; const bool is_field = group.name() == "FIELD";
if (group.wellgroup()) {
int igrpCount = 0;
//group has child wells
//store the well number (sequence index) in iGrp according to the sequence they are defined
for (const auto& well_name : group.wells()) {
const auto& well = sched.getWell(well_name, simStep);
iGrp[igrpCount] = well.seqIndex() + 1;
igrpCount += 1;
}
} else if (!group.groups().empty()) {
int igrpCount = 0;
for (const auto& group_name : group.groups()) {
const auto& child_group = sched.getGroup(group_name, simStep);
iGrp[igrpCount] = child_group.insert_index();
igrpCount += 1;
}
}
storeGroupTree(sched, group, nwgmax, ngmaxz, simStep, iGrp); //assign the number of child wells or child groups to
storeFlowingWells(group, nwgmax, sumState, iGrp); // location nwgmax
iGrp[nwgmax] = groupSize(group);
iGrp[nwgmax + 17] = -1; // Find number of active production wells and injection wells for group
iGrp[nwgmax + 22] = -1; const double g_act_pwells = is_field ? sumState.get("FMWPR", 0) : sumState.get_group_var(group.name(), "GMWPR", 0);
const double g_act_iwells = is_field ? sumState.get("FMWIN", 0) : sumState.get_group_var(group.name(), "GMWIN", 0);
iGrp[nwgmax + IGroup::FlowingWells] = g_act_pwells + g_act_iwells;
// Treat al groups which are *not* pure injection groups. // Treat al groups which are *not* pure injection groups.
if (group.getGroupType() != Opm::Group::GroupType::INJECTION) if (group.getGroupType() != Opm::Group::GroupType::INJECTION)
productionGroup(sched, group, nwgmax, simStep, sumState, pCtrlToPCmode, iGrp); productionGroup(sched, group, nwgmax, simStep, sumState, pCtrlToPCmode, iGrp);
//default value -
iGrp[nwgmax + 17] = -1;
iGrp[nwgmax + 22] = -1;
// Treat al groups which are *not* pure production groups. // Treat al groups which are *not* pure production groups.
if (group.getGroupType() != Opm::Group::GroupType::PRODUCTION) if (group.getGroupType() != Opm::Group::GroupType::PRODUCTION)
injectionGroup(sched, group, nwgmax, simStep, sumState, cmodeToNum, iGrp); injectionGroup(sched, group, nwgmax, simStep, sumState, cmodeToNum, iGrp);
iGrp[nwgmax + 26] = groupType(group);
//find group level ("FIELD" is level 0) and store the level in
//location nwgmax + 27
iGrp[nwgmax+27] = currentGroupLevel(sched, group, simStep);
// set values for group probably connected to GCONPROD settings
//
if (is_field) if (is_field)
{ {
//the maximum number of groups in the model //the maximum number of groups in the model
@ -907,6 +907,21 @@ void staticContrib(const Opm::Schedule& sched,
iGrp[nwgmax+95] = group.insert_index(); iGrp[nwgmax+95] = group.insert_index();
iGrp[nwgmax+96] = group.insert_index(); iGrp[nwgmax+96] = group.insert_index();
} }
//find parent group and store index of parent group in
//location nwgmax + IGroup::ParentGroup
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
if (is_field)
iGrp[nwgmax + IGroup::ParentGroup] = 0;
else {
const auto& parent_group = sched.getGroup(group.parent(), simStep);
if (parent_group.name() == "FIELD")
iGrp[nwgmax + IGroup::ParentGroup] = ngmaxz;
else
iGrp[nwgmax + IGroup::ParentGroup] = parent_group.insert_index();
}
} }
} // Igrp } // Igrp

View File

@ -87,17 +87,9 @@ bool WellType::gas_injector(int ecl_wtype) {
return ecl_wtype == ecl::gas_injector; return ecl_wtype == ecl::gas_injector;
} }
Phase WellType::injection_phase() const {
if (this->m_producer)
throw std::logic_error("Asked for injection phase in a producer");
return this->m_injection_phase;
}
WellType::WellType(int ecl_wtype, int ecl_phase) : WellType::WellType(int ecl_wtype, int ecl_phase) :
m_injection_phase(ecl::from_ecl_phase(ecl_phase)), injection_phase(ecl::from_ecl_phase(ecl_phase)),
m_welspecs_phase(ecl::from_ecl_phase(ecl_phase)) m_welspecs_phase(ecl::from_ecl_phase(ecl_phase))
{ {
this->m_producer = false; this->m_producer = false;
@ -106,13 +98,13 @@ WellType::WellType(int ecl_wtype, int ecl_phase) :
this->m_producer = true; this->m_producer = true;
break; break;
case ecl::oil_injector: case ecl::oil_injector:
this->m_injection_phase = Phase::OIL; this->injection_phase = Phase::OIL;
break; break;
case ecl::water_injector: case ecl::water_injector:
this->m_injection_phase = Phase::WATER; this->injection_phase = Phase::WATER;
break; break;
case ecl::gas_injector: case ecl::gas_injector:
this->m_injection_phase = Phase::GAS; this->injection_phase = Phase::GAS;
break; break;
default: default:
throw std::invalid_argument("Invalid integer well type ID"); throw std::invalid_argument("Invalid integer well type ID");
@ -122,7 +114,7 @@ WellType::WellType(int ecl_wtype, int ecl_phase) :
WellType::WellType(bool producer, Phase phase) : WellType::WellType(bool producer, Phase phase) :
m_producer(producer), m_producer(producer),
m_injection_phase(phase), injection_phase(phase),
m_welspecs_phase(phase) m_welspecs_phase(phase)
{} {}
@ -134,7 +126,7 @@ WellType WellType::serializeObject()
{ {
WellType result; WellType result;
result.m_producer = true; result.m_producer = true;
result.m_injection_phase = Phase::OIL; result.injection_phase = Phase::OIL;
result.m_welspecs_phase = Phase::WATER; result.m_welspecs_phase = Phase::WATER;
return result; return result;
@ -156,8 +148,8 @@ bool WellType::update(InjectorType injector_type) {
} }
auto inj_phase = from_injector_type(injector_type); auto inj_phase = from_injector_type(injector_type);
if (this->m_injection_phase != inj_phase) { if (this->injection_phase != inj_phase) {
this->m_injection_phase = inj_phase; this->injection_phase = inj_phase;
ret_value = true; ret_value = true;
} }
@ -176,7 +168,7 @@ int WellType::ecl_wtype() const {
if (this->m_producer) if (this->m_producer)
return ecl::producer; return ecl::producer;
switch (this->m_injection_phase) { switch (this->injection_phase) {
case Phase::OIL: case Phase::OIL:
return ecl::oil_injector; return ecl::oil_injector;
case Phase::WATER: case Phase::WATER:
@ -209,13 +201,13 @@ int WellType::ecl_phase() const {
Phase WellType::preferred_phase() const { Phase WellType::preferred_phase() const {
return this->injector() ? this->m_injection_phase : this->m_welspecs_phase; return this->injector() ? this->injection_phase : this->m_welspecs_phase;
} }
bool WellType::operator==(const WellType& other) const { bool WellType::operator==(const WellType& other) const {
return this->m_welspecs_phase == other.m_welspecs_phase && return this->m_welspecs_phase == other.m_welspecs_phase &&
this->m_injection_phase == other.m_injection_phase && this->injection_phase == other.injection_phase &&
this->m_producer == other.m_producer; this->m_producer == other.m_producer;
} }
@ -224,7 +216,7 @@ InjectorType WellType::injector_type() const {
if (this->producer()) if (this->producer())
throw std::invalid_argument("Asked for injector type for a well which is a producer"); throw std::invalid_argument("Asked for injector type for a well which is a producer");
switch (this->m_injection_phase) { switch (this->injection_phase) {
case Phase::OIL: case Phase::OIL:
return InjectorType::OIL; return InjectorType::OIL;
case Phase::WATER: case Phase::WATER: