From dcdcf997582c1e47d14ef5471c407bca7676a469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Thu, 28 Apr 2016 16:20:03 +0200 Subject: [PATCH] Support and tests for history matching G-keywords --- src/opm/output/eclipse/Summary.cpp | 82 ++++++++++++++++++++++++++++-- tests/summary_deck.DATA | 28 ++++++++++ tests/test_Summary.cpp | 75 ++++++++++++++++++++++++++- 3 files changed, 181 insertions(+), 4 deletions(-) diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index 4801c9caf..360602d2a 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -179,6 +179,19 @@ enum class E : out::Summary::kwtype { GWIT, GGIR, GGIT, + GGIRH, + GWIRH, + GOIRH, + GGITH, + GWITH, + GWPRH, + GOPRH, + GGPRH, + GLPRH, + GWPTH, + GOPTH, + GGPTH, + GLPTH, GWCT, GGOR, UNSUPPORTED, @@ -233,7 +246,20 @@ const std::map< std::string, E > keyhash = { { "GWIR", E::GWIR }, { "GWIT", E::GWIT }, { "GGIR", E::GGIR }, + { "GWPRH", E::GWPRH }, + { "GOPRH", E::GOPRH }, + { "GGPRH", E::GGPRH }, + { "GLPRH", E::GLPRH }, + { "GWPTH", E::GWPTH }, + { "GOPTH", E::GOPTH }, + { "GGPTH", E::GGPTH }, + { "GLPTH", E::GLPTH }, + { "GGIRH", E::GGIRH }, + { "GWIRH", E::GWIRH }, + { "GOIRH", E::GOIRH }, { "GGIT", E::GGIT }, + { "GWITH", E::GWITH }, + { "GGITH", E::GGITH }, { "GWCT", E::GWCT }, { "GGOR", E::GGOR }, }; @@ -528,11 +554,26 @@ inline double sum_vol( const std::vector< const data::Well* >& wells, throw std::runtime_error( "Reached impossible state in prodrate" ); } +template< typename F, typename Phase > +inline double sum_hist( F f, + const WellSet& wells, + size_t tstep, + Phase phase, + const double* conversion_table ) { + double res = 0; + for( const auto& well : wells ) + res += f( *well.second, tstep, phase, conversion_table ); + + return res; +} + inline double group_keywords( E keyword, const smspec_node_type* node, const ecl_sum_tstep_type* prev, const double* conversion_table, - const std::vector< const data::Well* >& sim_wells ) { + size_t tstep, + const std::vector< const data::Well* >& sim_wells, + const WellSet& state_wells ) { const auto* genkey = smspec_node_get_gen_key1( node ); const auto accu = prev ? ecl_sum_tstep_get_from_key( prev, genkey ) : 0; @@ -545,6 +586,22 @@ inline double group_keywords( E keyword, return sum_vol( sim_wells, phase, conversion_table ); }; + const auto histprate = [&]( WT phase ) { + return sum_hist( prodrate, state_wells, tstep, phase, conversion_table ); + }; + + const auto histpvol = [&]( WT phase ) { + return sum_hist( prodvol, state_wells, tstep, phase, conversion_table ); + }; + + const auto histirate = [&]( WellInjector::TypeEnum phase ) { + return sum_hist( injerate, state_wells, tstep, phase, conversion_table ); + }; + + const auto histivol = [&]( WellInjector::TypeEnum phase ) { + return sum_hist( injevol, state_wells, tstep, phase, conversion_table ); + }; + switch( keyword ) { /* Production rates */ case E::GWPR: return rate( rt::wat ); @@ -567,6 +624,23 @@ inline double group_keywords( E keyword, case E::GWCT: return wct( rate( rt::wat ), rate( rt::oil ) ); case E::GGOR: return glr( rate( rt::gas ), rate( rt::oil ) ); + /* Historical rates */ + case E::GWPRH: return histprate( WT::wat ); + case E::GOPRH: return histprate( WT::oil ); + case E::GGPRH: return histprate( WT::gas ); + case E::GLPRH: return histprate( WT::wat ) + histprate( WT::oil ); + case E::GWIRH: return histirate( WellInjector::WATER ); + case E::GOIRH: return histirate( WellInjector::OIL ); + case E::GGIRH: return histirate( WellInjector::GAS ); + + /* Historical totals */ + case E::GWPTH: return accu + histpvol( WT::wat ); + case E::GOPTH: return accu + histpvol( WT::oil ); + case E::GGPTH: return accu + histpvol( WT::gas ); + case E::GLPTH: return accu + histpvol( WT::wat ) + histpvol( WT::oil ); + case E::GGITH: return accu + histivol( WellInjector::GAS ); + case E::GWITH: return accu + histivol( WellInjector::WATER ); + default: return -1; } @@ -665,15 +739,17 @@ void Summary::add_timestep( int report_step, for( const auto& pair : this->gvar ) { const auto* gname = pair.first; const auto& state_group = *es.getSchedule()->getGroup( gname ); + const auto& state_wells = state_group.getWells( report_step ); std::vector< const data::Well* > sim_wells; - for( const auto& well : state_group.getWells( report_step ) ) + for( const auto& well : state_wells ) sim_wells.push_back( &wells.at( well.first ) ); for( const auto& node : pair.second ) { auto val = group_keywords( static_cast< E >( node.kw ), node.node, this->prev_tstep, - this->conversions, sim_wells ); + this->conversions, report_step, + sim_wells, state_wells ); ecl_sum_tstep_set_from_node( tstep, node.node, val ); } } diff --git a/tests/summary_deck.DATA b/tests/summary_deck.DATA index c2285b88b..14f7d2936 100644 --- a/tests/summary_deck.DATA +++ b/tests/summary_deck.DATA @@ -93,6 +93,8 @@ ROP -- Group data -- GPR / +GLPR +/ GOPT / GGPT @@ -109,14 +111,40 @@ GWPR / GGIR / +GGIRH +/ GGIT / +GGITH +/ GWCT / GGOR / GWIR / +GWIT +/ +GWIRH +/ +GWITH +/ +GWPRH +/ +GOPRH +/ +GGPRH +/ +GLPRH +/ +GWPTH +/ +GOPTH +/ +GGPTH +/ +GLPTH +/ -- Well Data -- Production Rates WWPR diff --git a/tests/test_Summary.cpp b/tests/test_Summary.cpp index a4f71186b..77d12dcb1 100644 --- a/tests/test_Summary.cpp +++ b/tests/test_Summary.cpp @@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(W_WOG_PRH) { } BOOST_AUTO_TEST_CASE(W_WOG_PTH) { - setup cfg( "sum_test_W_WOG_PRH" ); + setup cfg( "sum_test_W_WOG_PTH" ); out::Summary writer( cfg.es, cfg.config, cfg.name ); writer.add_timestep( 1, 1, cfg.es, cfg.wells ); @@ -417,6 +417,79 @@ BOOST_AUTO_TEST_CASE(G_WOG_PT) { BOOST_CHECK_CLOSE( 2 * 30.2 / day, ecl_sum_get_group_var( resp, 1, "G_2", "GGPT" ), 1e-5 ); } +BOOST_AUTO_TEST_CASE(G_WOG_PRH) { + setup cfg( "sum_test_G_WOG_PRH" ); + + out::Summary writer( cfg.es, cfg.config, cfg.name ); + writer.add_timestep( 1, 1, cfg.es, cfg.wells ); + writer.write(); + + auto res = readsum( cfg.name ); + const auto* resp = res.get(); + + BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_group_var( resp, 0, "G_1", "GWPRH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GWPRH" ), 1e-5 ); + + BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_group_var( resp, 0, "G_1", "GOPRH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GOPRH" ), 1e-5 ); + + BOOST_CHECK_CLOSE( 10.2 + 20.2, ecl_sum_get_group_var( resp, 0, "G_1", "GGPRH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GGPRH" ), 1e-5 ); + + BOOST_CHECK_CLOSE( 10.0 + 10.1 + 20.0 + 20.1, + ecl_sum_get_group_var( resp, 0, "G_1", "GLPRH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GLPRH" ), 1e-5 ); +} + +BOOST_AUTO_TEST_CASE(G_WG_ITH) { + setup cfg( "sum_test_G_WG_ITH" ); + + out::Summary writer( cfg.es, cfg.config, cfg.name ); + writer.add_timestep( 1, 1, cfg.es, cfg.wells ); + writer.add_timestep( 2, 1, cfg.es, cfg.wells ); + writer.write(); + + auto res = readsum( cfg.name ); + const auto* resp = res.get(); + + BOOST_CHECK_CLOSE( 30.0 / day, ecl_sum_get_group_var( resp, 0, "G_2", "GWITH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GGITH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 60.0 / day, ecl_sum_get_group_var( resp, 1, "G_2", "GWITH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 1, "G_2", "GGITH" ), 1e-5 ); +} + +BOOST_AUTO_TEST_CASE(G_WOG_PRT) { + setup cfg( "sum_test_G_WOG_PRT" ); + + out::Summary writer( cfg.es, cfg.config, cfg.name ); + writer.add_timestep( 1, 1, cfg.es, cfg.wells ); + writer.add_timestep( 2, 1, cfg.es, cfg.wells ); + writer.write(); + + auto res = readsum( cfg.name ); + const auto* resp = res.get(); + + BOOST_CHECK_CLOSE( (10.0 + 20.0) / day, ecl_sum_get_group_var( resp, 0, "G_1", "GWPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GWPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( (10.1 + 20.1) / day, ecl_sum_get_group_var( resp, 0, "G_1", "GOPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GOPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( (10.2 + 20.2) / day, ecl_sum_get_group_var( resp, 0, "G_1", "GGPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GGPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( (10.0 + 20.0 + 10.1 + 20.1) / day, + ecl_sum_get_group_var( resp, 0, "G_1", "GLPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 0, "G_2", "GLPTH" ), 1e-5 ); + + BOOST_CHECK_CLOSE( 2 * (10.0 + 20.0) / day, ecl_sum_get_group_var( resp, 1, "G_1", "GWPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 1, "G_2", "GWPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * (10.1 + 20.1) / day, ecl_sum_get_group_var( resp, 1, "G_1", "GOPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 1, "G_2", "GOPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * (10.2 + 20.2) / day, ecl_sum_get_group_var( resp, 1, "G_1", "GGPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 1, "G_2", "GGPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * (10.0 + 20.0 + 10.1 + 20.1) / day, + ecl_sum_get_group_var( resp, 1, "G_1", "GLPTH" ), 1e-5 ); + BOOST_CHECK_CLOSE( 0, ecl_sum_get_group_var( resp, 1, "G_2", "GLPTH" ), 1e-5 ); +} + BOOST_AUTO_TEST_CASE(GWCT) { setup cfg( "sum_test_GWCT" );