Add basic functionality for validating special case keywords

This commit is contained in:
Joakim Hove 2021-07-23 09:58:52 +02:00
parent 725800cec7
commit 060eac4999
7 changed files with 153 additions and 31 deletions

View File

@ -38,6 +38,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/flow/countGlobalCells.cpp
opm/simulators/flow/KeywordValidation.cpp
opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.cpp
opm/simulators/flow/ValidationFunctions.cpp
opm/simulators/linalg/ExtractParallelGridInformationToISTL.cpp
opm/simulators/linalg/FlexibleSolver1.cpp
opm/simulators/linalg/FlexibleSolver2.cpp
@ -230,6 +231,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/simulators/flow/NonlinearSolverEbos.hpp
opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp
opm/simulators/flow/KeywordValidation.hpp
opm/simulators/flow/ValidationFunctions.hpp
opm/core/props/BlackoilPhases.hpp
opm/core/props/phaseUsageFromDeck.hpp
opm/core/props/satfunc/RelpermDiagnostics.hpp

View File

@ -33,9 +33,12 @@
namespace Opm
{
namespace KeywordValidation
{
std::string get_error_report(const std::vector<ValidationError>& errors, const bool critical)
{
const std::string keyword_format = " {keyword}: keyword not supported\n";
@ -75,13 +78,22 @@ namespace KeywordValidation
}
void
KeywordValidator::validateDeck(const Deck& deck, const ParseContext& parse_context, ErrorGuard& error_guard) const
KeywordValidator::validateDeck(const Deck& deck,
const ParseContext& parse_context,
ErrorGuard& error_guard) const
{
// Make a vector with all problems encountered in the deck.
std::vector<ValidationError> errors;
for (const auto& keyword : deck)
for (const auto& keyword : deck) {
validateDeckKeyword(keyword, errors);
const auto& special_it = this->m_special_validation.find(keyword.name());
if (special_it != this->m_special_validation.end()) {
const auto& validator = special_it->second;
validator(keyword, errors);
}
}
// First report non-critical problems as a warning.
auto warning_report = get_error_report(errors, false);
if (!warning_report.empty()) {

View File

@ -83,24 +83,35 @@ namespace KeywordValidation
// them, the result will be an empty string.
std::string get_error_report(const std::vector<ValidationError>& errors, const bool critical);
// These are special case validation functions for keyword which do not fit nicely into the general
// validation framework. The validation function itself is void, but error conditions are signalled by
// appending ValidationError instances to the @errors vector.
void validateBRINE(const DeckKeyword& keyword, std::vector<ValidationError>& errors);
class KeywordValidator
{
public:
KeywordValidator(const UnsupportedKeywords& keywords,
const PartiallySupportedKeywords<std::string>& string_items,
const PartiallySupportedKeywords<int>& int_items,
const PartiallySupportedKeywords<double>& double_items)
const PartiallySupportedKeywords<double>& double_items,
const std::unordered_map<std::string, std::function<void(const DeckKeyword& keyword, std::vector<ValidationError>& errors)>>& special_validation)
: m_keywords(keywords)
, m_string_items(string_items)
, m_int_items(int_items)
, m_double_items(double_items)
, m_special_validation(special_validation)
{
}
// 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.
void validateDeck(const Deck& deck, const ParseContext& parse_context, ErrorGuard& error_guard) const;
void validateDeck(const Deck& deck,
const ParseContext& parse_context,
ErrorGuard& error_guard) const;
// Validate a single deck keyword. If a problem is encountered, add the
// relevant information to the errors vector.
@ -126,6 +137,7 @@ namespace KeywordValidation
const PartiallySupportedKeywords<std::string> m_string_items;
const PartiallySupportedKeywords<int> m_int_items;
const PartiallySupportedKeywords<double> m_double_items;
const std::unordered_map<std::string, std::function<void(const DeckKeyword& keyword, std::vector<ValidationError>& errors)>> m_special_validation;
};

View File

@ -0,0 +1,44 @@
/*
Copyright 2021 Equinor.
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/>.
*/
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/simulators/flow/KeywordValidation.hpp>
namespace Opm
{
namespace KeywordValidation
{
void validateBRINE(const DeckKeyword& keyword, std::vector<ValidationError>& errors) {
if (keyword.size() == 0)
return;
bool critical = false;
errors.push_back( ValidationError{ critical,
keyword.location(),
0, // not relevant
0, // not relevant
std::nullopt,
std::string{"The BRINE keyword does not accept any salt name arguments"}} );
}
}
}

View File

@ -0,0 +1,46 @@
/*
Copyright 2021 Equinor.
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/>.
*/
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/simulators/flow/KeywordValidation.hpp>
namespace Opm
{
namespace KeywordValidation
{
void validateBRINE(const DeckKeyword& keyword, std::vector<ValidationError>& errors);
// This is a mapping between keyword names and small functions
// for validation of special keywords.
std::unordered_map<std::string, std::function<void(const DeckKeyword& keyword, std::vector<KeywordValidation::ValidationError>& errors)>> specialValidation() {
return {{"BRINE", validateBRINE}};
};
}
}

View File

@ -55,6 +55,7 @@
#include "UnsupportedFlowKeywords.hpp"
#include "PartiallySupportedFlowKeywords.hpp"
#include <opm/simulators/flow/KeywordValidation.hpp>
#include <opm/simulators/flow/ValidationFunctions.hpp>
#include <opm/simulators/utils/ParallelEclipseState.hpp>
#include <opm/simulators/utils/ParallelSerialization.hpp>
@ -62,7 +63,9 @@
#include <fmt/format.h>
#include <cstdlib>
#include <functional>
#include <memory>
#include <unordered_map>
#include <utility>
namespace Opm
@ -210,6 +213,7 @@ void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& d
if (!deck)
{
Opm::Parser parser;
deck = std::make_unique<Opm::Deck>( parser.parseFile(deckFilename , *parseContext, *errorGuard));
@ -217,7 +221,9 @@ void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& d
Opm::FlowKeywordValidation::unsupportedKeywords(),
Opm::FlowKeywordValidation::partiallySupported<std::string>(),
Opm::FlowKeywordValidation::partiallySupported<int>(),
Opm::FlowKeywordValidation::partiallySupported<double>());
Opm::FlowKeywordValidation::partiallySupported<double>(),
Opm::KeywordValidation::specialValidation());
keyword_validator.validateDeck(*deck, *parseContext, *errorGuard);
if ( checkDeck )

View File

@ -91,7 +91,7 @@ ECHO
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ECHO");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(!errors[0].critical);
@ -108,7 +108,7 @@ NOECHO
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("NOECHO");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(errors[0].critical);
@ -126,7 +126,7 @@ PINCH
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("PINCH");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(!errors[0].critical);
@ -144,7 +144,7 @@ PINCH
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("PINCH");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(errors[0].critical);
@ -162,7 +162,7 @@ ENDSCALE
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(!errors[0].critical);
@ -180,7 +180,7 @@ ENDSCALE
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(errors[0].critical);
@ -197,7 +197,7 @@ EHYSTR
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("EHYSTR");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(errors.size() == 0);
@ -211,7 +211,7 @@ EHYSTR
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("EHYSTR");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(!errors[0].critical);
@ -228,7 +228,7 @@ EHYSTR
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("EHYSTR");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(!errors[0].critical);
@ -248,7 +248,7 @@ ENDSCALE
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword1 = deck.getKeyword("PINCH");
const auto& test_keyword2 = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword1, errors);
validator.validateDeckKeyword(test_keyword2, errors);
@ -270,7 +270,7 @@ ECHO
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ECHO");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -289,7 +289,7 @@ ECHO
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ECHO");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -304,7 +304,7 @@ NOECHO
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("NOECHO");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -322,7 +322,7 @@ NOECHO
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("NOECHO");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -338,7 +338,7 @@ PINCH
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("PINCH");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -361,7 +361,7 @@ COMPDAT
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("COMPDAT");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -382,7 +382,7 @@ PINCH
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("PINCH");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -398,7 +398,7 @@ ENDSCALE
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -417,7 +417,7 @@ ENDSCALE
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -433,7 +433,7 @@ ENDSCALE
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -452,7 +452,7 @@ ENDSCALE
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
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);
@ -475,7 +475,7 @@ ENDSCALE
const auto& test_keyword2 = deck.getKeyword("NOECHO");
const auto& test_keyword3 = deck.getKeyword("PINCH");
const auto& test_keyword4 = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword1, errors);
validator.validateDeckKeyword(test_keyword2, errors);
@ -506,7 +506,7 @@ ENDSCALE
const auto& test_keyword2 = deck.getKeyword("NOECHO");
const auto& test_keyword3 = deck.getKeyword("PINCH");
const auto& test_keyword4 = deck.getKeyword("ENDSCALE");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword1, errors);
validator.validateDeckKeyword(test_keyword2, errors);
@ -531,7 +531,7 @@ EQLOPTS
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("EQLOPTS");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(errors.size() == 0);
@ -547,7 +547,7 @@ EQLOPTS
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("EQLOPTS");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(errors.size() == 1);
@ -566,7 +566,7 @@ EQLOPTS
)"};
const auto deck = Parser {}.parseString(keywords_string);
const auto& test_keyword = deck.getKeyword("EQLOPTS");
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items);
KeywordValidator validator(test_unsupported_keywords, test_string_items, test_int_items, test_double_items, {});
std::vector<ValidationError> errors;
validator.validateDeckKeyword(test_keyword, errors);
BOOST_CHECK(errors.size() == 0);