From 882ce83e910c3de42250ec3345e3f39a93785a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 19 Sep 2019 23:50:41 +0200 Subject: [PATCH] Schedule: Add Query For Particular Group at Particular Time This commit adds a new query method, bool Schedule::hasGroup(groupName, timeStep) which report whether or not a particular named group exists at a particular time step (zero-based report step index). If this function returns 'true', then it is always safe to call Schedule::getGroup2(groupName, timeStep) with the same arguments. Otherwise, the latter will throw an exception. The new 'hasGroup' overload thus enables the same query types as the existing 'hasWell' overload set. The immediate use case for this new overload is a reworking of the system for evaluating derived summary parameters (e.g., FOPT or GGLR). Add a new unit test to exercise the new overload. --- .../EclipseState/Schedule/Schedule.hpp | 1 + .../EclipseState/Schedule/Schedule.cpp | 9 +++ tests/parser/ScheduleTests.cpp | 79 +++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index a22aa5a14..4a4f2434f 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -190,6 +190,7 @@ namespace Opm size_t numGroups() const; size_t numGroups(size_t timeStep) const; bool hasGroup(const std::string& groupName) const; + bool hasGroup(const std::string& groupName, std::size_t timeStep) const; const Group2& getGroup2(const std::string& groupName, size_t timeStep) const; const Tuning& getTuning() const; diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 09d48aec6..ac8c42ff8 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -2369,6 +2369,15 @@ void Schedule::handleGRUPTREE( const DeckKeyword& keyword, size_t currentStep, c return groups.count(groupName) > 0; } + bool Schedule::hasGroup(const std::string& groupName, std::size_t timeStep) const { + if (timeStep >= this->size()) + return false; + + auto grpMap = this->groups.find(groupName); + + return (grpMap != this->groups.end()) + && grpMap->second.at(timeStep); + } void Schedule::addGroupToGroup( const std::string& parent_group, const Group2& child_group, size_t timeStep) { // Add to new parent diff --git a/tests/parser/ScheduleTests.cpp b/tests/parser/ScheduleTests.cpp index 0977398f0..66f877450 100644 --- a/tests/parser/ScheduleTests.cpp +++ b/tests/parser/ScheduleTests.cpp @@ -526,6 +526,85 @@ BOOST_AUTO_TEST_CASE(EmptyScheduleHasFIELDGroup) { BOOST_CHECK_THROW( schedule.getGroup2("GROUP", 0) , std::invalid_argument ); } +BOOST_AUTO_TEST_CASE(HasGroup_At_Time) { + const auto input = std::string { R"( +RUNSPEC +DIMENS + 5 5 5 / +OIL +WATER +TABDIMS +/ +WELLDIMS + 2 10 3 2 / +GRID +DXV + 5*100 / +DYV + 5*100 / +DZV + 5*5 / +TOPS + 25*2500 / +PERMX + 125*500 / +COPY + 'PERMX' 'PERMY' / + 'PERMX' 'PERMZ' / +/ +MULTIPLY + 'PERMZ' 0.1 / +/ +PROPS +SWOF +0 0 1 0 +1 1 0 0 / +SCHEDULE +WELSPECS +-- Group 'P' exists from the first report step + 'P1' 'P' 1 1 2502.5 'OIL' / +/ +WCONPROD + 'P1' 'OPEN' 'ORAT' 123.4 4* 50.0 / +/ +TSTEP + 10 20 30 40 / +WELSPECS +-- Group 'I' does not exist before now (report step 4, zero-based = 3) + 'I1' 'I' 5 5 2522.5 'WATER' / +/ +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 200 1* 450.0 / +/ +TSTEP + 50 50 / +END +)" + }; + + const auto deck = ::Opm::Parser{}.parseString(input); + const auto es = ::Opm::EclipseState{deck}; + const auto sched = ::Opm::Schedule{ deck, es }; + + BOOST_CHECK_MESSAGE(sched.hasGroup("P"), R"(Group "P" Must Exist)"); + BOOST_CHECK_MESSAGE(sched.hasGroup("I"), R"(Group "I" Must Exist)"); + + BOOST_CHECK_MESSAGE( sched.hasGroup("P", 3), R"(Group "P" Must Exist at Report Step 3)"); + BOOST_CHECK_MESSAGE(! sched.hasGroup("I", 3), R"(Group "I" Must NOT Exist at Report Step 3)"); + BOOST_CHECK_MESSAGE( sched.hasGroup("I", 4), R"(Group "I" Must Exist at Report Step 4)"); + + BOOST_CHECK_MESSAGE(sched.hasGroup("P", 6), R"(Group "P" Must Exist At Last Report Step)"); + BOOST_CHECK_MESSAGE(sched.hasGroup("I", 6), R"(Group "I" Must Exist At Last Report Step)"); + + BOOST_CHECK_MESSAGE(! sched.hasGroup("P", 7), R"(Group "P" Must NOT Exist Immediately After Last Report Step)"); + BOOST_CHECK_MESSAGE(! sched.hasGroup("I", 7), R"(Group "I" Must NOT Exist Immediately After Last Report Step)"); + + BOOST_CHECK_MESSAGE(! sched.hasGroup("P", 1729), R"(Group "P" Must NOT Exist Long After Last Report Step)"); + BOOST_CHECK_MESSAGE(! sched.hasGroup("I", 1729), R"(Group "I" Must NOT Exist Long After Last Report Step)"); + + BOOST_CHECK_THROW(const auto& grp = sched.getGroup2("I", 3), std::invalid_argument); +} + BOOST_AUTO_TEST_CASE(WellsIterator_Empty_EmptyVectorReturned) { EclipseGrid grid(10,10,10); auto deck = createDeck();