Merge pull request #4604 from atgeirr/strict-parsing-parameter

Strict parsing parameter
This commit is contained in:
Atgeirr Flø Rasmussen 2023-04-25 15:19:44 +02:00 committed by GitHub
commit b90cf68d46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 81 additions and 51 deletions

View File

@ -65,7 +65,7 @@ struct EnableOpmRstFile {
using type = UndefinedProperty;
};
template<class TypeTag, class MyTypeTag>
struct EclStrictParsing {
struct ParsingStrictness {
using type = UndefinedProperty;
};
template<class TypeTag, class MyTypeTag>
@ -134,8 +134,8 @@ struct EnableOpmRstFile<TypeTag, TTag::EclBaseVanguard> {
static constexpr bool value = false;
};
template<class TypeTag>
struct EclStrictParsing<TypeTag, TTag::EclBaseVanguard> {
static constexpr bool value = false;
struct ParsingStrictness<TypeTag, TTag::EclBaseVanguard> {
static constexpr auto value = "normal";
};
template<class TypeTag>
struct SchedRestart<TypeTag, TTag::EclBaseVanguard> {
@ -231,8 +231,11 @@ public:
"Include OPM-specific keywords in the ECL restart file to enable restart of OPM simulators from these files");
EWOMS_REGISTER_PARAM(TypeTag, std::string, IgnoreKeywords,
"List of Eclipse keywords which should be ignored. As a ':' separated string.");
EWOMS_REGISTER_PARAM(TypeTag, bool, EclStrictParsing,
"Use strict mode for parsing - all errors are collected before the applicaton exists.");
EWOMS_REGISTER_PARAM(TypeTag, std::string, ParsingStrictness,
"Set strictness of parsing process. Available options are "
"normal (stop for critical errors), "
"high (stop for all errors) and "
"low (as normal, except do not stop due to unsupported keywords even if marked critical");
EWOMS_REGISTER_PARAM(TypeTag, bool, SchedRestart,
"When restarting: should we try to initialize wells and groups from historical SCHEDULE section.");
EWOMS_REGISTER_PARAM(TypeTag, int, EdgeWeightsMethod,
@ -290,7 +293,6 @@ public:
#endif
enableDistributedWells_ = EWOMS_GET_PARAM(TypeTag, bool, AllowDistributedWells);
ignoredKeywords_ = EWOMS_GET_PARAM(TypeTag, std::string, IgnoreKeywords);
eclStrictParsing_ = EWOMS_GET_PARAM(TypeTag, bool, EclStrictParsing);
int output_param = EWOMS_GET_PARAM(TypeTag, int, EclOutputInterval);
if (output_param >= 0)
outputInterval_ = output_param;

View File

@ -133,7 +133,7 @@ void EclGenericVanguard::readDeck(const std::string& filename)
modelParams_.actionState_,
modelParams_.wtestState_,
modelParams_.eclSummaryConfig_,
nullptr, false, false, false, {});
nullptr, "normal", false, false, {});
modelParams_.setupTime_ = setupTimer.stop();
}

View File

@ -296,7 +296,6 @@ protected:
#endif
bool enableDistributedWells_;
std::string ignoredKeywords_;
bool eclStrictParsing_;
std::optional<int> outputInterval_;
bool useMultisegmentWell_;
bool enableExperiments_;

View File

@ -27,10 +27,12 @@
#include <fmt/format.h>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/utility/OpmInputError.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
#include <opm/input/eclipse/Parser/InputErrorAction.hpp>
#include <opm/input/eclipse/Parser/ParseContext.hpp>
#include <opm/simulators/flow/KeywordValidation.hpp>
@ -43,7 +45,7 @@ namespace KeywordValidation
{
std::string get_error_report(const std::vector<ValidationError>& errors, const bool critical)
std::string get_error_report(const std::vector<ValidationError>& errors, const bool include_noncritical, const bool include_critical)
{
const std::string keyword_format = " {keyword}: keyword not supported\n";
const std::string item_format1 = " {{keyword}}: invalid value '{}' for item {}\n";
@ -52,7 +54,7 @@ namespace KeywordValidation
std::string report;
for (const ValidationError& err : errors) {
if (err.critical == critical) {
if ((err.critical && include_critical) || (!err.critical && include_noncritical)) {
if (err.item_number && err.item_value) {
std::string message;
if (err.record_number == 0) {
@ -84,6 +86,7 @@ namespace KeywordValidation
void
KeywordValidator::validateDeck(const Deck& deck,
const ParseContext& parse_context,
const bool treat_critical_as_noncritical,
ErrorGuard& error_guard) const
{
// Make a vector with all problems encountered in the deck.
@ -98,18 +101,31 @@ namespace KeywordValidation
}
}
// First report non-critical problems as a warning.
auto warning_report = get_error_report(errors, false);
if (!warning_report.empty()) {
parse_context.handleError(
ParseContext::SIMULATOR_KEYWORD_NOT_SUPPORTED, warning_report, std::nullopt, error_guard);
}
if (treat_critical_as_noncritical) {
// Get both critical and noncritical errors.
auto warning_report = get_error_report(errors, true, true);
if (!warning_report.empty()) {
// Report all as warnings.
parse_context.handleError(ParseContext::SIMULATOR_KEYWORD_NOT_SUPPORTED, warning_report, std::nullopt, error_guard);
}
} else {
// First report non-critical problems as a warning.
auto warning_report = get_error_report(errors, true, false);
if (!warning_report.empty()) {
parse_context.handleError(
ParseContext::SIMULATOR_KEYWORD_NOT_SUPPORTED, warning_report, std::nullopt, error_guard);
}
// Then report critical problems as an error.
auto error_report = get_error_report(errors, true);
if (!error_report.empty()) {
parse_context.handleError(
ParseContext::SIMULATOR_KEYWORD_NOT_SUPPORTED_CRITICAL, error_report, std::nullopt, error_guard);
// Then report critical problems as an error.
auto error_report = get_error_report(errors, false, true);
if (!error_report.empty()) {
OpmLog::info("\nOPM Flow will terminate due to unsupported critical keywords.\n"
"These are keywords that would change the simulator results if supported.\n"
"If you need to override this behaviour, you can use the command line argument --parsing-strictness=low,\n"
"this will reduce the severity of this to a warning instead of an error.");
parse_context.handleError(
ParseContext::SIMULATOR_KEYWORD_NOT_SUPPORTED_CRITICAL, error_report, std::nullopt, error_guard);
}
}
}

View File

@ -78,11 +78,12 @@ namespace KeywordValidation
};
// Get a formatted error report from a vector of validation errors. Set
// critical to true if the report should contain only critical errors. If
// critical is false, only non-critical errors are reported. If not
// critical/non-critical errors are present, but the critical flag to reset
// them, the result will be an empty string.
std::string get_error_report(const std::vector<ValidationError>& errors, const bool critical);
// include_noncritical to true if the report should include noncritical errors, and
// include_critical to true if the report should include critical errors. These may
// be set independently. If no errors are included the result will be an empty string.
std::string get_error_report(const std::vector<ValidationError>& errors,
const bool include_noncritical,
const bool include_critical);
@ -109,9 +110,12 @@ namespace KeywordValidation
// Validate a deck, reporting warnings and errors. If there are only
// warnings, these will be reported. If there are errors, these are
// reported, and execution of the program is halted.
// reported, and execution of the program is halted, unless the argument
// treat_critical_as_noncritical is true, then these also will only be
// reported and not cause termination.
void validateDeck(const Deck& deck,
const ParseContext& parse_context,
const bool treat_critical_as_noncritical,
ErrorGuard& error_guard) const;
// Validate a single deck keyword. If a problem is encountered, add the

View File

@ -171,7 +171,7 @@ void Main::readDeck(const std::string& deckFilename,
const std::string& outputMode,
const bool init_from_restart_file,
const bool allRanksDbgPrtLog,
const bool strictParsing,
const std::string& parsingStrictness,
const int mpiRank,
const int output_param,
const std::string& parameters,
@ -202,7 +202,7 @@ void Main::readDeck(const std::string& deckFilename,
wtestState_,
summaryConfig_,
std::make_shared<Python>(),
strictParsing,
parsingStrictness,
init_from_restart_file,
outputCout_,
outputInterval);

View File

@ -374,7 +374,7 @@ private:
EWOMS_GET_PARAM(PreTypeTag, std::string, OutputMode),
!EWOMS_GET_PARAM(PreTypeTag, bool, SchedRestart),
EWOMS_GET_PARAM(PreTypeTag, bool, EnableLoggingFalloutWarning),
EWOMS_GET_PARAM(PreTypeTag, bool, EclStrictParsing),
EWOMS_GET_PARAM(PreTypeTag, std::string, ParsingStrictness),
mpiRank,
EWOMS_GET_PARAM(PreTypeTag, int, EclOutputInterval),
cmdline_params,
@ -626,7 +626,7 @@ private:
const std::string& outputMode,
const bool init_from_restart_file,
const bool allRanksDbgPrtLog,
const bool strictParsing,
const std::string& parsingStrictness,
const int mpiRank,
const int output_param,
const std::string& parameters,

View File

@ -191,6 +191,7 @@ namespace {
const bool checkDeck,
const Opm::Parser& parser,
const Opm::ParseContext& parseContext,
const bool treatCriticalAsNonCritical,
Opm::ErrorGuard& errorGuard)
{
Opm::Deck deck(parser.parseFile(deckFilename, parseContext, errorGuard));
@ -203,7 +204,7 @@ namespace {
Opm::KeywordValidation::specialValidation()
};
keyword_validator.validateDeck(deck, parseContext, errorGuard);
keyword_validator.validateDeck(deck, parseContext, treatCriticalAsNonCritical, errorGuard);
if (checkDeck) {
Opm::checkDeck(deck, parser, parseContext, errorGuard);
@ -235,6 +236,7 @@ namespace {
std::shared_ptr<Opm::Python> python,
const bool initFromRestart,
const bool checkDeck,
const bool treatCriticalAsNonCritical,
const std::optional<int>& outputInterval,
Opm::ErrorGuard& errorGuard)
{
@ -248,7 +250,7 @@ namespace {
auto parser = Opm::Parser{};
const auto deck = readDeckFile(deckFilename, checkDeck, parser,
*parseContext, errorGuard);
*parseContext, treatCriticalAsNonCritical, errorGuard);
if (eclipseState == nullptr) {
eclipseState = createEclipseState(comm, deck);
@ -490,7 +492,7 @@ void Opm::readDeck(Opm::Parallel::Communication comm,
std::unique_ptr<WellTestState>& wtestState,
std::shared_ptr<SummaryConfig>& summaryConfig,
std::shared_ptr<Python> python,
const bool strictParsing,
const std::string& parsingStrictness,
const bool initFromRestart,
const bool checkDeck,
const std::optional<int>& outputInterval)
@ -500,13 +502,20 @@ void Opm::readDeck(Opm::Parallel::Communication comm,
int parseSuccess = 1; // > 0 is success
std::string failureMessage;
if (parsingStrictness != "high" && parsingStrictness != "normal" && parsingStrictness != "low") {
OPM_THROW(std::runtime_error,
fmt::format("Incorrect value {} for parameter ParsingStrictness, must be 'high', 'normal', or 'low'", parsingStrictness));
}
if (comm.rank() == 0) { // Always true when !HAVE_MPI
const bool exitOnAllErrors = (parsingStrictness == "high");
const bool treatCriticalAsNonCritical = (parsingStrictness == "low");
try {
auto parseContext = setupParseContext(strictParsing);
auto parseContext = setupParseContext(exitOnAllErrors);
readOnIORank(comm, deckFilename, parseContext.get(),
eclipseState, schedule, udqState, actionState, wtestState,
summaryConfig, std::move(python), initFromRestart,
checkDeck, outputInterval, *errorGuard);
checkDeck, treatCriticalAsNonCritical, outputInterval, *errorGuard);
}
catch (const OpmInputError& input_error) {
failureMessage = input_error.what();

View File

@ -60,7 +60,7 @@ enum class FileOutputMode {
void
ensureOutputDirExists(const std::string& cmdline_output_dir);
std::unique_ptr<ParseContext> setupParseContext(const bool strictParsing);
std::unique_ptr<ParseContext> setupParseContext(const bool exitOnAllErrors);
// Setup the OpmLog backends
FileOutputMode
@ -85,7 +85,7 @@ void readDeck(Parallel::Communication comm,
std::unique_ptr<WellTestState>& wtestState,
std::shared_ptr<SummaryConfig>& summaryConfig,
std::shared_ptr<Python> python,
bool strictParsing,
const std::string& parsingStrictness,
bool initFromRestart,
bool checkDeck,
const std::optional<int>& outputInterval);

View File

@ -277,7 +277,7 @@ ECHO
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, false);
const auto report = get_error_report(errors, true, false);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" ECHO: keyword not supported\n"
@ -296,7 +296,7 @@ ECHO
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, true);
const auto report = get_error_report(errors, false, true);
BOOST_CHECK(report.empty());
}
@ -311,7 +311,7 @@ NOECHO
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, true);
const auto report = get_error_report(errors, false, true);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" NOECHO: keyword not supported\n"
@ -329,7 +329,7 @@ NOECHO
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, false);
const auto report = get_error_report(errors, true, false);
BOOST_CHECK(report.empty());
}
@ -345,7 +345,7 @@ PINCH
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, false);
const auto report = get_error_report(errors, true, false);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" PINCH: invalid value 'FOO' for item 2\n"
@ -368,7 +368,7 @@ COMPDAT
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, false);
const auto report = get_error_report(errors, true, false);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" COMPDAT: invalid value '0' in record 1 for item 2\n"
@ -389,7 +389,7 @@ PINCH
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, true);
const auto report = get_error_report(errors, false, true);
BOOST_CHECK(report.empty());
}
@ -405,7 +405,7 @@ ENDSCALE
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, false);
const auto report = get_error_report(errors, true, false);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" ENDSCALE: invalid value '0' for item 3\n"
@ -424,7 +424,7 @@ ENDSCALE
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, true);
const auto report = get_error_report(errors, false, true);
BOOST_CHECK(report.empty());
}
@ -440,7 +440,7 @@ ENDSCALE
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, true);
const auto report = get_error_report(errors, false, true);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" ENDSCALE: invalid value '0' for item 4\n"
@ -459,7 +459,7 @@ ENDSCALE
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
const auto report = get_error_report(errors, false);
const auto report = get_error_report(errors, true, false);
BOOST_CHECK(report.empty());
}
@ -485,7 +485,7 @@ ENDSCALE
validator.validateDeckKeyword(test_keyword2, errors);
validator.validateDeckKeyword(test_keyword3, errors);
validator.validateDeckKeyword(test_keyword4, errors);
const auto report = get_error_report(errors, false);
const auto report = get_error_report(errors, true, false);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" ECHO: keyword not supported\n"
@ -516,7 +516,7 @@ ENDSCALE
validator.validateDeckKeyword(test_keyword2, errors);
validator.validateDeckKeyword(test_keyword3, errors);
validator.validateDeckKeyword(test_keyword4, errors);
const auto report = get_error_report(errors, true);
const auto report = get_error_report(errors, false, true);
BOOST_CHECK(report
== "Unsupported keywords or keyword items:\n\n"
" NOECHO: keyword not supported\n"