Merge pull request #1949 from joakim-hove/error-prepare

Error prepare
This commit is contained in:
Joakim Hove
2020-09-24 07:33:22 +02:00
committed by GitHub
15 changed files with 76 additions and 33 deletions

View File

@@ -20,10 +20,25 @@
#ifndef KEYWORD_LOCATION_HPP #ifndef KEYWORD_LOCATION_HPP
#define KEYWORD_LOCATION_HPP #define KEYWORD_LOCATION_HPP
#include <string>
namespace Opm { namespace Opm {
class KeywordLocation { class KeywordLocation {
public: public:
/*
Observe that many error messages whcih should print out the name of the
problem keyword along with the location {} placeholders can be used. The
convention is:
{keyword} -> keyword
{file} -> filename
{line} -> lineno
This convention must be adhered to at the call site *creating the output
string*.
*/
std::string keyword; std::string keyword;
std::string filename = "<memory string>"; std::string filename = "<memory string>";
std::size_t lineno = 0; std::size_t lineno = 0;

View File

@@ -21,7 +21,9 @@
#include <iosfwd> #include <iosfwd>
#include <string> #include <string>
#include <optional>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp> #include <opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp>
#include <opm/parser/eclipse/EclipseState/EndpointScaling.hpp> #include <opm/parser/eclipse/EclipseState/EndpointScaling.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
@@ -106,11 +108,17 @@ public:
return this->nWMax; return this->nWMax;
} }
const std::optional<KeywordLocation>& location() const {
return this->m_location;
}
bool operator==(const Welldims& data) const { bool operator==(const Welldims& data) const {
return this->maxConnPerWell() == data.maxConnPerWell() && return this->maxConnPerWell() == data.maxConnPerWell() &&
this->maxWellsPerGroup() == data.maxWellsPerGroup() && this->maxWellsPerGroup() == data.maxWellsPerGroup() &&
this->maxGroupsInField() == data.maxGroupsInField() && this->maxGroupsInField() == data.maxGroupsInField() &&
this->maxWellsInField() == data.maxWellsInField(); this->maxWellsInField() == data.maxWellsInField() &&
this->location() == data.location();
} }
template<class Serializer> template<class Serializer>
@@ -120,6 +128,7 @@ public:
serializer(nCWMax); serializer(nCWMax);
serializer(nWGMax); serializer(nWGMax);
serializer(nGMax); serializer(nGMax);
serializer(m_location);
} }
private: private:
@@ -127,6 +136,7 @@ private:
int nCWMax { 0 }; int nCWMax { 0 };
int nWGMax { 0 }; int nWGMax { 0 };
int nGMax { 0 }; int nGMax { 0 };
std::optional<KeywordLocation> m_location;
}; };
class WellSegmentDims { class WellSegmentDims {

View File

@@ -123,7 +123,7 @@ namespace Opm {
SectionNameSet::const_iterator validSectionNamesBegin() const; SectionNameSet::const_iterator validSectionNamesBegin() const;
SectionNameSet::const_iterator validSectionNamesEnd() const; SectionNameSet::const_iterator validSectionNamesEnd() const;
DeckKeyword parse(const ParseContext& parseContext, ErrorGuard& errors, RawKeyword& rawKeyword, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& filename) const; DeckKeyword parse(const ParseContext& parseContext, ErrorGuard& errors, RawKeyword& rawKeyword, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem) const;
enum ParserKeywordSizeEnum getSizeType() const; enum ParserKeywordSizeEnum getSizeType() const;
const KeywordSize& getKeywordSize() const; const KeywordSize& getKeywordSize() const;
bool isDataKeyword() const; bool isDataKeyword() const;

View File

@@ -35,6 +35,7 @@ namespace Opm {
class RawRecord; class RawRecord;
class ErrorGuard; class ErrorGuard;
class UnitSystem; class UnitSystem;
class KeywordLocation;
class ParserRecord { class ParserRecord {
public: public:
@@ -44,7 +45,7 @@ namespace Opm {
void addDataItem( ParserItem item ); void addDataItem( ParserItem item );
const ParserItem& get(size_t index) const; const ParserItem& get(size_t index) const;
const ParserItem& get(const std::string& itemName) const; const ParserItem& get(const std::string& itemName) const;
DeckRecord parse( const ParseContext&, ErrorGuard&, RawRecord&, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& keyword, const std::string& filename) const; DeckRecord parse( const ParseContext&, ErrorGuard&, RawRecord&, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const KeywordLocation& location) const;
bool isDataRecord() const; bool isDataRecord() const;
bool equal(const ParserRecord& other) const; bool equal(const ParserRecord& other) const;
bool hasDimension() const; bool hasDimension() const;

View File

@@ -97,19 +97,23 @@ bool Phases::operator==(const Phases& data) const {
Welldims::Welldims(const Deck& deck) Welldims::Welldims(const Deck& deck)
{ {
if (deck.hasKeyword("WELLDIMS")) { using WD = ParserKeywords::WELLDIMS;
const auto& wd = deck.getKeyword("WELLDIMS", 0).getRecord(0); if (deck.hasKeyword<WD>()) {
const auto& keyword = deck.getKeyword<WD>(0);
const auto& wd = keyword.getRecord(0);
this->nCWMax = wd.getItem("MAXCONN") .get<int>(0); this->nCWMax = wd.getItem<WD::MAXCONN>().get<int>(0);
this->nWGMax = wd.getItem("MAX_GROUPSIZE").get<int>(0); this->nWGMax = wd.getItem<WD::MAX_GROUPSIZE>().get<int>(0);
// This is the E100 definition. E300 instead uses // This is the E100 definition. E300 instead uses
// //
// Max{ "MAXGROUPS", "MAXWELLS" } // Max{ "MAXGROUPS", "MAXWELLS" }
// //
// i.e., the maximum of item 1 and item 4 here. // i.e., the maximum of item 1 and item 4 here.
this->nGMax = wd.getItem("MAXGROUPS").get<int>(0); this->nGMax = wd.getItem<WD::MAXGROUPS>().get<int>(0);
this->nWMax = wd.getItem("MAXWELLS").get<int>(0); this->nWMax = wd.getItem<WD::MAXWELLS>().get<int>(0);
this->m_location = keyword.location();
} }
} }
@@ -120,7 +124,7 @@ Welldims Welldims::serializeObject()
result.nCWMax = 2; result.nCWMax = 2;
result.nWGMax = 3; result.nWGMax = 3;
result.nGMax = 4; result.nGMax = 4;
result.m_location = KeywordLocation::serializeObject();
return result; return result;
} }

View File

@@ -56,6 +56,9 @@ GPMaint GPMaint::serializeObject() {
gpm.m_flow_target = FlowTarget::SURF_GINJ; gpm.m_flow_target = FlowTarget::SURF_GINJ;
gpm.m_region_name = "FIPNUM"; gpm.m_region_name = "FIPNUM";
gpm.m_region_number = 26; gpm.m_region_number = 26;
gpm.m_pressure_target = 100.0;
gpm.m_prop_constant = 200.0;
gpm.m_time_constant = 300.0;
return gpm; return gpm;
} }

View File

@@ -67,6 +67,7 @@ Group Group::serializeObject()
result.injection_properties = {{Opm::Phase::OIL, GroupInjectionProperties::serializeObject()}}; result.injection_properties = {{Opm::Phase::OIL, GroupInjectionProperties::serializeObject()}};
result.production_properties = GroupProductionProperties::serializeObject(); result.production_properties = GroupProductionProperties::serializeObject();
result.m_topup_phase = {Phase::OIL, true}; result.m_topup_phase = {Phase::OIL, true};
result.m_gpmaint = GPMaint::serializeObject();
return result; return result;
} }

View File

@@ -919,8 +919,7 @@ bool parseState( ParserState& parserState, const Parser& parser ) {
parserState.errors, parserState.errors,
*rawKeyword, *rawKeyword,
parserState.deck.getActiveUnitSystem(), parserState.deck.getActiveUnitSystem(),
parserState.deck.getDefaultUnitSystem(), parserState.deck.getDefaultUnitSystem()));
filename ) );
} catch (const std::exception& exc) { } catch (const std::exception& exc) {
/* /*
This catch-all of parsing errors is to be able to write a good This catch-all of parsing errors is to be able to write a good

View File

@@ -551,7 +551,7 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
std::string_view rep = !st.hasValue() std::string_view rep = !st.hasValue()
? std::string_view{ one_star } ? std::string_view{ one_star }
: std::string_view{ token.begin() + value_start, size }; : std::string_view{ token.begin() + value_start, size };
record.prepend( st.count() - 1, rep ); record.push_front(rep, st.count() - 1);
return; return;
} }

View File

@@ -532,8 +532,7 @@ void set_dimensions( ParserItem& item,
ErrorGuard& errors, ErrorGuard& errors,
RawKeyword& rawKeyword, RawKeyword& rawKeyword,
UnitSystem& active_unitsystem, UnitSystem& active_unitsystem,
UnitSystem& default_unitsystem, UnitSystem& default_unitsystem) const {
const std::string& filename) const {
if( !rawKeyword.isFinished() ) if( !rawKeyword.isFinished() )
throw std::invalid_argument("Tried to create a deck keyword from an incomplete raw keyword " + rawKeyword.getKeywordName()); throw std::invalid_argument("Tried to create a deck keyword from an incomplete raw keyword " + rawKeyword.getKeywordName());
@@ -555,7 +554,7 @@ void set_dimensions( ParserItem& item,
record_nr = 0; record_nr = 0;
} }
else { else {
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.getKeywordName(), filename ) ); keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.location() ) );
record_nr++; record_nr++;
} }
} }
@@ -566,7 +565,7 @@ void set_dimensions( ParserItem& item,
if( m_records.size() == 0 && rawRecord.size() > 0 ) if( m_records.size() == 0 && rawRecord.size() > 0 )
throw std::invalid_argument("Missing item information " + rawKeyword.getKeywordName()); throw std::invalid_argument("Missing item information " + rawKeyword.getKeywordName());
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.getKeywordName(), filename ) ); keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.location() ) );
record_nr++; record_nr++;
} }
} }

View File

@@ -24,6 +24,8 @@
#include <opm/parser/eclipse/Parser/ParserItem.hpp> #include <opm/parser/eclipse/Parser/ParserItem.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp> #include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include "raw/RawRecord.hpp" #include "raw/RawRecord.hpp"
namespace Opm { namespace Opm {
@@ -118,14 +120,14 @@ namespace {
} }
DeckRecord ParserRecord::parse(const ParseContext& parseContext , ErrorGuard& errors , RawRecord& rawRecord, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& keyword, const std::string& filename) const { DeckRecord ParserRecord::parse(const ParseContext& parseContext , ErrorGuard& errors , RawRecord& rawRecord, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const KeywordLocation& location) const {
std::vector< DeckItem > items; std::vector< DeckItem > items;
items.reserve( this->size() + 20 ); items.reserve( this->size() + 20 );
for( const auto& parserItem : *this ) for( const auto& parserItem : *this )
items.emplace_back( parserItem.scan( rawRecord, active_unitsystem, default_unitsystem ) ); items.emplace_back( parserItem.scan( rawRecord, active_unitsystem, default_unitsystem ) );
if (rawRecord.size() > 0) { if (rawRecord.size() > 0) {
std::string msg = "The RawRecord for keyword \"" + keyword + "\" in file\"" + filename + "\" contained " + std::string msg = "The RawRecord for keyword \"" + location.keyword + "\" in file\"" + location.filename + "\" contained " +
std::to_string(rawRecord.size()) + std::to_string(rawRecord.size()) +
" too many items according to the spec. RawRecord was: " + rawRecord.getRecordString(); " too many items according to the spec. RawRecord was: " + rawRecord.getRecordString();
parseContext.handleError(ParseContext::PARSE_EXTRA_DATA , msg, errors); parseContext.handleError(ParseContext::PARSE_EXTRA_DATA , msg, errors);

View File

@@ -90,17 +90,23 @@ inline bool even_quotes( const T& str ) {
throw std::invalid_argument("Input string is not a complete record string, " throw std::invalid_argument("Input string is not a complete record string, "
"offending string: '" + std::string(singleRecordString) + "'"); "offending string: '" + std::string(singleRecordString) + "'");
} }
this->m_max_size = this->m_recordItems.size();
} }
RawRecord::RawRecord(const std::string_view& singleRecordString) : RawRecord::RawRecord(const std::string_view& singleRecordString) :
RawRecord(singleRecordString, false) RawRecord(singleRecordString, false)
{} {}
void RawRecord::prepend( size_t count, std::string_view tok ) { void RawRecord::push_front( std::string_view tok, std::size_t count ) {
this->m_recordItems.insert( this->m_recordItems.begin(), count, tok ); this->m_recordItems.insert( this->m_recordItems.begin(), count, tok );
this->m_max_size += count;
} }
std::string RawRecord::getRecordString() const { std::string RawRecord::getRecordString() const {
return std::string(m_sanitizedRecordString); return std::string(m_sanitizedRecordString);
} }
std::size_t RawRecord::max_size() const {
return this->m_max_size;
}
} }

View File

@@ -39,9 +39,9 @@ namespace Opm {
inline std::string_view pop_front(); inline std::string_view pop_front();
inline std::string_view front() const; inline std::string_view front() const;
void push_front( std::string_view token ); void push_front( std::string_view token, std::size_t count );
void prepend( size_t count, std::string_view token );
inline size_t size() const; inline size_t size() const;
std::size_t max_size() const;
std::string getRecordString() const; std::string getRecordString() const;
inline std::string_view getItem(size_t index) const; inline std::string_view getItem(size_t index) const;
@@ -49,6 +49,7 @@ namespace Opm {
private: private:
std::string_view m_sanitizedRecordString; std::string_view m_sanitizedRecordString;
std::deque< std::string_view > m_recordItems; std::deque< std::string_view > m_recordItems;
std::size_t m_max_size;
}; };
/* /*

View File

@@ -485,10 +485,11 @@ BOOST_AUTO_TEST_CASE(StringsWithSpaceOK) {
ParseContext parseContext; ParseContext parseContext;
ErrorGuard errors; ErrorGuard errors;
UnitSystem active_unitsystem(UnitSystem::UnitType::UNIT_TYPE_LAB); UnitSystem active_unitsystem(UnitSystem::UnitType::UNIT_TYPE_LAB);
KeywordLocation loc;
record1.addItem( itemString ); record1.addItem( itemString );
const auto deckRecord = record1.parse( parseContext, errors , rawRecord, active_unitsystem, active_unitsystem, "KEYWORD", "filename" ); const auto deckRecord = record1.parse( parseContext, errors , rawRecord, active_unitsystem, active_unitsystem, loc);
BOOST_CHECK_EQUAL(" VALUE " , deckRecord.getItem(0).get< std::string >(0)); BOOST_CHECK_EQUAL(" VALUE " , deckRecord.getItem(0).get< std::string >(0));
} }

View File

@@ -1056,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_noThrow) {
ErrorGuard errors; ErrorGuard errors;
RawRecord raw( std::string_view( "100 443" ) ); RawRecord raw( std::string_view( "100 443" ) );
UnitSystem unit_system; UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , unit_system, unit_system, "KEYWORD", "filename") ); BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , unit_system, unit_system, KeywordLocation()) );
} }
BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) { BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
@@ -1065,7 +1065,7 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
ParseContext parseContext; ParseContext parseContext;
ErrorGuard errors; ErrorGuard errors;
UnitSystem unit_system; UnitSystem unit_system;
const auto deckRecord = record.parse(parseContext , errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename"); const auto deckRecord = record.parse(parseContext , errors, rawRecord, unit_system, unit_system, KeywordLocation());
BOOST_CHECK_EQUAL(2U, deckRecord.size()); BOOST_CHECK_EQUAL(2U, deckRecord.size());
} }
@@ -1097,7 +1097,7 @@ BOOST_AUTO_TEST_CASE(parse_validMixedRecord_noThrow) {
ParseContext parseContext; ParseContext parseContext;
ErrorGuard errors; ErrorGuard errors;
UnitSystem unit_system; UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename")); BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, rawRecord, unit_system, unit_system, KeywordLocation()));
} }
BOOST_AUTO_TEST_CASE(Equal_Equal_ReturnsTrue) { BOOST_AUTO_TEST_CASE(Equal_Equal_ReturnsTrue) {
@@ -1223,13 +1223,13 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooManyItems_Throws) {
RawRecord rawRecord( "3 3 3 " ); RawRecord rawRecord( "3 3 3 " );
UnitSystem unit_system; UnitSystem unit_system;
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename")); BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, KeywordLocation()));
RawRecord rawRecordOneExtra( "3 3 3 4 " ); RawRecord rawRecordOneExtra( "3 3 3 4 " );
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordOneExtra, unit_system, unit_system, "KEYWORD", "filename"), std::invalid_argument); BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordOneExtra, unit_system, unit_system, KeywordLocation()), std::invalid_argument);
RawRecord rawRecordForgotRecordTerminator( "3 3 3 \n 4 4 4 " ); RawRecord rawRecordForgotRecordTerminator( "3 3 3 \n 4 4 4 " );
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordForgotRecordTerminator, unit_system, unit_system, "KEYWORD", "filename"), std::invalid_argument); BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordForgotRecordTerminator, unit_system, unit_system, KeywordLocation()), std::invalid_argument);
} }
@@ -1248,10 +1248,11 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems) {
ErrorGuard errors; ErrorGuard errors;
RawRecord rawRecord( "3 3 " ); RawRecord rawRecord( "3 3 " );
UnitSystem unit_system; UnitSystem unit_system;
KeywordLocation location;
// no default specified for the third item, record can be parsed just fine but trying // no default specified for the third item, record can be parsed just fine but trying
// to access the data will raise an exception...; // to access the data will raise an exception...;
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEWYORD", "filename")); BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, location));
auto record = parserRecord.parse(parseContext, errors , rawRecord, unit_system, unit_system, "KEYWORD", "filename"); auto record = parserRecord.parse(parseContext, errors , rawRecord, unit_system, unit_system, location);
BOOST_CHECK_NO_THROW(record.getItem(2)); BOOST_CHECK_NO_THROW(record.getItem(2));
BOOST_CHECK_THROW(record.getItem(2).get< int >(0), std::invalid_argument); BOOST_CHECK_THROW(record.getItem(2).get< int >(0), std::invalid_argument);
} }
@@ -1633,7 +1634,7 @@ BOOST_AUTO_TEST_CASE(ParseEmptyRecord) {
record.addItem(item); record.addItem(item);
tabdimsKeyword.addRecord( record ); tabdimsKeyword.addRecord( record );
const auto deckKeyword = tabdimsKeyword.parse( parseContext, errors, rawkeyword , unit_system, unit_system, "filename"); const auto deckKeyword = tabdimsKeyword.parse( parseContext, errors, rawkeyword , unit_system, unit_system);
BOOST_REQUIRE_EQUAL( 1U , deckKeyword.size()); BOOST_REQUIRE_EQUAL( 1U , deckKeyword.size());
const auto& deckRecord = deckKeyword.getRecord(0); const auto& deckRecord = deckKeyword.getRecord(0);