From 2193118a5cb17241eda3294a83bcf1b28f717445 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Mon, 2 Dec 2019 11:12:17 +0100 Subject: [PATCH] Make sure well is closed if all connections are closed for ACTIONX --- .../EclipseState/Schedule/Well/Well.hpp | 2 +- .../EclipseState/Schedule/Schedule.cpp | 3 +- .../EclipseState/Schedule/Well/Well.cpp | 22 ++++++++- tests/msim/actionx1.include | 2 +- tests/parser/WellTests.cpp | 46 +++++++++++++++++++ 5 files changed, 71 insertions(+), 4 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp b/opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp index a7aa711aa..f033c2c55 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp @@ -425,7 +425,7 @@ public: bool handleWELSEGS(const DeckKeyword& keyword); bool handleCOMPSEGS(const DeckKeyword& keyword, const EclipseGrid& grid, const ParseContext& parseContext, ErrorGuard& errors); - bool handleWELOPEN(const DeckRecord& record, Connection::State status); + bool handleWELOPEN(const DeckRecord& record, Connection::State status, bool action_mode); bool handleCOMPLUMP(const DeckRecord& record); bool handleWPIMULT(const DeckRecord& record); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 2329af038..e43c4006c 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -1358,6 +1358,7 @@ namespace { }; constexpr auto open = Well::Status::OPEN; + bool action_mode = !matching_wells.empty(); for( const auto& record : keyword ) { const auto& wellNamePattern = record.getItem( "WELL" ).getTrimmedString(0); @@ -1399,7 +1400,7 @@ namespace { { auto& dynamic_state = this->wells_static.at(wname); auto well_ptr = std::make_shared( *dynamic_state[currentStep] ); - if (well_ptr->handleWELOPEN(record, comp_status)) { + if (well_ptr->handleWELOPEN(record, comp_status, action_mode)) { // The updateWell call breaks test at line 825 and 831 in ScheduleTests this->updateWell(well_ptr, currentStep); const auto well_status = Well::StatusFromString( status_str ); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp index fa70ceff8..31f6b7a4c 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp @@ -528,7 +528,22 @@ Phase Well::getPreferredPhase() const { return this->phase; } -bool Well::handleWELOPEN(const DeckRecord& record, Connection::State state_arg) { +/* + When all connections of a well are closed with the WELOPEN keywords, the well + itself should also be SHUT. In the main parsing code this is handled by the + function checkIfAllConnectionsIsShut() which is called at the end of every + report step in Schedule::iterateScheduleSection(). This is donn in this way + because there is some twisted logic aggregating connection changes over a + complete report step. + + However - when the WELOPEN is called as a ACTIONX action the full + Schedule::iterateScheduleSection() is not run and the check if all connections + is closed is not done. Therefor we have a action_mode flag here which makes + sure to close the well in this case. +*/ + + +bool Well::handleWELOPEN(const DeckRecord& record, Connection::State state_arg, bool action_mode) { auto match = [=]( const Connection &c) -> bool { if (!match_eq(c.getI(), record, "I" , -1)) return false; @@ -548,6 +563,11 @@ bool Well::handleWELOPEN(const DeckRecord& record, Connection::State state_arg) new_connections->add(c); } + if (action_mode) { + if (new_connections->allConnectionsShut()) + this->status = Status::SHUT; + } + return this->updateConnections(new_connections); } diff --git a/tests/msim/actionx1.include b/tests/msim/actionx1.include index c6c75f74d..5be8ad39f 100644 --- a/tests/msim/actionx1.include +++ b/tests/msim/actionx1.include @@ -423,7 +423,7 @@ ACTIONX / WELOPEN - '?' 'SHUT' / + '?' 'SHUT' 0 0 0 2* / / ENDACTIO diff --git a/tests/parser/WellTests.cpp b/tests/parser/WellTests.cpp index 21ddbc6fe..7d68f37ab 100644 --- a/tests/parser/WellTests.cpp +++ b/tests/parser/WellTests.cpp @@ -797,3 +797,49 @@ BOOST_AUTO_TEST_CASE(ExtraAccessors) { BOOST_CHECK_EQUAL(inj.vfp_table_number(), 100); BOOST_CHECK_EQUAL(prod.vfp_table_number(), 200); } + +BOOST_AUTO_TEST_CASE(WELOPEN) { + Opm::Parser parser; + std::string input = + "START -- 0 \n" + "19 JUN 2007 / \n" + "SCHEDULE\n" + "DATES -- 1\n" + " 10 OKT 2008 / \n" + "/\n" + "WELSPECS\n" + " 'OP_1' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n" + "/\n" + "COMPDAT\n" + " 'OP_1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n" + " 'OP_1' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n" + " 'OP_1' 9 9 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 / \n" + "/\n" + "WELOPEN \n" + " 'OP_1' 'OPEN' /\n" + "/\n" + "DATES -- 2\n" + " 20 JAN 2010 / \n" + "/\n" + "WELOPEN \n" + " 'OP_1' 'SHUT' 0 0 0 2* /\n" + "/\n"; + + + auto deck = parser.parseString(input); + Opm::EclipseGrid grid(10,10,10); + TableManager table ( deck ); + Eclipse3DProperties eclipseProperties ( deck , table, grid); + FieldPropsManager fp(deck, grid, table); + Opm::Runspec runspec (deck); + Opm::Schedule schedule(deck, grid , fp, eclipseProperties, runspec); + { + const auto& op_1 = schedule.getWell("OP_1", 1); + BOOST_CHECK(op_1.getStatus() == Well::Status::OPEN); + } + { + const auto& op_1 = schedule.getWell("OP_1", 2); + BOOST_CHECK(op_1.getStatus() == Well::Status::SHUT); + } + +}