From c157760ac759dd910805b31ab50ce5e8aacaf11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 11 Nov 2020 15:17:06 +0100 Subject: [PATCH] CxL: Account for Dynamically Changing Set of Connections This commit adds a new helper function getCompletionNumberFromGlobalConnectionIndex which returns an optional containing the completion number of the connection with the associated global cell index, or nullopt if no such connection exists. We then reimplement the CxL summary keywords in terms of this function to handle connections being added dynamically during the simulation. The connections at the end of the simulation, from which we configure all connection-related summary nodes, might not accurately reflect the connections existing at all times during the simulation. --- .../Schedule/Well/WellConnections.hpp | 5 ++ src/opm/output/eclipse/Summary.cpp | 8 +- .../Schedule/Well/WellConnections.cpp | 16 ++++ tests/parser/ConnectionTests.cpp | 84 +++++++++++++++++++ 4 files changed, 111 insertions(+), 2 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp b/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp index 974c47e81..2147dcf2b 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -163,6 +164,10 @@ namespace Opm { int headI, headJ; std::vector< Connection > m_connections; }; + + std::optional + getCompletionNumberFromGlobalConnectionIndex(const WellConnections& connections, + const std::size_t global_index); } diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index ff301b583..e8a931081 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -579,9 +579,13 @@ inline quantity cratel( const fn_args& args ) { const auto& well_data = args.wells.at( name ); if (well_data.current_control.isProducer == injection) return zero; + const auto complnum = getCompletionNumberFromGlobalConnectionIndex(well.getConnections(), args.num - 1); + if (!complnum.has_value()) + // Connection might not yet have come online. + return zero; + double sum = 0; - const auto& conn0 = well.getConnections().getFromGlobalIndex( args.num - 1); - const auto& connections = well.getConnections(conn0.complnum()) ; + const auto& connections = well.getConnections(*complnum); for (const auto& conn_ptr : connections) { const size_t global_index = conn_ptr->global_index(); const auto& conn_data = std::find_if(well_data.connections.begin(), diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp index 001682d48..35554f8ec 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp @@ -633,4 +633,20 @@ inline std::array< size_t, 3> directionIndices(const Opm::Connection::Direction } + std::optional + getCompletionNumberFromGlobalConnectionIndex(const WellConnections& connections, + const std::size_t global_index) + { + auto connPos = std::find_if(connections.begin(), connections.end(), + [global_index](const Connection& conn) + { + return conn.global_index() == global_index; + }); + + if (connPos == connections.end()) + // No connection exists with the requisite 'global_index' + return {}; + + return { connPos->complnum() }; + } } diff --git a/tests/parser/ConnectionTests.cpp b/tests/parser/ConnectionTests.cpp index 65f5ff795..3df6d7b9d 100644 --- a/tests/parser/ConnectionTests.cpp +++ b/tests/parser/ConnectionTests.cpp @@ -518,3 +518,87 @@ END BOOST_CHECK_CLOSE(connP[2].CF(), 50.0*cp_rm3_per_db(), 1.0e-10); } } + +BOOST_AUTO_TEST_CASE(Completion_From_Global_Connection_Index) { + const auto deck = Opm::Parser{}.parseString(R"(RUNSPEC +START +7 OCT 2020 / + +DIMENS + 10 10 3 / + +GRID +DXV + 10*100.0 / +DYV + 10*100.0 / +DZV + 3*10.0 / + +DEPTHZ + 121*2000.0 / + +PERMX + 300*100.0 / +PERMY + 300*100.0 / +PERMZ + 300*10.0 / +PORO + 300*0.3 / + +SCHEDULE +WELSPECS + 'P' 'G' 10 10 2005 'LIQ' / +/ +COMPDAT + 'P' 0 0 1 1 OPEN 1 100 / +/ + +TSTEP + 10 +/ + +COMPDAT + 'P' 0 0 2 2 OPEN 1 50 / +/ + +TSTEP + 10 +/ + +END +)"); + + const auto es = Opm::EclipseState{ deck }; + const auto sched = Opm::Schedule{ deck, es }; + + { + const auto connP = sched.getWell("P", 0).getConnections(); + + const auto complnum_100 = + getCompletionNumberFromGlobalConnectionIndex(connP, 100 - 1); + const auto complnum_200 = + getCompletionNumberFromGlobalConnectionIndex(connP, 200 - 1); + + BOOST_CHECK_MESSAGE( complnum_100.has_value(), "Completion number must be defined at time 0 for connection in cell (10,10,1)"); + BOOST_CHECK_MESSAGE(! complnum_200.has_value(), "Completion number must NOT be defined at time 0 for connection in cell (10,10,2)"); + + BOOST_CHECK_EQUAL(complnum_100.value(), 1); + } + + { + const auto connP = sched.getWell("P", 1).getConnections(); + + const auto complnum_100 = + getCompletionNumberFromGlobalConnectionIndex(connP, 100 - 1); + const auto complnum_200 = + getCompletionNumberFromGlobalConnectionIndex(connP, 200 - 1); + + BOOST_CHECK_MESSAGE(complnum_100.has_value(), "Completion number must be defined at time 0 for connection in cell (10,10,1)"); + BOOST_CHECK_MESSAGE(complnum_200.has_value(), "Completion number must be defined at time 0 for connection in cell (10,10,2)"); + + BOOST_CHECK_EQUAL(complnum_100.value(), 1); + BOOST_CHECK_EQUAL(complnum_200.value(), 2); + } +}