From 5976efa9534eea09e18328c97bb11da1ac38aec0 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 27 Aug 2020 07:57:28 +0200 Subject: [PATCH 1/5] Add fip regioin name to summaryconfig node --- .../SummaryConfig/SummaryConfig.hpp | 6 +++- .../SummaryConfig/SummaryConfig.cpp | 34 +++++++++++++------ tests/parser/SummaryConfigTests.cpp | 27 +++++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp index 3824fd6dc..a01c24633 100644 --- a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp +++ b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp @@ -51,6 +51,7 @@ namespace Opm { SummaryConfigNode& namedEntity(std::string name); SummaryConfigNode& number(const int num); SummaryConfigNode& isUserDefined(const bool userDefined); + SummaryConfigNode& fip_region(const std::string& fip_region); const std::string& keyword() const { return this->keyword_; } Category category() const { return this->category_; } @@ -58,12 +59,13 @@ namespace Opm { const std::string& namedEntity() const { return this->name_; } int number() const { return this->number_; } bool isUserDefined() const { return this->userDefined_; } + const std::string& fip_region() const { return this->fip_region_; } std::string uniqueNodeKey() const; const Location& location( ) const { return this->loc; } operator Opm::EclIO::SummaryNode() const { - return { keyword_, category_, type_, name_, number_ }; + return { keyword_, category_, type_, name_, number_, fip_region_ }; } template @@ -75,6 +77,7 @@ namespace Opm { serializer(type_); serializer(name_); serializer(number_); + serializer(fip_region_); serializer(userDefined_); } @@ -85,6 +88,7 @@ namespace Opm { Type type_{ Type::Undefined }; std::string name_{}; int number_{std::numeric_limits::min()}; + std::string fip_region_; bool userDefined_{false}; }; diff --git a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp index 594bde6eb..6e1582fa2 100644 --- a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp @@ -460,19 +460,25 @@ inline void keywordR2R( SummaryConfig::keyword_list& /* list */, } - inline void keywordR( SummaryConfig::keyword_list& list, - const DeckKeyword& keyword, - const TableManager& tables, - const ParseContext& parseContext, - ErrorGuard& errors ) { +inline void keywordR( SummaryConfig::keyword_list& list, + const DeckKeyword& deck_keyword, + const TableManager& tables, + const ParseContext& parseContext, + ErrorGuard& errors ) { - if( is_region_to_region(keyword.name()) ) { - keywordR2R( list, parseContext, errors, keyword ); + auto keyword = deck_keyword.name(); + if( is_region_to_region(keyword) ) { + keywordR2R( list, parseContext, errors, deck_keyword ); return; } + std::string region_name = "FIPNUM"; + if (keyword.size() > 5) { + auto dash_pos = keyword.find("_"); + region_name = "FIP" + keyword.substr(5,3); + } const size_t numfip = tables.numFIPRegions( ); - const auto& item = keyword.getDataRecord().getDataItem(); + const auto& item = deck_keyword.getDataRecord().getDataItem(); std::vector regions; if (item.data_size() > 0) @@ -482,11 +488,11 @@ inline void keywordR2R( SummaryConfig::keyword_list& /* list */, regions.push_back( region ); } - // Don't (currently) need parameter type for region keywords auto param = SummaryConfigNode { - keyword.name(), SummaryConfigNode::Category::Region, keyword.location() + keyword, SummaryConfigNode::Category::Region, deck_keyword.location() } - .isUserDefined( is_udq(keyword.name()) ); + .fip_region( region_name ) + .isUserDefined( is_udq(keyword) ); for( const int region : regions ) { if (region >= 1 && region <= static_cast(numfip)) @@ -872,6 +878,12 @@ SummaryConfigNode SummaryConfigNode::serializeObject() return result; } +SummaryConfigNode& SummaryConfigNode::fip_region(const std::string& fip_region) +{ + this->fip_region_ = fip_region; + return *this; +} + SummaryConfigNode& SummaryConfigNode::parameterType(const Type type) { this->type_ = type; diff --git a/tests/parser/SummaryConfigTests.cpp b/tests/parser/SummaryConfigTests.cpp index abed3ec3d..81c2588a6 100644 --- a/tests/parser/SummaryConfigTests.cpp +++ b/tests/parser/SummaryConfigTests.cpp @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -96,6 +97,8 @@ static Deck createDeck( const std::string& summary ) { "REGIONS\n" "FIPNUM\n" "200*1 300*2 500*3 /\n" + "FIPREG\n" + "200*10 300*20 500*30 /\n" "SCHEDULE\n" "WELSPECS\n" " \'W_1\' \'OP\' 1 1 3.33 \'OIL\' 7* / \n" @@ -1037,3 +1040,27 @@ RUNSUM BOOST_CHECK( summary_config2.createRunSummary()); BOOST_CHECK(!summary_config2.hasKeyword("RUNSUM")); } + + +BOOST_AUTO_TEST_CASE(FIPREG) { + std::string deck_string = R"( +RPR__REG +/ + +ROPT_REG +/ +)"; + const auto& summary_config = createSummary(deck_string); + BOOST_CHECK(summary_config.hasKeyword("RPR__REG")); + BOOST_CHECK(summary_config.hasKeyword("ROPT_REG")); + for (const auto& node : summary_config) { + if (node.category() == EclIO::SummaryNode::Category::Region) + BOOST_CHECK_EQUAL( node.fip_region(), "FIPREG" ); + } + + const auto& fip_regions = summary_config.fip_regions(); + BOOST_CHECK_EQUAL(fip_regions.size(), 1); + + auto reg_iter = fip_regions.find("FIPREG"); + BOOST_CHECK( reg_iter != fip_regions.end() ); +} From 3587c0c6b7e61030786f255f7200cd0803589c8f Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 27 Aug 2020 07:58:15 +0200 Subject: [PATCH 2/5] Add fip_region member to SummaryNode --- opm/io/eclipse/SummaryNode.hpp | 1 + src/opm/output/eclipse/Summary.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/opm/io/eclipse/SummaryNode.hpp b/opm/io/eclipse/SummaryNode.hpp index 428abedaa..7301aa422 100644 --- a/opm/io/eclipse/SummaryNode.hpp +++ b/opm/io/eclipse/SummaryNode.hpp @@ -55,6 +55,7 @@ struct SummaryNode { Type type; std::string wgname; int number; + std::string fip_region; constexpr static int default_number { std::numeric_limits::min() }; diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index 5ba1d9386..259db6b51 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -173,7 +173,7 @@ namespace { const std::string& name) -> void { for (const auto& vector : vectors) { - entities.push_back({kwpref + vector.kw, cat, vector.type, name, Opm::EclIO::SummaryNode::default_number }); + entities.push_back({kwpref + vector.kw, cat, vector.type, name, Opm::EclIO::SummaryNode::default_number, "" }); } }; @@ -183,7 +183,7 @@ namespace { const std::string& wgname) -> void { for (const auto &extra_vector : extra_vectors) { - entities.push_back({ extra_vector.kw, category, extra_vector.type, wgname, Opm::EclIO::SummaryNode::default_number }); + entities.push_back({ extra_vector.kw, category, extra_vector.type, wgname, Opm::EclIO::SummaryNode::default_number, "" }); } }; @@ -224,7 +224,7 @@ namespace { const int segNumber) -> void { for (const auto &requiredVector : requiredVectors) { - ret.push_back({requiredVector.first, category, requiredVector.second, well, segNumber}); + ret.push_back({requiredVector.first, category, requiredVector.second, well, segNumber, ""}); } }; From d5a21427b4be886c073aeba8a348d2c2c5f01724 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 27 Aug 2020 07:59:15 +0200 Subject: [PATCH 3/5] Add fip_region to summary context argument --- src/opm/output/eclipse/Summary.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index 259db6b51..cb3e1a8df 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -379,6 +379,7 @@ struct fn_args { double duration; const int sim_step; int num; + const std::string fip_region; const Opm::SummaryState& st; const Opm::data::Wells& wells; const Opm::data::GroupValues& groups; @@ -1640,6 +1641,7 @@ namespace Evaluator { const fn_args args { wells, group_name, stepSize, static_cast(sim_step), std::max(0, this->node_.number), + this->node_.fip_region, st, simRes.wellSol, simRes.groupSol, input.reg, input.grid, std::move(efac.factors) }; @@ -2094,6 +2096,7 @@ namespace Evaluator { const fn_args args { {}, "", 0.0, 0, std::max(0, this->node_->number), + this->node_->fip_region, this->st_, {}, {}, reg, this->grid_, {} }; From dad067835cc9ae3449c3f70d4836753506b0a6a4 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 27 Aug 2020 07:59:50 +0200 Subject: [PATCH 4/5] RegionCache object can manage multiple fip regions --- opm/output/eclipse/RegionCache.hpp | 10 ++++--- .../SummaryConfig/SummaryConfig.hpp | 1 + src/opm/output/eclipse/RegionCache.cpp | 30 +++++++++++-------- src/opm/output/eclipse/Summary.cpp | 6 ++-- .../SummaryConfig/SummaryConfig.cpp | 12 ++++++++ tests/test_SummaryNode.cpp | 24 ++++++++------- tests/test_regionCache.cpp | 6 ++-- 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/opm/output/eclipse/RegionCache.hpp b/opm/output/eclipse/RegionCache.hpp index a132e2b6a..a328e3994 100644 --- a/opm/output/eclipse/RegionCache.hpp +++ b/opm/output/eclipse/RegionCache.hpp @@ -20,23 +20,25 @@ #ifndef OPM_REGION_CACHE_HPP #define OPM_REGION_CACHE_HPP +#include +#include #include namespace Opm { class Schedule; class EclipseGrid; + class FieldPropsManager; namespace out { class RegionCache { public: RegionCache() = default; - RegionCache(const std::vector& fipnum, const EclipseGrid& grid, const Schedule& schedule); - const std::vector>& connections( int region_id ) const; + RegionCache(const std::set& fip_regions, const FieldPropsManager& fp, const EclipseGrid& grid, const Schedule& schedule); + const std::vector>& connections( const std::string& region_name, int region_id ) const; private: std::vector> connections_empty; - - std::map>> connection_map; + std::map , std::vector>> connection_map; }; } } diff --git a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp index a01c24633..2831581dc 100644 --- a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp +++ b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp @@ -178,6 +178,7 @@ namespace Opm { is required to calculate the summary variables. */ bool require3DField( const std::string& keyword) const; + std::set fip_regions() const; bool operator==(const SummaryConfig& data) const; diff --git a/src/opm/output/eclipse/RegionCache.cpp b/src/opm/output/eclipse/RegionCache.cpp index 6eef34560..d252053c4 100644 --- a/src/opm/output/eclipse/RegionCache.cpp +++ b/src/opm/output/eclipse/RegionCache.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -28,25 +29,30 @@ namespace Opm { namespace out { -RegionCache::RegionCache(const std::vector& fipnum, const EclipseGrid& grid, const Schedule& schedule) { +RegionCache::RegionCache(const std::set& fip_regions, const FieldPropsManager& fp, const EclipseGrid& grid, const Schedule& schedule) { + for (const auto& fip_name : fip_regions) { + const auto& fip_region = fp.get_int(fip_name); - const auto& wells = schedule.getWellsatEnd(); - for (const auto& well : wells) { - const auto& connections = well.getConnections( ); - for (const auto& c : connections) { - if (grid.cellActive(c.getI(), c.getJ(), c.getK())) { - size_t active_index = grid.activeIndex(c.getI(), c.getJ(), c.getK()); - int region_id = fipnum[active_index]; - auto& well_index_list = this->connection_map[ region_id ]; - well_index_list.push_back( { well.name() , active_index } ); + const auto& wells = schedule.getWellsatEnd(); + for (const auto& well : wells) { + const auto& connections = well.getConnections( ); + for (const auto& c : connections) { + if (grid.cellActive(c.getI(), c.getJ(), c.getK())) { + size_t active_index = grid.activeIndex(c.getI(), c.getJ(), c.getK()); + int region_id = fip_region[active_index]; + auto key = std::make_pair(fip_name, region_id); + auto& well_index_list = this->connection_map[ key ]; + well_index_list.push_back( { well.name() , active_index } ); + } } } } } - const std::vector>& RegionCache::connections( int region_id ) const { - const auto iter = this->connection_map.find( region_id ); + const std::vector>& RegionCache::connections( const std::string& region_name, int region_id ) const { + auto key = std::make_pair(region_name, region_id); + const auto iter = this->connection_map.find( key ); if (iter == this->connection_map.end()) return this->connections_empty; else diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index cb3e1a8df..2577ffb6e 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -717,7 +717,7 @@ inline quantity duration( const fn_args& args ) { template quantity region_rate( const fn_args& args ) { double sum = 0; - const auto& well_connections = args.regionCache.connections( args.num ); + const auto& well_connections = args.regionCache.connections( args.fip_region, args.num ); for (const auto& pair : well_connections) { @@ -1438,7 +1438,7 @@ inline std::vector find_wells( const Opm::Schedule& schedule, const auto region = node.number; - for ( const auto& connection : regionCache.connections( region ) ){ + for ( const auto& connection : regionCache.connections( node.fip_region, region ) ){ const auto& w_name = connection.first; if (schedule.hasWell(w_name, sim_step)) { const auto& well = schedule.getWell( w_name, sim_step ); @@ -2393,7 +2393,7 @@ SummaryImplementation(const EclipseState& es, const Schedule& sched, const std::string& basename) : grid_ (std::cref(grid)) - , regCache_ (es.globalFieldProps().get_int("FIPNUM"), grid, sched) + , regCache_ (sumcfg.fip_regions(), es.globalFieldProps(), grid, sched) , deferredSMSpec_(makeDeferredSMSpecCreation(es, grid, sched)) , rset_ (makeResultSet(es.cfg().io(), basename)) , fmt_ { es.cfg().io().getFMTOUT() } diff --git a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp index 6e1582fa2..7077d485d 100644 --- a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp @@ -1161,6 +1161,18 @@ bool SummaryConfig::require3DField( const std::string& keyword ) const { } + +std::set SummaryConfig::fip_regions() const { + std::set reg_set; + for (const auto& node : this->keywords) { + const auto& fip_region = node.fip_region(); + if (fip_region.size() > 0) + reg_set.insert( fip_region ); + } + return reg_set; +} + + bool SummaryConfig::operator==(const Opm::SummaryConfig& data) const { return this->keywords == data.keywords && this->short_keywords == data.short_keywords && diff --git a/tests/test_SummaryNode.cpp b/tests/test_SummaryNode.cpp index 1efbd0d01..999f5bb51 100644 --- a/tests/test_SummaryNode.cpp +++ b/tests/test_SummaryNode.cpp @@ -35,14 +35,14 @@ BOOST_AUTO_TEST_CASE(UniqueKey) { using Category = Opm::EclIO::SummaryNode::Category; using Type = Opm::EclIO::SummaryNode::Type; - expect_key( { "KEYW", Category::Well, Type::Rate, "NORA", 1 }, "KEYW:NORA" ); - expect_key( { "KEYW", Category::Group, Type::Rate, "NORA", 2 }, "KEYW:NORA" ); - expect_key( { "KEYW", Category::Field, Type::Rate, "NORA", 3 }, "KEYW" ); - expect_key( { "KEYW", Category::Region, Type::Rate, "NORA", 4 }, "KEYW:4" ); - expect_key( { "KEYW", Category::Block, Type::Rate, "NORA", 5 }, "KEYW:5" ); - expect_key( { "KEYW", Category::Connection, Type::Rate, "NORA", 6 }, "KEYW:NORA:6" ); - expect_key( { "KEYW", Category::Segment, Type::Rate, "NORA", 7 }, "KEYW:NORA:7" ); - expect_key( { "KEYW", Category::Miscellaneous, Type::Rate, "NORA", 8 }, "KEYW" ); + expect_key( { "KEYW", Category::Well, Type::Rate, "NORA", 1 ,""}, "KEYW:NORA" ); + expect_key( { "KEYW", Category::Group, Type::Rate, "NORA", 2 ,""}, "KEYW:NORA" ); + expect_key( { "KEYW", Category::Field, Type::Rate, "NORA", 3 ,""}, "KEYW" ); + expect_key( { "KEYW", Category::Region, Type::Rate, "NORA", 4 ,""}, "KEYW:4" ); + expect_key( { "KEYW", Category::Block, Type::Rate, "NORA", 5 ,""}, "KEYW:5" ); + expect_key( { "KEYW", Category::Connection, Type::Rate, "NORA", 6 ,""}, "KEYW:NORA:6" ); + expect_key( { "KEYW", Category::Segment, Type::Rate, "NORA", 7 ,""}, "KEYW:NORA:7" ); + expect_key( { "KEYW", Category::Miscellaneous, Type::Rate, "NORA", 8 ,""}, "KEYW" ); } BOOST_AUTO_TEST_CASE(InjectedNumberRenderer) { @@ -54,7 +54,8 @@ BOOST_AUTO_TEST_CASE(InjectedNumberRenderer) { Category::Region, Type::Undefined, "-", - 2 + 2, + "" }; Opm::EclIO::SummaryNode negativeNode { @@ -62,7 +63,8 @@ BOOST_AUTO_TEST_CASE(InjectedNumberRenderer) { Category::Region, Type::Undefined, "-", - -2 + -2, + "" }; auto chooseSign = [](const Opm::EclIO::SummaryNode& node) -> std::string { @@ -74,7 +76,7 @@ BOOST_AUTO_TEST_CASE(InjectedNumberRenderer) { } BOOST_AUTO_TEST_CASE(user_defined) { - auto summary_node = Opm::EclIO::SummaryNode{"FU_VAR1", Opm::EclIO::SummaryNode::Category::Field, Opm::EclIO::SummaryNode::Type::Undefined, "", -1 }; + auto summary_node = Opm::EclIO::SummaryNode{"FU_VAR1", Opm::EclIO::SummaryNode::Category::Field, Opm::EclIO::SummaryNode::Type::Undefined, "", -1 , ""}; BOOST_CHECK( summary_node.is_user_defined() ); } diff --git a/tests/test_regionCache.cpp b/tests/test_regionCache.cpp index 5bc88da82..f25d02f81 100644 --- a/tests/test_regionCache.cpp +++ b/tests/test_regionCache.cpp @@ -46,14 +46,14 @@ BOOST_AUTO_TEST_CASE(create) { EclipseState es(deck); const EclipseGrid& grid = es.getInputGrid(); Schedule schedule( deck, es, python); - out::RegionCache rc(es.fieldProps().get_int("FIPNUM"), grid, schedule); + out::RegionCache rc({"FIPNUM"}, es.fieldProps(), grid, schedule); { - const auto& empty = rc.connections( 4 ); + const auto& empty = rc.connections( "FIPNUM", 4 ); BOOST_CHECK_EQUAL( empty.size() , 0 ); } { - const auto& top_layer = rc.connections( 1 ); + const auto& top_layer = rc.connections( "FIPNUM", 1 ); BOOST_CHECK_EQUAL( top_layer.size() , 3 ); { auto pair = top_layer[0]; From c3f94834c3d5b5e6dab5a7d0db20429e45506159 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Mon, 7 Sep 2020 09:59:35 +0200 Subject: [PATCH 5/5] Add wildcard matching of keywords in SummaryConfig --- .../EclipseState/SummaryConfig/SummaryConfig.hpp | 8 ++++++++ .../EclipseState/SummaryConfig/SummaryConfig.cpp | 13 +++++++++++++ tests/parser/SummaryConfigTests.cpp | 3 +++ 3 files changed, 24 insertions(+) diff --git a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp index 2831581dc..b02a74b84 100644 --- a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp +++ b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp @@ -168,6 +168,14 @@ namespace Opm { */ bool hasKeyword( const std::string& keyword ) const; + + /* + Will check if the SummaryConfig object contains any keyword + matching the pattern argument. The matching is done with + fnmatch(). + */ + bool match(const std::string& keywordPattern) const; + /* The hasSummaryKey() method will look for fully qualified keys like 'RPR:3' and 'BPR:10,15,20. diff --git a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp index 7077d485d..fc3e9719c 100644 --- a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp @@ -16,6 +16,8 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ +#include + #include #include #include @@ -1132,6 +1134,17 @@ bool SummaryConfig::hasSummaryKey(const std::string& keyword ) const { } +bool SummaryConfig::match(const std::string& keywordPattern) const { + int flags = 0; + for (const auto& keyword : this->short_keywords) { + if (fnmatch(keywordPattern.c_str(), keyword.c_str(), flags) == 0) + return true; + } + return false; +} + + + size_t SummaryConfig::size() const { return this->keywords.size(); } diff --git a/tests/parser/SummaryConfigTests.cpp b/tests/parser/SummaryConfigTests.cpp index 81c2588a6..ccec28ff8 100644 --- a/tests/parser/SummaryConfigTests.cpp +++ b/tests/parser/SummaryConfigTests.cpp @@ -1053,6 +1053,9 @@ ROPT_REG const auto& summary_config = createSummary(deck_string); BOOST_CHECK(summary_config.hasKeyword("RPR__REG")); BOOST_CHECK(summary_config.hasKeyword("ROPT_REG")); + BOOST_CHECK(!summary_config.hasKeyword("RPR")); + BOOST_CHECK(!summary_config.match("BPR*")); + BOOST_CHECK(summary_config.match("RPR*")); for (const auto& node : summary_config) { if (node.category() == EclIO::SummaryNode::Category::Region) BOOST_CHECK_EQUAL( node.fip_region(), "FIPREG" );