Add min_size setting ParserKeywords

This commit is contained in:
Joakim Hove 2021-07-22 17:45:18 +02:00
parent 48a0d91e49
commit 946fcca4fd
9 changed files with 133 additions and 49 deletions

View File

@ -49,13 +49,16 @@ namespace Opm {
*/
class KeywordSize {
public:
KeywordSize();
KeywordSize(const std::string& in_keyword, const std::string& in_item, int in_shift);
KeywordSize(const std::string& in_keyword, const std::string& in_item);
KeywordSize(const std::string& in_keyword, const std::string& in_item, bool table_collection, int in_shift);
KeywordSize();
KeywordSize(ParserKeywordSizeEnum size_type);
KeywordSize(std::size_t fixed_size);
KeywordSize(std::size_t min_size, const std::string& in_keyword, const std::string& in_item, bool table_collection, int in_shift);
explicit KeywordSize(ParserKeywordSizeEnum size_type);
explicit KeywordSize(std::size_t fixed_size);
KeywordSize(std::size_t fixed_size, bool code);
KeywordSize(std::size_t min_size, std::size_t fixed_size, bool code);
bool table_collection() const;
ParserKeywordSizeEnum size_type() const;
@ -64,6 +67,7 @@ namespace Opm {
const std::string& keyword() const;
const std::string& item() const;
std::optional<std::size_t> min_size() const;
void min_size(int s);
const std::optional<std::variant<std::size_t, std::pair<std::string, std::string>>>& max_size() const;
std::string construct() const;
@ -101,6 +105,7 @@ namespace Opm {
std::vector< ParserRecord >::const_iterator end() const;
const std::string className() const;
const std::string& getName() const;
std::optional<std::size_t> min_size() const;
size_t getFixedSize() const;
bool hasFixedSize() const;
bool isTableCollection() const;

View File

@ -689,6 +689,7 @@ RawKeyword * newRawKeyword(const ParserKeyword& parserKeyword, const std::string
parserState.line(),
raw_string_keyword,
size_type,
parserKeyword.min_size(),
parserKeyword.getFixedSize());
}
@ -708,6 +709,7 @@ RawKeyword * newRawKeyword(const ParserKeyword& parserKeyword, const std::string
parserState.line(),
raw_string_keyword,
size_type,
parserKeyword.min_size(),
targetSize);
}
@ -729,6 +731,7 @@ RawKeyword * newRawKeyword(const ParserKeyword& parserKeyword, const std::string
parserState.line(),
raw_string_keyword,
size_type,
parserKeyword.min_size(),
targetSize);
}
@ -867,7 +870,7 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
continue;
}
if (rawKeyword->getSizeType() == Raw::UNKNOWN) {
if (rawKeyword->can_complete()) {
/*
When we are spinning through a keyword of size type UNKNOWN it
is essential to recognize a string as the next keyword. The
@ -923,7 +926,7 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
}
if (rawKeyword) {
if (rawKeyword->getSizeType() == Raw::UNKNOWN)
if (rawKeyword->can_complete())
rawKeyword->terminateKeyword();
if (!rawKeyword->isFinished())

View File

@ -55,6 +55,12 @@ KeywordSize::KeywordSize(const std::string& in_keyword, const std::string& in_it
{
}
KeywordSize::KeywordSize(std::size_t in_min_size, const std::string& in_keyword, const std::string& in_item, bool table_collection, int in_shift)
: KeywordSize(in_keyword, in_item, table_collection, in_shift)
{
this->min_size(in_min_size);
}
KeywordSize::KeywordSize()
: KeywordSize(SLASH_TERMINATED)
{
@ -87,6 +93,12 @@ KeywordSize::KeywordSize(std::size_t fixed_size, bool code)
{
}
KeywordSize::KeywordSize(std::size_t in_min_size, std::size_t fixed_size, bool code)
: KeywordSize(fixed_size, code)
{
this->min_size(in_min_size);
}
bool
KeywordSize::operator==(const KeywordSize&) const
{
@ -146,22 +158,29 @@ KeywordSize::max_size() const
return this->m_max_size;
}
void KeywordSize::min_size(int s) {
this->m_min_size = s;
}
std::string
KeywordSize::construct() const
{
if (this->m_size_type == SLASH_TERMINATED)
return "KeywordSize()";
if (this->m_size_type == UNKNOWN || this->m_size_type == DOUBLE_SLASH_TERMINATED)
if (this->m_size_type == UNKNOWN || this->m_size_type == DOUBLE_SLASH_TERMINATED || this->m_size_type == SLASH_TERMINATED)
return fmt::format("KeywordSize({})", ParserKeywordSizeEnum2String(this->m_size_type));
if (this->m_size_type == FIXED || this->m_size_type == FIXED_CODE)
return fmt::format("KeywordSize({}, {})", std::get<std::size_t>(this->m_max_size.value()), this->is_code);
if (this->m_size_type == FIXED || this->m_size_type == FIXED_CODE) {
if (this->min_size().has_value())
return fmt::format("KeywordSize({}, {}, {})", this->min_size().value(), std::get<std::size_t>(this->m_max_size.value()), this->is_code);
else
return fmt::format("KeywordSize({}, {})", std::get<std::size_t>(this->m_max_size.value()), this->is_code);
}
if (this->m_size_type == OTHER_KEYWORD_IN_DECK) {
const auto& [size_kw, size_item] = std::get<1>(this->m_max_size.value());
return fmt::format(
"KeywordSize(\"{}\", \"{}\", {}, {})", size_kw, size_item, this->is_table_collection, this->shift);
if (this->min_size().has_value())
return fmt::format("KeywordSize({}, \"{}\", \"{}\", {}, {})", this->min_size().value(), size_kw, size_item, this->is_table_collection, this->shift);
else
return fmt::format("KeywordSize(\"{}\", \"{}\", {}, {})", size_kw, size_item, this->is_table_collection, this->shift);
}
throw std::logic_error("No string serialization known?");
@ -227,7 +246,6 @@ KeywordSize::construct() const
this->keyword_size = KeywordSize( sizeObject.as_int() );
else
initSizeKeyword(false, sizeObject);
return;
}
@ -292,6 +310,11 @@ KeywordSize::construct() const
clearDeckNames();
initSize(jsonConfig);
if (jsonConfig.has_item("min_size")) {
auto min_size = jsonConfig.get_int("min_size");
this->keyword_size.min_size(min_size);
}
initDeckNames(jsonConfig);
initSectionNames(jsonConfig);
initMatchRegex(jsonConfig);
@ -730,6 +753,10 @@ void set_dimensions( ParserItem& item,
return keyword;
}
std::optional<std::size_t> ParserKeyword::min_size() const {
return this->keyword_size.min_size();
}
size_t ParserKeyword::getFixedSize() const {
if (!hasFixedSize())
throw std::logic_error("The parser keyword "+getName()+" does not have a fixed size!");

View File

@ -43,11 +43,12 @@ namespace {
}
RawKeyword::RawKeyword(const std::string& name, const std::string& filename, std::size_t lineNR, bool raw_string, Raw::KeywordSizeEnum sizeType, std::size_t size_arg) :
m_name(keyword_name(name)),
m_location(name, filename, lineNR),
raw_string_keyword(raw_string),
m_sizeType(sizeType)
RawKeyword::RawKeyword(const std::string& name, const std::string& filename, std::size_t lineNR, bool raw_string, Raw::KeywordSizeEnum sizeType, const std::optional<std::size_t>& min_size, std::size_t size_arg)
: m_name(keyword_name(name))
, m_location(name, filename, lineNR)
, raw_string_keyword(raw_string)
, m_sizeType(sizeType)
, m_min_size(min_size.value_or(size_arg))
{
if (this->m_sizeType == Raw::FIXED) {
this->m_fixedSize = size_arg;
@ -76,7 +77,7 @@ namespace {
RawKeyword::RawKeyword(const std::string& name, const std::string& filename, std::size_t lineNR, bool raw_string, Raw::KeywordSizeEnum sizeType) :
RawKeyword(name, filename, lineNR, raw_string, sizeType, sizeType == Raw::CODE ? 1 : 0)
RawKeyword(name, filename, lineNR, raw_string, sizeType, {}, sizeType == Raw::CODE ? 1 : 0)
{
if (this->m_sizeType == Raw::FIXED || this->m_sizeType == Raw::TABLE_COLLECTION)
throw std::logic_error("Internal error - wrong constructor has been used. Keyword: " + name + " at " + filename + ":" + std::to_string(lineNR));
@ -105,6 +106,12 @@ namespace {
m_isFinished = true;
}
if (this->m_sizeType == Raw::FIXED) {
if (this->m_records.size() >= this->m_min_size)
this->m_isFinished = true;
}
if( m_sizeType == Raw::UNKNOWN)
m_isFinished = true;
@ -169,5 +176,18 @@ namespace {
return this->m_records.size();
}
bool RawKeyword::can_complete() const {
if (this->m_sizeType == Raw::UNKNOWN)
return true;
if (this->m_min_size < this->m_fixedSize) {
if (this->m_records.size() >= this->m_min_size)
return true;
}
return false;
}
}

View File

@ -20,10 +20,11 @@
#ifndef RAWKEYWORD_HPP
#define RAWKEYWORD_HPP
#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <cstddef>
#include <opm/common/OpmLog/KeywordLocation.hpp>
@ -36,7 +37,7 @@ namespace Opm {
class RawKeyword {
public:
RawKeyword(const std::string& name, const std::string& filename, std::size_t lineNR, bool raw_string, Raw::KeywordSizeEnum sizeType);
RawKeyword(const std::string& name, const std::string& filename, std::size_t lineNR, bool raw_string, Raw::KeywordSizeEnum sizeType, std::size_t size_arg);
RawKeyword(const std::string& name, const std::string& filename, std::size_t lineNR, bool raw_string, Raw::KeywordSizeEnum sizeType, const std::optional<std::size_t>& min_size, std::size_t size_arg);
bool terminateKeyword();
bool addRecord(RawRecord record);
@ -49,9 +50,9 @@ namespace Opm {
const RawRecord& getFirstRecord( ) const;
bool isFinished() const;
bool unKnownSize() const;
bool rawStringKeyword() const;
const KeywordLocation& location() const;
bool can_complete() const;
using const_iterator = std::vector< RawRecord >::const_iterator;
using iterator = std::vector< RawRecord >::iterator;
@ -67,9 +68,10 @@ namespace Opm {
bool raw_string_keyword;
Raw::KeywordSizeEnum m_sizeType;
size_t m_fixedSize = 0;
size_t m_numTables = 0;
size_t m_currentNumTables = 0;
std::size_t m_min_size = 0;
std::size_t m_fixedSize = 0;
std::size_t m_numTables = 0;
std::size_t m_currentNumTables = 0;
bool m_isTempFinished = false;
bool m_isFinished = false;

View File

@ -3,5 +3,13 @@
"sections": [
"RUNSPEC"
],
"comment": "Multi-Component Brine Model not supported"
"min_size" : 0,
"size" : 1,
"items" : [
{
"name" : "SALTS",
"size_type" : "ALL",
"value_type" : "STRING"
}
]
}

View File

@ -1627,7 +1627,7 @@ BOOST_AUTO_TEST_CASE(ParseEmptyRecord) {
auto tabdimsKeyword = createFixedSized("TEST" , 1);
ParserRecord record;
ParserItem item("ITEM", INT);
RawKeyword rawkeyword( tabdimsKeyword.getName() , "FILE" , 10U , false, Raw::FIXED, 1);
RawKeyword rawkeyword( tabdimsKeyword.getName() , "FILE" , 10U , false, Raw::FIXED, {}, 1);
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;

View File

@ -34,13 +34,13 @@ using namespace Opm;
BOOST_AUTO_TEST_CASE(RawKeywordConstructor) {
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::FIXED), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::TABLE_COLLECTION), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::TABLE_COLLECTION, 0), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::SLASH_TERMINATED, 5), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::UNKNOWN, 5), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::CODE, 2), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::TABLE_COLLECTION, {}, 0), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::SLASH_TERMINATED, {}, 5), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::UNKNOWN, {}, 5), std::logic_error);
BOOST_CHECK_THROW( RawKeyword("NAME", "file", 10, false, Raw::CODE, {}, 2), std::logic_error);
RawKeyword kw1("NAME", "file", 10, false, Raw::SLASH_TERMINATED);
RawKeyword kw2("NAME", "file", 10, false, Raw::FIXED, 10);
RawKeyword kw3("NAME", "file", 10, false, Raw::TABLE_COLLECTION, 7);
RawKeyword kw2("NAME", "file", 10, false, Raw::FIXED, {}, 10);
RawKeyword kw3("NAME", "file", 10, false, Raw::TABLE_COLLECTION, {}, 7);
RawKeyword kw4("NAME", "file", 10, false, Raw::CODE);
}
@ -49,11 +49,11 @@ BOOST_AUTO_TEST_CASE(IsFinished) {
std::string_view line(storage);
RawRecord rec(line, KeywordLocation("KW", "file", 100 ));
RawKeyword kw1("NAME", "file", 10, false, Raw::FIXED, 0);
RawKeyword kw1("NAME", "file", 10, false, Raw::FIXED, {}, 0);
BOOST_CHECK(kw1.isFinished());
{
RawKeyword kw2("NAME", "file", 10, false, Raw::FIXED, 2);
RawKeyword kw2("NAME", "file", 10, false, Raw::FIXED, {}, 2);
BOOST_CHECK(!kw2.isFinished());
BOOST_CHECK(!kw2.addRecord(rec));
@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(IsFinished) {
}
{
RawKeyword kw3("NAME", "file", 10, false, Raw::TABLE_COLLECTION, 2);
RawKeyword kw3("NAME", "file", 10, false, Raw::TABLE_COLLECTION, {}, 2);
BOOST_CHECK(!kw3.isFinished());
BOOST_CHECK(!kw3.terminateKeyword());

View File

@ -64,19 +64,25 @@ CECON
BOOST_AUTO_TEST_CASE( COORDSYS ) {
const std::string input = R"(
RUNSPEC
NUMRES
1 /
BRINE
NUMRES
1 /
GRID
COORDSYS
1 1141 /
COORDSYS
1 1141 'COMP' 'JOIN' 1 2 /
COORDSYS
1 1141 'COMP' 'JOIN' /
COORDSYS
1 1141 'INCOMP' /
COORDSYS
1 1141 /
COORDSYS
1 1141 'COMP' 'JOIN' 1 2 /
COORDSYS
1 1141 'COMP' 'JOIN' /
COORDSYS
1 1141 'INCOMP' /
)";
Parser().parseString( input );
const auto& deck = Parser().parseString( input );
const auto& brine = deck.getKeyword("BRINE");
BOOST_CHECK_EQUAL(brine.size(), 0);
}
BOOST_AUTO_TEST_CASE( DENSITY ) {
@ -1477,6 +1483,9 @@ RUNSPEC
OIL
GAS
BRINE
NACL KCL /
TABDIMS
1 2 /
@ -1503,11 +1512,21 @@ SGOF
0.9 0.5 0.1 8.0
1.0 1.0 0.1 9.0 /
)";
Parser parser;
auto deck = Parser{}.parseString(input);
const auto& keyword = parser.getParserKeywordFromDeckName("BRINE");
BOOST_CHECK_EQUAL(keyword.getFixedSize(), 1);
BOOST_CHECK_EQUAL(keyword.min_size().value(), 0);
auto deck = parser.parseString(input);
const auto& pvtwsalt = deck.getKeyword("PVTWSALT");
BOOST_CHECK_EQUAL(pvtwsalt.size(), 4);
const auto& sgof = deck.getKeyword("SGOF");
BOOST_CHECK_EQUAL(sgof.size(), 1);
const auto& brine = deck.getKeyword("BRINE");
const auto& salts = brine.getRecord(0).getItem(0);
BOOST_CHECK_EQUAL( salts.data_size(), 2);
}