diff --git a/opm/output/data/Wells.hpp b/opm/output/data/Wells.hpp index d9d9e1d45..0850a440b 100644 --- a/opm/output/data/Wells.hpp +++ b/opm/output/data/Wells.hpp @@ -137,6 +137,7 @@ namespace Opm { double cell_saturation_water; double cell_saturation_gas; double effective_Kh; + double trans_factor; bool operator==(const Connection& conn2) const { @@ -508,6 +509,7 @@ namespace Opm { buffer.write(this->cell_saturation_water); buffer.write(this->cell_saturation_gas); buffer.write(this->effective_Kh); + buffer.write(this->trans_factor); } template @@ -589,6 +591,7 @@ namespace Opm { buffer.read(this->cell_saturation_water); buffer.read(this->cell_saturation_gas); buffer.read(this->effective_Kh); + buffer.read(this->trans_factor); } template diff --git a/src/opm/output/eclipse/AggregateConnectionData.cpp b/src/opm/output/eclipse/AggregateConnectionData.cpp index 0b44bd71f..281bad33e 100755 --- a/src/opm/output/eclipse/AggregateConnectionData.cpp +++ b/src/opm/output/eclipse/AggregateConnectionData.cpp @@ -199,6 +199,23 @@ namespace { sConn[Ix::item31] = -1.0e+20f; sConn[Ix::CFInDeck] = (conn.ctfAssignedFromInput()) ? 1 : 0; } + + template + void dynamicContrib(const Opm::data::Connection& xconn, + const Opm::UnitSystem& units, + SConnArray& sConn) + { + using M = ::Opm::UnitSystem::measure; + using Ix = ::Opm::RestartIO::Helpers::VectorItems::SConn::index; + + auto scprop = [&units](const M u, const double x) -> float + { + return static_cast(units.from_si(u, x)); + }; + + sConn[Ix::item12] = sConn[Ix::ConnTrans] = + scprop(M::transmissibility, xconn.trans_factor); + } } // SConn namespace XConn { @@ -298,7 +315,11 @@ captureDeclaredConnData(const Schedule& sched, SConn::staticContrib(conn, units, sc); if (dynConnRes != nullptr) { + // Simulator provides dynamic connection results such as flow + // rates and PI-adjusted transmissibility factors. auto xc = this->xConn_(wellID, connID); + + SConn::dynamicContrib(*dynConnRes, units, sc); XConn::dynamicContrib(*dynConnRes, units, xc); } }); diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index 14faea5ef..10a5bf640 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -585,31 +585,32 @@ inline quantity srate( const fn_args& args ) { } inline quantity trans_factors ( const fn_args& args ) { - const quantity zero = { 0, measure::transmissibility }; + const quantity zero = { 0.0, measure::transmissibility }; - if( args.schedule_wells.empty() ) return zero; - // Like completion rate we need to look - // up a connection with offset 0. + if (args.schedule_wells.empty()) + // No wells. Before simulation starts? + return zero; + + auto xwPos = args.wells.find(args.schedule_wells.front().name()); + if (xwPos == args.wells.end()) + // No dynamic results for this well. Not open? + return zero; + + // Like completion rate we need to look up a connection with offset 0. const size_t global_index = args.num - 1; + const auto& connections = xwPos->second.connections; + auto connPos = std::find_if(connections.begin(), connections.end(), + [global_index](const Opm::data::Connection& c) + { + return c.index == global_index; + }); - const auto& well = args.schedule_wells.front(); - const auto& name = well.name(); - if( args.wells.count( name ) == 0 ) return zero; + if (connPos == connections.end()) + // No dynamic results for this connection. + return zero; - const auto& grid = args.grid; - const auto& connections = well.getConnections(); - - const auto& connection = std::find_if( - connections.begin(), - connections.end(), - [=]( const Opm::Connection& c ) { - return grid.getGlobalIndex(c.getI(), c.getJ(), c.getK()) == global_index; - } ); - - if( connection == connections.end() ) return zero; - - const auto& v = connection->CF(); - return { v, measure::transmissibility }; + // Dynamic connection result's "trans_factor" includes PI-adjustment. + return { connPos->trans_factor, measure::transmissibility }; } template diff --git a/tests/test_AggregateConnectionData.cpp b/tests/test_AggregateConnectionData.cpp index c5b0fe11f..66907129b 100644 --- a/tests/test_AggregateConnectionData.cpp +++ b/tests/test_AggregateConnectionData.cpp @@ -471,9 +471,7 @@ END return Opm::Parser{}.parseString(input); } - - Opm::data::WellRates - wr(const Opm::Schedule& sched) + Opm::data::WellRates wr(const Opm::Schedule& sched) { using o = ::Opm::data::Rates::opt; @@ -497,12 +495,15 @@ END .set(o::gas, qg * (float(i) + 1.)); c.pressure = 215.; c.index = connections[i].global_index(); + c.trans_factor = connections[i].CF(); } + auto seg = Opm::data::Segment {}; for (std::size_t i = 1; i < 5; i++) { xw["PROD"].segments.insert(std::pair(i, seg)); } } + { const auto& well = sched.getWell("WINJ", 0); const auto& connections = well.getConnections(); @@ -519,34 +520,32 @@ END c.rates.set(o::wat, qw * (float(i) + 1.)).set(o::oil, 0.).set(o::gas, 0.); c.pressure = 218.; c.index = connections[i].global_index(); + c.trans_factor = connections[i].CF(); } } } + return xw; } - } // namespace +} // namespace - struct SimulationCase { - explicit SimulationCase(const Opm::Deck& deck) - : es(deck) - , python(std::make_shared()) - , grid(deck) - , sched(deck, es, python) - { - } +struct SimulationCase { + explicit SimulationCase(const Opm::Deck& deck) + : es (deck) + , grid (deck) + , sched(deck, es, std::make_shared()) + {} - // Order requirement: 'es' must be declared/initialised before 'sched'. - Opm::EclipseState es; - std::shared_ptr python; - Opm::EclipseGrid grid; - Opm::Schedule sched; - }; + // Order requirement: 'es' must be declared/initialised before 'sched'. + Opm::EclipseState es; + Opm::EclipseGrid grid; + Opm::Schedule sched; +}; // ===================================================================== BOOST_AUTO_TEST_SUITE(Aggregate_ConnData) - // test dimensions of Connection data BOOST_AUTO_TEST_CASE (Constructor) { @@ -559,7 +558,6 @@ BOOST_AUTO_TEST_CASE (Constructor) BOOST_CHECK_EQUAL(amconn.getXConn().size(), ih.nwells * ih.ncwmax * ih.nxconz); } - BOOST_AUTO_TEST_CASE(Declared_Connection_Data) { const auto simCase = SimulationCase {first_sim()}; @@ -730,7 +728,6 @@ BOOST_AUTO_TEST_CASE(Declared_Connection_Data) } } - BOOST_AUTO_TEST_CASE(InactiveCell) { auto simCase = SimulationCase{first_sim()}; const auto rptStep = std::size_t{1}; diff --git a/tests/test_RFT.cpp b/tests/test_RFT.cpp index daea4da47..d1e0d64a1 100644 --- a/tests/test_RFT.cpp +++ b/tests/test_RFT.cpp @@ -291,12 +291,12 @@ BOOST_AUTO_TEST_CASE(test_RFT) std::vector well1_comps(9); for (size_t i = 0; i < 9; ++i) { - Opm::data::Connection well_comp { grid.getGlobalIndex(8,8,i) ,r1, 0.0 , 0.0, (double)i, 0.1*i,0.2*i, 1.2e3}; + Opm::data::Connection well_comp { grid.getGlobalIndex(8,8,i) ,r1, 0.0 , 0.0, (double)i, 0.1*i,0.2*i, 1.2e3, 4.321}; well1_comps[i] = std::move(well_comp); } std::vector well2_comps(6); for (size_t i = 0; i < 6; ++i) { - Opm::data::Connection well_comp { grid.getGlobalIndex(3,3,i+3) ,r2, 0.0 , 0.0, (double)i, i*0.1,i*0.2, 0.15}; + Opm::data::Connection well_comp { grid.getGlobalIndex(3,3,i+3) ,r2, 0.0 , 0.0, (double)i, i*0.1,i*0.2, 0.15, 0.54321}; well2_comps[i] = std::move(well_comp); } @@ -420,12 +420,12 @@ BOOST_AUTO_TEST_CASE(test_RFT2) std::vector well1_comps(9); for (size_t i = 0; i < 9; ++i) { - Opm::data::Connection well_comp { grid.getGlobalIndex(8,8,i) ,r1, 0.0 , 0.0, (double)i, 0.1*i,0.2*i, 3.14e5}; + Opm::data::Connection well_comp { grid.getGlobalIndex(8,8,i) ,r1, 0.0 , 0.0, (double)i, 0.1*i,0.2*i, 3.14e5, 0.1234}; well1_comps[i] = std::move(well_comp); } std::vector well2_comps(6); for (size_t i = 0; i < 6; ++i) { - Opm::data::Connection well_comp { grid.getGlobalIndex(3,3,i+3) ,r2, 0.0 , 0.0, (double)i, i*0.1,i*0.2, 355.113}; + Opm::data::Connection well_comp { grid.getGlobalIndex(3,3,i+3) ,r2, 0.0 , 0.0, (double)i, i*0.1,i*0.2, 355.113, 0.9876}; well2_comps[i] = std::move(well_comp); } @@ -493,6 +493,7 @@ namespace { c.cell_saturation_gas = 0.15; c.cell_saturation_water = 0.3 + con/20.0; + c.trans_factor = 0.98765; } return xcon; @@ -522,6 +523,7 @@ namespace { c.cell_saturation_gas = 0.6 - con/20.0; c.cell_saturation_water = 0.25; + c.trans_factor = 0.12345; } return xcon; diff --git a/tests/test_Restart.cpp b/tests/test_Restart.cpp index 6d7e72e19..a5f5262d0 100644 --- a/tests/test_Restart.cpp +++ b/tests/test_Restart.cpp @@ -174,15 +174,15 @@ data::Wells mkWells() { * the completion keys (active indices) and well names correspond to the * input deck. All other entries in the well structures are arbitrary. */ - w1.connections.push_back( { 88, rc1, 30.45, 123.4, 543.21, 0.62, 0.15, 1.0e3 } ); - w1.connections.push_back( { 288, rc2, 33.19, 123.4, 432.1, 0.26, 0.45, 2.56 } ); + w1.connections.push_back( { 88, rc1, 30.45, 123.4, 543.21, 0.62, 0.15, 1.0e3, 1.234 } ); + w1.connections.push_back( { 288, rc2, 33.19, 123.4, 432.1, 0.26, 0.45, 2.56, 2.345 } ); w2.rates = r2; w2.thp = 2.0; w2.bhp = 2.34; w2.temperature = 4.56; w2.control = 2; - w2.connections.push_back( { 188, rc3, 36.22, 123.4, 256.1, 0.55, 0.0125, 314.15 } ); + w2.connections.push_back( { 188, rc3, 36.22, 123.4, 256.1, 0.55, 0.0125, 314.15, 3.456 } ); { data::Wells wellRates; diff --git a/tests/test_Summary.cpp b/tests/test_Summary.cpp index f8d5ae833..8137a6233 100755 --- a/tests/test_Summary.cpp +++ b/tests/test_Summary.cpp @@ -63,6 +63,12 @@ namespace { return unit::cubic(unit::meter) / unit::day; } + double cp_rm3_per_db() + { + return prefix::centi*unit::Poise * unit::cubic(unit::meter) + / (unit::day * unit::barsa); + } + std::string toupper(std::string input) { for (auto& c : input) { @@ -247,11 +253,12 @@ data::Wells result_wells(const bool w3_injector = true) syncronized with the global index in the COMPDAT keyword in the input deck. */ - data::Connection well1_comp1 { 0 , crates1, 1.9 , 123.4, 314.15, 0.35, 0.25, 2.718e2}; - data::Connection well2_comp1 { 1 , crates2, 1.10 , 123.4, 212.1, 0.78, 0.0, 12.34}; - data::Connection well2_comp2 { 101, crates3, 1.11 , 123.4, 150.6, 0.001, 0.89, 100.0}; - data::Connection well3_comp1 { 2 , crates3, 1.11 , 123.4, 456.78, 0.0, 0.15, 432.1}; - data::Connection well6_comp1 { 5 , crates6, 6.11 , 623.4, 656.78, 0.0, 0.65, 632.1}; + data::Connection well1_comp1 { 0 , crates1, 1.9 , 123.4, 314.15, 0.35 , 0.25, 2.718e2, 111.222*cp_rm3_per_db() }; + data::Connection well2_comp1 { 1 , crates2, 1.10 , 123.4, 212.1 , 0.78 , 0.0 , 12.34 , 222.333*cp_rm3_per_db() }; + data::Connection well2_comp2 { 101, crates3, 1.11 , 123.4, 150.6 , 0.001, 0.89, 100.0 , 333.444*cp_rm3_per_db() }; + data::Connection well3_comp1 { 2 , crates3, 1.11 , 123.4, 456.78, 0.0 , 0.15, 432.1 , 444.555*cp_rm3_per_db() }; + data::Connection well6_comp1 { 5 , crates6, 6.11 , 623.4, 656.78, 0.0 , 0.65, 632.1 , 555.666*cp_rm3_per_db() }; + /* The completions */ @@ -1477,13 +1484,13 @@ BOOST_AUTO_TEST_CASE(BLOCK_VARIABLES) { BOOST_CHECK_CLOSE( 31.0 , units.to_si( UnitSystem::measure::viscosity , ecl_sum_get_general_var( resp, 1, "BVOIL:1,1,1")) , 1e-5); BOOST_CHECK_CLOSE( 33.0 , units.to_si( UnitSystem::measure::viscosity , ecl_sum_get_general_var( resp, 1, "BOVIS:1,1,1")) , 1e-5); - BOOST_CHECK_CLOSE( 100 , ecl_sum_get_well_completion_var( resp, 1, "W_1", "CTFAC", 1, 1, 1), 1e-5); - BOOST_CHECK_CLOSE( 2.1430730819702148 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 1), 1e-5); - BOOST_CHECK_CLOSE( 2.6788413524627686 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 2), 1e-5); - BOOST_CHECK_CLOSE( 2.7855057716369629 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CTFAC", 3, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_completion_var( resp, 1, "W_1", "CTFAC", 1, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 222.333 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 333.444 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 2), 1e-5); + BOOST_CHECK_CLOSE( 444.555 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CTFAC", 3, 1, 1), 1e-5); - BOOST_CHECK_CLOSE( 50 , ecl_sum_get_well_completion_var( resp, 3, "W_1", "CTFAC", 1, 1, 1), 1e-5); - BOOST_CHECK_CLOSE( 25 , ecl_sum_get_well_completion_var( resp, 4, "W_1", "CTFAC", 1, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_completion_var( resp, 3, "W_1", "CTFAC", 1, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_completion_var( resp, 4, "W_1", "CTFAC", 1, 1, 1), 1e-5); // Cell is not active BOOST_CHECK( !ecl_sum_has_general_var( resp , "BPR:2,1,10")); diff --git a/tests/test_Summary_Group.cpp b/tests/test_Summary_Group.cpp index 84f10307f..b3beb3ecc 100644 --- a/tests/test_Summary_Group.cpp +++ b/tests/test_Summary_Group.cpp @@ -169,7 +169,7 @@ static data::Wells result_wells() { syncronized with the global index in the COMPDAT keyword in the input deck. */ - data::Connection well1_comp1 { 0 , crates1, 1.9 , 123.4, 314.15, 0.35, 0.25, 2.718e2}; + data::Connection well1_comp1 { 0 , crates1, 1.9 , 123.4, 314.15, 0.35, 0.25, 2.718e2, 0.12345}; /* The completions diff --git a/tests/test_Wells.cpp b/tests/test_Wells.cpp index 95274a52b..9e47a5c50 100644 --- a/tests/test_Wells.cpp +++ b/tests/test_Wells.cpp @@ -103,14 +103,14 @@ BOOST_AUTO_TEST_CASE(get_completions) { * the completion keys (active indices) and well names correspond to the * input deck. All other entries in the well structures are arbitrary. */ - w1.connections.push_back( { 88, rc1, 30.45, 123.45, 543.21, 0.123, 0.5, 17.29 } ); - w1.connections.push_back( { 288, rc2, 33.19, 67.89, 98.76, 0.5, 0.125, 355.113 } ); + w1.connections.push_back( { 88, rc1, 30.45, 123.45, 543.21, 0.123, 0.5, 17.29, 0.1729 } ); + w1.connections.push_back( { 288, rc2, 33.19, 67.89, 98.76, 0.5, 0.125, 355.113, 0.355113 } ); w2.rates = r2; w2.bhp = 2.34; w2.temperature = 4.56; w2.control = 2; - w2.connections.push_back( { 188, rc3, 36.22, 19.28, 28.91, 0.125, 0.125, 3.141 } ); + w2.connections.push_back( { 188, rc3, 36.22, 19.28, 28.91, 0.125, 0.125, 3.141, 0.31415 } ); data::Wells wellRates;