opm-common/tests/parser/SummaryConfigTests.cpp
Bård Skaflestad ecbfd4e9c4 Support Region Set Tags For All Region Level Summary Vectors
This commit switches the existing, somewhat spotty, support for
matching region set tags on region level summary vector keywords.
We leverage the recent support for 'deck_name_regex_suffix' keys in
the JSON keyword model to extend the keyword matching algorithm to
also account for these region set tags.

There is a potential for false positives here, but we'll use this
as an initial proof-of-concept implementation.
2023-09-21 18:26:36 +02:00

2273 lines
75 KiB
C++

/*
Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_MODULE SummaryConfigTests
#include <boost/test/unit_test.hpp>
#include <fmt/format.h>
#include <opm/common/utility/OpmInputError.hpp>
#include <opm/io/eclipse/SummaryNode.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
#include <opm/input/eclipse/Parser/InputErrorAction.hpp>
#include <opm/input/eclipse/Parser/ParseContext.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <algorithm>
using namespace Opm;
static Deck createDeck_no_wells( const std::string& summary ) {
Opm::Parser parser;
std::string input =
"START -- 0 \n"
"10 MAI 2007 / \n"
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"REGDIMS\n"
" 3/\n"
"GRID\n"
"DXV \n 10*400 /\n"
"DYV \n 10*400 /\n"
"DZV \n 10*400 /\n"
"TOPS \n 100*2202 / \n"
"PERMX\n"
" 1000*0.25 /\n"
"COPY\n"
" PERMX PERMY /\n"
" PERMX PERMZ /\n"
"/\n"
"PORO \n"
" 1000*0.15 /\n"
"REGIONS\n"
"FIPNUM\n"
"200*1 300*2 500*3 /\n"
"SCHEDULE\n"
"SUMMARY\n"
+ summary;
return parser.parseString(input);
}
static Deck createDeck( const std::string& summary ) {
Opm::Parser parser;
std::string input = R"(
START -- 0
10 MAI 2007 /
RUNSPEC
DIMENS
10 10 10 /
REGDIMS
3 3 /
AQUDIMS
4 4 1* 1* 3 200 1* 1* /
GRID
DXV
10*400 /
DYV
10*400 /
DZV
10*400 /
TOPS
100*2202 /
PERMX
1000*0.25 /
COPY
PERMX PERMY /
PERMX PERMZ /
/
PORO
1000*0.15 /
AQUNUM
4 1 1 1 15000 5000 0.3 30 2700 / aq cell
5 2 1 1 150000 9000 0.3 30 2700 / aq cell
6 3 1 1 150000 9000 0.3 30 2700 / aq cell
7 4 1 1 150000 9000 0.3 30 2700 / aq cell
/
AQUCON
-- # I1 I2 J1 J2 K1 K2 Face
4 1 1 16 18 19 20 'I-' / connecting cells
5 2 2 16 18 19 20 'I-' / connecting cells
6 3 3 16 18 19 20 'I-' / connecting cells
7 4 4 16 18 19 20 'I-' / connecting cells
/
REGIONS
FIPNUM
200*1 300*2 500*3 /
FIPREG
200*10 300*20 500*30 /
FIPXYZ
200*2 300*3 500*1 /
SOLUTION
AQUCT
1 2040 1* 1000 .3 3.0e-5 1330 10 360.0 1 1* /
2 2040 1* 1000 .3 3.0e-5 1330 10 360.0 1 1* /
3 2040 1* 1000 .3 3.0e-5 1330 10 360.0 1 1* /
/
AQUANCON
1 1 10 10 2 10 10 'I-' 0.88 1 /
2 9 10 10 10 10 10 'I+' 0.88 1 /
3 9 9 8 10 9 8 'I+' 0.88 1 /
/
SCHEDULE
WELSPECS
'W_1' 'OP' 1 1 3.33 'OIL' 7* /
'WX2' 'OP' 2 2 3.33 'OIL' 7* /
'W_3' 'OP' 2 5 3.92 'OIL' 7* /
'PRODUCER' 'G' 5 5 2000 'GAS' /
/
COMPDAT
'PRODUCER' 5 5 1 1 'OPEN' 1* -1 0.5 /
'W_1' 3 7 2 2 'OPEN' 1* * 0.311 4332.346 2* 'X' 22.123 /
'W_1' 2 2 1 1 /
'W_1' 2 2 2 2 /
'WX2' 2 2 1 1 /
/
COMPLUMP
W_1 3 7 2 2 2 /
W_1 2 2 2 2 2 /
W_1 2 2 1 1 4 /
/
SUMMARY
)" + summary;
return parser.parseString(input);
}
static std::vector< std::string > sorted_names( const SummaryConfig& summary ) {
std::vector< std::string > ret;
for( const auto& x : summary ) {
auto wgname = x.namedEntity();
if(wgname.size())
ret.push_back( wgname );
}
std::sort( ret.begin(), ret.end() );
return ret;
}
static std::vector< std::string > sorted_keywords( const SummaryConfig& summary ) {
std::vector< std::string > ret;
for( const auto& x : summary )
ret.push_back( x.keyword() );
std::sort( ret.begin(), ret.end() );
return ret;
}
static std::vector< std::string > sorted_key_names( const SummaryConfig& summary ) {
std::vector< std::string > ret;
for( const auto& x : summary ) {
ret.push_back( x.uniqueNodeKey() );
}
std::sort( ret.begin(), ret.end() );
return ret;
}
static SummaryConfig createSummary(const std::string& input , const ParseContext& parseContext = ParseContext()) {
ErrorGuard errors;
auto deck = createDeck( input );
auto python = std::make_shared<Python>();
EclipseState state( deck );
Schedule schedule(deck, state, parseContext, errors, python);
return SummaryConfig(deck, schedule, state.fieldProps(), state.aquifer(), parseContext, errors);
}
BOOST_AUTO_TEST_CASE(wells_all) {
const auto input = "WWCT\n/\n";
const auto summary = createSummary( input );
const auto wells = { "PRODUCER", "WX2", "W_1", "W_3" };
const auto names = sorted_names( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
wells.begin(), wells.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(WSTATE) {
const auto input = "WSTAT\n/\n";
const auto summary = createSummary( input );
const auto wells = { "PRODUCER", "WX2", "W_1", "W_3" };
for (const auto& well : wells)
BOOST_CHECK(summary.hasSummaryKey(fmt::format("WSTAT:{}", well)));
}
BOOST_AUTO_TEST_CASE(EMPTY) {
auto deck = createDeck_no_wells( "" );
auto python = std::make_shared<Python>();
EclipseState state( deck );
Schedule schedule(deck, state, python);
SummaryConfig conf(deck, schedule, state.fieldProps(), state.aquifer());
BOOST_CHECK_EQUAL( conf.size(), 0U );
}
BOOST_AUTO_TEST_CASE(wells_missingI) {
auto python = std::make_shared<Python>();
ParseContext parseContext;
ErrorGuard errors;
const auto input = "WWCT\n/\n";
auto deck = createDeck_no_wells( input );
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputErrorAction::THROW_EXCEPTION);
EclipseState state( deck );
Schedule schedule(deck, state, parseContext, errors, python );
BOOST_CHECK_NO_THROW(SummaryConfig(deck, schedule, state.fieldProps(), state.aquifer(), parseContext, errors));
}
BOOST_AUTO_TEST_CASE(wells_select) {
const auto input = "WWCT\n'W_1' 'WX2' /\n";
const auto summary = createSummary( input );
const auto wells = { "WX2", "W_1" };
const auto names = sorted_names( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
wells.begin(), wells.end(),
names.begin(), names.end() );
BOOST_CHECK_EQUAL( summary.size(), 2U );
}
BOOST_AUTO_TEST_CASE(groups_all) {
const auto summary = createSummary( "GWPR \n /\n" );
const auto groups = { "G", "OP" };
const auto names = sorted_names( summary );
BOOST_CHECK_EQUAL_COLLECTIONS( groups.begin(), groups.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(wells_pattern) {
const auto input = "WWCT\n'W*' /\n";
const auto summary = createSummary( input );
const auto wells = { "WX2", "W_1", "W_3" };
const auto names = sorted_names( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
wells.begin(), wells.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(fields) {
const auto input = "FOPT\n";
const auto summary = createSummary( input );
const auto keywords = { "FOPT" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(tracer) {
const auto input = "FTIRSEA\n WTICSEA\n'W_1'/\n WTPRSEA\n'W_3' 'WX2'/\n";
const auto summary = createSummary( input );
const auto keywords = { "FTIRSEA", "WTICSEA", "WTPRSEA", "WTPRSEA" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(field_oil_efficiency) {
const auto input = "FOE\n";
const auto summary = createSummary( input );
BOOST_CHECK_EQUAL( true , summary.hasKeyword( "FOE"));
}
BOOST_AUTO_TEST_CASE(blocks) {
const auto input = "BPR\n"
"3 3 6 /\n"
"4 3 6 /\n"
"/";
const auto summary = createSummary( input );
const auto keywords = { "BPR", "BPR" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(aquifer) {
const auto input = R"(
ALQR -- This is completely ignored
'ALQ1' 'ALQ2' /
AAQR
1 2 /
AAQT
1 /
AAQP
1 2 3/
)";
const auto summary = createSummary( input );
const auto keywords = { "AAQP", "AAQP", "AAQP", "AAQR", "AAQR", "AAQT" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(regions) {
const auto input = "ROIP\n"
"1 2 3 /\n"
"RWIP\n"
"/\n"
"RGIP\n"
"1 2 /\n";
const auto summary = createSummary( input );
const auto keywords = { "RGIP", "RGIP",
"ROIP", "ROIP", "ROIP",
"RWIP", "RWIP", "RWIP" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(region2region) {
const auto input = std::string { R"(ROFT
1 2/
3 4/
/
ROFT+
1 2/
3 4/
/
ROFT-
1 2/
3 4/
/
ROFR
1 2/
3 4/
/
ROFR+
1 2/
3 4/
/
ROFR-
1 2/
3 4/
/
ROFTL
1 2/
3 4/
/
ROFTG
1 2/
3 4/
1 3/
/
RGFT
5 6/
7 8/
/
RGFT+
5 6/
7 8/
/
RGFT-
5 6/
7 8/
/
RGFR
5 6/
7 8/
/
RGFR+
5 6/
7 8/
/
RGFR-
5 6/
7 8/
/
RGFTL
1 2 /
1 3 /
/
RGFTG
1 2 /
1 3 /
/
RWFT
2 3 /
/
RWFT+
2 3 /
/
RWFT-
2 3 /
/
RWFR
2 3 /
/
RWFR+
2 3 /
/
RWFR-
2 3 /
/
RWIP
/
)" };
ParseContext parseContext;
const auto summary = createSummary(input, parseContext);
{
const auto expect_kw = std::vector<std::string> {
"ROFT", "ROFT+", "ROFT-", "ROFR", "ROFR+", "ROFR-", "ROFTL", "ROFTG",
"RGFT", "RGFT+", "RGFT-", "RGFR", "RGFR+", "RGFR-", "RGFTL", "RGFTG",
"RGFT", "RGFT+", "RGFT-", "RGFR", "RGFR+", "RGFR-",
};
for (const auto& kw : expect_kw) {
BOOST_CHECK_MESSAGE(summary.hasKeyword(kw),
"SummaryConfig MUST have keyword '" << kw << "'");
}
}
{
const auto kw = summary.keywords("ROFT");
BOOST_CHECK_EQUAL(kw.size(), 2);
BOOST_CHECK_MESSAGE(kw[1].namedEntity().empty(),
"ROFT vector must NOT have an associated named entity");
BOOST_CHECK_MESSAGE(kw[0].type() == SummaryConfigNode::Type::Total,
"ROFT must be a Cumulative Total");
BOOST_CHECK_MESSAGE(kw[1].category() == SummaryConfigNode::Category::Region,
"ROFT must be a Region vector");
const auto expect_number = std::vector<int> {
393'217, // 1 2
458'755, // 3 4
};
const auto n1 = kw[0].number();
const auto n2 = kw[1].number();
BOOST_CHECK_MESSAGE(((n1 == expect_number[0]) && (n2 == expect_number[1])) ||
((n2 == expect_number[0]) && (n1 == expect_number[1])),
R"(ROFT 'NUMS' must match expected set)");
}
{
const auto kw = summary.keywords("RGFR-");
BOOST_CHECK_EQUAL(kw.size(), 2);
BOOST_CHECK_MESSAGE(kw[1].namedEntity().empty(),
"RGFR- vector must NOT have an associated named entity");
BOOST_CHECK_MESSAGE(kw[0].type() == SummaryConfigNode::Type::Rate,
"RGFR- must be a Rate");
BOOST_CHECK_MESSAGE(kw[1].category() == SummaryConfigNode::Category::Region,
"RGFR- must be a Region vector");
const auto expect_number = std::vector<int> {
524'293, // 5 6
589'831, // 7 8
};
const auto n1 = kw[0].number();
const auto n2 = kw[1].number();
BOOST_CHECK_MESSAGE(((n1 == expect_number[0]) && (n2 == expect_number[1])) ||
((n2 == expect_number[0]) && (n1 == expect_number[1])),
R"(RGFR- 'NUMS' must match expected set)");
}
{
const auto kw = summary.keywords("ROFTG");
BOOST_CHECK_EQUAL(kw.size(), 3);
BOOST_CHECK_MESSAGE(kw[1].namedEntity().empty(),
"ROFTG vector must NOT have an associated named entity");
BOOST_CHECK_MESSAGE(kw[0].type() == SummaryConfigNode::Type::Total,
"ROFTG must be a Cumulative Total");
BOOST_CHECK_MESSAGE(kw[1].category() == SummaryConfigNode::Category::Region,
"ROFTG must be a Region vector");
const auto expect_number = std::vector<int> {
393'217, // 1 2
458'755, // 3 4
425'985, // 1 3
};
const auto actual = std::vector<int> {
kw[0].number(),
kw[1].number(),
kw[2].number(),
};
BOOST_CHECK_MESSAGE(std::is_permutation(actual .begin(), actual .end(),
expect_number.begin(), expect_number.end()),
R"(ROFTG 'NUMS' must match expected set)");
}
}
BOOST_AUTO_TEST_CASE(region2region_unsupported) {
const auto input = std::string { R"(REFR-
2 3 /
/
RKFT
2 3 /
/
)" };
ParseContext parseContext;
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW( createSummary(input, parseContext), OpmInputError);
}
BOOST_AUTO_TEST_CASE(completions) {
const auto input = "CWIR\n" // all specified
"'PRODUCER' /\n"
"'WX2' 1 1 1 /\n"
"'WX2' 2 2 1 /\n"
"/\n"
"CWIT\n" // block defaulted
"'W_1' /\n"
"/\n"
"CGIT\n" // well defaulted
"* 2 2 1 /\n"
"/\n"
"CGIR\n" // all defaulted
" '*' /\n"
"/\n"
"CPRL\n" // all defaulted
" '*' /\n"
"/\n";
const auto summary = createSummary( input );
const auto keywords = { "CGIR", "CGIR", "CGIR", "CGIR", "CGIR",
"CGIT", "CGIT",
"CPRL", "CPRL", "CPRL", "CPRL", "CPRL",
"CWIR", "CWIR",
"CWIT", "CWIT", "CWIT" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE( merge ) {
const auto input1 = "WWCT\n/\n";
auto summary1 = createSummary( input1 );
const auto keywords = { "FOPT", "WWCT", "WWCT", "WWCT", "WWCT" };
const auto wells = { "PRODUCER", "WX2", "W_1", "W_3" };
const auto input2 = "FOPT\n";
const auto summary2 = createSummary( input2 );
summary1.merge( summary2 );
const auto kw_names = sorted_keywords( summary1 );
const auto well_names = sorted_names( summary1 );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
kw_names.begin(), kw_names.end() );
BOOST_CHECK_EQUAL_COLLECTIONS(
wells.begin(), wells.end(),
well_names.begin(), well_names.end() );
}
BOOST_AUTO_TEST_CASE( merge_move ) {
const auto input = "WWCT\n/\n";
auto summary = createSummary( input );
const auto keywords = { "FOPT", "WWCT", "WWCT", "WWCT", "WWCT" };
const auto wells = { "PRODUCER", "WX2", "W_1", "W_3" };
summary.merge( createSummary( "FOPT\n" ) );
const auto kw_names = sorted_keywords( summary );
const auto well_names = sorted_names( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
kw_names.begin(), kw_names.end() );
BOOST_CHECK_EQUAL_COLLECTIONS(
wells.begin(), wells.end(),
well_names.begin(), well_names.end() );
}
static const auto ALL_keywords = {
"FAQR", "FAQRG", "FAQT", "FAQTG", "FGIP", "FGIPG", "FGIPL",
"FGIR", "FGIT", "FGOR", "FGPR", "FGPT", "FOIP", "FOIPG",
"FOIPL", "FOIR", "FOIT", "FOPR", "FOPT", "FPR", "FVIR",
"FVIT", "FVPR", "FVPT", "FWCT", "FWGR", "FWIP", "FWIR",
"FWIT", "FWPR", "FWPT",
"GGIR", "GGIT", "GGOR", "GGPR", "GGPT", "GOIR", "GOIT",
"GOPR", "GOPT", "GVIR", "GVIT", "GVPR", "GVPT", "GWCT",
"GWGR", "GWIR", "GWIT", "GWPR", "GWPT",
"WBHP", "WGIR", "WGIT", "WGOR", "WGPR", "WGPT", "WOIR",
"WOIT", "WOPR", "WOPT", "WPI", "WTHP", "WVIR", "WVIT",
"WVPR", "WVPT", "WWCT", "WWGR", "WWIR", "WWIT", "WWPR",
"WWPT", "WGLIR",
// ALL will not expand to these keywords yet
"AAQR", "AAQRG", "AAQT", "AAQTG"
};
BOOST_AUTO_TEST_CASE(summary_ALL) {
const auto input = "ALL\n";
const auto summary = createSummary( input );
const auto key_names = sorted_key_names( summary );
std::vector<std::string> all;
for( std::string keyword: ALL_keywords ) {
if(keyword[0]=='A' && keyword !="ALL") {
all.push_back(keyword + ":1");
all.push_back(keyword + ":2");
all.push_back(keyword + ":3");
}
if(keyword[0]=='F') {
all.push_back(keyword);
}
else if (keyword[0]=='G') {
auto kn = keyword + ":";
all.push_back(kn + "G");
all.push_back(kn + "OP");
}
else if (keyword[0]=='W') {
auto kn = keyword + ":";
all.push_back(kn + "W_1");
all.push_back(kn + "WX2");
all.push_back(kn + "W_3");
all.push_back(kn + "PRODUCER");
}
}
std::sort(all.begin(), all.end());
BOOST_CHECK_EQUAL_COLLECTIONS(
all.begin(), all.end(),
key_names.begin(), key_names.end());
BOOST_CHECK_EQUAL( true , summary.hasKeyword( "FOPT"));
BOOST_CHECK_EQUAL( true , summary.hasKeyword( "GGIT"));
BOOST_CHECK_EQUAL( true , summary.hasKeyword( "WWCT"));
BOOST_CHECK_EQUAL( false, summary.hasKeyword( "WOPP"));
BOOST_CHECK_EQUAL( false, summary.hasKeyword( "FOPP"));
BOOST_CHECK_EQUAL( false , summary.hasKeyword("NO-NOT-THIS"));
}
BOOST_AUTO_TEST_CASE(INVALID_WELL1) {
ParseContext parseContext;
const auto input = "CWIR\n"
"NEW-WELL /\n"
"/\n";
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputErrorAction::THROW_EXCEPTION );
BOOST_CHECK_THROW( createSummary( input , parseContext ) , OpmInputError);
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputErrorAction::IGNORE );
BOOST_CHECK_NO_THROW( createSummary( input , parseContext ));
}
BOOST_AUTO_TEST_CASE(INVALID_WELL2) {
ParseContext parseContext;
const auto input = "WWCT\n"
" NEW-WELL /\n";
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputErrorAction::THROW_EXCEPTION );
BOOST_CHECK_THROW( createSummary( input , parseContext ) , OpmInputError);
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputErrorAction::IGNORE );
BOOST_CHECK_NO_THROW( createSummary( input , parseContext ));
}
BOOST_AUTO_TEST_CASE(UNDEFINED_UDQ_WELL) {
ParseContext parseContext;
const auto input = "WUWCT\n"
"/\n";
parseContext.updateKey( ParseContext::SUMMARY_UNDEFINED_UDQ, InputErrorAction::THROW_EXCEPTION );
BOOST_CHECK_THROW( createSummary( input , parseContext ) , OpmInputError);
parseContext.updateKey( ParseContext::SUMMARY_UNDEFINED_UDQ, InputErrorAction::IGNORE );
BOOST_CHECK_NO_THROW( createSummary( input , parseContext ));
}
BOOST_AUTO_TEST_CASE(INVALID_GROUP) {
ParseContext parseContext;
const auto input = "GWCT\n"
" NEW-GR /\n";
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_GROUP , InputErrorAction::THROW_EXCEPTION );
BOOST_CHECK_THROW( createSummary( input , parseContext ) , OpmInputError);
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_GROUP , InputErrorAction::IGNORE );
BOOST_CHECK_NO_THROW( createSummary( input , parseContext ));
}
BOOST_AUTO_TEST_CASE( REMOVE_DUPLICATED_ENTRIES ) {
ParseContext parseContext;
const auto input = "WGPR \n/\n"
"WGPR \n/\n"
"ALL\n";
const auto summary = createSummary( input );
const auto keys = sorted_key_names( summary );
auto uniq_keys = keys;
uniq_keys.erase( std::unique( uniq_keys.begin(),
uniq_keys.end(),
std::equal_to< std::string >() ),
uniq_keys.end() );
BOOST_CHECK_EQUAL_COLLECTIONS(
keys.begin(), keys.end(),
uniq_keys.begin(), uniq_keys.end() );
}
BOOST_AUTO_TEST_CASE( ANALYTICAL_AQUIFERS ) {
{
const auto faulty_input = std::string {R"(
AAQT
-- Neither of these are analytic aquifers => input error
4 5 6 7 /
)" };
BOOST_CHECK_THROW(const auto summary = createSummary(faulty_input),
OpmInputError);
}
{
const auto faulty_input = std::string {R"(
AAQP
-- Aquifer ID out of range => input error
1729 /
)" };
BOOST_CHECK_THROW(const auto summary = createSummary(faulty_input),
OpmInputError);
}
const std::string input = R"(
AAQR
1 2 /
AAQP
2 1 /
AAQT
/
AAQRG
/
AAQTG
/
AAQTD
/
AAQPD
/
)";
const auto summary = createSummary( input );
const auto keywords = { "AAQP", "AAQP", "AAQPD", "AAQPD", "AAQPD",
"AAQR", "AAQR", "AAQRG", "AAQRG", "AAQRG",
"AAQT", "AAQT", "AAQT", "AAQTD", "AAQTD", "AAQTD",
"AAQTG", "AAQTG", "AAQTG"
};
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE( NUMERICAL_AQUIFERS )
{
{
const auto faulty_input = std::string {R"(
ANQR
-- Neither of these are numeric aquifers => input error
1 2 3 /
)" };
BOOST_CHECK_THROW(const auto summary = createSummary(faulty_input),
OpmInputError);
}
{
const auto faulty_input = std::string {R"(
ANQP
-- Aquifer ID out of range => input error
42 /
)" };
BOOST_CHECK_THROW(const auto summary = createSummary(faulty_input),
OpmInputError);
}
const std::string input = R"(
ANQR
5 /
ANQP
4 7 /
ANQT
/
)";
const auto summary = createSummary( input );
const auto keywords = { "ANQP", "ANQP", "ANQR", "ANQT", "ANQT", "ANQT", "ANQT" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
static const auto GMWSET_keywords = {
"GMWPT", "GMWPR", "GMWPA", "GMWPU", "GMWPG", "GMWPO", "GMWPS",
"GMWPV", "GMWPP", "GMWPL", "GMWIT", "GMWIN", "GMWIA", "GMWIU", "GMWIG",
"GMWIS", "GMWIV", "GMWIP", "GMWDR", "GMWDT", "GMWWO", "GMWWT"
};
BOOST_AUTO_TEST_CASE( summary_GMWSET ) {
const auto input = "GMWSET\n";
const auto summary = createSummary( input );
const auto key_names = sorted_key_names( summary );
std::vector< std::string > all;
for( std::string kw : GMWSET_keywords ) {
all.emplace_back(kw + ":G");
all.emplace_back(kw + ":OP");
}
std::sort( all.begin(), all.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( all.begin(), all.end(),
key_names.begin(), key_names.end() );
BOOST_CHECK( summary.hasKeyword( "GMWPS" ) );
BOOST_CHECK( summary.hasKeyword( "GMWPT" ) );
BOOST_CHECK( summary.hasKeyword( "GMWPR" ) );
BOOST_CHECK( !summary.hasKeyword("NO-NOT-THIS") );
}
static const auto FMWSET_keywords = {
"FMCTF", "FMWPT", "FMWPR", "FMWPA", "FMWPU", "FMWPF", "FMWPO", "FMWPS",
"FMWPV", "FMWPP", "FMWPL", "FMWIT", "FMWIN", "FMWIA", "FMWIU", "FMWIF",
"FMWIS", "FMWIV", "FMWIP", "FMWDR", "FMWDT", "FMWWO", "FMWWT"
};
BOOST_AUTO_TEST_CASE( summary_FMWSET ) {
const auto input = "FMWSET\n";
const auto summary = createSummary( input );
const auto key_names = sorted_key_names( summary );
std::vector< std::string > all( FMWSET_keywords.begin(),
FMWSET_keywords.end() );
std::sort( all.begin(), all.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( all.begin(), all.end(),
key_names.begin(), key_names.end() );
BOOST_CHECK( summary.hasKeyword( "FMWPS" ) );
BOOST_CHECK( summary.hasKeyword( "FMWPT" ) );
BOOST_CHECK( summary.hasKeyword( "FMWPR" ) );
BOOST_CHECK( !summary.hasKeyword("NO-NOT-THIS") );
}
BOOST_AUTO_TEST_CASE(FMWPA) {
const auto input = "FMWPA\n";
const auto summary = createSummary( input );
BOOST_CHECK_EQUAL(1U , summary.size() );
}
BOOST_AUTO_TEST_CASE( summary_require3DField ) {
{
const auto input = "WWCT\n/\n";
const auto summary = createSummary( input );
BOOST_CHECK( !summary.require3DField( "NO-NOT-THIS"));
BOOST_CHECK( !summary.require3DField( "PRESSURE"));
BOOST_CHECK( !summary.require3DField( "OIP"));
BOOST_CHECK( !summary.require3DField( "GIP"));
BOOST_CHECK( !summary.require3DField( "WIP"));
BOOST_CHECK( !summary.require3DField( "OIPL"));
BOOST_CHECK( !summary.require3DField( "OIPG"));
BOOST_CHECK( !summary.require3DField( "GIPL"));
BOOST_CHECK( !summary.require3DField( "GIPG"));
BOOST_CHECK( !summary.require3DField( "SWAT"));
BOOST_CHECK( !summary.require3DField( "SGAS"));
}
{
const auto input = "BPR\n"
"3 3 6 /\n"
"4 3 6 /\n"
"/";
const auto summary = createSummary( input );
BOOST_CHECK( summary.require3DField( "PRESSURE"));
}
{
const auto input = "FPR\n";
const auto summary = createSummary( input );
BOOST_CHECK( summary.require3DField( "PRESSURE"));
}
{
const auto input = "BSWAT\n"
"3 3 6 /\n"
"4 3 6 /\n"
"/";
const auto summary = createSummary( input );
BOOST_CHECK( summary.require3DField( "SWAT"));
}
{
const auto input = "BSGAS\n"
"3 3 6 /\n" // 523
"4 3 6 /\n" // 524
"/";
const auto summary = createSummary( input );
BOOST_CHECK( summary.require3DField( "SGAS"));
BOOST_CHECK( summary.hasSummaryKey( "BSGAS:523" ) );
}
{
const auto input = "RPR\n/\n";
const auto summary = createSummary( input );
BOOST_CHECK( summary.require3DField( "PRESSURE"));
BOOST_CHECK( summary.hasKeyword( "RPR" ) );
BOOST_CHECK( summary.hasSummaryKey( "RPR:1" ) );
BOOST_CHECK( summary.hasSummaryKey( "RPR:3" ) );
BOOST_CHECK( !summary.hasSummaryKey( "RPR:4" ) );
}
{
const auto input = "RPR\n 10 /\n";
BOOST_CHECK_NO_THROW( createSummary( input ) );
}
{
const auto input = "RGIPL\n/\n";
const auto summary = createSummary( input );
BOOST_CHECK( summary.require3DField( "GIPL"));
}
}
BOOST_AUTO_TEST_CASE( SUMMARY_MISC) {
{
const auto summary = createSummary( "TCPU\n" );
BOOST_CHECK( summary.hasKeyword( "TCPU" ) );
}
{
const auto summary = createSummary( "PERFORMA\n" );
BOOST_CHECK( summary.hasKeyword( "ELAPSED" ) );
BOOST_CHECK( !summary.hasKeyword("PERFORMA"));
}
}
BOOST_AUTO_TEST_CASE(Summary_Segment)
{
auto python = std::make_shared<Python>();
const auto input = std::string { "SOFR_TEST.DATA" };
const auto deck = Parser{}.parseFile(input);
const auto state = EclipseState { deck };
const auto schedule = Schedule { deck, state, python};
const auto summary = SummaryConfig {
deck, schedule, state.fieldProps(), state.aquifer()
};
// SOFR PROD01 segments 1, 10, 21.
BOOST_CHECK(deck.hasKeyword("SOFR"));
BOOST_CHECK(summary.hasKeyword("SOFR"));
BOOST_CHECK(summary.hasSummaryKey("SOFR:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SOFR:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:20"));
BOOST_CHECK(summary.hasSummaryKey("SOFR:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:PROD01:27"));
BOOST_CHECK(!summary.hasSummaryKey("SOFR:INJE01:1"));
{
auto sofr = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SOFR";
});
BOOST_REQUIRE(sofr != summary.end());
BOOST_CHECK_MESSAGE(sofr->category() == SummaryConfigNode::Category::Segment,
R"("SOFR" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sofr->type() == SummaryConfigNode::Type::Rate,
R"("SOFR" keyword type must be "Rate")"
);
BOOST_CHECK_EQUAL(sofr->namedEntity(), "PROD01");
}
// SOFRF PROD01 segments 1, 10, 21.
BOOST_CHECK(deck.hasKeyword("SOFRF"));
BOOST_CHECK(summary.hasKeyword("SOFRF"));
BOOST_CHECK(summary.hasSummaryKey("SOFRF:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SOFRF:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:20"));
BOOST_CHECK(summary.hasSummaryKey("SOFRF:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:PROD01:27"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRF:INJE01:1"));
{
auto sofrf = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SOFRF";
});
BOOST_REQUIRE(sofrf != summary.end());
BOOST_CHECK_MESSAGE(sofrf->category() == SummaryConfigNode::Category::Segment,
R"("SOFRF" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sofrf->type() == SummaryConfigNode::Type::Rate,
R"("SOFRF" keyword type must be "Rate")"
);
BOOST_CHECK_EQUAL(sofrf->namedEntity(), "PROD01");
}
// SOFRS PROD01 segments 1, 10, 21.
BOOST_CHECK(deck.hasKeyword("SOFRS"));
BOOST_CHECK(summary.hasKeyword("SOFRS"));
BOOST_CHECK(summary.hasSummaryKey("SOFRS:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SOFRS:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:20"));
BOOST_CHECK(summary.hasSummaryKey("SOFRS:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:PROD01:27"));
BOOST_CHECK(!summary.hasSummaryKey("SOFRS:INJE01:1"));
{
auto sofrs = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SOFRS";
});
BOOST_REQUIRE(sofrs != summary.end());
BOOST_CHECK_MESSAGE(sofrs->category() == SummaryConfigNode::Category::Segment,
R"("SOFRS" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sofrs->type() == SummaryConfigNode::Type::Rate,
R"("SOFRS" keyword type must be "Rate")"
);
BOOST_CHECK_EQUAL(sofrs->namedEntity(), "PROD01");
}
// SOGR PROD01 segments 5 and 7.
BOOST_CHECK(deck.hasKeyword("SOGR"));
BOOST_CHECK(summary.hasKeyword("SOGR"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:4"));
BOOST_CHECK(summary.hasSummaryKey("SOGR:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:6"));
BOOST_CHECK(summary.hasSummaryKey("SOGR:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:9"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:PROD01:27"));
BOOST_CHECK(!summary.hasSummaryKey("SOGR:INJE01:1"));
{
auto sogr = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SOGR";
});
BOOST_REQUIRE(sogr != summary.end());
BOOST_CHECK_MESSAGE(sogr->category() == SummaryConfigNode::Category::Segment,
R"("SOGR" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sogr->type() == SummaryConfigNode::Type::Ratio,
R"("SOGR" keyword type must be "Ratio")"
);
BOOST_CHECK_EQUAL(sogr->namedEntity(), "PROD01");
}
// SGFR in all segments of PROD01
BOOST_CHECK(deck.hasKeyword("SGFR"));
BOOST_CHECK(summary.hasKeyword("SGFR"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:1"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:2"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:3"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:4"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:5"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:6"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:7"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:8"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:10"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:11"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:12"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:13"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:14"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:15"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:16"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:17"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:18"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:19"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:20"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:21"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:22"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:23"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:24"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:25"));
BOOST_CHECK(summary.hasSummaryKey("SGFR:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SGFR:PROD01:27")); // No such segment.
{
auto sgfr = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SGFR";
});
BOOST_REQUIRE(sgfr != summary.end());
BOOST_CHECK_MESSAGE(sgfr->category() == SummaryConfigNode::Category::Segment,
R"("SGFR" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sgfr->type() == SummaryConfigNode::Type::Rate,
R"("SGFR" keyword type must be "Rate")"
);
BOOST_CHECK_EQUAL(sgfr->namedEntity(), "PROD01");
}
// SGFRF in segment 2 of PROD01
BOOST_CHECK(deck.hasKeyword("SGFRF"));
BOOST_CHECK(summary.hasKeyword("SGFRF"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:1"));
BOOST_CHECK(summary.hasSummaryKey("SGFRF:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:9"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRF:PROD01:27")); // No such segment.
{
auto sgfrf = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SGFRF";
});
BOOST_REQUIRE(sgfrf != summary.end());
BOOST_CHECK_MESSAGE(sgfrf->category() == SummaryConfigNode::Category::Segment,
R"("SGFRF" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sgfrf->type() == SummaryConfigNode::Type::Rate,
R"("SGFRF" keyword type must be "Rate")"
);
BOOST_CHECK_EQUAL(sgfrf->namedEntity(), "PROD01");
}
// SGFRF in segment 3 of PROD01
BOOST_CHECK(deck.hasKeyword("SGFRS"));
BOOST_CHECK(summary.hasKeyword("SGFRS"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:2"));
BOOST_CHECK(summary.hasSummaryKey("SGFRS:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:9"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SGFRS:PROD01:27")); // No such segment.
{
auto sgfrs = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SGFRS";
});
BOOST_REQUIRE(sgfrs != summary.end());
BOOST_CHECK_MESSAGE(sgfrs->category() == SummaryConfigNode::Category::Segment,
R"("SGFRS" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sgfrs->type() == SummaryConfigNode::Type::Rate,
R"("SGFRS" keyword type must be "Rate")"
);
BOOST_CHECK_EQUAL(sgfrs->namedEntity(), "PROD01");
}
// SGOR PROD01 segment 10 only.
BOOST_CHECK(deck.hasKeyword("SGOR"));
BOOST_CHECK(summary.hasKeyword("SGOR"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SGOR:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SGOR:INJE01:10"));
{
auto sgor = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SGOR";
});
BOOST_REQUIRE(sgor != summary.end());
BOOST_CHECK_MESSAGE(sgor->category() == SummaryConfigNode::Category::Segment,
R"("SGOR" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sgor->type() == SummaryConfigNode::Type::Ratio,
R"("SGOR" keyword type must be "Ratio")"
);
BOOST_CHECK_EQUAL(sgor->namedEntity(), "PROD01");
}
// SPR PROD01 segment 10 only.
BOOST_CHECK(deck.hasKeyword("SPR"));
BOOST_CHECK(summary.hasKeyword("SPR"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SPR:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SPR:INJE01:10"));
{
auto spr = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SPR";
});
BOOST_REQUIRE(spr != summary.end());
BOOST_CHECK_MESSAGE(spr->category() == SummaryConfigNode::Category::Segment,
R"("SPR" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(spr->type() == SummaryConfigNode::Type::Pressure,
R"("SPR" keyword type must be "Pressure")"
);
BOOST_CHECK_EQUAL(spr->namedEntity(), "PROD01");
}
// SWFR for all segments in all MS wells.
BOOST_CHECK(deck.hasKeyword("SWFR"));
BOOST_CHECK(summary.hasKeyword("SWFR"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:1"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:2"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:3"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:4"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:5"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:6"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:7"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:8"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:10"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:11"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:12"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:13"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:14"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:15"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:16"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:17"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:18"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:19"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:20"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:21"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:22"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:23"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:24"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:25"));
BOOST_CHECK(summary.hasSummaryKey("SWFR:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SWFR:INJE01:1"));
{
auto swfr = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SWFR";
});
BOOST_REQUIRE(swfr != summary.end());
BOOST_CHECK_MESSAGE(swfr->category() == SummaryConfigNode::Category::Segment,
R"("SWFR" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(swfr->type() == SummaryConfigNode::Type::Rate,
R"("SWFR" keyword type must be "Rate")"
);
BOOST_CHECK_EQUAL(swfr->namedEntity(), "PROD01");
}
// SWGR for segment 3 in all MS wells.
BOOST_CHECK(deck.hasKeyword("SWGR"));
BOOST_CHECK(summary.hasKeyword("SWGR"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:2"));
BOOST_CHECK(summary.hasSummaryKey("SWGR:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:9"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:15"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SWGR:INJE01:1"));
{
auto swgr = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SWGR";
});
BOOST_REQUIRE(swgr != summary.end());
BOOST_CHECK_MESSAGE(swgr->category() == SummaryConfigNode::Category::Segment,
R"("SWGR" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(swgr->type() == SummaryConfigNode::Type::Ratio,
R"("SWGR" keyword type must be "Ratio")"
);
BOOST_CHECK_EQUAL(swgr->namedEntity(), "PROD01");
}
// SPRD for all segments in all MS wells.
BOOST_CHECK(deck.hasKeyword("SPRD"));
BOOST_CHECK(summary.hasKeyword("SPRD"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:1"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:2"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:3"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:4"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:5"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:6"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:7"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:8"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:10"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:11"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:12"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:13"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:14"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:15"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:16"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:17"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:18"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:19"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:20"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:21"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:22"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:23"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:24"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:25"));
BOOST_CHECK(summary.hasSummaryKey("SPRD:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SPRD:INJE01:1"));
{
auto sprd = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SPRD";
});
BOOST_REQUIRE(sprd != summary.end());
BOOST_CHECK_MESSAGE(sprd->category() == SummaryConfigNode::Category::Segment,
R"("SPRD" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sprd->type() == SummaryConfigNode::Type::Pressure,
R"("SPRD" keyword type must be "Pressure")"
);
BOOST_CHECK_EQUAL(sprd->namedEntity(), "PROD01");
}
// SPRDH for all segments of MS well PROD01.
BOOST_CHECK(deck.hasKeyword("SPRDH"));
BOOST_CHECK(summary.hasKeyword("SPRDH"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:1"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:2"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:3"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:4"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:5"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:6"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:7"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:8"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:10"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:11"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:12"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:13"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:14"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:15"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:16"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:17"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:18"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:19"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:20"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:21"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:22"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:23"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:24"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:25"));
BOOST_CHECK(summary.hasSummaryKey("SPRDH:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDH:INJE01:1"));
{
auto sprdh = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SPRDH";
});
BOOST_REQUIRE(sprdh != summary.end());
BOOST_CHECK_MESSAGE(sprdh->category() == SummaryConfigNode::Category::Segment,
R"("SPRDH" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sprdh->type() == SummaryConfigNode::Type::Pressure,
R"("SPRDH" keyword type must be "Pressure")"
);
BOOST_CHECK_EQUAL(sprdh->namedEntity(), "PROD01");
}
// SPRDF for segments 10 and 16 of MS well PROD01.
BOOST_CHECK(deck.hasKeyword("SPRDF"));
BOOST_CHECK(summary.hasKeyword("SPRDF"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SPRDF:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:15"));
BOOST_CHECK(summary.hasSummaryKey("SPRDF:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDF:INJE01:1"));
{
auto sprdf = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SPRDF";
});
BOOST_REQUIRE(sprdf != summary.end());
BOOST_CHECK_MESSAGE(sprdf->category() == SummaryConfigNode::Category::Segment,
R"("SPRDF" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sprdf->type() == SummaryConfigNode::Type::Pressure,
R"("SPRDF" keyword type must be "Pressure")"
);
BOOST_CHECK_EQUAL(sprdf->namedEntity(), "PROD01");
}
// SPRDA for segments 10 and 16 of all MS wells
BOOST_CHECK(deck.hasKeyword("SPRDA"));
BOOST_CHECK(summary.hasKeyword("SPRDA"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:2"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:3"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:4"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:5"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:6"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:7"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:8"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:9"));
BOOST_CHECK(summary.hasSummaryKey("SPRDA:PROD01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:11"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:12"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:13"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:14"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:15"));
BOOST_CHECK(summary.hasSummaryKey("SPRDA:PROD01:16"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:17"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:18"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:19"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:20"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:21"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:22"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:23"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:24"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:25"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:PROD01:26"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:INJE01:1"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:INJE01:10"));
BOOST_CHECK(!summary.hasSummaryKey("SPRDA:INJE01:16"));
{
auto sprda = std::find_if(summary.begin(), summary.end(),
[](const SummaryConfigNode& node)
{
return node.keyword() == "SPRDA";
});
BOOST_REQUIRE(sprda != summary.end());
BOOST_CHECK_MESSAGE(sprda->category() == SummaryConfigNode::Category::Segment,
R"("SPRDA" keyword category must be "Segment")"
);
BOOST_CHECK_MESSAGE(sprda->type() == SummaryConfigNode::Type::Pressure,
R"("SPRDA" keyword type must be "Pressure")"
);
BOOST_CHECK_EQUAL(sprda->namedEntity(), "PROD01");
}
}
BOOST_AUTO_TEST_CASE(Summary_Network) {
// Example data adapted from opm-tests/model5/1_NETWORK_MODEL5.DATA.
const auto deck = ::Opm::Parser{}.parseString(R"(RUNSPEC
START
21 SEP 2020 12:34:56 /
DIMENS
10 10 3 /
GRID
DXV
10*100.0
/
DYV
10*100.0
/
DZV
5 3 2
/
DEPTHZ
121*2000.0
/
SUMMARY
GPR
/
SCHEDULE
GRUPTREE
'PROD' 'FIELD' /
'M5S' 'PLAT-A' /
'M5N' 'PLAT-A' /
'C1' 'M5N' /
'F1' 'M5N' /
'B1' 'M5S' /
'G1' 'M5S' /
/
BRANPROP
-- Downtree Uptree #VFP ALQ
B1 PLAT-A 5 1* /
C1 PLAT-A 4 1* /
/
NODEPROP
-- Node_name Press autoChoke? addGasLift? Group_name
PLAT-A 21.0 NO NO 1* /
B1 1* NO NO 1* /
C1 1* NO NO 1* /
/
TSTEP
10*10 /
END
)");
ErrorGuard errors;
const auto parseContext = ParseContext{};
const auto state = EclipseState (deck);
const auto schedule = Schedule (deck, state, parseContext, errors, std::make_shared<const Python>());
const auto smry = SummaryConfig(deck, schedule, state.fieldProps(), state.aquifer(), parseContext, errors);
BOOST_CHECK_MESSAGE(deck.hasKeyword("GPR"), R"(Deck must have "GPR" keyword)");
BOOST_CHECK_MESSAGE(smry.hasKeyword("GPR"), R"(SummaryConfig must have "GPR" keyword)");
BOOST_CHECK_MESSAGE(smry.hasSummaryKey("GPR:PLAT-A"), R"(SummaryConfig must have "GPR:PLAT-A" key)");
BOOST_CHECK_MESSAGE(smry.hasSummaryKey("GPR:B1"), R"(SummaryConfig must have "GPR:B1" key)");
BOOST_CHECK_MESSAGE(smry.hasSummaryKey("GPR:C1"), R"(SummaryConfig must have "GPR:C1" key)");
BOOST_CHECK_MESSAGE(!smry.hasSummaryKey("GPR:PROD"), R"(SummaryConfig must NOT have "GPR:PROD" key)");
BOOST_CHECK_MESSAGE(!smry.hasSummaryKey("GPR:FIELD"), R"(SummaryConfig must NOT have "GPR:FIELD" key)");
BOOST_CHECK_MESSAGE(!smry.hasSummaryKey("GPR:M5N"), R"(SummaryConfig must NOT have "GPR:M5N" key)");
BOOST_CHECK_MESSAGE(!smry.hasSummaryKey("GPR:M5S"), R"(SummaryConfig must NOT have "GPR:M5S" key)");
BOOST_CHECK_MESSAGE(!smry.hasSummaryKey("GPR:F1"), R"(SummaryConfig must NOT have "GPR:F1" key)");
BOOST_CHECK_MESSAGE(!smry.hasSummaryKey("GPR:G1"), R"(SummaryConfig must NOT have "GPR:G1" key)");
}
BOOST_AUTO_TEST_CASE(ProcessingInstructions) {
const std::string deck_string = R"(
RPTONLY
RUNSUM
NARROW
SEPARATE
)";
const auto& summary_config = createSummary(deck_string);
BOOST_CHECK(!summary_config.hasKeyword("NARROW"));
BOOST_CHECK(!summary_config.hasKeyword("RPTONLY"));
BOOST_CHECK(!summary_config.hasKeyword("RUNSUM"));
BOOST_CHECK(!summary_config.hasKeyword("SEPARATE"));
BOOST_CHECK(!summary_config.hasKeyword("SUMMARY"));
}
BOOST_AUTO_TEST_CASE(EnableRSM) {
std::string deck_string1 = "";
std::string deck_string2 = R"(
RUNSUM
)";
const auto& summary_config1 = createSummary(deck_string1);
const auto& summary_config2 = createSummary(deck_string2);
BOOST_CHECK(!summary_config1.createRunSummary());
BOOST_CHECK(!summary_config1.hasKeyword("RUNSUM"));
BOOST_CHECK( summary_config2.createRunSummary());
BOOST_CHECK(!summary_config2.hasKeyword("RUNSUM"));
}
BOOST_AUTO_TEST_CASE(FIPREG) {
const std::string deck_string = R"(
-- Both the FIPREG and the FIPXYZ region sets have three distinct
-- values (i.e., region IDs). Consequently, there will be three
-- separate *_REG or *XYZ summary configuration nodes for each
-- region level summary vector requested here.
RPR__REG
/
RPRP_REG
/
RPRH_REG
/
RODENXYZ
/
ROPT_REG
/
RRPV_REG
/
ROEW_REG
/
RHPV_REG
/
)";
const auto summary_config = createSummary(deck_string);
// The +5 corresponds to five additional COPT summary config keywords
// which have been automatically added for the ROEW calculation.
const auto numRegKw = 8;
BOOST_CHECK_EQUAL(summary_config.size(), numRegKw*3 + 5);
BOOST_CHECK( summary_config.hasKeyword("RPR__REG"));
BOOST_CHECK( summary_config.hasKeyword("RPRP_REG"));
BOOST_CHECK( summary_config.hasKeyword("RPRH_REG"));
BOOST_CHECK( summary_config.hasKeyword("RODENXYZ"));
BOOST_CHECK( summary_config.hasKeyword("ROPT_REG"));
BOOST_CHECK( summary_config.hasKeyword("RRPV_REG"));
BOOST_CHECK( summary_config.hasKeyword("ROEW_REG"));
BOOST_CHECK( summary_config.hasKeyword("RHPV_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) {
if (node.keyword() == "RODENXYZ") {
BOOST_CHECK_EQUAL(node.fip_region(), "FIPXYZ");
}
else {
BOOST_CHECK_EQUAL(node.fip_region(), "FIPREG");
}
}
}
{
const auto& fip_regions = summary_config.fip_regions();
BOOST_CHECK_EQUAL(fip_regions.size(), 2U);
auto reg_iter = fip_regions.find("FIPREG");
BOOST_CHECK(reg_iter != fip_regions.end());
}
{
auto rpr = summary_config.keywords("RP*");
BOOST_CHECK_EQUAL(rpr.size(), 9U);
}
// See comment on the roew() function in Summary.cpp for this ugliness.
BOOST_CHECK(summary_config.hasKeyword("COPT"));
}
BOOST_AUTO_TEST_CASE(InterReg_Flows) {
const auto deck_string = std::string { R"(
ROFT
1 2 /
/
ROFTGXYZ
1 2 /
/
RGFT_XYZ
1 2 /
/
RWFR-XYZ
1 3 /
2 3 /
/
RGFR+XYZ
1 3 /
2 3 /
/
RGFTL
2 3 /
/
)" };
const auto summary_config = createSummary(deck_string);
BOOST_CHECK_EQUAL(summary_config.size(), 8);
BOOST_CHECK(summary_config.hasKeyword("ROFT"));
BOOST_CHECK(summary_config.hasKeyword("ROFTGXYZ"));
BOOST_CHECK(summary_config.hasKeyword("RGFT_XYZ"));
BOOST_CHECK(summary_config.hasKeyword("RWFR-XYZ"));
BOOST_CHECK(summary_config.hasKeyword("RGFR+XYZ"));
BOOST_CHECK(summary_config.hasKeyword("RGFTL"));
const auto fip_regions_ireg = summary_config.fip_regions_interreg_flow();
const auto expect = std::vector<std::string> {
"FIPNUM", "FIPXYZ",
};
BOOST_CHECK_MESSAGE(std::is_permutation(fip_regions_ireg.begin(), fip_regions_ireg.end(),
expect.begin(), expect.end()),
"Inter-regional arrays must match expected set");
}
BOOST_AUTO_TEST_CASE( WOPRL ) {
const std::string input1 = R"(
WOPRL
'W_1' 2 /
'xxx' 2 /
/
)";
const std::string input2 = R"(
WOPRL
'W_1' 2 /
'W_1' 999 /
/
)";
ParseContext parseContext;
// Invalid well
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW(createSummary( input1, parseContext ), OpmInputError);
// Invalid completion
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW(createSummary( input2, parseContext ), OpmInputError);
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputErrorAction::IGNORE);
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputErrorAction::IGNORE);
const auto& summary_config1 = createSummary(input1, parseContext);
BOOST_CHECK(summary_config1.hasKeyword("WOPRL__2"));
BOOST_CHECK_EQUAL(summary_config1.size(), 1);
const auto& summary_config2 = createSummary(input2, parseContext );
BOOST_CHECK(summary_config2.hasKeyword("WOPRL__2"));
BOOST_CHECK(!summary_config2.hasKeyword("WOPRL999"));
const auto& node = summary_config2[0];
BOOST_CHECK_EQUAL( node.number(), 2 );
BOOST_CHECK(node.type() == EclIO::SummaryNode::Type::Rate);
}
BOOST_AUTO_TEST_CASE( COPRL ) {
const std::string input1 = R"(
COPRL
'W_1' 3 7 2 /
'xxx' 3 7 2 /
/
)";
const std::string input2 = R"(
COPRL
'W_1' 3 7 2 /
'W_1' 2 6 1 /
/
)";
const std::string input3 = R"(
COPRL
'W_1' /
/
)";
ParseContext parseContext;
// Invalid well
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW(createSummary( input1, parseContext ), OpmInputError);
// Invalid connection
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW(createSummary( input2, parseContext ), OpmInputError);
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputErrorAction::IGNORE);
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputErrorAction::IGNORE);
const auto& summary_config1 = createSummary(input1, parseContext);
BOOST_CHECK(summary_config1.hasKeyword("COPRL"));
BOOST_CHECK_EQUAL(summary_config1.size(), 1);
EclipseGrid grid(10,10,10);
const auto g1 = grid.getGlobalIndex(1,1,0) + 1;
const auto g2 = grid.getGlobalIndex(1,1,1) + 1;
const auto g3 = grid.getGlobalIndex(2,6,1) + 1;
const auto& summary_config2 = createSummary(input2, parseContext );
BOOST_CHECK(summary_config2.hasKeyword("COPRL"));
BOOST_CHECK_EQUAL( summary_config2.size(), 1);
{
const auto& node = summary_config2[0];
BOOST_CHECK_EQUAL( node.number(), g3);
BOOST_CHECK(node.type() == EclIO::SummaryNode::Type::Rate);
}
const auto& summary_config3 = createSummary(input3, parseContext );
BOOST_CHECK(summary_config3.hasKeyword("COPRL"));
BOOST_CHECK_EQUAL( summary_config3.size(), 3);
{
const auto& node = summary_config3[0];
BOOST_CHECK_EQUAL( node.number(), g1);
}
{
const auto& node = summary_config3[1];
BOOST_CHECK_EQUAL( node.number(), g2);
}
{
const auto& node = summary_config3[2];
BOOST_CHECK_EQUAL( node.number(), g3);
}
}
BOOST_AUTO_TEST_CASE( WBP ) {
const std::string input = R"(
MSUMERR
MSUMLINP
WBP
/
WBP4
/
WBP5
/
WBP9
/
)";
const auto& summary_config = createSummary(input);
BOOST_CHECK(summary_config.hasKeyword("WBP"));
BOOST_CHECK(summary_config.hasKeyword("WBP4"));
BOOST_CHECK(summary_config.hasKeyword("WBP5"));
BOOST_CHECK(summary_config.hasKeyword("WBP9"));
}
BOOST_AUTO_TEST_CASE( SUMMARY_INVALID_FIPNUM ) {
const std::string input = R"(
RPR__ABC
1 2 3 /
RWIP_REG
1 2 3 /
)";
const std::string input_too_large = R"(
RPR
1 2 3 99 /
)";
const std::string input_empty= R"(
RPR__REG
15 /
)";
ParseContext parse_context;
{
parse_context.update(ParseContext::SUMMARY_INVALID_FIPNUM, InputErrorAction::IGNORE);
const auto& summary_config = createSummary(input, parse_context);
BOOST_CHECK(summary_config.hasKeyword("RWIP_REG"));
BOOST_CHECK(!summary_config.hasKeyword("RPR__ABC"));
}
{
parse_context.update(ParseContext::SUMMARY_INVALID_FIPNUM, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW(createSummary(input, parse_context), std::exception);
}
{
parse_context.update(ParseContext::SUMMARY_REGION_TOO_LARGE, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW(createSummary(input_too_large, parse_context), std::exception);
}
{
parse_context.update(ParseContext::SUMMARY_REGION_TOO_LARGE, InputErrorAction::IGNORE);
const auto& summary_config = createSummary(input_too_large, parse_context);
BOOST_CHECK_EQUAL( summary_config.size(), 3);
}
{
parse_context.update(ParseContext::SUMMARY_EMPTY_REGION, InputErrorAction::THROW_EXCEPTION);
BOOST_CHECK_THROW(createSummary(input_empty, parse_context), std::exception);
}
{
parse_context.update(ParseContext::SUMMARY_EMPTY_REGION, InputErrorAction::IGNORE);
const auto& summary_config = createSummary(input_empty, parse_context);
BOOST_CHECK_EQUAL( summary_config.size(), 1);
}
}