From 372b7e86a4ba55d6f41889781d0b2487ad76ef8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20H=C3=A6gland?= Date: Wed, 10 Nov 2021 09:33:46 +0100 Subject: [PATCH 1/3] Support for adding keywords to schedule from Python. Adds support for adding keywords to the SCHEDULE section of the deck after the deck has been read from file from Python. --- .../EclipseState/Schedule/Schedule.hpp | 1 + python/cxx/deck.cpp | 2 +- python/cxx/schedule.cpp | 43 +++++++++++++++++-- .../EclipseState/Schedule/Schedule.cpp | 39 +++++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index 536dbe6ce..3ad549554 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -301,6 +301,7 @@ namespace Opm for the schedule instances created by loading a restart file. */ static bool cmp(const Schedule& sched1, const Schedule& sched2, std::size_t report_step); + void applyKeywords(std::vector& keywords, std::size_t timeStep); template void serializeOp(Serializer& serializer) diff --git a/python/cxx/deck.cpp b/python/cxx/deck.cpp index 98348a95f..ea7330e90 100644 --- a/python/cxx/deck.cpp +++ b/python/cxx/deck.cpp @@ -45,7 +45,7 @@ namespace { void python::common::export_Deck(py::module &module) { - // Note: In the below class we std::shared_ptr as the holder type, see: + // Note: In the below class we use std::shared_ptr as the holder type, see: // // https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html // diff --git a/python/cxx/schedule.cpp b/python/cxx/schedule.cpp index a8914087a..c14070d8c 100644 --- a/python/cxx/schedule.cpp +++ b/python/cxx/schedule.cpp @@ -1,7 +1,9 @@ #include #include +#include #include +#include #include @@ -92,13 +94,38 @@ namespace { return sch[index]; } + void insert_keywords( + Schedule& sch, + const std::string& deck_string, + std::size_t index, + const UnitSystem& unit_system + ) + { + Parser parser; + std::string str {unit_system.deck_name() + "\n\n" + deck_string}; + auto deck = parser.parseString(str); + std::vector keywords; + for (auto &keyword : deck) { + keywords.push_back(&keyword); + } + sch.applyKeywords(keywords, index); + } + + void insert_keywords( + Schedule& sch, py::list& deck_keywords, std::size_t index) + { + Parser parser; + std::vector keywords; + for (py::handle item : deck_keywords) { + DeckKeyword &keyword = item.cast(); + keywords.push_back(&keyword); + } + sch.applyKeywords(keywords, index); + } } - - - void python::common::export_Schedule(py::module& module) { @@ -107,7 +134,7 @@ void python::common::export_Schedule(py::module& module) { .def("group", &get_group, ref_internal); - // Note: In the below class we std::shared_ptr as the holder type, see: + // Note: In the below class we use std::shared_ptr as the holder type, see: // // https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html // @@ -128,6 +155,14 @@ void python::common::export_Schedule(py::module& module) { .def( "get_wells", &Schedule::getWells) .def("well_names", py::overload_cast(&Schedule::wellNames, py::const_)) .def( "get_well", &get_well) + .def( "insert_keywords", + py::overload_cast(&insert_keywords), + py::arg("keywords"), py::arg("step")) + .def( "insert_keywords", + py::overload_cast< + Schedule&, const std::string&, std::size_t, const UnitSystem& + >(&insert_keywords), + py::arg("data"), py::arg("step"), py::arg("unit_system")) .def( "__contains__", &has_well ); } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index ab56730ee..649d37395 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -1273,6 +1273,45 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e return std::chrono::duration_cast(elapsed).count(); } + void Schedule::applyKeywords( + std::vector& keywords, std::size_t reportStep) { + ParseContext parseContext; + ErrorGuard errors; + ScheduleGrid grid(this->completed_cells); + std::unordered_set affected_wells; + std::unordered_map target_wellpi; + std::vector matching_wells; + const std::string prefix = "| "; /* logger prefix string */ + this->snapshots.resize(reportStep + 1); + auto& input_block = this->m_sched_deck[reportStep]; + for (auto keyword : keywords) { + input_block.push_back(*keyword); + this->handleKeyword(reportStep, + input_block, + *keyword, + parseContext, + errors, + grid, + /*FieldPropsManager *fp=*/nullptr, + matching_wells, + /*actionx_mode=*/false, + &affected_wells, + &target_wellpi); + } + this->end_report(reportStep); + if (reportStep < this->m_sched_deck.size() - 1) { + iterateScheduleSection( + reportStep + 1, + this->m_sched_deck.size(), + parseContext, + errors, + grid, + &target_wellpi, + /*FieldPropsManager *fp=*/nullptr, + prefix); + } + } + SimulatorUpdate Schedule::applyAction(std::size_t reportStep, const time_point&, const Action::ActionX& action, const Action::Result& result, const std::unordered_map& target_wellpi) { const std::string prefix = "| "; From 928a33d2eae38318032c12c70515e54366dff76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20H=C3=A6gland?= Date: Fri, 12 Nov 2021 23:12:54 +0100 Subject: [PATCH 2/3] Add comment about insert_keywords() Add comment explaining that one of the insert_keywords() overloads does not work yet. --- python/cxx/schedule.cpp | 4 ++++ src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/python/cxx/schedule.cpp b/python/cxx/schedule.cpp index c14070d8c..8c23f7029 100644 --- a/python/cxx/schedule.cpp +++ b/python/cxx/schedule.cpp @@ -111,6 +111,10 @@ namespace { sch.applyKeywords(keywords, index); } + // NOTE: this overload does currently not work, see PR #2833. The plan + // is to fix this in a later commit. For now, the overload insert_keywords() + // above taking a deck_string (std::string) instead of a list of DeckKeywords + // has to be used instead. void insert_keywords( Schedule& sch, py::list& deck_keywords, std::size_t index) { diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 649d37395..3ce5aef38 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -1278,7 +1278,7 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e ParseContext parseContext; ErrorGuard errors; ScheduleGrid grid(this->completed_cells); - std::unordered_set affected_wells; + SimulatorUpdate sim_update; std::unordered_map target_wellpi; std::vector matching_wells; const std::string prefix = "| "; /* logger prefix string */ @@ -1295,7 +1295,7 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e /*FieldPropsManager *fp=*/nullptr, matching_wells, /*actionx_mode=*/false, - &affected_wells, + &sim_update, &target_wellpi); } this->end_report(reportStep); From 07f11585aa3dc7782fb91bbd132363567eb0b0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20H=C3=A6gland?= Date: Sun, 14 Nov 2021 13:52:35 +0100 Subject: [PATCH 3/3] Fix rebase error. --- src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 3ce5aef38..570356dc1 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -1292,7 +1292,6 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e parseContext, errors, grid, - /*FieldPropsManager *fp=*/nullptr, matching_wells, /*actionx_mode=*/false, &sim_update, @@ -1307,7 +1306,6 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e errors, grid, &target_wellpi, - /*FieldPropsManager *fp=*/nullptr, prefix); } }