commit
f16375f5ee
@ -61,6 +61,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
WInjCMode = 16,
|
||||
GConProdCMode = 10,
|
||||
GInjCMode = 21,
|
||||
GroupType = 26,
|
||||
GroupLevel = 27,
|
||||
ParentGroup = 28,
|
||||
FlowingWells = 33,
|
||||
};
|
||||
@ -76,6 +78,12 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
Form = 8,
|
||||
Comb = 9,
|
||||
};
|
||||
|
||||
enum GroupType : int {
|
||||
WellGroup = 0,
|
||||
TreeGroup = 1,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,13 +58,14 @@ public:
|
||||
int ecl_phase() const;
|
||||
Phase preferred_phase() const;
|
||||
InjectorType injector_type() const;
|
||||
Phase injection_phase() const;
|
||||
bool operator==(const WellType& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(m_producer);
|
||||
serializer(injection_phase);
|
||||
serializer(m_injection_phase);
|
||||
serializer(m_welspecs_phase);
|
||||
}
|
||||
|
||||
@ -83,7 +84,7 @@ private:
|
||||
used when initializing the well equations for a producer.
|
||||
*/
|
||||
|
||||
Phase injection_phase;
|
||||
Phase m_injection_phase;
|
||||
Phase m_welspecs_phase;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -87,9 +87,17 @@ bool WellType::gas_injector(int ecl_wtype) {
|
||||
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) :
|
||||
injection_phase(ecl::from_ecl_phase(ecl_phase)),
|
||||
m_injection_phase(ecl::from_ecl_phase(ecl_phase)),
|
||||
m_welspecs_phase(ecl::from_ecl_phase(ecl_phase))
|
||||
{
|
||||
this->m_producer = false;
|
||||
@ -98,13 +106,13 @@ WellType::WellType(int ecl_wtype, int ecl_phase) :
|
||||
this->m_producer = true;
|
||||
break;
|
||||
case ecl::oil_injector:
|
||||
this->injection_phase = Phase::OIL;
|
||||
this->m_injection_phase = Phase::OIL;
|
||||
break;
|
||||
case ecl::water_injector:
|
||||
this->injection_phase = Phase::WATER;
|
||||
this->m_injection_phase = Phase::WATER;
|
||||
break;
|
||||
case ecl::gas_injector:
|
||||
this->injection_phase = Phase::GAS;
|
||||
this->m_injection_phase = Phase::GAS;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("Invalid integer well type ID");
|
||||
@ -114,7 +122,7 @@ WellType::WellType(int ecl_wtype, int ecl_phase) :
|
||||
|
||||
WellType::WellType(bool producer, Phase phase) :
|
||||
m_producer(producer),
|
||||
injection_phase(phase),
|
||||
m_injection_phase(phase),
|
||||
m_welspecs_phase(phase)
|
||||
{}
|
||||
|
||||
@ -126,7 +134,7 @@ WellType WellType::serializeObject()
|
||||
{
|
||||
WellType result;
|
||||
result.m_producer = true;
|
||||
result.injection_phase = Phase::OIL;
|
||||
result.m_injection_phase = Phase::OIL;
|
||||
result.m_welspecs_phase = Phase::WATER;
|
||||
|
||||
return result;
|
||||
@ -148,8 +156,8 @@ bool WellType::update(InjectorType injector_type) {
|
||||
}
|
||||
|
||||
auto inj_phase = from_injector_type(injector_type);
|
||||
if (this->injection_phase != inj_phase) {
|
||||
this->injection_phase = inj_phase;
|
||||
if (this->m_injection_phase != inj_phase) {
|
||||
this->m_injection_phase = inj_phase;
|
||||
ret_value = true;
|
||||
}
|
||||
|
||||
@ -168,7 +176,7 @@ int WellType::ecl_wtype() const {
|
||||
if (this->m_producer)
|
||||
return ecl::producer;
|
||||
|
||||
switch (this->injection_phase) {
|
||||
switch (this->m_injection_phase) {
|
||||
case Phase::OIL:
|
||||
return ecl::oil_injector;
|
||||
case Phase::WATER:
|
||||
@ -201,13 +209,13 @@ int WellType::ecl_phase() const {
|
||||
|
||||
|
||||
Phase WellType::preferred_phase() const {
|
||||
return this->injector() ? this->injection_phase : this->m_welspecs_phase;
|
||||
return this->injector() ? this->m_injection_phase : this->m_welspecs_phase;
|
||||
}
|
||||
|
||||
|
||||
bool WellType::operator==(const WellType& other) const {
|
||||
return this->m_welspecs_phase == other.m_welspecs_phase &&
|
||||
this->injection_phase == other.injection_phase &&
|
||||
this->m_injection_phase == other.m_injection_phase &&
|
||||
this->m_producer == other.m_producer;
|
||||
}
|
||||
|
||||
@ -216,7 +224,7 @@ InjectorType WellType::injector_type() const {
|
||||
if (this->producer())
|
||||
throw std::invalid_argument("Asked for injector type for a well which is a producer");
|
||||
|
||||
switch (this->injection_phase) {
|
||||
switch (this->m_injection_phase) {
|
||||
case Phase::OIL:
|
||||
return InjectorType::OIL;
|
||||
case Phase::WATER:
|
||||
|
Loading…
Reference in New Issue
Block a user