Make SummaryConfig Nodes for Inter-Region Flows
This commit adds new nodes pertaining to the inter-region flows to the summary configuration keyword list. We combine the pair of region IDs into a single 'NUMS' value as part of creating the node. We also split inter-region nodes into a "supported" and an "unsupported" set, with the former containing the oil, gas, and water keywords. While here, also correct a misprint in a diagnostic message which I noticed as part of developing the new feature.
This commit is contained in:
parent
4b2a37a39e
commit
5a2876642e
@ -344,7 +344,7 @@ public:
|
||||
case FieldProps::GetStatus::MISSING_KEYWORD:
|
||||
throw std::out_of_range("No such keyword in deck: " + keyword);
|
||||
case FieldProps::GetStatus::NOT_SUPPPORTED_KEYWORD:
|
||||
throw std::logic_error("The kewyord " + keyword + " is not supported");
|
||||
throw std::logic_error("The keyword " + keyword + " is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,34 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
|
||||
#include <opm/io/eclipse/EclUtil.hpp>
|
||||
|
||||
#include <opm/common/utility/OpmInputError.hpp>
|
||||
#include <opm/common/utility/shmatch.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Network/ExtNetwork.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/Connection.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParseContext.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckSection.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
@ -25,37 +53,14 @@
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <opm/input/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/common/utility/OpmInputError.hpp>
|
||||
#include <opm/common/utility/shmatch.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckSection.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Network/ExtNetwork.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/Connection.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace {
|
||||
@ -218,6 +223,11 @@ struct SummaryConfigContext {
|
||||
bool is_rate(const std::string& keyword) {
|
||||
static const keyword_set ratekw {
|
||||
"OPR", "GPR", "WPR", "GLIR", "LPR", "NPR", "CPR", "VPR", "TPR", "TPC",
|
||||
|
||||
"OFR", "OFR+", "OFR-",
|
||||
"GFR", "GFR+", "GFR-",
|
||||
"WFR", "WFR+", "WFR-",
|
||||
|
||||
"OPGR", "GPGR", "WPGR", "VPGR",
|
||||
"OPRH", "GPRH", "WPRH", "LPRH",
|
||||
"OVPR", "GVPR", "WVPR",
|
||||
@ -233,7 +243,10 @@ struct SummaryConfigContext {
|
||||
"AQR", "AQRG", "NQR",
|
||||
};
|
||||
|
||||
return is_in_set(ratekw, keyword.substr(1)) || (keyword.length() > 4 && is_in_set({"TPR","TPC","TIR","TIC"}, keyword.substr(1,3)));;
|
||||
return is_in_set(ratekw, keyword.substr(1))
|
||||
|| ((keyword.length() > 4) &&
|
||||
is_in_set({ "TPR", "TPC", "TIR", "TIC" },
|
||||
keyword.substr(1, 3)));
|
||||
}
|
||||
|
||||
bool is_ratio(const std::string& keyword) {
|
||||
@ -252,13 +265,20 @@ struct SummaryConfigContext {
|
||||
"WPTH", "OPTH", "GPTH", "LPTH",
|
||||
"GPTS", "OPTS", "GPTF", "OPTF",
|
||||
|
||||
"OFT", "OFT+", "OFT-", "OFTL", "OFTG",
|
||||
"GFT", "GFT+", "GFT-", "GFTL", "GFTG",
|
||||
"WFT", "WFT+", "WFT-",
|
||||
|
||||
"WIT", "OIT", "GIT", "LIT", "NIT", "CIT", "VIT", "TIT",
|
||||
"WITH", "OITH", "GITH", "WVIT", "OVIT", "GVIT",
|
||||
|
||||
"AQT", "AQTG", "NQT",
|
||||
};
|
||||
|
||||
return is_in_set(totalkw, keyword.substr(1)) || (keyword.length() > 4 && is_in_set({"TPT","TIT"}, keyword.substr(1,3)));
|
||||
return is_in_set(totalkw, keyword.substr(1))
|
||||
|| ((keyword.length() > 4) &&
|
||||
is_in_set({ "TPT", "TIT" },
|
||||
keyword.substr(1, 3)));
|
||||
}
|
||||
|
||||
bool is_count(const std::string& keyword) {
|
||||
@ -293,15 +313,27 @@ struct SummaryConfigContext {
|
||||
return keyword == "WPIL";
|
||||
}
|
||||
|
||||
bool is_region_to_region(const std::string& keyword)
|
||||
bool is_supported_region_to_region(const std::string& keyword)
|
||||
{
|
||||
static const auto rate = std::regex { R"(R[OGWEK]F[RT][-+GL]?)" };
|
||||
static const auto ngl = std::regex { R"(RNLF[RT][-+]?)" };
|
||||
static const auto supported_kw = std::regex { R"(R[OGW]F[RT][-+GL]?)" };
|
||||
|
||||
// R[OGW]F[RT][-+GL]? (e.g., "ROFTG", "RGFR+", or "RWFT")
|
||||
// RNLF[RT].? (e.g., "RNLFR-" or "RNLFT")
|
||||
return std::regex_match(keyword, rate)
|
||||
|| std::regex_match(keyword, ngl);
|
||||
return std::regex_match(keyword, supported_kw);
|
||||
}
|
||||
|
||||
bool is_unsupported_region_to_region(const std::string& keyword)
|
||||
{
|
||||
static const auto unsupported_kw = std::regex { R"(R([EK]|NL)F[RT][-+]?)" };
|
||||
|
||||
// R[EK]F[RT][-+]? (e.g., "REFT" or "RKFR+")
|
||||
// RNLF[RT][-+]? (e.g., "RNLFR-" or "RNLFT")
|
||||
return std::regex_match(keyword, unsupported_kw);
|
||||
}
|
||||
|
||||
bool is_region_to_region(const std::string& keyword)
|
||||
{
|
||||
return is_supported_region_to_region (keyword)
|
||||
|| is_unsupported_region_to_region(keyword);
|
||||
}
|
||||
|
||||
bool is_aquifer(const std::string& keyword)
|
||||
@ -799,52 +831,129 @@ inline void keywordB( SummaryConfig::keyword_list& list,
|
||||
}
|
||||
}
|
||||
|
||||
inline void keywordR2R( SummaryConfig::keyword_list& /* list */,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors,
|
||||
const DeckKeyword& keyword)
|
||||
inline std::optional<std::string>
|
||||
establishRegionContext(const DeckKeyword& keyword,
|
||||
const FieldPropsManager& field_props,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors,
|
||||
SummaryConfigContext& context)
|
||||
{
|
||||
const auto& location = keyword.location();
|
||||
std::string msg_fmt = "Region to region summary keyword {keyword} is ignored\n"
|
||||
"In {file} line {line}";
|
||||
parseContext.handleError(ParseContext::SUMMARY_UNHANDLED_KEYWORD, msg_fmt, location, errors);
|
||||
auto region_name = std::string { "FIPNUM" };
|
||||
|
||||
if (keyword.name().size() > 5) {
|
||||
region_name = "FIP" + keyword.name().substr(5, 3);
|
||||
|
||||
if (! field_props.has_int(region_name)) {
|
||||
const auto msg_fmt =
|
||||
fmt::format("Problem with summary keyword {{keyword}}\n"
|
||||
"In {{file}} line {{line}}\n"
|
||||
"FIP region {} not defined in "
|
||||
"REGIONS section - {{keyword}} ignored", region_name);
|
||||
|
||||
parseContext.handleError(ParseContext::SUMMARY_INVALID_FIPNUM,
|
||||
msg_fmt, keyword.location(), errors);
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (context.regions.count(region_name) == 0) {
|
||||
const auto& fipnum = field_props.get_int(region_name);
|
||||
context.regions.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(region_name),
|
||||
std::forward_as_tuple(fipnum.begin(), fipnum.end()));
|
||||
}
|
||||
|
||||
return { region_name };
|
||||
}
|
||||
|
||||
inline void keywordR2R_unsupported(const DeckKeyword& keyword,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors)
|
||||
{
|
||||
const auto msg_fmt = std::string {
|
||||
"Region to region summary keyword {keyword} is ignored\n"
|
||||
"In {file} line {line}"
|
||||
};
|
||||
|
||||
parseContext.handleError(ParseContext::SUMMARY_UNHANDLED_KEYWORD,
|
||||
msg_fmt, keyword.location(), errors);
|
||||
}
|
||||
|
||||
inline void keywordR2R(const DeckKeyword& keyword,
|
||||
const FieldPropsManager& field_props,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors,
|
||||
SummaryConfigContext& context,
|
||||
SummaryConfig::keyword_list& list)
|
||||
{
|
||||
if (is_unsupported_region_to_region(keyword.name())) {
|
||||
keywordR2R_unsupported(keyword, parseContext, errors);
|
||||
}
|
||||
|
||||
if (is_udq(keyword.name())) {
|
||||
throw std::invalid_argument {
|
||||
"Inter-Region quantity '"
|
||||
+ keyword.name() + "' "
|
||||
+ "cannot be a user-defined quantity"
|
||||
};
|
||||
}
|
||||
|
||||
const auto region_name = establishRegionContext(keyword, field_props,
|
||||
parseContext, errors,
|
||||
context);
|
||||
|
||||
if (! region_name.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto param = SummaryConfigNode {
|
||||
keyword.name(), SummaryConfigNode::Category::Region, keyword.location()
|
||||
}
|
||||
.parameterType(parseKeywordType(keyword.name()))
|
||||
.fip_region(region_name.value())
|
||||
.isUserDefined(false);
|
||||
|
||||
// Expected format:
|
||||
//
|
||||
// ROFT
|
||||
// 1 2 /
|
||||
// 1 4 /
|
||||
// /
|
||||
for (const auto& record : keyword) {
|
||||
// We *intentionally* record/use one-based region IDs here.
|
||||
const auto r1 = record.getItem("REGION1").get<int>(0);
|
||||
const auto r2 = record.getItem("REGION2").get<int>(0);
|
||||
|
||||
list.push_back(param.number(EclIO::combineSummaryNumbers(r1, r2)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void keywordR( SummaryConfig::keyword_list& list,
|
||||
SummaryConfigContext& context,
|
||||
const DeckKeyword& deck_keyword,
|
||||
const Schedule& schedule,
|
||||
const FieldPropsManager& field_props,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors ) {
|
||||
|
||||
auto keyword = deck_keyword.name();
|
||||
if( is_region_to_region(keyword) ) {
|
||||
keywordR2R( list, parseContext, errors, deck_keyword );
|
||||
inline void keywordR(SummaryConfig::keyword_list& list,
|
||||
SummaryConfigContext& context,
|
||||
const DeckKeyword& deck_keyword,
|
||||
const Schedule& schedule,
|
||||
const FieldPropsManager& field_props,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors)
|
||||
{
|
||||
const auto keyword = deck_keyword.name();
|
||||
if (is_region_to_region(keyword)) {
|
||||
keywordR2R(deck_keyword, field_props, parseContext, errors, context, list);
|
||||
return;
|
||||
}
|
||||
std::string region_name = "FIPNUM";
|
||||
if (keyword.size() > 5) {
|
||||
region_name = "FIP" + keyword.substr(5,3);
|
||||
if (!field_props.has_int(region_name)) {
|
||||
std::string msg_fmt = fmt::format("Problem with summary keyword {{keyword}}\n"
|
||||
"In {{file}} line {{line}}\n"
|
||||
"FIP region {} not defined in REGIONS section - {{keyword}} ignored", region_name);
|
||||
parseContext.handleError(ParseContext::SUMMARY_INVALID_FIPNUM, msg_fmt, deck_keyword.location(), errors);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (context.regions.count(region_name) == 0) {
|
||||
const auto& fipnum = field_props.get_int(region_name);
|
||||
context.regions.emplace( region_name, std::set<int>{ fipnum.begin(), fipnum.end()});
|
||||
|
||||
const auto region_name = establishRegionContext(deck_keyword, field_props,
|
||||
parseContext, errors,
|
||||
context);
|
||||
|
||||
if (! region_name.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& item = deck_keyword.getDataRecord().getDataItem();
|
||||
std::vector<int> regions;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Assume that the FIPNUM array contains the values {1,2,4}; i.e. the maximum
|
||||
value is 4 and the value 3 is missing. Values which are too large, i.e. >
|
||||
@ -863,12 +972,12 @@ inline void keywordR( SummaryConfig::keyword_list& list,
|
||||
|
||||
if (item.data_size() > 0) {
|
||||
for (const auto& region_id : item.getData<int>()) {
|
||||
const auto& region_set = context.regions.at(region_name);
|
||||
const auto& region_set = context.regions.at(region_name.value());
|
||||
auto max_iter = region_set.rbegin();
|
||||
if (region_id > *max_iter) {
|
||||
std::string msg_fmt = fmt::format("Problem with summary keyword {{keyword}}\n"
|
||||
"In {{file}} line {{line}}\n"
|
||||
"FIP region {} not present in {} - ignored", region_id, region_name);
|
||||
"FIP region {} not present in {} - ignored", region_id, region_name.value());
|
||||
parseContext.handleError(ParseContext::SUMMARY_REGION_TOO_LARGE, msg_fmt, deck_keyword.location(), errors);
|
||||
continue;
|
||||
}
|
||||
@ -876,14 +985,15 @@ inline void keywordR( SummaryConfig::keyword_list& list,
|
||||
if (region_set.count(region_id) == 0) {
|
||||
std::string msg_fmt = fmt::format("Problem with summary keyword {{keyword}}\n"
|
||||
"In {{file}} line {{line}}\n"
|
||||
"FIP region {} not present in {} - will use 0", region_id, region_name);
|
||||
"FIP region {} not present in {} - will use 0", region_id, region_name.value());
|
||||
parseContext.handleError(ParseContext::SUMMARY_EMPTY_REGION, msg_fmt, deck_keyword.location(), errors);
|
||||
}
|
||||
|
||||
regions.push_back( region_id );
|
||||
}
|
||||
} else {
|
||||
for (const auto& region_id : context.regions.at(region_name))
|
||||
}
|
||||
else {
|
||||
for (const auto& region_id : context.regions.at(region_name.value()))
|
||||
regions.push_back( region_id );
|
||||
}
|
||||
|
||||
@ -899,17 +1009,16 @@ inline void keywordR( SummaryConfig::keyword_list& list,
|
||||
list.push_back( copt_node );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
auto param = SummaryConfigNode {
|
||||
keyword, SummaryConfigNode::Category::Region, deck_keyword.location()
|
||||
}
|
||||
.fip_region( region_name )
|
||||
.parameterType(parseKeywordType(keyword))
|
||||
.fip_region( region_name.value() )
|
||||
.isUserDefined( is_udq(keyword) );
|
||||
|
||||
for( const auto& region : regions )
|
||||
for (const auto& region : regions)
|
||||
list.push_back( param.number( region ) );
|
||||
}
|
||||
|
||||
|
@ -388,6 +388,7 @@ ROFTL
|
||||
ROFTG
|
||||
1 2/
|
||||
3 4/
|
||||
1 3/
|
||||
/
|
||||
RGFT
|
||||
5 6/
|
||||
@ -441,17 +442,118 @@ RWFR-
|
||||
/
|
||||
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, InputError::IGNORE);
|
||||
|
||||
const auto summary = createSummary( input, parseContext );
|
||||
const auto keywords = { "RWIP", "RWIP", "RWIP" };
|
||||
const auto names = sorted_keywords( summary );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(keywords.begin(), keywords.end(),
|
||||
names.begin(), names.end() );
|
||||
|
||||
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW( createSummary(input, parseContext), OpmInputError);
|
||||
|
Loading…
Reference in New Issue
Block a user