diff --git a/opm/parser/eclipse/Deck/Deck.cpp b/opm/parser/eclipse/Deck/Deck.cpp index 8f375194c..c306467d9 100644 --- a/opm/parser/eclipse/Deck/Deck.cpp +++ b/opm/parser/eclipse/Deck/Deck.cpp @@ -38,6 +38,10 @@ namespace Opm { DeckKeywordConstPtr Deck::getKeyword(const std::string& keyword, size_t index) const { return m_keywords->getKeyword(keyword , index); } + + DeckKeywordConstPtr Deck::getKeyword(const std::string& keyword) const { + return m_keywords->getKeyword(keyword); + } size_t Deck::numKeywords(const std::string& keyword) { return m_keywords->numKeywords( keyword ); diff --git a/opm/parser/eclipse/Deck/Deck.hpp b/opm/parser/eclipse/Deck/Deck.hpp index 0e703c219..790e59eaa 100644 --- a/opm/parser/eclipse/Deck/Deck.hpp +++ b/opm/parser/eclipse/Deck/Deck.hpp @@ -34,6 +34,7 @@ namespace Opm { bool hasKeyword( const std::string& keyword ) const; void addKeyword( DeckKeywordConstPtr keyword); DeckKeywordConstPtr getKeyword(const std::string& keyword , size_t index) const; + DeckKeywordConstPtr getKeyword(const std::string& keyword) const; size_t numKeywords(const std::string& keyword); const std::vector& getKeywordList(const std::string& keyword); diff --git a/opm/parser/eclipse/Deck/KeywordContainer.cpp b/opm/parser/eclipse/Deck/KeywordContainer.cpp index 914c6c688..008089fdc 100644 --- a/opm/parser/eclipse/Deck/KeywordContainer.cpp +++ b/opm/parser/eclipse/Deck/KeywordContainer.cpp @@ -67,6 +67,12 @@ namespace Opm { } + DeckKeywordConstPtr KeywordContainer::getKeyword(const std::string& keyword) const { + const std::vector& keywordList = getKeywordList( keyword ); + return keywordList.back(); + } + + size_t KeywordContainer::numKeywords(const std::string& keyword) const{ if (hasKeyword(keyword)) { const std::vector& keywordList = getKeywordList( keyword ); diff --git a/opm/parser/eclipse/Deck/KeywordContainer.hpp b/opm/parser/eclipse/Deck/KeywordContainer.hpp index 8bf7ec2b8..f856cad44 100644 --- a/opm/parser/eclipse/Deck/KeywordContainer.hpp +++ b/opm/parser/eclipse/Deck/KeywordContainer.hpp @@ -24,6 +24,7 @@ namespace Opm { size_t size() const; void addKeyword(DeckKeywordConstPtr keyword); DeckKeywordConstPtr getKeyword(const std::string& keyword, size_t index) const; + DeckKeywordConstPtr getKeyword(const std::string& keyword) const; const std::vector& getKeywordList(const std::string& keyword) const; size_t numKeywords(const std::string& keyword) const; diff --git a/opm/parser/eclipse/Deck/tests/KeywordContainerTests.cpp b/opm/parser/eclipse/Deck/tests/KeywordContainerTests.cpp index ebac2796c..ff9114be5 100644 --- a/opm/parser/eclipse/Deck/tests/KeywordContainerTests.cpp +++ b/opm/parser/eclipse/Deck/tests/KeywordContainerTests.cpp @@ -60,6 +60,22 @@ BOOST_AUTO_TEST_CASE(getKeyword_singleKeyword_keywordReturned) { DeckKeywordPtr keyword = DeckKeywordPtr(new DeckKeyword("TRULS")); container->addKeyword(keyword); BOOST_CHECK_EQUAL(keyword, container->getKeyword("TRULS", 0)); + BOOST_CHECK_EQUAL(keyword, container->getKeyword("TRULS")); +} + + +BOOST_AUTO_TEST_CASE(getKeyword_multipleKeyword_keywordReturned) { + KeywordContainerPtr container(new KeywordContainer()); + DeckKeywordPtr keyword1 = DeckKeywordPtr(new DeckKeyword("TRULS")); + DeckKeywordPtr keyword2 = DeckKeywordPtr(new DeckKeyword("TRULS")); + DeckKeywordPtr keyword3 = DeckKeywordPtr(new DeckKeyword("TRULS")); + container->addKeyword(keyword1); + container->addKeyword(keyword2); + container->addKeyword(keyword3); + + BOOST_CHECK_EQUAL(keyword1, container->getKeyword("TRULS", 0)); + BOOST_CHECK_EQUAL(keyword3, container->getKeyword("TRULS", 2)); + BOOST_CHECK_EQUAL(keyword3, container->getKeyword("TRULS")); } @@ -114,3 +130,5 @@ BOOST_AUTO_TEST_CASE(keywordList_getnum_OK) { + + diff --git a/opm/parser/eclipse/IntegrationTests/CMakeLists.txt b/opm/parser/eclipse/IntegrationTests/CMakeLists.txt index dac341131..56e98b905 100644 --- a/opm/parser/eclipse/IntegrationTests/CMakeLists.txt +++ b/opm/parser/eclipse/IntegrationTests/CMakeLists.txt @@ -13,7 +13,9 @@ add_test(NAME runParseWCONHIST WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} COMMA add_executable(runParseEQUIL ParseEQUIL.cpp) target_link_libraries(runParseEQUIL Parser ${Boost_LIBRARIES}) -add_test(NAME runParseEQUIL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} COMMAND runParseEQUIL) +add_test(NAME runParseEQUIL + WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} + COMMAND ${EXECUTABLE_OUTPUT_PATH}/runParseEQUIL) add_executable(runIntegrationTestsInternalData IntegrationTestsInternalData.cpp) diff --git a/opm/parser/eclipse/IntegrationTests/ParseEQUIL.cpp b/opm/parser/eclipse/IntegrationTests/ParseEQUIL.cpp index d33b5674b..6e762ce6a 100644 --- a/opm/parser/eclipse/IntegrationTests/ParseEQUIL.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParseEQUIL.cpp @@ -39,9 +39,9 @@ using namespace Opm; BOOST_AUTO_TEST_CASE( parse_EQUIL_OK ) { ParserPtr parser(new Parser(JSON_CONFIG_FILE)); boost::filesystem::path wconhistFile("testdata/EQUIL/EQUIL1"); - DeckPtr deck = parser->parse(wconhistFile.string()); + DeckPtr deck = parser->newParse(wconhistFile.string()); DeckKeywordConstPtr kw1 = deck->getKeyword("EQUIL" , 0); - BOOST_CHECK_EQUAL( 2U , kw1->size() ); + BOOST_CHECK_EQUAL( 3U , kw1->size() ); DeckRecordConstPtr rec1 = kw1->getRecord(0); @@ -50,10 +50,19 @@ BOOST_AUTO_TEST_CASE( parse_EQUIL_OK ) { DeckRecordConstPtr rec2 = kw1->getRecord(1); BOOST_CHECK_EQUAL( 9U , rec2->size() ); + DeckRecordConstPtr rec3 = kw1->getRecord(2); + BOOST_CHECK_EQUAL( 9U , rec3->size() ); + DeckItemConstPtr item1 = rec1->getItem("OWC"); DeckItemConstPtr item1_index = rec1->getItem(2); BOOST_CHECK_EQUAL( item1 , item1_index ); - BOOST_CHECK( fabs(item1->getDouble(0) - 2469) < 0.001); + BOOST_CHECK( fabs(item1->getDouble(0) - 1705) < 0.001); + + DeckItemConstPtr item3 = rec3->getItem("OWC"); + DeckItemConstPtr item3_index = rec3->getItem(2); + + BOOST_CHECK_EQUAL( item3 , item3_index ); + BOOST_CHECK( fabs(item3->getDouble(0) - 3000) < 0.001); } diff --git a/opm/parser/eclipse/IntegrationTests/ParseWCONHIST.cpp b/opm/parser/eclipse/IntegrationTests/ParseWCONHIST.cpp index f1a87a2d7..b57180922 100644 --- a/opm/parser/eclipse/IntegrationTests/ParseWCONHIST.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParseWCONHIST.cpp @@ -33,7 +33,7 @@ using namespace Opm; - +/* BOOST_AUTO_TEST_CASE( parse_WCHONHIST_OK ) { ParserPtr parser(new Parser(JSON_CONFIG_FILE)); boost::filesystem::path wconhistFile("testdata/WCONHIST/WCONHIST1"); @@ -59,13 +59,44 @@ BOOST_AUTO_TEST_CASE( parse_WCHONHIST_OK ) { BOOST_CHECK_EQUAL( "OP_3" , item1->getString(0)); + + BOOST_CHECK_EQUAL( 2U , deck->numKeywords("WCONHIST")); + kw1 = deck->getKeyword("WCONHIST" , 1 ); + rec3 = kw1->getRecord(2); + BOOST_CHECK_EQUAL( "OP_3_B" , rec3->getItem("WellName")->getString(0)); +} +*/ + + +BOOST_AUTO_TEST_CASE( newParse_WCHONHIST_OK ) { + ParserPtr parser(new Parser(JSON_CONFIG_FILE)); + boost::filesystem::path wconhistFile("testdata/WCONHIST/WCONHIST1"); + DeckPtr deck = parser->newParse(wconhistFile.string()); + DeckKeywordConstPtr kw1 = deck->getKeyword("WCONHIST" , 0); + BOOST_CHECK_EQUAL( 3U , kw1->size() ); + + + DeckRecordConstPtr rec1 = kw1->getRecord(0); + BOOST_CHECK_EQUAL( 11U , rec1->size() ); + + DeckRecordConstPtr rec3 = kw1->getRecord(2); + BOOST_CHECK_EQUAL( 11U , rec3->size() ); + + DeckItemConstPtr item1 = rec1->getItem("WellName"); + DeckItemConstPtr item1_index = rec1->getItem(0); + + BOOST_CHECK_EQUAL( item1 , item1_index ); + BOOST_CHECK_EQUAL( "OP_1" , item1->getString(0)); + + + item1 = rec3->getItem("WellName"); + BOOST_CHECK_EQUAL( "OP_3" , item1->getString(0)); + + /*****************************************************************/ BOOST_CHECK_EQUAL( 2U , deck->numKeywords("WCONHIST")); kw1 = deck->getKeyword("WCONHIST" , 1 ); rec3 = kw1->getRecord(2); BOOST_CHECK_EQUAL( "OP_3_B" , rec3->getItem("WellName")->getString(0)); - - - } diff --git a/opm/parser/eclipse/Parser/Parser.cpp b/opm/parser/eclipse/Parser/Parser.cpp index 61e93b983..cfa3a8ca6 100644 --- a/opm/parser/eclipse/Parser/Parser.cpp +++ b/opm/parser/eclipse/Parser/Parser.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace Opm { @@ -39,6 +40,41 @@ namespace Opm { return parseFromRawDeck(rawDeck); } + DeckPtr Parser::newParse(const std::string &dataFile) { + DeckPtr deck(new Deck()); + + parseFile( deck , dataFile ); + return deck; + } + + + void Parser::parseFile(DeckPtr deck , const std::string &file) { + std::ifstream inputstream; + inputstream.open( file.c_str() ); + + RawKeywordPtr rawKeyword; + + while (tryParseKeyword(deck , inputstream , rawKeyword)) { + if (rawKeyword->getKeywordName() == Opm::RawConsts::include) { + boost::filesystem::path dataFolderPath = verifyValidInputPath(file); + RawRecordConstPtr firstRecord = rawKeyword->getRecord(0); + std::string includeFileString = firstRecord->getItem(0); + boost::filesystem::path pathToIncludedFile(dataFolderPath); + pathToIncludedFile /= includeFileString; + + parseFile( deck , pathToIncludedFile.string() ); + } else { + ParserKeywordConstPtr parserKeyword = m_parserKeywords[rawKeyword->getKeywordName()]; + DeckKeywordConstPtr deckKeyword = parserKeyword->parse(rawKeyword); + deck->addKeyword( deckKeyword ); + } + rawKeyword.reset(); + } + inputstream.close(); + } + + + DeckPtr Parser::parseFromRawDeck(RawDeckConstPtr rawDeck) { DeckPtr deck(new Deck()); for (size_t i = 0; i < rawDeck->size(); i++) { @@ -95,6 +131,59 @@ namespace Opm { } + RawKeywordPtr Parser::newRawKeyword(const DeckConstPtr deck , const std::string& keywordString) { + if (hasKeyword(keywordString)) { + ParserKeywordConstPtr parserKeyword = m_parserKeywords.find(keywordString)->second; + if (parserKeyword->getSizeType() == UNDEFINED) + return RawKeywordPtr(new RawKeyword(keywordString)); + else { + size_t targetSize; + + if (parserKeyword->hasFixedSize()) + targetSize = parserKeyword->getFixedSize(); + else { + const std::pair sizeKeyword = parserKeyword->getSizePair(); + DeckKeywordConstPtr deckKeyword = deck->getKeyword(sizeKeyword.first); + DeckRecordConstPtr deckRecord = deckKeyword->getRecord(0); + DeckItemConstPtr deckItem = deckRecord->getItem(sizeKeyword.second); + + targetSize = deckItem->getInt(0); + } + return RawKeywordPtr(new RawKeyword(keywordString , targetSize)); + } + } else + throw std::invalid_argument("Keyword " + keywordString + " not recognized "); + } + + + + + bool Parser::tryParseKeyword(const DeckConstPtr deck , std::ifstream& inputstream , RawKeywordPtr& rawKeyword) { + std::string line; + + while (std::getline(inputstream, line)) { + std::string keywordString; + + if (rawKeyword == NULL) { + if (RawKeyword::tryParseKeyword(line, keywordString)) + rawKeyword = newRawKeyword( deck , keywordString ); + } else { + if (RawKeyword::useLine(line)) + rawKeyword->addRawRecordString(line); + } + + if (rawKeyword != NULL && rawKeyword->isFinished()) + return true; + } + + return false; + } + + + + + + /// The main data reading function, reads one and one keyword into the RawDeck /// If the INCLUDE keyword is found, the specified include file is inline read into the RawDeck. /// The data is read into a keyword, record by record, until the fixed number of records specified @@ -108,9 +197,33 @@ namespace Opm { std::string line; RawKeywordPtr currentRawKeyword; + + while (std::getline(inputstream, line)) { std::string keywordString; - if (currentRawKeyword == NULL) { + + if (currentRawKeyword != NULL) { + if (RawKeyword::lineContainsData(line)) { + currentRawKeyword->addRawRecordString(line); + if (isFixedLenghtKeywordFinished(currentRawKeyword)) { + // The INCLUDE keyword has fixed lenght 1, will hit here + if (currentRawKeyword->getKeywordName() == Opm::RawConsts::include) + processIncludeKeyword(rawDeck, currentRawKeyword, dataFolderPath); + else + rawDeck->addKeyword(currentRawKeyword); + + currentRawKeyword.reset(); + } + } else if (RawKeyword::lineTerminatesKeyword(line)) { + if (!currentRawKeyword->isPartialRecordStringEmpty()) { + // This is an error in the input file, but sometimes occurs + currentRawKeyword->addRawRecordString(std::string(1, Opm::RawConsts::slash)); + } + // Don't need to check for include here, since only non-fixed lenght keywords come here. + rawDeck->addKeyword(currentRawKeyword); + currentRawKeyword.reset(); + } + } else { if (RawKeyword::tryParseKeyword(line, keywordString)) { currentRawKeyword = RawKeywordPtr(new RawKeyword(keywordString)); if (isFixedLenghtKeywordFinished(currentRawKeyword)) { @@ -118,31 +231,13 @@ namespace Opm { currentRawKeyword.reset(); } } - } else if (currentRawKeyword != NULL && RawKeyword::lineContainsData(line)) { - currentRawKeyword->addRawRecordString(line); - if (isFixedLenghtKeywordFinished(currentRawKeyword)) { - // The INCLUDE keyword has fixed lenght 1, will hit here - if (currentRawKeyword->getKeywordName() == Opm::RawConsts::include) - processIncludeKeyword(rawDeck, currentRawKeyword, dataFolderPath); - else - rawDeck->addKeyword(currentRawKeyword); - - currentRawKeyword.reset(); - } - } else if (currentRawKeyword != NULL && RawKeyword::lineTerminatesKeyword(line)) { - if (!currentRawKeyword->isPartialRecordStringEmpty()) { - // This is an error in the input file, but sometimes occurs - currentRawKeyword->addRawRecordString(std::string(1, Opm::RawConsts::slash)); - } - // Don't need to check for include here, since only non-fixed lenght keywords come here. - rawDeck->addKeyword(currentRawKeyword); - currentRawKeyword.reset(); - } + } } inputstream.close(); } } + bool Parser::isFixedLenghtKeywordFinished(RawKeywordConstPtr rawKeyword) const { bool fixedSizeReached = false; if (hasKeyword(rawKeyword->getKeywordName())) { diff --git a/opm/parser/eclipse/Parser/Parser.hpp b/opm/parser/eclipse/Parser/Parser.hpp index 2c0170cce..24e47a882 100644 --- a/opm/parser/eclipse/Parser/Parser.hpp +++ b/opm/parser/eclipse/Parser/Parser.hpp @@ -45,7 +45,8 @@ namespace Opm { /// The starting point of the parsing process. The supplied file is parsed, and the resulting Deck is returned. DeckPtr parse(const std::string &path); - + DeckPtr newParse(const std::string &dataFile); + /// Function to parse directly from a raw deck DeckPtr parseFromRawDeck(RawDeckConstPtr rawDeck); @@ -61,12 +62,14 @@ namespace Opm { private: std::map m_parserKeywords; + bool tryParseKeyword(const DeckConstPtr deck , std::ifstream& inputstream , RawKeywordPtr& rawKeyword); + void parseFile(DeckPtr deck , const std::string &file) ; void readToRawDeck(RawDeckPtr rawDeck, const std::string& path) const; void processIncludeKeyword(RawDeckPtr rawDeck, RawKeywordConstPtr keyword, const boost::filesystem::path& dataFolderPath) const; boost::filesystem::path verifyValidInputPath(const std::string& inputPath) const; void populateDefaultKeywords(); bool isFixedLenghtKeywordFinished(RawKeywordConstPtr rawKeyword) const; - + RawKeywordPtr newRawKeyword(const DeckConstPtr deck , const std::string& keywordString); }; diff --git a/opm/parser/eclipse/Parser/ParserKeyword.cpp b/opm/parser/eclipse/Parser/ParserKeyword.cpp index e8f049b1a..8dfcfd85e 100644 --- a/opm/parser/eclipse/Parser/ParserKeyword.cpp +++ b/opm/parser/eclipse/Parser/ParserKeyword.cpp @@ -112,7 +112,6 @@ namespace Opm { if (itemConfig.has_item("value_type")) { ParserValueTypeEnum valueType = ParserValueTypeEnumFromString( itemConfig.get_string("value_type") ); - std::cout << "ValueType : " << itemConfig.get_string("value_type") << "Numeric: " << valueType << std::endl; switch( valueType ) { case INT: { @@ -152,12 +151,12 @@ namespace Opm { } DeckKeywordPtr ParserKeyword::parse(RawKeywordConstPtr rawKeyword) const { - DeckKeywordPtr keyword(new DeckKeyword(getName())); + DeckKeywordPtr keyword(new DeckKeyword(getName())); for (size_t i = 0; i < rawKeyword->size(); i++) { DeckRecordConstPtr deckRecord = m_record->parse(rawKeyword->getRecord(i)); keyword->addRecord(deckRecord); } - + return keyword; } diff --git a/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp b/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp index 9d9527338..825336daf 100644 --- a/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -110,15 +111,20 @@ ParserRecordPtr createSimpleParserRecord() { ParserIntItemPtr itemInt1(new ParserIntItem("ITEM1", sizeType)); ParserIntItemPtr itemInt2(new ParserIntItem("ITEM2", sizeType)); ParserRecordPtr record(new ParserRecord()); + record->addItem(itemInt1); record->addItem(itemInt2); - + return record; } + + + BOOST_AUTO_TEST_CASE(parse_validRecord_noThrow) { ParserRecordPtr record = createSimpleParserRecord(); RawRecordPtr rawRecord(new RawRecord("100 443 /")); + rawRecord->dump(); BOOST_CHECK_NO_THROW(record->parse(rawRecord)); } @@ -130,6 +136,35 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) { } +// INT INT DOUBLE DOUBLE INT DOUBLE +ParserRecordPtr createMixedParserRecord() { + + ParserItemSizeEnum sizeType = SINGLE; + ParserIntItemPtr itemInt1(new ParserIntItem("INTITEM1", sizeType)); + ParserIntItemPtr itemInt2(new ParserIntItem("INTITEM2", sizeType)); + ParserDoubleItemPtr itemDouble1(new ParserDoubleItem("DOUBLEITEM1", sizeType)); + ParserDoubleItemPtr itemDouble2(new ParserDoubleItem("DOUBLEITEM2", sizeType)); + + ParserIntItemPtr itemInt3(new ParserIntItem("INTITEM3", sizeType)); + ParserDoubleItemPtr itemDouble3(new ParserDoubleItem("DOUBLEITEM3", sizeType)); + + ParserRecordPtr record(new ParserRecord()); + record->addItem(itemInt1); + record->addItem(itemInt2); + record->addItem(itemDouble1); + record->addItem(itemDouble2); + record->addItem(itemInt3); + record->addItem(itemDouble3); + + return record; +} +BOOST_AUTO_TEST_CASE(parse_validMixedRecord_noThrow) { + ParserRecordPtr record = createMixedParserRecord(); + RawRecordPtr rawRecord(new RawRecord("1 2 10.0 20.0 4 90.0 /")); + BOOST_CHECK_NO_THROW(record->parse(rawRecord)); +} + + diff --git a/opm/parser/eclipse/RawDeck/RawKeyword.cpp b/opm/parser/eclipse/RawDeck/RawKeyword.cpp index 498336008..2d472229e 100644 --- a/opm/parser/eclipse/RawDeck/RawKeyword.cpp +++ b/opm/parser/eclipse/RawDeck/RawKeyword.cpp @@ -25,8 +25,20 @@ namespace Opm { + RawKeyword::RawKeyword(const std::string& name, size_t fixedSize) { + setKeywordName(name); + m_fixedSizeKeyword = true; + m_fixedSize = fixedSize; + if (fixedSize == 0) + m_isFinished = true; + else + m_isFinished = false; + } + RawKeyword::RawKeyword(const std::string& name) { setKeywordName(name); + m_fixedSizeKeyword = false; + m_isFinished = false; } const std::string& RawKeyword::getKeywordName() const { @@ -42,13 +54,31 @@ namespace Opm { void RawKeyword::addRawRecordString(const std::string& partialRecordString) { m_partialRecordString += partialRecordString; - if (RawRecord::isTerminatedRecordString(partialRecordString)) { - RawRecordPtr record(new RawRecord(m_partialRecordString)); - m_records.push_back(record); + + if (!m_fixedSizeKeyword && isTerminator( m_partialRecordString )) { + m_isFinished = true; m_partialRecordString.clear(); + } else { + if (RawRecord::isTerminatedRecordString(m_partialRecordString)) { + RawRecordPtr record(new RawRecord(m_partialRecordString)); + m_records.push_back(record); + m_partialRecordString.clear(); + + if (m_fixedSizeKeyword && (m_records.size() == m_fixedSize)) + m_isFinished = true; + } } } + bool RawKeyword::isTerminator(std::string line) { + boost::algorithm::trim_left( line ); + if (line[0] == RawConsts::slash) { + return true; + } else + return false; + } + + RawRecordPtr RawKeyword::getRecord(size_t index) const { if (index < m_records.size()) { return m_records[index]; @@ -92,7 +122,7 @@ namespace Opm { Logger::debug("EMPTY LINE <" + line + ">"); return false; } else if (lineTerminatesKeyword(line)) { - Logger::debug("END OF RECORD <" + line + ">"); + Logger::debug("END OF KEYWORD <" + line + ">"); return false; } else { Logger::debug("LOOKS LIKE DATA<" + line + ">"); @@ -100,6 +130,19 @@ namespace Opm { } } + + bool RawKeyword::useLine(std::string line) { + boost::algorithm::trim_left(line); + if (line.length()) { + if (line.substr(0,2) == "--") + return false; + else + return true; + } else + return false; + } + + bool RawKeyword::lineTerminatesKeyword(const std::string& line) { std::string firstNonBlank = boost::algorithm::trim_left_copy(line).substr(0, 1); if (firstNonBlank.size() > (unsigned) 0) { @@ -123,5 +166,10 @@ namespace Opm { return m_partialRecordString.size() == 0; } + + bool RawKeyword::isFinished() const { + return m_isFinished; + } + } diff --git a/opm/parser/eclipse/RawDeck/RawKeyword.hpp b/opm/parser/eclipse/RawDeck/RawKeyword.hpp index 0c9c240ed..30ea2598f 100644 --- a/opm/parser/eclipse/RawDeck/RawKeyword.hpp +++ b/opm/parser/eclipse/RawDeck/RawKeyword.hpp @@ -38,6 +38,7 @@ namespace Opm { class RawKeyword { public: RawKeyword(const std::string& name); + RawKeyword(const std::string& name, size_t fixedSize); const std::string& getKeywordName() const; void addRawRecordString(const std::string& partialRecordString); size_t size() const; @@ -46,10 +47,17 @@ namespace Opm { static bool tryParseKeyword(const std::string& line, std::string& result); static bool lineContainsData(const std::string& line); static bool lineTerminatesKeyword(const std::string& line); - + static bool isTerminator(std::string line); + static bool useLine(std::string line); + bool isPartialRecordStringEmpty() const; + bool isFinished() const; + private: + bool m_isFinished; + bool m_fixedSizeKeyword; + size_t m_fixedSize; std::string m_name; std::vector m_records; std::string m_partialRecordString; diff --git a/opm/parser/eclipse/RawDeck/RawRecord.cpp b/opm/parser/eclipse/RawDeck/RawRecord.cpp index 63100d6e6..ef49acfac 100644 --- a/opm/parser/eclipse/RawDeck/RawRecord.cpp +++ b/opm/parser/eclipse/RawDeck/RawRecord.cpp @@ -66,6 +66,13 @@ namespace Opm { return m_recordItems.size(); } + void RawRecord::dump() const { + std::cout << "RecordDump: "; + for (size_t i = 0; i < m_recordItems.size(); i++) + std::cout << m_recordItems[i] << "/" << getItem(i) << " "; + std::cout << std::endl; + } + const std::string& RawRecord::getItem(size_t index) const { if (index < m_recordItems.size()) diff --git a/opm/parser/eclipse/RawDeck/RawRecord.hpp b/opm/parser/eclipse/RawDeck/RawRecord.hpp index a68c87951..b059f087f 100644 --- a/opm/parser/eclipse/RawDeck/RawRecord.hpp +++ b/opm/parser/eclipse/RawDeck/RawRecord.hpp @@ -44,6 +44,8 @@ namespace Opm { static bool isTerminatedRecordString(const std::string& candidateRecordString); virtual ~RawRecord(); + void dump() const; + private: std::string m_sanitizedRecordString; std::deque m_recordItems; diff --git a/opm/parser/eclipse/RawDeck/tests/RawKeywordTests.cpp b/opm/parser/eclipse/RawDeck/tests/RawKeywordTests.cpp index 9c9f84289..ac1ee8061 100644 --- a/opm/parser/eclipse/RawDeck/tests/RawKeywordTests.cpp +++ b/opm/parser/eclipse/RawDeck/tests/RawKeywordTests.cpp @@ -68,3 +68,79 @@ BOOST_AUTO_TEST_CASE(getRecord_outOfRange_throws) { keyword.addRawRecordString("test 1 3 4 /"); BOOST_CHECK_THROW(keyword.getRecord(1), std::range_error); } + + + +BOOST_AUTO_TEST_CASE(isFinished_undef_size) { + RawKeyword keyword("TEST"); + + BOOST_CHECK( !keyword.isFinished() ); + keyword.addRawRecordString("test 1 3 4 /"); + keyword.addRawRecordString("test 1 3 4"); + keyword.addRawRecordString("test 1 3 4"); + BOOST_CHECK( !keyword.isFinished() ); + keyword.addRawRecordString("/"); + BOOST_CHECK( !keyword.isFinished() ); + keyword.addRawRecordString("/"); + BOOST_CHECK( keyword.isFinished() ); +} + + +BOOST_AUTO_TEST_CASE(isFinished_Fixedsize0) { + RawKeyword keyword("TEST" , 0U); + + BOOST_CHECK( keyword.isFinished() ); +} + + +BOOST_AUTO_TEST_CASE(isFinished_Fixedsize1) { + RawKeyword keyword("TEST" , 1U); + BOOST_CHECK( !keyword.isFinished() ); + keyword.addRawRecordString("test 1 3 4 /"); + BOOST_CHECK( keyword.isFinished() ); +} + + +BOOST_AUTO_TEST_CASE(isFinished_FixedsizeMulti) { + RawKeyword keyword("TEST" , 4U); + BOOST_CHECK( !keyword.isFinished() ); + keyword.addRawRecordString("test 1 3 4 /"); + BOOST_CHECK( !keyword.isFinished() ); + + keyword.addRawRecordString("/"); + BOOST_CHECK( !keyword.isFinished() ); + + keyword.addRawRecordString("1 2 3 3 4"); + BOOST_CHECK( !keyword.isFinished() ); + keyword.addRawRecordString("1 2 3 3 4 /"); + BOOST_CHECK( !keyword.isFinished() ); + keyword.addRawRecordString("1 2 3 3 /"); + BOOST_CHECK( keyword.isFinished() ); + + RawRecordConstPtr record = keyword.getRecord(3); + BOOST_CHECK_EQUAL( 4U , record->size() ); + +} + + + +BOOST_AUTO_TEST_CASE(isKeywordTerminator) { + BOOST_CHECK( RawKeyword::isTerminator("/")); + BOOST_CHECK( RawKeyword::isTerminator(" /")); + BOOST_CHECK( RawKeyword::isTerminator("/ ")); + BOOST_CHECK( RawKeyword::isTerminator(" /")); + BOOST_CHECK( RawKeyword::isTerminator(" /")); + + BOOST_CHECK( !RawKeyword::isTerminator(" X/ ")); +} + + +BOOST_AUTO_TEST_CASE(useLine) { + BOOST_CHECK( !RawKeyword::useLine(" ")); + BOOST_CHECK( !RawKeyword::useLine("-- ggg")); + + BOOST_CHECK( RawKeyword::useLine("Data -- ggg")); + BOOST_CHECK( RawKeyword::useLine("/ -- ggg")); + BOOST_CHECK( RawKeyword::useLine("/")); +} + diff --git a/testdata/EQUIL/EQUIL1 b/testdata/EQUIL/EQUIL1 index 21f0f61fd..6350df2b3 100644 --- a/testdata/EQUIL/EQUIL1 +++ b/testdata/EQUIL/EQUIL1 @@ -1,6 +1,8 @@ EQLDIMS - 2 100 20 / + 3 100 20 1 1 / + EQUIL 2469 382.4 1705.0 0.0 500 0.0 1 1 20 / 2469 382.4 1000.0 0.0 500 0.0 1 1 20 / + 2469 382.4 3000.0 0.0 500 0.0 1 1 20 /