diff --git a/eclipse/docs/keywordtypes.txt b/docs/keywordtypes.txt
similarity index 100%
rename from eclipse/docs/keywordtypes.txt
rename to docs/keywordtypes.txt
diff --git a/eclipse/CMakeLists.txt b/eclipse/CMakeLists.txt
deleted file mode 100644
index 814b7bb27..000000000
--- a/eclipse/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-add_subdirectory (src)
-file(COPY testdata DESTINATION ${CMAKE_BINARY_DIR})
diff --git a/eclipse/src/Parser.cpp b/eclipse/src/Parser.cpp
deleted file mode 100644
index 2c253b24d..000000000
--- a/eclipse/src/Parser.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- Copyright 2013 Statoil ASA.
-
- 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 .
- */
-
-#include
-#include
-namespace fs = boost::filesystem;
-
-#include
-
-#include "Parser.hpp"
-
-namespace Opm {
-
- Parser::Parser() {
- }
-
- Parser::Parser(const std::string &path) {
- m_dataFilePath = path;
- }
-
- EclipseDeck Parser::parse(const std::string &path) {
- m_logger.setLogLevel(Opm::Logger::INFO);
- fs::path pathToCheck(path);
- if (!fs::is_regular_file(pathToCheck)) {
- m_logger.error("Unable to open file with path: " + path);
- throw std::invalid_argument("Given path is not a valid file-path, path: " + path);
- }
-
- ifstream file;
- initInputStream(path, file);
- EclipseDeck deck = doFileParsing(file);
- file.close();
- return deck;
- }
-
- EclipseDeck Parser::parse() {
- return parse(m_dataFilePath);
- }
-
- EclipseDeck Parser::doFileParsing(ifstream& inputstream) {
- EclipseDeck deck;
- std::string line;
- while (std::getline(inputstream, line)) {
- if (line.substr(0, 2) == "--") {
- m_logger.debug("COMMENT LINE < " + line + ">");
- } else if (boost::algorithm::trim_copy(line).length() == 0) {
- m_logger.debug("EMPTY LINE <" + line + ">");
- } else if (line.substr(0, 1) != " " && boost::algorithm::to_upper_copy(line) == line) {
- deck.addKeyword(line);
- m_logger.debug("KEYWORD LINE <" + line + ">");
- } else {
- m_logger.debug("SOMETHING ELSE <" + line + ">");
- }
- }
- return deck;
- }
-
- void Parser::initInputStream(const std::string &path, ifstream& file) {
- m_logger.info("Initializing from file: " + path);
- file.open(path.c_str());
- }
-
- Parser::~Parser() {
- }
-} // namespace Opm
diff --git a/eclipse/testdata/gurbat_trimmed.DATA b/eclipse/testdata/gurbat_trimmed.DATA
deleted file mode 100644
index 63d8adcc1..000000000
--- a/eclipse/testdata/gurbat_trimmed.DATA
+++ /dev/null
@@ -1,160 +0,0 @@
--- AUTO-SMOOTHER
-
------------------------------------------------------------------
------------------------------------------------------------------
--- This is the DATA file used by EnKF to run ECLIPSE. It is nearly a 100%
--- normal ECLIPSE DATA file, but there have been som modifications to use
--- it with EnkF. There are essentially three types of modifications:
---
--- * The parameters we want to update/estimate with EnKF are separated
--- out in separate files, which are included into this file.
---
--- * There are som 'magic strings' looking like this: . These are
--- replaced withother content by EnKF before the simulations starts -
--- observe that the 'magic strings' never represent parameters to
--- update.
---
--- * There are some special ECLIPSE keywords which must/must not be
--- present in the DATA file.
---
--- All the places[1] where the DATA file has been update for EnKF are marked
--- with EnKF.
---
--- [1]: There are many places with the string /private/joaho/ERT/git/ert/Gurbat - that is
--- not essential EnKF - just convenience to get EnKF to insert the
--- include path. The value of INCLUDE_PATH must be set with DATA_KW in
--- the main configuration file.
------------------------------------------------------------------
------------------------------------------------------------------
-
-
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
--- Reservoir Simulation Model Building Basic Principles: Generic Reservoir
--- by Gurbat S. Agaev, 26.06.2006
---
--- Objective: Explain simulation modelling steps
--- 3-phase model
--- Geological Grid - 120 x 200 x 42
------------------------------------------------------------------------------------------
---
---
--- **************************************************************************************
--- In this section simulation run specification is given
--- **************************************************************************************
---
------------------------------------------------------------------------------------------
--- **************************************************************************************
-RUNSPEC
--- **************************************************************************************
--- Simulation run title
-TITLE
-Reservoir Simulation Model Building Basic Principles
---
--- --------------------------------------------------------------------------------------
--- Simulation grid dimension (Imax, Jmax, Kmax)
-DIMENS
- 40 64 14 /
---
--- --------------------------------------------------------------------------------------
--- Big Model
---BIGMODEL
---
--- --------------------------------------------------------------------------------------
--- Simulation run start
-START
-----
- 1 JAN 2000 /
---
--- --------------------------------------------------------------------------------------
--- Fluid phases present
-OIL
-GAS
-WATER
-DISGAS
-VAPOIL
---
--- --------------------------------------------------------------------------------------
--- Measurement unit used
-METRIC
---
--- --------------------------------------------------------------------------------------
---Options to process grid data
---If MULTX-, MULTY- and MULTZ- are used, set first parameter= 'YES'
-GRIDOPTS
--- MULTNUM? NRMULT
- 'YES' 1* /
-INCLUDE
- 'include/example_summary.txt' /
-
--- Tracer data to be written to SUMMARY file
---FTPRSK1
---FTPRSK2
---FTPRSK3
-
---FTPTSK1
---FTPTSK2
---FTPTSK3
-
---WTPRSK1
---/
---WTPRSK2
---/
---WTPRSK3
---/
-
---WTPTSK1
---/
---WTPTSK2
---/
---WTPTSK3
---/
---
---
--- **************************************************************************************
--- In this section data required to describe history and prediction is given
--- - well completions, well production/injection, well constraints
--- - platform/production unit constraints, etc.
--- **************************************************************************************
---
------------------------------------------------------------------------------------------
--- **************************************************************************************
-SCHEDULE
--- **************************************************************************************
------------------------------------------------------------------------------------------
--- EnKF: RPTSCHED must have RESTART=2 for EnKF to work.
-RPTSCHED
- RESTART=2 /
-
--- EnKF: The keyword 'SKIPREST' in the SCHEDULE section is essential
--- EnKF: for EnKF to work.
-SKIPREST
-NOECHO
---
--- --------------------------------------------------------------------------------------
--- Schedule file (well comptetions, well constraints, well groups, rates, etc.)
--- Generated by SCHEDULE software
--- Input data required and input data formats are given in directory
---
-INCLUDE
- 'target.SCH' /
-
---INCLUDE
--- 'include/target.SCH' /
-
---
--- --------------------------------------------------------------------------------------
--- Production well VFP table (used for predictions)
---INCLUDE
--- 'include/example_vfp.vfp' /
-
---
--- --------------------------------------------------------------------------------------
--- If injection well VFP tables are required, include them in this section
---
-
---INCLUDE
--- 'prediction.sch' /
-
-END
diff --git a/eclipse/testdata/single.data b/eclipse/testdata/single.data
deleted file mode 100644
index 921a11873..000000000
--- a/eclipse/testdata/single.data
+++ /dev/null
@@ -1,2 +0,0 @@
--- Dette er en supertest
-HALLOEN
\ No newline at end of file
diff --git a/eclipse/src/CMakeLists.txt b/opm/parser/eclipse/CMakeLists.txt
similarity index 53%
rename from eclipse/src/CMakeLists.txt
rename to opm/parser/eclipse/CMakeLists.txt
index c26e06020..7d25f6ff2 100644
--- a/eclipse/src/CMakeLists.txt
+++ b/opm/parser/eclipse/CMakeLists.txt
@@ -1,7 +1,5 @@
-add_library(Parser Parser.cpp EclipseDeck.cpp)
+add_library(Parser Parser.cpp EclipseDeck.cpp KeywordRawData.cpp)
add_library(Logger Logger.cpp)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_subdirectory(tests)
-
diff --git a/eclipse/src/EclipseDeck.cpp b/opm/parser/eclipse/EclipseDeck.cpp
similarity index 100%
rename from eclipse/src/EclipseDeck.cpp
rename to opm/parser/eclipse/EclipseDeck.cpp
diff --git a/eclipse/src/EclipseDeck.hpp b/opm/parser/eclipse/EclipseDeck.hpp
similarity index 100%
rename from eclipse/src/EclipseDeck.hpp
rename to opm/parser/eclipse/EclipseDeck.hpp
diff --git a/opm/parser/eclipse/KeywordRawData.cpp b/opm/parser/eclipse/KeywordRawData.cpp
new file mode 100644
index 000000000..a2ec0e2b2
--- /dev/null
+++ b/opm/parser/eclipse/KeywordRawData.cpp
@@ -0,0 +1,38 @@
+/*
+ Copyright 2013 Statoil ASA.
+
+ 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 .
+ */
+
+#include
+#include "KeywordRawData.hpp"
+namespace Opm {
+
+ KeywordRawData::KeywordRawData() {
+ }
+
+ void KeywordRawData::addKeywordDataBlob(const std::string& keyword, const std::list& blob) {
+ m_keywordRawData.push_back(std::make_pair(keyword, blob));
+ }
+
+ int KeywordRawData::numberOfKeywords() {
+ return m_keywordRawData.size();
+ }
+
+ KeywordRawData::~KeywordRawData() {
+ }
+}
+
diff --git a/opm/parser/eclipse/KeywordRawData.hpp b/opm/parser/eclipse/KeywordRawData.hpp
new file mode 100644
index 000000000..224868f98
--- /dev/null
+++ b/opm/parser/eclipse/KeywordRawData.hpp
@@ -0,0 +1,28 @@
+/*
+ * File: KeywordRawData.hpp
+ * Author: kflik
+ *
+ * Created on March 20, 2013, 3:59 PM
+ */
+
+#ifndef KEYWORDRAWDATA_HPP
+#define KEYWORDRAWDATA_HPP
+
+#include
+#include
+#include
+
+namespace Opm {
+
+ class KeywordRawData {
+ public:
+ KeywordRawData();
+ void addKeywordDataBlob(const std::string& keyword, const std::list& blob);
+ int numberOfKeywords();
+ virtual ~KeywordRawData();
+ private:
+ std::list< std::pair< std::string, std::list > > m_keywordRawData;
+ };
+}
+#endif /* KEYWORDRAWDATA_HPP */
+
diff --git a/eclipse/src/Logger.cpp b/opm/parser/eclipse/Logger.cpp
similarity index 100%
rename from eclipse/src/Logger.cpp
rename to opm/parser/eclipse/Logger.cpp
diff --git a/eclipse/src/Logger.hpp b/opm/parser/eclipse/Logger.hpp
similarity index 100%
rename from eclipse/src/Logger.hpp
rename to opm/parser/eclipse/Logger.hpp
diff --git a/opm/parser/eclipse/Parser.cpp b/opm/parser/eclipse/Parser.cpp
new file mode 100644
index 000000000..f2b920359
--- /dev/null
+++ b/opm/parser/eclipse/Parser.cpp
@@ -0,0 +1,131 @@
+/*
+ Copyright 2013 Statoil ASA.
+
+ 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 .
+ */
+#include
+#include
+#include
+
+#include
+namespace fs = boost::filesystem;
+#include
+
+#include "Parser.hpp"
+
+namespace Opm {
+
+ Parser::Parser() {
+ m_keywordRawData = new KeywordRawData();
+ }
+
+ Parser::Parser(const std::string &path) {
+ m_keywordRawData = new KeywordRawData();
+ m_dataFilePath = path;
+ }
+
+ void Parser::parse(const std::string &path) {
+ m_logger.setLogLevel(Opm::Logger::DEBUG);
+
+ fs::path pathToCheck(path);
+ if (!fs::is_regular_file(pathToCheck)) {
+ m_logger.error("Unable to open file with path: " + path);
+ throw std::invalid_argument("Given path is not a valid file-path, path: " + path);
+ }
+
+ std::ifstream file;
+ initInputStream(path, file);
+ createKeywordAndRawData(file);
+ file.close();
+ }
+
+ void Parser::parse() {
+ parse(m_dataFilePath);
+ }
+
+ int Parser::getNumberOfKeywords() {
+ return m_keywordRawData -> numberOfKeywords();
+ }
+
+ void Parser::createKeywordAndRawData(std::ifstream& inputstream) {
+ EclipseDeck deck;
+ std::string line;
+ std::string currentKeyword = "";
+ std::list currentDataBlob;
+ while (std::getline(inputstream, line)) {
+ if (isKeyword(line)) {
+ if (currentKeyword != "") {
+ m_keywordRawData->addKeywordDataBlob(line, currentDataBlob);
+ }
+ currentDataBlob = std::list();
+ currentKeyword = line;
+ } else {
+ addDataToBlob(line, currentDataBlob);
+ }
+ }
+ if (currentKeyword != "") {
+ m_keywordRawData->addKeywordDataBlob(line, currentDataBlob);
+ }
+ }
+
+ void Parser::addDataToBlob(const std::string& line, std::list& currentDataBlob) {
+ if (looksLikeData(line)) {
+ currentDataBlob.push_back(line);
+ }
+ }
+
+ bool Parser::looksLikeData(const std::string& line) {
+ if (line.substr(0, 2) == "--") {
+ m_logger.debug("COMMENT LINE <" + line + ">");
+ return false;
+ } else if (boost::algorithm::trim_copy(line).length() == 0) {
+ m_logger.debug("EMPTY LINE <" + line + ">");
+ return false;
+ } else {
+ m_logger.debug("LOOKS LIKE DATA<" + line + ">");
+ return true;
+ }
+ }
+
+ bool Parser::isKeyword(const std::string& line) {
+ std::string keywordRegex = "^[A-Z]{1,8}$";
+ int status;
+ regex_t re;
+ regmatch_t rm;
+ if (regcomp(&re, keywordRegex.c_str(), REG_EXTENDED) != 0) {
+ m_logger.error("Unable to compile regular expression for keyword! Expression: " + keywordRegex);
+ throw std::runtime_error("Unable to compile regular expression for keyword! Expression: " + keywordRegex);
+ }
+
+ status = regexec(&re, line.c_str(), 1, &rm, 0);
+ regfree(&re);
+
+ if (status == 0) {
+ m_logger.debug("KEYWORD LINE <" + line + ">");
+ return true;
+ }
+ return false;
+ }
+
+ void Parser::initInputStream(const std::string &path, std::ifstream& file) {
+ m_logger.info("Initializing from file: " + path);
+ file.open(path.c_str());
+ }
+
+ Parser::~Parser() {
+ delete m_keywordRawData;
+ }
+} // namespace Opm
diff --git a/eclipse/src/Parser.hpp b/opm/parser/eclipse/Parser.hpp
similarity index 67%
rename from eclipse/src/Parser.hpp
rename to opm/parser/eclipse/Parser.hpp
index 94376386a..6db2277c2 100644
--- a/eclipse/src/Parser.hpp
+++ b/opm/parser/eclipse/Parser.hpp
@@ -19,13 +19,12 @@
#ifndef PARSER_H
#define PARSER_H
-
#include
#include
-using std::ifstream;
#include "EclipseDeck.hpp"
#include "Logger.hpp"
+#include "KeywordRawData.hpp"
namespace Opm {
@@ -33,15 +32,20 @@ namespace Opm {
public:
Parser();
Parser(const std::string &path);
- EclipseDeck parse();
- EclipseDeck parse(const std::string &path);
- std::string getLog();
+ void parse();
+ void parse(const std::string &path);
+ int getNumberOfKeywords();
virtual ~Parser();
private:
std::string m_dataFilePath;
Logger m_logger;
- void initInputStream(const std::string &path, ifstream& file);
- EclipseDeck doFileParsing(ifstream& inputstream);
+ KeywordRawData* m_keywordRawData;
+ void initInputStream(const std::string &path, std::ifstream& file);
+ void createKeywordAndRawData(std::ifstream& inputstream);
+ bool isKeyword(const std::string& line);
+ void addDataToBlob(const std::string& line, std::list& dataBlob);
+ bool looksLikeData(const std::string& line);
+
};
} // namespace Opm
#endif /* PARSER_H */
diff --git a/testdata/small.data b/testdata/small.data
new file mode 100644
index 000000000..2b83f42aa
--- /dev/null
+++ b/testdata/small.data
@@ -0,0 +1,18 @@
+-- Dette er en supertest, 8 tegn kommer
+HALLOENZ
+
+-- Saa bare en
+A
+
+-- Saa kommer en for lang en
+
+ABCXYZFFD
+
+-- Og en med tall
+
+ABC5ADFC
+
+
+-- Og en med mellomrom etter
+
+ABC5AD
diff --git a/eclipse/src/tests/CMakeLists.txt b/tests/CMakeLists.txt
similarity index 99%
rename from eclipse/src/tests/CMakeLists.txt
rename to tests/CMakeLists.txt
index 8525e58e1..7c3065d88 100644
--- a/eclipse/src/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,6 +1,5 @@
# Add test executable
add_executable(runUnitTests ParserTests.cpp)
-
target_link_libraries(runUnitTests Parser Logger ${Boost_LIBRARIES})
add_test(NAME runUnitTests WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} COMMAND ${EXECUTABLE_OUTPUT_PATH}/runUnitTests )
diff --git a/eclipse/src/tests/ParserTests.cpp b/tests/ParserTests.cpp
similarity index 79%
rename from eclipse/src/tests/ParserTests.cpp
rename to tests/ParserTests.cpp
index 063982ec8..93d939f22 100644
--- a/eclipse/src/tests/ParserTests.cpp
+++ b/tests/ParserTests.cpp
@@ -18,6 +18,7 @@
*/
#include
+#include
#include
#include
#include
@@ -25,8 +26,8 @@
#define BOOST_TEST_MODULE ParserTests
#include
-#include "Parser.hpp"
-#include "EclipseDeck.hpp"
+#include "opm/parser/eclipse/Parser.hpp"
+#include "opm/parser/eclipse/EclipseDeck.hpp"
using namespace Opm;
@@ -46,7 +47,7 @@ BOOST_AUTO_TEST_CASE(ParseWithInvalidInputFileThrows) {
}
BOOST_AUTO_TEST_CASE(ParseWithValidFileSetOnParseCallNoThrow) {
- boost::filesystem::path singleKeywordFile("testdata/single.data");
+ boost::filesystem::path singleKeywordFile("testdata/small.data");
Parser parser;
BOOST_REQUIRE_NO_THROW(parser.parse(singleKeywordFile.string()));
}
@@ -58,21 +59,17 @@ BOOST_AUTO_TEST_CASE(ParseWithInValidFileSetOnParseCallThrows) {
}
BOOST_AUTO_TEST_CASE(ParseFileWithOneKeyword) {
- boost::filesystem::path singleKeywordFile("testdata/single.data");
+ boost::filesystem::path singleKeywordFile("testdata/small.data");
Parser parser(singleKeywordFile.string());
- EclipseDeck deck = parser.parse();
-
- BOOST_REQUIRE_EQUAL(1, deck.getNumberOfKeywords());
- BOOST_REQUIRE_EQUAL((unsigned int)1, deck.getKeywords().size());
+ parser.parse();
+ BOOST_REQUIRE_EQUAL(2, parser.getNumberOfKeywords());
}
BOOST_AUTO_TEST_CASE(ParseFileWithManyKeywords) {
boost::filesystem::path multipleKeywordFile("testdata/gurbat_trimmed.DATA");
Parser parser(multipleKeywordFile.string());
- EclipseDeck deck = parser.parse();
-
- BOOST_REQUIRE_EQUAL(18, deck.getNumberOfKeywords());
- BOOST_REQUIRE_EQUAL((unsigned int)18, deck.getKeywords().size());
+ parser.parse();
+ BOOST_REQUIRE_EQUAL(18, parser.getNumberOfKeywords());
}