diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index eb7cc0f43..b8e13e2c1 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ namespace Opm { createTimeMap(deck); m_tuning.reset(new Tuning(m_timeMap)); m_events.reset(new Events(m_timeMap)); + m_modifierDeck.reset( new DynamicVector >( m_timeMap , std::shared_ptr( 0 ) )); addGroup( "FIELD", 0 ); initRootGroupTreeNode(getTimeMap()); initOilVaporization(getTimeMap()); @@ -86,21 +88,29 @@ namespace Opm { } void Schedule::iterateScheduleSection(const ParseMode& parseMode , std::shared_ptr section, IOConfigPtr ioConfig) { + /* + geoModifiers is a list of geo modifiers which can be found in the schedule + section. This is only partly supported, support is indicated by the bool + value. The keywords which are supported will be assembled in a per-timestep + 'minideck', whereas ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER will be + consulted for the others. + */ + const std::map geoModifiers = {{"MULTFLT" , true}, - {"MULTPV" , true}, - {"MULTX" , true}, - {"MULTX-" , true}, - {"MULTY" , true}, - {"MULTY-" , true}, - {"MULTZ" , true}, - {"MULTZ-" , true}, - {"MULTREGT" , true}, - {"MULTR" , true}, - {"MULTR-" , true}, - {"MULTSIG" , true}, - {"MULTSIGV" , true}, - {"MULTTHT" , true}, - {"MULTTHT-" , true}}; + {"MULTPV" , false}, + {"MULTX" , false}, + {"MULTX-" , false}, + {"MULTY" , false}, + {"MULTY-" , false}, + {"MULTZ" , false}, + {"MULTZ-" , false}, + {"MULTREGT" , false}, + {"MULTR" , false}, + {"MULTR-" , false}, + {"MULTSIG" , false}, + {"MULTSIGV" , false}, + {"MULTTHT" , false}, + {"MULTTHT-" , false}}; size_t currentStep = 0; std::vector > rftProperties; @@ -197,13 +207,25 @@ namespace Opm { if (geoModifiers.find( keyword->name() ) != geoModifiers.end()) { - { + bool supported = geoModifiers.at( keyword->name() ); + if (supported) { + /* + If the deck stored at currentStep is a null pointer (i.e. evaluates + to false) we must first create a new deck and install that under + index currentstep; then we fetch the deck (newly created - or old) + from the container and add the keyword. + */ + if (!m_modifierDeck->iget(currentStep)) + m_modifierDeck->iset( currentStep , std::make_shared( )); + { + const std::shared_ptr deck = m_modifierDeck->iget( currentStep ); + deck->addKeyword( keyword ); + } + m_events->addEvent( ScheduleEvents::GEO_MODIFIER , currentStep); + } else { std::string msg = "OPM does not support grid property modifier " + keyword->name() + " in the Schedule section. Error at report: " + std::to_string( currentStep ); parseMode.handleError( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg ); } - { - m_events->addEvent( ScheduleEvents::GEO_MODIFIER , currentStep); - } } } @@ -1562,6 +1584,11 @@ namespace Opm { return m_tuning; } + std::shared_ptr Schedule::getModifierDeck(size_t timeStep) const { + return m_modifierDeck->iget( timeStep ); + } + + const Events& Schedule::getEvents() const { return *m_events; } diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index c3a93c7ae..172f79396 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -71,7 +71,7 @@ namespace Opm bool initOnly() const; const Events& getEvents() const; bool hasOilVaporizationProperties(); - + std::shared_ptr getModifierDeck(size_t timeStep) const; @@ -83,6 +83,7 @@ namespace Opm std::shared_ptr > m_rootGroupTree; std::shared_ptr > m_oilvaporizationproperties; std::shared_ptr m_events; + std::shared_ptr > > m_modifierDeck; TuningPtr m_tuning; bool nosim; diff --git a/opm/parser/eclipse/EclipseState/Schedule/tests/GeomodifierTests.cpp b/opm/parser/eclipse/EclipseState/Schedule/tests/GeomodifierTests.cpp index a6e88ac51..d5e095e5f 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/tests/GeomodifierTests.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/tests/GeomodifierTests.cpp @@ -49,6 +49,9 @@ BOOST_AUTO_TEST_CASE( CheckUnsoppertedInSCHEDULE ) { "MULTFLT\n" " 'F1' 100 /\n" "/\n" + "MULTFLT\n" + " 'F2' 77 /\n" + "/\n" "TSTEP -- 3,4\n" " 10 10/\n" "\n"; @@ -67,5 +70,27 @@ BOOST_AUTO_TEST_CASE( CheckUnsoppertedInSCHEDULE ) { BOOST_CHECK_EQUAL( false , events.hasEvent( ScheduleEvents::GEO_MODIFIER , 1 )); BOOST_CHECK_EQUAL( true , events.hasEvent( ScheduleEvents::GEO_MODIFIER , 2 )); BOOST_CHECK_EQUAL( false , events.hasEvent( ScheduleEvents::GEO_MODIFIER , 3 )); + + + BOOST_CHECK( !schedule.getModifierDeck(1) ); + BOOST_CHECK( !schedule.getModifierDeck(3) ); + + std::shared_ptr multflt_deck = schedule.getModifierDeck(2); + BOOST_CHECK_EQUAL( 2U , multflt_deck->size()); + BOOST_CHECK( multflt_deck->hasKeyword() ); + + auto multflt1 = multflt_deck->getKeyword(0); + BOOST_CHECK_EQUAL( 1U , multflt1->size( ) ); + + auto record0 = multflt1->getRecord( 0 ); + BOOST_CHECK_EQUAL( 100.0 , record0->getItem()->getRawDouble(0)); + BOOST_CHECK_EQUAL( "F1" , record0->getItem()->getString(0)); + + auto multflt2 = multflt_deck->getKeyword(1); + BOOST_CHECK_EQUAL( 1U , multflt2->size( ) ); + + auto record1 = multflt2->getRecord( 0 ); + BOOST_CHECK_EQUAL( 77.0 , record1->getItem()->getRawDouble(0)); + BOOST_CHECK_EQUAL( "F2" , record1->getItem()->getString(0)); } } diff --git a/opm/parser/eclipse/Parser/tests/ParseModeTests.cpp b/opm/parser/eclipse/Parser/tests/ParseModeTests.cpp index e9dc22726..33002679b 100644 --- a/opm/parser/eclipse/Parser/tests/ParseModeTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParseModeTests.cpp @@ -104,7 +104,18 @@ BOOST_AUTO_TEST_CASE( CheckMissingSizeKeyword) { BOOST_AUTO_TEST_CASE( CheckUnsoppertedInSCHEDULE ) { - const char * deckString = + const char * deckStringUnSupported = + "START\n" + " 10 'JAN' 2000 /\n" + "RUNSPEC\n" + "DIMENS\n" + " 10 10 10 / \n" + "SCHEDULE\n" + "MULTZ\n" + " 1000*0.10 /\n" + "\n"; + + const char * deckStringSupported = "START\n" " 10 'JAN' 2000 /\n" "RUNSPEC\n" @@ -112,22 +123,26 @@ BOOST_AUTO_TEST_CASE( CheckUnsoppertedInSCHEDULE ) { " 10 10 10 / \n" "SCHEDULE\n" "MULTFLT\n" - " 'F1' 100 /\n" + " 'F1' 0.10 /\n" "/\n" "\n"; + ParseMode parseMode; Parser parser(true); - auto deck = parser.parseString( deckString , parseMode ); - std::shared_ptr grid = std::make_shared( deck ); + auto deckSupported = parser.parseString( deckStringSupported , parseMode ); + auto deckUnSupported = parser.parseString( deckStringUnSupported , parseMode ); + std::shared_ptr grid = std::make_shared( deckSupported ); std::shared_ptr ioconfig = std::make_shared( "path" ); parseMode.update( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::IGNORE ); - BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig )); + BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deckSupported , ioconfig )); + BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deckUnSupported , ioconfig )); parseMode.update( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::THROW_EXCEPTION ); - BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument ); + BOOST_CHECK_THROW( Schedule( parseMode , grid , deckUnSupported , ioconfig ), std::invalid_argument ); + BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deckSupported , ioconfig )); }