Using Schedule::getWells( group, time_step)

When evaluating a group variable, like e.g. GOPR we need to traverse the
group tree all the way down to the leaf nodes, i.e. wells.
This commit is contained in:
Joakim Hove 2017-07-25 14:34:36 +02:00
parent 9ffc7ebab2
commit 23e3bd8d4b
3 changed files with 583 additions and 10 deletions

View File

@ -772,16 +772,7 @@ inline std::vector< const Well* > find_wells( const Schedule& schedule,
if( type == ECL_SMSPEC_GROUP_VAR ) {
if( !schedule.hasGroup( name ) ) return {};
const auto& names = schedule.getGroup( name ).getWells( timestep );
auto get = [&schedule]( const std::string& w ) {
return schedule.getWell( w );
};
std::vector< const Well* > wells;
auto insert = std::back_inserter( wells );
std::transform( names.begin(), names.end(), insert, get );
return wells;
return schedule.getWells( name, timestep );
}
if( type == ECL_SMSPEC_FIELD_VAR )

525
tests/group_group.DATA Normal file
View File

@ -0,0 +1,525 @@
-- Synthetic test deck based on Norne. This data set is meant to be a simple,
-- well-documented deck for the behaviour of SUMMARY specified output. Data
-- is mostly entered to *traceable* and does not necessarily make sense from
-- a simulation point of view.
START
10 MAI 2007 /
RUNSPEC
TITLE
SUMMARYTESTS
-- A simple 10x10x10 cube. Simple to reason about, large enough for all tests
DIMENS
10 10 10 /
REGDIMS
10 /
OIL
GAS
WATER
GRID
DX
1000*1 /
DY
1000*1 /
DZ
1000*1 /
TOPS
100*1 /
-- Cell 2,1,10 is inactive
ACTNUM
901*1 0 98*1 /
PORO
1000*0.2 /
REGIONS
FIPNUM
100*1
100*2
100*3
100*4
100*5
100*6
100*7
100*8
100*9
100*10 /
SUMMARY
DATE
PERFORMA
--
-- Field Data
-- Production Rates
FVPR
FWPR
FWPRH
FOPR
FOPRH
FGPR
FGPRH
FLPR
FLPRH
FGSR
FGCR
FNPR -- solvent
--FTPRSEA
-- Injection Rates
FVIR
FWIR
FWIRH
FGIR
FNIR -- solvent
FGIRH
-- Production Cummulatives
FVPT
FWPT
FOPT
FLPT
FLPTH
FGPT
FNPT
FOPTH
FGPTH
FWPTH
FGST
FGCT
-- Injection Cummulatives
FVIT
FWIT
FWITH
FGIT
FNIT
FGITH
-- In place
FWIP
FOIP
FGIP
-- Ratios
FWCT
FWCTH
FGOR
FGORH
-- From model2
FMWPR
FMWIN
FOE
-- Pressures
FPR
BPR
1 1 1 /
1 1 2 /
1 1 3 /
1 1 4 /
1 1 5 /
1 1 6 /
1 1 7 /
1 1 8 /
1 1 9 /
1 1 10 /
2 1 10 / -- This cell is not ACTIVE
/
BSGAS
1 1 1 /
/
BSWAT
1 1 1 /
/
-- Region data
RPR
/
ROPT
/
RGPT
/
RWPT
/
RGFT
/
RWFT
/
ROIP
/
ROP
/
ROPR
/
RGPR
/
RWPR
/
RGIR
/
RGIT
/
RWIR
/
RWIT
/
RWPT
/
ROIPL
/
ROIPG
/
RGIP
/
RGIPL
/
RGIPG
/
RWIP
/
RPPO
/
-- Group data --
GPR
/
GLPR
/
GOPT
/
GGPT
/
GWPT
/
GNPT
/
GOPR
/
GGPR
/
GWPR
/
GWPRH
/
GGIR
/
GNPR
/
GNIR
/
GGIRH
/
GGIT
/
GNIT
/
GGITH
/
GWCT
/
GWCTH
/
GGOR
/
GGORH
/
GWIR
/
GWIT
/
GWIRH
/
GWITH
/
GOPRH
/
GGPRH
/
GLPRH
/
GWPTH
/
GOPTH
/
GGPTH
/
GLPTH
/
GPRG
/
GPRW
/
GOPTF
/
GOPTS
/
GOPTH
/
GOPRF
/
GOPRS
/
GOPRH
/
GGPTF
/
GGPTS
/
GGPTH
/
GGPTF
/
GGPTS
/
GGPTH
/
GGLR
/
GGLIR
/
GGLRH
/
GVPR
/
GVPT
/
GMCTP
/
GOPP
/
GVIR
/
GVIT
/
GVPRT
/
GMWPR
/
GMWIN
/
-- Well Data
-- Production Rates
WWPR
/
WWPRH
/
WOPR
/
WOPRH
/
WGPR
/
WNPR
/
WGPRH
/
WLPR
/
WLPRH
/
WLPT
/
WLPTH
/
-- Production Cummulatives
WWPT
/
WWPTH
/
WOPT
/
WOPTH
/
WGPT
/
WGPTH
/
WNPT
/
-- Tracers
--WTPRSEA
--/
--WTPTSEA
--/
-- Injection Cummulatives
-- Ratios
WWCT
/
WWCTH
/
WGOR
/
WGORH
/
WGLR
/
WGLRH
/
-- Performance
WBHP
/
WBHPH
/
WTHP
/
WTHPH
/
WPI
/
WBP
/
WBP4
/
-- from model2
WOPTF
/
WOPTS
/
WOPTH
/
WOPRS
/
WOPRF
/
WGPTF
/
WGPTS
/
WGPRF
/
WTPRS
/
WGLIR
/
WVPR
/
WVPT
/
WOPP
/
WVIR
/
WVIT
/
WMCTL
/
-- Water injection per connection
CWIR
* /
/
CGIT
* /
/
-- Production per connection
-- Using all the different ways of specifying connections here
-- as an informal test that we still get the data we want
CWPR
'W_1' 1 1 1 /
/
COPR
'W_1' /
'W_2' /
/
CGPR
'*' /
/
CNFR
'*' /
/
CNPT
'*' /
/
CNIT
'*' /
/
CWPT
'W_1' 1 1 1 /
/
COPT
'W_1' /
/
CGPT
'W_1' /
'W_2' /
/
---- Connection production rates
----CGFR
----'E-4AH' /
----/
----CWFR
----'E-2H' /
----/
SCHEDULE
GRUPTREE
'G_1' 'G' /
'G_2' 'G' /
/
WELSPECS
'W_1' 'G_1' 1 1 3.33 'OIL' 7* /
'W_2' 'G_2' 2 1 3.33 'OIL' 7* /
/
-- Completion data.
COMPDAT
-- 'Well' I J K1 K2
-- Passing 0 to I/J means they'll get the well head I/J
W_1 0 0 1 1 / -- Active index: 0
W_2 0 0 1 1 / -- Active index: 1
W_2 0 0 2 2 / -- Active index: 101
/
WCONHIST
-- history rates are set so that W_1 produces 1, W_2 produces 2 etc.
-- index.offset.
-- organised as oil-water-gas
W_1 'OPEN' ORAT 10.1 10 10.2 /
W_2 'OPEN' ORAT 20.1 20 20.2 /
/
TSTEP
-- register time steps (in days). This allows us to write *two* report steps (1
-- and 2. Without this, totals/accumulations would fail (segfault) when looking
-- up historical rates and volumes. These volumes however don't change, i.e.
-- every time step has the same set of values
10 10 /
TSTEP
10 10 /

View File

@ -108,6 +108,11 @@ static data::Solution make_solution( const EclipseGrid& grid ) {
return sol;
}
/*
This is quite misleading, because the values prepared in the test
input deck are NOT used.
*/
static data::Wells result_wells() {
/* populate with the following pattern:
*
@ -468,6 +473,58 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
BOOST_CHECK_EQUAL( 0, ecl_sum_get_group_var( resp, 1, "G_2", "GMWPR" ) );
}
BOOST_AUTO_TEST_CASE(group_group) {
setup cfg( "test_Summary_group_group" , "group_group.DATA");
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.name );
writer.add_timestep( 0, 0 * day, cfg.es, cfg.wells , cfg.solution , {});
writer.add_timestep( 1, 1 * day, cfg.es, cfg.wells , cfg.solution , {});
writer.add_timestep( 2, 2 * day, cfg.es, cfg.wells , cfg.solution , {});
writer.write();
auto res = readsum( cfg.name );
const auto* resp = res.get();
/* Production rates */
BOOST_CHECK_CLOSE( 10.0 , ecl_sum_get_well_var( resp, 1, "W_1", "WWPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.0 , ecl_sum_get_group_var( resp, 1, "G_1", "GWPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.1 , ecl_sum_get_well_var( resp, 1, "W_1", "WOPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.1 , ecl_sum_get_group_var( resp, 1, "G_1", "GOPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.2 , ecl_sum_get_well_var( resp, 1, "W_1", "WGPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.2 , ecl_sum_get_group_var( resp, 1, "G_1", "GGPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.0 , ecl_sum_get_well_var( resp, 1, "W_2", "WWPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.0 , ecl_sum_get_group_var( resp, 1, "G_2", "GWPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.1 , ecl_sum_get_well_var( resp, 1, "W_2", "WOPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.1 , ecl_sum_get_group_var( resp, 1, "G_2", "GOPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.2 , ecl_sum_get_well_var( resp, 1, "W_2", "WGPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.2 , ecl_sum_get_group_var( resp, 1, "G_2", "GGPR" ), 1e-5 );
// Production totals
for (int step = 1; step <= 2; step++) {
BOOST_CHECK( ecl_sum_get_group_var( resp , step , "G_1" , "GWPT" ) == ecl_sum_get_well_var( resp , step , "W_1" , "WWPT"));
BOOST_CHECK( ecl_sum_get_group_var( resp , step , "G_1" , "GOPT" ) == ecl_sum_get_well_var( resp , step , "W_1" , "WOPT"));
BOOST_CHECK( ecl_sum_get_group_var( resp , step , "G_1" , "GGPT" ) == ecl_sum_get_well_var( resp , step , "W_1" , "WGPT"));
BOOST_CHECK( ecl_sum_get_group_var( resp , step , "G_2" , "GWPT" ) == ecl_sum_get_well_var( resp , step , "W_2" , "WWPT"));
BOOST_CHECK( ecl_sum_get_group_var( resp , step , "G_2" , "GOPT" ) == ecl_sum_get_well_var( resp , step , "W_2" , "WOPT"));
BOOST_CHECK( ecl_sum_get_group_var( resp , step , "G_2" , "GGPT" ) == ecl_sum_get_well_var( resp , step , "W_2" , "WGPT"));
}
for (const auto& gvar : {"GGPR", "GOPR", "GWPR"})
BOOST_CHECK_CLOSE( ecl_sum_get_group_var( resp , 1 , "G" , gvar) ,
ecl_sum_get_group_var( resp , 1 , "G_1" , gvar) + ecl_sum_get_group_var( resp , 1 , "G_2" , gvar) , 1e-5);
for (int step = 1; step <= 2; step++) {
for (const auto& gvar : {"GGPT", "GOPT", "GWPT"})
BOOST_CHECK_CLOSE( ecl_sum_get_group_var( resp , step , "G" , gvar) ,
ecl_sum_get_group_var( resp , step , "G_1" , gvar) + ecl_sum_get_group_var( resp , step , "G_2" , gvar) , 1e-5);
}
}
BOOST_AUTO_TEST_CASE(completion_kewords) {
setup cfg( "test_Summary_completion" );