Merge pull request #1789 from joakim-hove/udqactive-gconprod

Make sure the UDQ usage in GCONPROD is recorded
This commit is contained in:
Joakim Hove 2020-05-15 13:17:02 +02:00 committed by GitHub
commit d1babffa8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 24 deletions

View File

@ -33,6 +33,8 @@
namespace Opm {
class SummaryState;
class UDQConfig;
class UDQActive;
class Group {
public:
@ -152,6 +154,12 @@ struct InjectionControls {
};
struct GroupProductionProperties {
GroupProductionProperties() = default;
GroupProductionProperties(const std::string& gname) :
name(gname)
{}
std::string name;
ProductionCMode cmode = ProductionCMode::NONE;
ExceedAction exceed_action = ExceedAction::NONE;
UDAValue oil_target;
@ -167,10 +175,12 @@ struct GroupProductionProperties {
int production_controls = 0;
bool operator==(const GroupProductionProperties& other) const;
bool operator!=(const GroupProductionProperties& other) const;
bool updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const;
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(name);
serializer(cmode);
serializer(exceed_action);
oil_target.serializeOp(serializer);
@ -297,7 +307,7 @@ private:
IOrderSet<std::string> m_groups;
std::map<Phase, GroupInjectionProperties> injection_properties;
GroupProductionProperties production_properties{};
GroupProductionProperties production_properties;
std::pair<Phase, bool> m_topup_phase{Phase::WATER, false};
};

View File

@ -48,10 +48,10 @@ public:
udq(udq_arg),
input_index(input_index_arg),
use_index(use_index_arg),
wgname(wgname_arg),
control(control_arg),
uad_code(UDQ::uadCode(control_arg)),
use_count(1)
use_count(1),
wgname(wgname_arg)
{}
bool operator==(const Record& other) const {
@ -85,12 +85,15 @@ public:
std::string udq;
std::size_t input_index;
std::size_t use_index = 0;
std::string wgname;
UDAControl control;
int uad_code;
std::size_t use_count;
private:
// The wgname is need in the update process, but it should
// not be exported out.
std::string wgname;
};
class InputRecord {
public:
InputRecord() :

View File

@ -20,6 +20,8 @@
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
#include "../eval_uda.hpp"
@ -39,7 +41,8 @@ Group::Group(const std::string& name, std::size_t insert_index_arg, std::size_t
group_type(GroupType::NONE),
gefac(1),
transfer_gefac(true),
vfp_table(0)
vfp_table(0),
production_properties(name)
{
// All groups are initially created as children of the "FIELD" group.
if (name != "FIELD")
@ -204,7 +207,8 @@ bool Group::GroupInjectionProperties::operator!=(const GroupInjectionProperties&
Group::GroupProductionProperties Group::GroupProductionProperties::serializeObject()
{
Group::GroupProductionProperties result;
Group::GroupProductionProperties result("Group123");
result.name = "Group123";
result.cmode = ProductionCMode::PRBL;
result.exceed_action = ExceedAction::WELL;
result.oil_target = UDAValue(1.0);
@ -222,6 +226,7 @@ Group::GroupProductionProperties Group::GroupProductionProperties::serializeObje
bool Group::GroupProductionProperties::operator==(const GroupProductionProperties& other) const {
return
this->name == other.name &&
this->cmode == other.cmode &&
this->exceed_action == other.exceed_action &&
this->oil_target == other.oil_target &&
@ -235,6 +240,18 @@ bool Group::GroupProductionProperties::operator==(const GroupProductionPropertie
this->resv_target == other.resv_target;
}
bool Group::GroupProductionProperties::updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const {
int update_count = 0;
update_count += active.update(udq_config, this->oil_target, this->name, UDAControl::GCONPROD_OIL_TARGET);
update_count += active.update(udq_config, this->water_target, this->name, UDAControl::GCONPROD_WATER_TARGET);
update_count += active.update(udq_config, this->gas_target, this->name, UDAControl::GCONPROD_GAS_TARGET);
update_count += active.update(udq_config, this->liquid_target, this->name, UDAControl::GCONPROD_LIQUID_TARGET);
return (update_count > 0);
}
bool Group::productionGroupControlAvailable() const {
if (this->m_name == "FIELD")
return false;
@ -256,6 +273,8 @@ bool Group::GroupProductionProperties::operator!=(const GroupProductionPropertie
return !(*this == other);
}
bool Group::hasType(GroupType gtype) const {
return ((this->group_type & gtype) == gtype);
}
@ -420,6 +439,9 @@ Group::ProductionControls Group::productionControls(const SummaryState& st) cons
return pc;
}
Group::InjectionControls Group::injectionControls(Phase phase, const SummaryState& st) const {
Group::InjectionControls ic;
const auto& inj = this->injection_properties.at(phase);

View File

@ -1760,12 +1760,12 @@ Schedule::Schedule(const Deck& deck, const EclipseState& es, const ParseContext&
}
}
}
auto resv_target = record.getItem("RESERVOIR_FLUID_TARGET").getSIDouble(0);
bool availableForGroupControl = DeckItem::to_bool(record.getItem("RESPOND_TO_PARENT").getTrimmedString(0))
&& (group_name != "FIELD");
bool availableForGroupControl = DeckItem::to_bool(record.getItem("RESPOND_TO_PARENT").getTrimmedString(0)) && (group_name != "FIELD");
{
auto group_ptr = std::make_shared<Group>(this->getGroup(group_name, currentStep));
Group::GroupProductionProperties production;
Group::GroupProductionProperties production(group_name);
auto resv_target = record.getItem("RESERVOIR_FLUID_TARGET").getSIDouble(0);
production.cmode = controlMode;
production.oil_target = oil_target;
production.gas_target = gas_target;
@ -1809,6 +1809,10 @@ Schedule::Schedule(const Deck& deck, const EclipseState& es, const ParseContext&
this->updateGroup(std::move(group_ptr), currentStep);
m_events.addEvent( ScheduleEvents::GROUP_PRODUCTION_UPDATE , currentStep);
this->addWellGroupEvent(group_name, ScheduleEvents::GROUP_PRODUCTION_UPDATE, currentStep);
auto udq = std::make_shared<UDQActive>(this->udqActive(currentStep));
if (production.updateUDQActive(this->getUDQConfig(currentStep), *udq))
this->updateUDQActive(currentStep, udq);
}
}
}

View File

@ -1374,7 +1374,6 @@ BOOST_AUTO_TEST_CASE(UDQ_USAGE) {
BOOST_CHECK_EQUAL( usage[1].use_count, 1);
const auto& rec = usage[0];
BOOST_CHECK_EQUAL(rec.wgname, "W1");
BOOST_CHECK_EQUAL(rec.udq, "WUX");
BOOST_CHECK(rec.control == UDAControl::WCONPROD_ORAT);
@ -1382,7 +1381,6 @@ BOOST_AUTO_TEST_CASE(UDQ_USAGE) {
for (std::size_t index = 0; index < usage.IUAD_size(); index++) {
const auto& record = usage[index];
BOOST_CHECK_EQUAL(record.input_index, 0);
BOOST_CHECK_EQUAL(record.wgname, "W1");
if (index == 0)
BOOST_CHECK(record.control == UDAControl::WCONPROD_ORAT);
@ -1400,32 +1398,35 @@ BOOST_AUTO_TEST_CASE(IntegrationTest) {
auto schedule = make_schedule(deck_string);
{
const auto& active = schedule.udqActive(1);
BOOST_CHECK_EQUAL(active.IUAD_size(), 4);
BOOST_CHECK_EQUAL(active.IUAD_size(), 6);
BOOST_CHECK(active[0].control == UDAControl::WCONPROD_ORAT);
BOOST_CHECK(active[1].control == UDAControl::WCONPROD_LRAT);
BOOST_CHECK(active[2].control == UDAControl::WCONPROD_ORAT);
BOOST_CHECK(active[3].control == UDAControl::WCONPROD_LRAT);
BOOST_CHECK(active[0].wgname == "OPL02");
BOOST_CHECK(active[1].wgname == "OPL02");
BOOST_CHECK(active[2].wgname == "OPU02");
BOOST_CHECK(active[3].wgname == "OPU02");
BOOST_CHECK(active[4].control == UDAControl::GCONPROD_LIQUID_TARGET);
BOOST_CHECK(active[5].control == UDAControl::GCONPROD_LIQUID_TARGET);
BOOST_CHECK(active[0].udq == "WUOPRL");
BOOST_CHECK(active[1].udq == "WULPRL");
BOOST_CHECK(active[2].udq == "WUOPRU");
BOOST_CHECK(active[3].udq == "WULPRU");
BOOST_CHECK(active[4].udq == "GULPR1");
BOOST_CHECK(active[5].udq == "GUOPR1");
BOOST_CHECK(active[0].input_index == 0);
BOOST_CHECK(active[1].input_index == 1);
BOOST_CHECK(active[2].input_index == 2);
BOOST_CHECK(active[3].input_index == 3);
BOOST_CHECK(active[4].input_index == 4);
BOOST_CHECK(active[5].input_index == 5);
BOOST_CHECK(active[0].use_count == 1);
BOOST_CHECK(active[1].use_count == 1);
BOOST_CHECK(active[2].use_count == 1);
BOOST_CHECK(active[3].use_count == 1);
BOOST_CHECK(active[4].use_count == 2);
BOOST_CHECK(active[5].use_count == 1);
}
}

View File

@ -603,6 +603,9 @@ WCONINJE
'WIL*' 'WATER' 'SHUT' 'GRUP' 10500 1* 400 /
/
UDQ
-- test
--oil & liquid capacities at GEFAC = 0.8995
@ -610,6 +613,8 @@ DEFINE WUOPRL (WOPR OPL01 - 150) * 0.90 /
DEFINE WULPRL (WLPR OPL01 - 200) * 0.90 /
DEFINE WUOPRU (WOPR OPU01 - 250) * 0.80 /
DEFINE WULPRU (WLPR OPU01 - 300) * 0.80 /
DEFINE GULPR1 (2500 - GOPR LOWER *0.03 - GOPR UPPER *0.15) * 0.899 /
DEFINE GUOPR1 (2500 - GOPR LOWER *0.03 - GOPR UPPER *0.15) * 0.899 /
-- units
UNITS WUOPRL SM3/DAY /
UNITS WULPRL SM3/DAY /
@ -619,11 +624,6 @@ UNITS WULPRU SM3/DAY /
/
GCONPROD
'TEST' 'LRAT' 6000 2* 6000 'RATE' 'NO' /
'LOWER' 'FLD' 6000 2* 6000 'RATE' 'YES' 1* 'FORM' /
'UPPER' 'FLD' 3000 2* 6000 'RATE' 'YES' 1* 'FORM' /
/
GCONINJE
@ -645,6 +645,11 @@ WCONPROD
'OPU02' 'OPEN' 'GRUP' 'WUOPRU' 2* 'WULPRU' 1* 60 /
/
GCONPROD
'TEST' 'LRAT' 6000 2* 'GULPR1' 'RATE' 'NO' /
'LOWER' 'FLD' 6000 2* 'GUOPR1' 'RATE' 'YES' 1* 'FORM' /
'UPPER' 'FLD' 3000 2* 'GULPR1' 'RATE' 'YES' 1* 'FORM' /
/
DATES
1 'SEP' 2018 /