Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support instantaneous flow rates in extended network (WEFAC and GEFAC item 3) #4094

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions opm/input/eclipse/Schedule/Group/Group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ Group::Group(const std::string& name, std::size_t insert_index_arg, double udq_u
unit_system(unit_system_arg),
group_type(GroupType::NONE),
gefac(1),
transfer_gefac(true),
use_efficiency_in_network(true),
production_properties(unit_system, name)
{
// All groups are initially created as children of the "FIELD" group.
Expand Down Expand Up @@ -249,7 +249,7 @@ Group Group::serializationTestObject()
result.unit_system = UnitSystem::serializationTestObject();
result.group_type = GroupType::PRODUCTION;
result.gefac = 4.0;
result.transfer_gefac = true;
result.use_efficiency_in_network = true;
result.parent_group = "test2";
result.m_wells = {{"test3", "test4"}, {"test5", "test6"}};
result.m_groups = {{"test7", "test8"}, {"test9", "test10"}};
Expand Down Expand Up @@ -680,27 +680,31 @@ void Group::delGroup(const std::string& group_name) {
};
}

bool Group::update_gefac(double gf, bool transfer_gf) {
bool Group::update_gefac(double gf, bool use_efficiency_in_network_arg) {
bool update = false;
if (this->gefac != gf) {
this->gefac = gf;
update = true;
}

if (this->transfer_gefac != transfer_gf) {
this->transfer_gefac = transfer_gf;
if (this->use_efficiency_in_network != use_efficiency_in_network_arg) {
this->use_efficiency_in_network = use_efficiency_in_network_arg;
update = true;
}

return update;
}

double Group::getGroupEfficiencyFactor() const {
double Group::getGroupEfficiencyFactor(bool network) const {
GitPaean marked this conversation as resolved.
Show resolved Hide resolved
if (network && !(this->use_efficiency_in_network)) {
return 1.0;
}

return this->gefac;
}

bool Group::getTransferGroupEfficiencyFactor() const {
return this->transfer_gefac;
bool Group::useEfficiencyInNetwork() const {
return this->use_efficiency_in_network;
}

const std::string& Group::parent() const {
Expand Down Expand Up @@ -1197,7 +1201,7 @@ bool Group::operator==(const Group& data) const
this->unit_system == data.unit_system &&
this->group_type == data.group_type &&
this->getGroupEfficiencyFactor() == data.getGroupEfficiencyFactor() &&
this->getTransferGroupEfficiencyFactor() == data.getTransferGroupEfficiencyFactor() &&
this->useEfficiencyInNetwork() == data.useEfficiencyInNetwork() &&
this->parent() == data.parent() &&
this->m_wells == data.m_wells &&
this->m_groups == data.m_groups &&
Expand Down
10 changes: 5 additions & 5 deletions opm/input/eclipse/Schedule/Group/Group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class Group {
const std::string& name() const;
bool is_field() const;

bool update_gefac(double gefac, bool transfer_gefac);
bool update_gefac(double gefac, bool use_efficiency_in_network);

// [[deprecated("use Group::control_group() or Group::flow_group()")]]
const std::string& parent() const;
Expand All @@ -293,8 +293,8 @@ class Group {
bool isInjectionGroup() const;
void setProductionGroup();
void setInjectionGroup();
double getGroupEfficiencyFactor() const;
bool getTransferGroupEfficiencyFactor() const;
double getGroupEfficiencyFactor(bool network = false) const;
bool useEfficiencyInNetwork() const;

std::size_t numWells() const;
bool addGroup(const std::string& group_name);
Expand Down Expand Up @@ -339,7 +339,7 @@ class Group {
serializer(unit_system);
serializer(group_type);
serializer(gefac);
serializer(transfer_gefac);
serializer(use_efficiency_in_network);
serializer(parent_group);
serializer(m_wells);
serializer(m_groups);
Expand All @@ -359,7 +359,7 @@ class Group {
UnitSystem unit_system;
GroupType group_type;
double gefac;
bool transfer_gefac;
bool use_efficiency_in_network;

std::string parent_group;
IOrderSet<std::string> m_wells;
Expand Down
4 changes: 2 additions & 2 deletions opm/input/eclipse/Schedule/Group/GroupKeywordHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,12 @@ void handleGEFAC(HandlerContext& handlerContext)
handlerContext.invalidNamePattern(groupNamePattern);
}

const bool transfer = DeckItem::to_bool(record.getItem("TRANSFER_EXT_NET").getTrimmedString(0));
const bool use_efficiency_in_network = DeckItem::to_bool(record.getItem("USE_GEFAC_IN_NETWORK").getTrimmedString(0));
const auto gefac = record.getItem("EFFICIENCY_FACTOR").get<double>(0);

for (const auto& group_name : group_names) {
auto new_group = handlerContext.state().groups.get(group_name);
if (new_group.update_gefac(gefac, transfer)) {
if (new_group.update_gefac(gefac, use_efficiency_in_network)) {
handlerContext.state().wellgroup_events().addEvent( group_name, ScheduleEvents::WELLGROUP_EFFICIENCY_UPDATE);
handlerContext.state().events().addEvent( ScheduleEvents::WELLGROUP_EFFICIENCY_UPDATE );
handlerContext.state().groups.update(std::move(new_group));
Expand Down
39 changes: 38 additions & 1 deletion opm/input/eclipse/Schedule/Network/ExtNetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <functional>

#include <opm/input/eclipse/Schedule/Network/ExtNetwork.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>

namespace Opm {
namespace Network {
Expand All @@ -34,6 +36,8 @@ ExtNetwork ExtNetwork::serializationTestObject() {
object.insert_indexed_node_names = {"test1", "test2"};
object.m_nodes = {{"test3", Node::serializationTestObject()}};
object.m_is_standard_network = false;
object.m_needs_instantaneous_rates = false;
object.m_previous_update_report_step = -1;
return object;
}

Expand All @@ -52,7 +56,9 @@ void ExtNetwork::set_standard_network(bool is_standard_network) {
bool ExtNetwork::operator==(const ExtNetwork& rhs) const {
return this->m_branches == rhs.m_branches
&& this->insert_indexed_node_names == rhs.insert_indexed_node_names
&& this->m_nodes == rhs.m_nodes;
&& this->m_nodes == rhs.m_nodes
&& this->m_needs_instantaneous_rates == rhs.m_needs_instantaneous_rates
&& this->m_previous_update_report_step == rhs.m_previous_update_report_step;
}


Expand Down Expand Up @@ -205,6 +211,37 @@ void ExtNetwork::update_node(Node node)
this->m_nodes.insert_or_assign(name, std::move(node) );
}

// @TODO@ : Make this ACTION safe
bool ExtNetwork::needs_instantaneous_rates(const Opm::Schedule& schedule, const int report_step) const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the usage of this function in OPM/opm-simulators#5410, it basically indicates whether we are handling network flow with extended network with "NO" in the item 3 in WEFAC or GEFAC.

Or more simply, we can use true for extended network and use false for standard network and group calculation. If we can introduce a flag to mark whether the network is extended network, we do not need this function anymore. And use_efficiency_in_ext_network will take care whether we will use instantaneous rate.

What do you think? I can understand this part wrong. Please let me know.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can certainly be skipped, but the intention is to save some computation in opm-simulators in the quite common situation with default value (YES) for all instances of WEFAC/GEFAC with wells/groups in the network.

One complication I see is action handling (i.e., if item3 is updated through actions), will need to ensure the check is performed again in this case. Can have a quick look, or we just drop this for now.

// Just return value if we already checked this report step
if (report_step == this->m_previous_update_report_step) {
return this->m_needs_instantaneous_rates;
}
// Otherwise, check and update
for (const auto& it : this->m_nodes) {
const auto& node_name = it.second.name();
if (!schedule.hasGroup(node_name, report_step))
continue;
const auto& group = schedule.getGroup(node_name, report_step);
if (!group.useEfficiencyInNetwork()) {
this->m_needs_instantaneous_rates = true;
this->m_previous_update_report_step = report_step;
return true;
}
for (const std::string& well_name : group.wells()) {
const auto& well = schedule.getWell(well_name, report_step);
if(!well.useEfficiencyInNetwork()) {
this->m_needs_instantaneous_rates = true;
this->m_previous_update_report_step = report_step;
return true;
}
}
}
this->m_previous_update_report_step = report_step;
this->m_needs_instantaneous_rates = false;
return false;
}

void ExtNetwork::add_indexed_node_name(std::string name)
{
this->insert_indexed_node_names.emplace_back(name);
Expand Down
7 changes: 7 additions & 0 deletions opm/input/eclipse/Schedule/Network/ExtNetwork.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <opm/input/eclipse/Schedule/Network/Node.hpp>

namespace Opm {
class Schedule;

namespace Network {


Expand All @@ -45,6 +47,7 @@ class ExtNetwork {
void drop_branch(const std::string& uptree_node, const std::string& downtree_node);
bool has_node(const std::string& name) const;
void update_node(Node node);
bool needs_instantaneous_rates(const Opm::Schedule& schedule, const int report_step) const;
const Node& node(const std::string& name) const;
std::vector<std::reference_wrapper<const Node>> roots() const;
std::vector<Branch> downtree_branches(const std::string& node) const;
Expand All @@ -63,13 +66,17 @@ class ExtNetwork {
serializer(insert_indexed_node_names);
serializer(m_nodes);
serializer(m_is_standard_network);
serializer(m_needs_instantaneous_rates);
serializer(m_previous_update_report_step);
}

private:
std::vector<Branch> m_branches;
std::vector<std::string> insert_indexed_node_names;
std::map<std::string, Node> m_nodes;
bool m_is_standard_network{false};
mutable bool m_needs_instantaneous_rates{false};
mutable int m_previous_update_report_step{-1};
bool has_indexed_node_name(const std::string& name) const;
void add_indexed_node_name(std::string name);
};
Expand Down
26 changes: 21 additions & 5 deletions opm/input/eclipse/Schedule/Well/Well.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ Well::Well(const RestartIO::RstWell& rst_well,
wtype(rst_well.wtype),
guide_rate(guideRate(rst_well)),
efficiency_factor(rst_well.efficiency_factor),
use_efficiency_in_network(true), // @TODO@ Find and read the actual value from restart
solvent_fraction(def_solvent_fraction),
prediction_mode(rst_well.hist_requested_control == 0),
econ_limits(economicLimits(rst_well)),
Expand Down Expand Up @@ -486,6 +487,7 @@ Well::Well(const std::string& wname_arg,
wtype(wtype_arg),
guide_rate({true, -1, Well::GuideRateTarget::UNDEFINED,ParserKeywords::WGRUPCON::SCALING_FACTOR::defaultValue}),
efficiency_factor(1.0),
use_efficiency_in_network(true),
solvent_fraction(0.0),
derive_refdepth_from_conns_{ ! ref_depth_arg.has_value() || (*ref_depth_arg < 0.0) },
econ_limits(std::make_shared<WellEconProductionLimits>()),
Expand Down Expand Up @@ -530,6 +532,7 @@ Well Well::serializationTestObject()
result.wtype = WellType(Phase::WATER);
result.guide_rate = WellGuideRate::serializationTestObject();
result.efficiency_factor = 8.0;
result.use_efficiency_in_network = true;
result.solvent_fraction = 9.0;
result.prediction_mode = false;
result.derive_refdepth_from_conns_ = false;
Expand Down Expand Up @@ -562,13 +565,19 @@ bool Well::updateWPAVE(const PAvg& pavg) {
return true;
}

bool Well::updateEfficiencyFactor(double efficiency_factor_arg) {
bool Well::updateEfficiencyFactor(double efficiency_factor_arg, bool use_efficiency_in_network_arg) {
bool update = false;
if (this->efficiency_factor != efficiency_factor_arg) {
this->efficiency_factor = efficiency_factor_arg;
return true;
update = true;
}

return false;
if (this->use_efficiency_in_network != use_efficiency_in_network_arg) {
this->use_efficiency_in_network = use_efficiency_in_network_arg;
update = true;
}

return update;
}

bool Well::updateWellGuideRate(double guide_rate_arg) {
Expand Down Expand Up @@ -1028,11 +1037,17 @@ double Well::getGuideRateScalingFactor() const {
return this->guide_rate.scale_factor;
}


double Well::getEfficiencyFactor() const {
double Well::getEfficiencyFactor(bool network) const {
if (network && (!this->use_efficiency_in_network)) {
return 1.0;
}
return this->efficiency_factor;
}

bool Well::useEfficiencyInNetwork() const {
return this->use_efficiency_in_network;
}

double Well::getSolventFraction() const {
return this->solvent_fraction;
}
Expand Down Expand Up @@ -1769,6 +1784,7 @@ bool Well::cmp_structure(const Well& other) const {
&& (this->getAllowCrossFlow() == other.getAllowCrossFlow())
&& (this->getAutomaticShutIn() == other.getAutomaticShutIn())
&& (this->getEfficiencyFactor() == other.getEfficiencyFactor())
&& (this->use_efficiency_in_network == other.use_efficiency_in_network)
;
}

Expand Down
7 changes: 5 additions & 2 deletions opm/input/eclipse/Schedule/Well/Well.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,8 @@ class Well {
bool hasRefDepth() const;
double getRefDepth() const;
double getDrainageRadius() const;
double getEfficiencyFactor() const;
double getEfficiencyFactor(bool network = false) const;
bool useEfficiencyInNetwork() const;
double getSolventFraction() const;
Status getStatus() const;
const std::string& groupName() const;
Expand Down Expand Up @@ -509,7 +510,7 @@ class Well {
bool updateWellGuideRate(bool available, double guide_rate, GuideRateTarget guide_phase, double scale_factor);
bool updateWellGuideRate(double guide_rate);
bool updateAvailableForGroupControl(bool available);
bool updateEfficiencyFactor(double efficiency_factor);
bool updateEfficiencyFactor(double efficiency_factor, bool se_efficiency_in_network = true);

bool updateSolventFraction(double solvent_fraction);
bool updateTracer(std::shared_ptr<WellTracerProperties> tracer_properties);
Expand Down Expand Up @@ -590,6 +591,7 @@ class Well {
serializer(wtype);
serializer(guide_rate);
serializer(efficiency_factor);
serializer(use_efficiency_in_network);
serializer(solvent_fraction);
serializer(has_produced);
serializer(has_injected);
Expand Down Expand Up @@ -639,6 +641,7 @@ class Well {
WellType wtype;
WellGuideRate guide_rate;
double efficiency_factor;
bool use_efficiency_in_network;
double solvent_fraction;
bool has_produced = false;
bool has_injected = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ void handleWEFAC(HandlerContext& handlerContext)
const auto well_names = handlerContext.wellNames(wellNamePattern);

const double& efficiencyFactor = record.getItem("EFFICIENCY_FACTOR").get<double>(0);
const bool useEfficiencyInNetwork = DeckItem::to_bool(record.getItem("USE_WEFAC_IN_NETWORK").getTrimmedString(0));

for (const auto& well_name : well_names) {
auto well2 = handlerContext.state().wells.get( well_name );
if (well2.updateEfficiencyFactor(efficiencyFactor)){
if (well2.updateEfficiencyFactor(efficiencyFactor, useEfficiencyInNetwork)){
handlerContext.state().wellgroup_events().addEvent( well_name, ScheduleEvents::WELLGROUP_EFFICIENCY_UPDATE);
handlerContext.state().events().addEvent(ScheduleEvents::WELLGROUP_EFFICIENCY_UPDATE);
handlerContext.state().wells.update( std::move(well2) );
Expand Down
2 changes: 1 addition & 1 deletion opm/input/eclipse/share/keywords/000_Eclipse100/G/GEFAC
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"default": 1
},
{
"name": "TRANSFER_EXT_NET",
"name": "USE_GEFAC_IN_NETWORK",
"value_type": "STRING",
"default": "YES",
"comment": "Not supported"
Expand Down
2 changes: 1 addition & 1 deletion opm/input/eclipse/share/keywords/000_Eclipse100/W/WEFAC
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"default": 1
},
{
"name": "EXTENDED_NETWORK_OPT",
"name": "USE_WEFAC_IN_NETWORK",
"value_type": "STRING",
"default": "YES"
}
Expand Down
2 changes: 1 addition & 1 deletion tests/parser/GroupTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ GEFAC

const auto& group1 = schedule.getGroup("PRODUC", 0);
BOOST_CHECK_EQUAL(group1.getGroupEfficiencyFactor(), 0.85);
BOOST_CHECK(group1.getTransferGroupEfficiencyFactor());
BOOST_CHECK(group1.useEfficiencyInNetwork());
}


Expand Down