From 278c2182bda7537f9455e2fad4a6f843f81b3408 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Fri, 13 Nov 2020 17:46:29 +0100 Subject: [PATCH] Handle WELPI keyword in ACTIONX blocks --- .../EclipseState/Schedule/Schedule.hpp | 1 + .../EclipseState/Schedule/Action/ActionX.cpp | 2 +- .../EclipseState/Schedule/KeywordHandlers.cpp | 22 ++++---- .../EclipseState/Schedule/Schedule.cpp | 15 +++--- tests/parser/ACTIONX.cpp | 51 +++++++++++++++++++ 5 files changed, 75 insertions(+), 16 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index 936859ebc..50a7d2628 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -503,6 +503,7 @@ namespace Opm void handleGCONPROD(const DeckKeyword& keyword, std::size_t current_step, const ParseContext& parseContext, ErrorGuard& errors); void handleGCONINJE(const DeckKeyword& keyword, std::size_t current_step, const ParseContext& parseContext, ErrorGuard& errors); void handleGLIFTOPT(const DeckKeyword& keyword, std::size_t report_step, const ParseContext& parseContext, ErrorGuard& errors); + void handleWELPI (const DeckKeyword& keyword, std::size_t report_step, const ParseContext& parseContext, ErrorGuard& errors); // Normal keyword handlers -- in KeywordHandlers.cpp void handleBRANPROP (const HandlerContext&, const ParseContext&, ErrorGuard&); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.cpp index 719f5ece0..08245de12 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.cpp @@ -33,7 +33,7 @@ namespace Action { bool ActionX::valid_keyword(const std::string& keyword) { - static std::unordered_set actionx_allowed_list = {"EXIT", "GCONINJE", "GCONPROD", "GLIFTOPT", "WELSPECS","WELOPEN", "UDQ"}; + static std::unordered_set actionx_allowed_list = {"EXIT", "GCONINJE", "GCONPROD", "GLIFTOPT", "WELSPECS","WELOPEN", "WELPI", "UDQ"}; return (actionx_allowed_list.find(keyword) != actionx_allowed_list.end()); } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp index fd3d14380..35aa4fa86 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp @@ -1101,10 +1101,14 @@ namespace { } void Schedule::handleWELOPEN (const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) { - return applyWELOPEN(handlerContext.keyword, handlerContext.currentStep, parseContext, errors); + this->applyWELOPEN(handlerContext.keyword, handlerContext.currentStep, parseContext, errors); } void Schedule::handleWELPI(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) { + this->handleWELPI(handlerContext.keyword, handlerContext.currentStep, parseContext, errors); + } + + void Schedule::handleWELPI(const DeckKeyword& keyword, std::size_t report_step, const ParseContext& parseContext, ErrorGuard& errors) { // Keyword structure // // WELPI @@ -1118,18 +1122,18 @@ namespace { using WELL_NAME = ParserKeywords::WELPI::WELL_NAME; using PI = ParserKeywords::WELPI::STEADY_STATE_PRODUCTIVITY_OR_INJECTIVITY_INDEX_VALUE; - for (const auto& record : handlerContext.keyword) { + for (const auto& record : keyword) { const auto well_names = this->wellNames(record.getItem().getTrimmedString(0), - handlerContext.currentStep); + report_step); if (well_names.empty()) this->invalidNamePattern(record.getItem().getTrimmedString(0), - handlerContext.currentStep, parseContext, - errors, handlerContext.keyword); + report_step, parseContext, + errors, keyword); const auto rawProdIndex = record.getItem().get(0); for (const auto& well_name : well_names) { - auto well2 = std::make_shared(this->getWell(well_name, handlerContext.currentStep)); + auto well2 = std::make_shared(this->getWell(well_name, report_step)); // Note: Need to ensure we have an independent copy of // well's connections because @@ -1138,13 +1142,13 @@ namespace { auto connections = std::make_shared(well2->getConnections()); well2->forceUpdateConnections(std::move(connections)); if (well2->updateWellProductivityIndex(rawProdIndex)) - this->updateWell(std::move(well2), handlerContext.currentStep); + this->updateWell(std::move(well2), report_step); - this->addWellGroupEvent(well_name, ScheduleEvents::WELL_PRODUCTIVITY_INDEX, handlerContext.currentStep); + this->addWellGroupEvent(well_name, ScheduleEvents::WELL_PRODUCTIVITY_INDEX, report_step); } } - this->m_events.addEvent(ScheduleEvents::WELL_PRODUCTIVITY_INDEX, handlerContext.currentStep); + this->m_events.addEvent(ScheduleEvents::WELL_PRODUCTIVITY_INDEX, report_step); } void Schedule::handleWELSEGS(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) { diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 9a02f2448..4ba14e35b 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -1506,15 +1506,9 @@ private: if (!Action::ActionX::valid_keyword(keyword.name())) throw std::invalid_argument("The keyword: " + keyword.name() + " can not be handled in the ACTION body"); - if (keyword.name() == "WELOPEN") - this->applyWELOPEN(keyword, reportStep, parseContext, errors, result.wells()); - if (keyword.name() == "EXIT") this->applyEXIT(keyword, reportStep); - if (keyword.name() == "UDQ") - this->updateUDQ(keyword, reportStep); - if (keyword.name() == "GCONINJE") this->handleGCONINJE(keyword, reportStep, parseContext, errors); @@ -1523,6 +1517,15 @@ private: if (keyword.name() == "GLIFTOPT") this->handleGLIFTOPT(keyword, reportStep, parseContext, errors); + + if (keyword.name() == "UDQ") + this->updateUDQ(keyword, reportStep); + + if (keyword.name() == "WELOPEN") + this->applyWELOPEN(keyword, reportStep, parseContext, errors, result.wells()); + + if (keyword.name() == "WELPI") + this->handleWELPI(keyword, reportStep, parseContext, errors); } } diff --git a/tests/parser/ACTIONX.cpp b/tests/parser/ACTIONX.cpp index 11a24ec9e..7b5b5c6fc 100644 --- a/tests/parser/ACTIONX.cpp +++ b/tests/parser/ACTIONX.cpp @@ -1056,3 +1056,54 @@ TSTEP } } + +BOOST_AUTO_TEST_CASE(Action_WELPI) { + const auto deck_string = std::string{ R"( +SCHEDULE + + +WELSPECS + 'PROD1' 'G1' 1 1 10 'OIL' / +/ + +COMPDAT + 'PROD1' 1 1 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / +/ + +ACTIONX +'A' / +WWCT 'OPX' > 0.75 AND / +FPR < 100 / +/ + +WELPI + 'PROD1' 1000 / +/ + +ENDACTIO + +TSTEP +10 / + + )"}; + + const auto st = SummaryState{ std::chrono::system_clock::now() }; + Schedule sched = make_schedule(deck_string); + const auto& action1 = sched.actions(0).get("A"); + { + const auto& well = sched.getWell("PROD1", 0); + BOOST_CHECK_EQUAL( well.getWellPIScalingFactor(1.0), 1.0); + } + + Action::Result action_result(true); + sched.applyAction(0, action1, action_result); + { + auto unit_system = UnitSystem::newMETRIC(); + const auto& well = sched.getWell("PROD1", 0); + const auto PI = unit_system.to_si(UnitSystem::measure::liquid_productivity_index, 1.0); + const auto scaling = well.getWellPIScalingFactor(PI); + BOOST_CHECK_CLOSE(scaling, 1000.0, 1.0e-10); + } +} + +