Moved files into structure similar to opm-core. Added KeywordRawData class to store 0th pass objects
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
add_subdirectory (src)
|
||||
file(COPY testdata DESTINATION ${CMAKE_BINARY_DIR})
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <boost/filesystem.hpp>
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#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
|
||||
160
eclipse/testdata/gurbat_trimmed.DATA
vendored
160
eclipse/testdata/gurbat_trimmed.DATA
vendored
@@ -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: <xxxx>. 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
|
||||
2
eclipse/testdata/single.data
vendored
2
eclipse/testdata/single.data
vendored
@@ -1,2 +0,0 @@
|
||||
-- Dette er en supertest
|
||||
HALLOEN
|
||||
@@ -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)
|
||||
|
||||
38
opm/parser/eclipse/KeywordRawData.cpp
Normal file
38
opm/parser/eclipse/KeywordRawData.cpp
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
#include "KeywordRawData.hpp"
|
||||
namespace Opm {
|
||||
|
||||
KeywordRawData::KeywordRawData() {
|
||||
}
|
||||
|
||||
void KeywordRawData::addKeywordDataBlob(const std::string& keyword, const std::list<std::string>& blob) {
|
||||
m_keywordRawData.push_back(std::make_pair(keyword, blob));
|
||||
}
|
||||
|
||||
int KeywordRawData::numberOfKeywords() {
|
||||
return m_keywordRawData.size();
|
||||
}
|
||||
|
||||
KeywordRawData::~KeywordRawData() {
|
||||
}
|
||||
}
|
||||
|
||||
28
opm/parser/eclipse/KeywordRawData.hpp
Normal file
28
opm/parser/eclipse/KeywordRawData.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* File: KeywordRawData.hpp
|
||||
* Author: kflik
|
||||
*
|
||||
* Created on March 20, 2013, 3:59 PM
|
||||
*/
|
||||
|
||||
#ifndef KEYWORDRAWDATA_HPP
|
||||
#define KEYWORDRAWDATA_HPP
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <list>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class KeywordRawData {
|
||||
public:
|
||||
KeywordRawData();
|
||||
void addKeywordDataBlob(const std::string& keyword, const std::list<std::string>& blob);
|
||||
int numberOfKeywords();
|
||||
virtual ~KeywordRawData();
|
||||
private:
|
||||
std::list< std::pair< std::string, std::list<std::string > > > m_keywordRawData;
|
||||
};
|
||||
}
|
||||
#endif /* KEYWORDRAWDATA_HPP */
|
||||
|
||||
131
opm/parser/eclipse/Parser.cpp
Normal file
131
opm/parser/eclipse/Parser.cpp
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <regex.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
namespace fs = boost::filesystem;
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#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<std::string> currentDataBlob;
|
||||
while (std::getline(inputstream, line)) {
|
||||
if (isKeyword(line)) {
|
||||
if (currentKeyword != "") {
|
||||
m_keywordRawData->addKeywordDataBlob(line, currentDataBlob);
|
||||
}
|
||||
currentDataBlob = std::list<std::string>();
|
||||
currentKeyword = line;
|
||||
} else {
|
||||
addDataToBlob(line, currentDataBlob);
|
||||
}
|
||||
}
|
||||
if (currentKeyword != "") {
|
||||
m_keywordRawData->addKeywordDataBlob(line, currentDataBlob);
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::addDataToBlob(const std::string& line, std::list<std::string>& 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
|
||||
@@ -19,13 +19,12 @@
|
||||
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
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<std::string>& dataBlob);
|
||||
bool looksLikeData(const std::string& line);
|
||||
|
||||
};
|
||||
} // namespace Opm
|
||||
#endif /* PARSER_H */
|
||||
18
testdata/small.data
vendored
Normal file
18
testdata/small.data
vendored
Normal file
@@ -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
|
||||
@@ -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 )
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
@@ -25,8 +26,8 @@
|
||||
#define BOOST_TEST_MODULE ParserTests
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#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());
|
||||
}
|
||||
Reference in New Issue
Block a user