Summary: Add Support for 'GPR' (Network Node Pressure) Keyword

This commit adds an evaluation function for the GPR summary vector.
We assume that the actual value is calculated elsewhere and passed
in unchanged from the caller of Summary::eval().  We therefore need
only convert the value to output units and hook this procedure up to
the table of known output functions.

Add a simple unit test for demonstration.
This commit is contained in:
Bård Skaflestad 2020-09-19 00:16:37 +02:00
parent d46628e8a1
commit 2d3432a9e0
3 changed files with 70 additions and 6 deletions

View File

@ -650,6 +650,16 @@ inline quantity thp_history( const fn_args& args ) {
return { thp_hist, measure::pressure };
}
inline quantity node_pressure(const fn_args& args)
{
auto nodePos = args.grp_nwrk.nodeData.find(args.group_name);
if (nodePos == args.grp_nwrk.nodeData.end()) {
return { 0.0, measure::pressure };
}
return { nodePos->second.pressure, measure::pressure };
}
template< Opm::Phase phase >
inline quantity production_history( const fn_args& args ) {
/*
@ -1063,6 +1073,8 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "GWPGR", group_guiderate<producer, Opm::data::GuideRateValue::Item::Water> },
{ "GVPGR", group_guiderate<producer, Opm::data::GuideRateValue::Item::ResV> },
{ "GPR", node_pressure },
{ "GWPT", mul( rate< rt::wat, producer >, duration ) },
{ "GOPT", mul( rate< rt::oil, producer >, duration ) },
{ "GGPT", mul( rate< rt::gas, producer >, duration ) },
@ -1623,8 +1635,7 @@ namespace Evaluator {
const SimulatorResults& simRes,
Opm::SummaryState& st) const override
{
const auto get_wells =
need_wells(node_);
const auto get_wells = need_wells(this->node_);
const auto wells = get_wells
? find_wells(input.sched, this->node_,
@ -1636,13 +1647,11 @@ namespace Evaluator {
// wells apply at this sim_step. Nothing to do.
return;
std::string group_name = this->node_.category == Opm::EclIO::SummaryNode::Category::Group ? this->node_.wgname : "";
EfficiencyFactor efac{};
efac.setFactors(this->node_, input.sched, wells, sim_step);
const fn_args args {
wells, group_name, stepSize, static_cast<int>(sim_step),
wells, this->group_name(), stepSize, static_cast<int>(sim_step),
std::max(0, this->node_.number),
this->node_.fip_region,
st, simRes.wellSol, simRes.grpNwrkSol, input.reg, input.grid,
@ -1657,7 +1666,19 @@ namespace Evaluator {
private:
Opm::EclIO::SummaryNode node_;
ofun fcn_;
ofun fcn_;
std::string group_name() const
{
using Cat = ::Opm::EclIO::SummaryNode::Category;
const auto need_grp_name =
(this->node_.category == Cat::Group) ||
(this->node_.category == Cat::Node);
return need_grp_name
? this->node_.wgname : std::string{""};
}
};
class BlockValue : public Base

View File

@ -464,6 +464,10 @@ GGIGR
GWIGR
G_1 /
-- Network reporting (extended network, node level)
GPR
/
-- Well Data
-- Production Rates
WWPR
@ -790,6 +794,19 @@ UDQ
UNITS WUBHP 'BARSA' /
/
BRANPROP
-- Downtree Uptree #VFP ALQ
G_1 PLAT-A 5 1* /
G_2 PLAT-A 4 1* /
/
NODEPROP
-- Node_name Press autoChoke? addGasLift? Group_name
PLAT-A 21.0 NO NO 1* /
G_1 1* NO NO 1* /
G_2 1* NO NO 1* /
/
-- Three wells, two producers (so that we can form a group) and one injector
WELSPECS
'W_1' 'G_1' 1 1 3.33 'OIL' 7* /

View File

@ -337,6 +337,10 @@ data::GroupAndNetworkValues result_group_nwrk()
cgc_group.set(p_cmode::NONE, i_cmode::NONE, i_cmode::NONE);
grp_nwrk.groupData["FIELD"].currentControl = cgc_group;
grp_nwrk.nodeData["G_1"].pressure = 33.44*Opm::unit::barsa;
grp_nwrk.nodeData["G_2"].pressure = 23.45*Opm::unit::barsa;
grp_nwrk.nodeData["PLAT-A"].pressure = 21.0*Opm::unit::barsa;
return grp_nwrk;
}
@ -1485,7 +1489,29 @@ BOOST_AUTO_TEST_CASE(BLOCK_VARIABLES) {
BOOST_CHECK( !ecl_sum_has_general_var( resp , "BPR:2,1,10"));
}
BOOST_AUTO_TEST_CASE(NODE_VARIABLES) {
setup cfg( "test_summary_node" );
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.es, cfg.schedule, cfg.wells , cfg.grp_nwrk, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.es, cfg.schedule, cfg.wells , cfg.grp_nwrk, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.es, cfg.schedule, cfg.wells , cfg.grp_nwrk, {});
writer.add_timestep( st, 2);
writer.write();
auto res = readsum( cfg.name );
const auto* resp = res.get();
BOOST_CHECK_CLOSE( 21.0 , ecl_sum_get_group_var( resp, 1, "PLAT-A", "GPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 33.44, ecl_sum_get_group_var( resp, 1, "G_1", "GPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 23.45, ecl_sum_get_group_var( resp, 1, "G_2", "GPR" ), 1e-5 );
}
/*
The SummaryConfig.require3DField( ) implementation is slightly ugly: