mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #4604 from atgeirr/strict-parsing-parameter
Strict parsing parameter
This commit is contained in:
commit
b90cf68d46
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -296,7 +296,6 @@ protected:
|
||||
#endif
|
||||
bool enableDistributedWells_;
|
||||
std::string ignoredKeywords_;
|
||||
bool eclStrictParsing_;
|
||||
std::optional<int> outputInterval_;
|
||||
bool useMultisegmentWell_;
|
||||
bool enableExperiments_;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user