|
|
|
|
@@ -116,90 +116,72 @@ int currentGroupLevel(const Opm::Schedule& sched, const Opm::Group& group, const
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool groupProductionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const size_t simStep)
|
|
|
|
|
void groupProductionControllable(const Opm::Schedule& sched, const Opm::SummaryState& sumState, const Opm::Group& group, const size_t simStep, bool& controllable)
|
|
|
|
|
{
|
|
|
|
|
using wellCtrlMode = ::Opm::RestartIO::Helpers::VectorItems::IWell::Value::WellCtrlMode;
|
|
|
|
|
bool controllable = false;
|
|
|
|
|
if (group.defined( simStep )) {
|
|
|
|
|
if (!group.wellgroup()) {
|
|
|
|
|
if(!group.groups().empty()) {
|
|
|
|
|
for (const auto& group_name : group.groups()) {
|
|
|
|
|
if (groupProductionControllable(sched, sumState, sched.getGroup(group_name, simStep), simStep)) {
|
|
|
|
|
controllable = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (controllable)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (const auto& group_name : group.groups())
|
|
|
|
|
groupProductionControllable(sched, sumState, sched.getGroup(group_name, simStep), simStep, controllable);
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
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;
|
|
|
|
|
bool controllable = false;
|
|
|
|
|
if (group.defined( simStep )) {
|
|
|
|
|
if (!group.wellgroup()) {
|
|
|
|
|
if(!group.groups().empty()) {
|
|
|
|
|
for (const auto& group_name : group.groups()) {
|
|
|
|
|
if (groupInjectionControllable(sched, sumState, sched.getGroup(group_name, simStep), iPhase, simStep)) {
|
|
|
|
|
controllable = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (controllable)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (const auto& group_name : group.groups())
|
|
|
|
|
groupInjectionControllable(sched, sumState, sched.getGroup(group_name, simStep), iPhase, simStep, controllable);
|
|
|
|
|
|
|
|
|
|
for (const auto& well_name : group.wells()) {
|
|
|
|
|
const auto& well = sched.getWell(well_name, simStep);
|
|
|
|
|
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,
|
|
|
|
|
@@ -395,20 +377,6 @@ 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 {
|
|
|
|
|
std::size_t entriesPerGroup(const std::vector<int>& inteHead)
|
|
|
|
|
@@ -429,6 +397,40 @@ 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>
|
|
|
|
|
void productionGroup(const Opm::Schedule& sched,
|
|
|
|
|
@@ -441,50 +443,23 @@ void productionGroup(const Opm::Schedule& sched,
|
|
|
|
|
{
|
|
|
|
|
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
|
|
|
|
|
namespace Value = ::Opm::RestartIO::Helpers::VectorItems::IGroup::Value;
|
|
|
|
|
const auto& prod_cmode = group.gconprod_cmode();
|
|
|
|
|
gconprodCMode(group, nwgmax, iGrp);
|
|
|
|
|
|
|
|
|
|
if (group.name() == "FIELD") {
|
|
|
|
|
iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::None;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if ENABLE_GCNTL_DEBUG_OUTPUT
|
|
|
|
|
else {
|
|
|
|
|
// std::stringstream str;
|
|
|
|
|
@@ -522,6 +497,7 @@ void productionGroup(const Opm::Schedule& sched,
|
|
|
|
|
iGrp[nwgmax + 5] = -1;
|
|
|
|
|
const int higher_lev_ctrl = higherLevelProdControlGroupSeqIndex(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]
|
|
|
|
|
// use default value if group is not available for group control
|
|
|
|
|
if (groupProductionControllable(sched, sumState, group, simStep)) {
|
|
|
|
|
@@ -529,31 +505,31 @@ void productionGroup(const Opm::Schedule& sched,
|
|
|
|
|
if (!group.productionGroupControlAvailable() && (higher_lev_ctrl <= 0)) {
|
|
|
|
|
// group can respond to higher level control
|
|
|
|
|
iGrp[nwgmax + 5] = 0;
|
|
|
|
|
} else if (((pctl_mode != Opm::Group::ProductionCMode::NONE)) && (higher_lev_ctrl < 0)) {
|
|
|
|
|
} else if (((active_cmode != Opm::Group::ProductionCMode::NONE)) && (higher_lev_ctrl < 0)) {
|
|
|
|
|
// group is constrained by its own limits or controls
|
|
|
|
|
// if (pctl_mode != Opm::Group::ProductionCMode::FLD) - need to use this test? - else remove
|
|
|
|
|
// if (active_cmode != 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
|
|
|
|
|
} else if (higher_lev_ctrl > 0) {
|
|
|
|
|
if (((prod_cmode == Opm::Group::ProductionCMode::FLD) || (prod_cmode == Opm::Group::ProductionCMode::NONE))
|
|
|
|
|
&& (group.productionControls(sumState).guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE)) {
|
|
|
|
|
if (((deck_cmode == Opm::Group::ProductionCMode::FLD) || (deck_cmode == Opm::Group::ProductionCMode::NONE))
|
|
|
|
|
&& (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE)) {
|
|
|
|
|
iGrp[nwgmax + 5] = higher_lev_ctrl;
|
|
|
|
|
} else {
|
|
|
|
|
iGrp[nwgmax + 5] = 1;
|
|
|
|
|
}
|
|
|
|
|
} else if (higherLevelProdCMode_NotNoneFld(sched, group, simStep)) {
|
|
|
|
|
if (!((prod_cmode == Opm::Group::ProductionCMode::FLD)
|
|
|
|
|
|| (prod_cmode == Opm::Group::ProductionCMode::NONE))) {
|
|
|
|
|
if (!((deck_cmode == Opm::Group::ProductionCMode::FLD)
|
|
|
|
|
|| (deck_cmode == Opm::Group::ProductionCMode::NONE))) {
|
|
|
|
|
iGrp[nwgmax + 5] = -1;
|
|
|
|
|
} else {
|
|
|
|
|
iGrp[nwgmax + 5] = 1;
|
|
|
|
|
}
|
|
|
|
|
} else if ((prod_cmode == Opm::Group::ProductionCMode::FLD)
|
|
|
|
|
|| (prod_cmode == Opm::Group::ProductionCMode::NONE)) {
|
|
|
|
|
} else if ((deck_cmode == Opm::Group::ProductionCMode::FLD)
|
|
|
|
|
|| (deck_cmode == Opm::Group::ProductionCMode::NONE)) {
|
|
|
|
|
iGrp[nwgmax + 5] = -1;
|
|
|
|
|
} else {
|
|
|
|
|
iGrp[nwgmax + 5] = -1;
|
|
|
|
|
}
|
|
|
|
|
} else if (prod_cmode == Opm::Group::ProductionCMode::NONE) {
|
|
|
|
|
} else if (deck_cmode == Opm::Group::ProductionCMode::NONE) {
|
|
|
|
|
iGrp[nwgmax + 5] = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -577,7 +553,7 @@ void productionGroup(const Opm::Schedule& sched,
|
|
|
|
|
iGrp[nwgmax + IGroup::ProdActiveCMode]
|
|
|
|
|
= (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE) ? higher_lev_ctrl_mode : 0;
|
|
|
|
|
} else {
|
|
|
|
|
switch (pctl_mode) {
|
|
|
|
|
switch (active_cmode) {
|
|
|
|
|
case Opm::Group::ProductionCMode::NONE:
|
|
|
|
|
iGrp[nwgmax + IGroup::ProdActiveCMode] = 0;
|
|
|
|
|
break;
|
|
|
|
|
@@ -606,41 +582,35 @@ void productionGroup(const Opm::Schedule& sched,
|
|
|
|
|
iGrp[nwgmax + 9] = iGrp[nwgmax + IGroup::ProdActiveCMode];
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 0 : 4;
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 0;
|
|
|
|
|
break;
|
|
|
|
|
case Opm::Group::ProductionCMode::ORAT:
|
|
|
|
|
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -40000 : 4;
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 1;
|
|
|
|
|
break;
|
|
|
|
|
case Opm::Group::ProductionCMode::WRAT:
|
|
|
|
|
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -4000 : 4;
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 2;
|
|
|
|
|
break;
|
|
|
|
|
case Opm::Group::ProductionCMode::GRAT:
|
|
|
|
|
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -400 : 4;
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 3;
|
|
|
|
|
break;
|
|
|
|
|
case Opm::Group::ProductionCMode::LRAT:
|
|
|
|
|
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -40 : 4;
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 4;
|
|
|
|
|
break;
|
|
|
|
|
case Opm::Group::ProductionCMode::RESV:
|
|
|
|
|
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? -4 : 4; // need to be checked
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 5;
|
|
|
|
|
break;
|
|
|
|
|
case Opm::Group::ProductionCMode::FLD:
|
|
|
|
|
if ((higher_lev_ctrl > 0) && (prod_guide_rate_def != Opm::Group::GuideRateTarget::NO_GUIDE_RATE)) {
|
|
|
|
|
iGrp[nwgmax + IGroup::GuideRateDef] = Value::GuideRateMode::Form;
|
|
|
|
|
}
|
|
|
|
|
iGrp[nwgmax + 7] = (p_exceed_act == Opm::Group::ExceedAction::NONE) ? 4 : 4;
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 0; // need to be checked!!
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
iGrp[nwgmax + 7] = 0;
|
|
|
|
|
iGrp[nwgmax + IGroup::GConProdCMode] = 0; // need to be checked!!
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -659,6 +629,7 @@ void injectionGroup(const Opm::Schedule& sched,
|
|
|
|
|
auto group_parent_list = groupParentSeqIndex(sched, group, simStep);
|
|
|
|
|
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// set "default value" in case a group is only injection group
|
|
|
|
|
if (group.isInjectionGroup() && !group.isProductionGroup()) {
|
|
|
|
|
iGrp[nwgmax + 5] = 1;
|
|
|
|
|
@@ -827,6 +798,67 @@ 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>
|
|
|
|
|
void staticContrib(const Opm::Schedule& sched,
|
|
|
|
|
@@ -839,54 +871,22 @@ void staticContrib(const Opm::Schedule& sched,
|
|
|
|
|
const std::map<Opm::Group::InjectionCMode, int>& cmodeToNum,
|
|
|
|
|
IGrpArray& iGrp)
|
|
|
|
|
{
|
|
|
|
|
using IGroup = ::Opm::RestartIO::Helpers::VectorItems::IGroup::index;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//assign the number of child wells or child groups to
|
|
|
|
|
// location nwgmax
|
|
|
|
|
iGrp[nwgmax] = groupSize(group);
|
|
|
|
|
storeGroupTree(sched, group, nwgmax, ngmaxz, simStep, iGrp);
|
|
|
|
|
storeFlowingWells(group, nwgmax, sumState, iGrp);
|
|
|
|
|
|
|
|
|
|
// Find number of active production wells and injection wells for group
|
|
|
|
|
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;
|
|
|
|
|
iGrp[nwgmax + 17] = -1;
|
|
|
|
|
iGrp[nwgmax + 22] = -1;
|
|
|
|
|
|
|
|
|
|
// Treat al groups which are *not* pure injection groups.
|
|
|
|
|
if (group.getGroupType() != Opm::Group::GroupType::INJECTION)
|
|
|
|
|
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.
|
|
|
|
|
if (group.getGroupType() != Opm::Group::GroupType::PRODUCTION)
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
//the maximum number of groups in the model
|
|
|
|
|
@@ -907,21 +907,6 @@ void staticContrib(const Opm::Schedule& sched,
|
|
|
|
|
iGrp[nwgmax+95] = 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
|
|
|
|
|
|
|
|
|
|
|