Effective LOD for ESmry

This commit is contained in:
Torbjørn Skille 2020-04-01 09:18:11 +02:00
parent 12b0537936
commit 54087e3bd8
9 changed files with 886 additions and 339 deletions

View File

@ -193,7 +193,11 @@ if(ENABLE_ECL_INPUT)
test_util/summary.cpp
)
foreach(target compareECL convertECL summary)
add_executable(test_esmry_lod
test_util/test_esmry_lod.cpp
)
foreach(target compareECL convertECL summary test_esmry_lod)
target_link_libraries(${target} opmcommon)
install(TARGETS ${target} DESTINATION bin)
endforeach()

View File

@ -24,12 +24,17 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <map>
#include <stdint.h>
#include <opm/common/utility/FileSystem.hpp>
#include <opm/io/eclipse/SummaryNode.hpp>
namespace Opm { namespace EclIO {
using ArrSourceEntry = std::tuple<std::string, std::string, int, uint64_t>;
using TimeStepEntry = std::tuple<int, int, uint64_t>;
class ESmry
{
public:
@ -49,6 +54,9 @@ public:
std::vector<float> get_at_rstep(const SummaryNode& node) const;
std::vector<std::chrono::system_clock::time_point> dates_at_rstep() const;
void LoadData(const std::vector<std::string>& vectList) const;
void LoadData() const;
std::chrono::system_clock::time_point startdate() const { return startdat; }
const std::vector<std::string>& keywordList() const;
@ -57,7 +65,7 @@ public:
int timestepIdxAtReportstepStart(const int reportStep) const;
size_t numberOfTimeSteps() const { return param[0].size(); }
size_t numberOfTimeSteps() const { return timeStepList.size(); }
const std::string& get_unit(const std::string& name) const;
const std::string& get_unit(const SummaryNode& node) const;
@ -67,15 +75,28 @@ public:
private:
Opm::filesystem::path inputFileName;
int nVect, nI, nJ, nK;
int nI, nJ, nK, nSpecFiles;
size_t nVect;
std::vector<bool> formattedFiles;
std::vector<std::string> dataFileList;
mutable std::vector<std::vector<float>> vectorData;
mutable std::vector<bool> vectorLoaded;
std::vector<TimeStepEntry> timeStepList;
std::vector<std::map<int, int>> arrayPos;
std::vector<std::string> keyword;
std::map<std::string, int> keyword_index;
std::vector<int> nParamsSpecFile;
std::vector<std::vector<std::string>> keywordListSpecFile;
std::vector<int> seqIndex;
void ijk_from_global_index(int glob, int &i, int &j, int &k) const;
std::vector<std::vector<float>> param;
std::vector<std::string> keyword;
std::vector<SummaryNode> summaryNodes;
std::unordered_map<std::string, std::string> kwunits;
std::vector<int> seqIndex;
std::chrono::system_clock::time_point startdat;
std::vector<std::string> checkForMultipleResultFiles(const Opm::filesystem::path& rootN, bool formatted) const;
@ -94,7 +115,6 @@ private:
void write_block(std::ostream &, bool write_dates, const std::vector<std::string>& time_column, const std::vector<SummaryNode>&) const;
template <typename T>
std::vector<T> rstep_vector(const std::vector<T>& full_vector) const {
std::vector<T> result;
@ -106,6 +126,9 @@ private:
return result;
}
std::vector<std::tuple <std::string, uint64_t>> getListOfArrays(std::string filename, bool formatted);
std::vector<int> makeKeywPosVector(int speInd) const;
};
}} // namespace Opm::EclIO

View File

@ -30,12 +30,26 @@ namespace Opm { namespace EclIO {
int64_t flipEndianLongInt(int64_t num);
float flipEndianFloat(float num);
double flipEndianDouble(double num);
bool isEOF(std::fstream* fileH);
std::tuple<int, int> block_size_data_binary(eclArrType arrType);
std::tuple<int, int, int> block_size_data_formatted(eclArrType arrType);
std::string trimr(const std::string &str1);
uint64_t sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrType);
uint64_t sizeOnDiskFormatted(const int64_t num, Opm::EclIO::eclArrType arrType);
void readBinaryHeader(std::fstream& fileH, std::string& tmpStrName,
int& tmpSize, std::string& tmpStrType);
void readBinaryHeader(std::fstream& fileH, std::string& arrName,
int64_t& size, Opm::EclIO::eclArrType &arrType);
void readFormattedHeader(std::fstream& fileH, std::string& arrName,
int64_t &num, Opm::EclIO::eclArrType &arrType);
}} // namespace Opm::EclIO
#endif // OPM_IO_ECLUTIL_HPP

View File

@ -17,6 +17,10 @@
*/
#include <opm/io/eclipse/ESmry.hpp>
#include <opm/common/utility/FileSystem.hpp>
#include <opm/common/utility/TimeService.hpp>
#include <opm/io/eclipse/EclFile.hpp>
#include <opm/io/eclipse/EclUtil.hpp>
#include <algorithm>
#include <chrono>
@ -27,10 +31,9 @@
#include <stdexcept>
#include <string>
#include <fnmatch.h>
#include <fstream>
#include <cmath>
#include <opm/common/utility/FileSystem.hpp>
#include <opm/common/utility/TimeService.hpp>
#include <opm/io/eclipse/EclFile.hpp>
/*
KEYWORDS WGNAMES NUMS | PARAM index Corresponding ERT key
@ -88,18 +91,15 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
Opm::filesystem::path rootName = inputFileName.parent_path() / inputFileName.stem();
// if root name (without any extension) given as first argument in constructor, binary will then be assumed
if (inputFileName.extension()==""){
if (inputFileName.extension()=="")
inputFileName+=".SMSPEC";
}
std::vector<bool> formattedVect;
if ((inputFileName.extension()!=".SMSPEC") && (inputFileName.extension()!=".FSMSPEC")){
throw std::invalid_argument("Inptut file should have extension .SMSPEC or .FSMSPEC");
}
if ((inputFileName.extension()!=".SMSPEC") && (inputFileName.extension()!=".FSMSPEC"))
throw std::invalid_argument("Input file should have extension .SMSPEC or .FSMSPEC");
const bool formatted = inputFileName.extension()==".SMSPEC" ? false : true;
formattedVect.push_back(formatted);
formattedFiles.push_back(formatted);
Opm::filesystem::path path = Opm::filesystem::current_path();
@ -138,10 +138,15 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspec.get<int>("NUMS");
const std::vector<std::string> units = smspec.get<std::string>("UNITS");
std::vector<std::string> combindKeyList;
combindKeyList.reserve(dimens[0]);
this->startdat = make_date(smspec.get<int>("STARTDAT"));
for (unsigned int i=0; i<keywords.size(); i++) {
const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[i]);
combindKeyList.push_back(keyString);
if (keyString.length() > 0) {
summaryNodes.push_back({
keywords[i],
@ -156,6 +161,7 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
}
}
keywordListSpecFile.push_back(combindKeyList);
getRstString(restartArray, pathRstFile, rstRootN);
smryArray.push_back({smspec_file.string(), dimens[5]});
@ -164,6 +170,7 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
// checking if this is a restart run. Supporting nested restarts (restart, from restart, ...)
// std::set keywList is storing keywords from all runs involved
while ((rstRootN.string() != "") && (loadBaseRunData)) {
Opm::filesystem::path rstFile = pathRstFile / rstRootN;
@ -175,7 +182,6 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
if (!Opm::filesystem::exists(rstFile)){
rstFile = pathRstFile / rstRootN;
rstFile += ".FSMSPEC";
baseRunFmt = true;
}
@ -189,10 +195,14 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspec_rst.get<int>("NUMS");
const std::vector<std::string> units = smspec_rst.get<std::string>("UNITS");
std::vector<std::string> combindKeyList;
combindKeyList.reserve(dimens[0]);
this->startdat = make_date(smspec_rst.get<int>("STARTDAT"));
for (size_t i = 0; i < keywords.size(); i++) {
const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[i]);
combindKeyList.push_back(keyString);
if (keyString.length() > 0) {
summaryNodes.push_back({
keywords[i],
@ -208,29 +218,30 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
}
smryArray.push_back({rstFile.string(),dimens[5]});
formattedVect.push_back(baseRunFmt);
keywordListSpecFile.push_back(combindKeyList);
formattedFiles.push_back(baseRunFmt);
getRstString(restartArray, pathRstFile, rstRootN);
}
const int nFiles = static_cast<int>(smryArray.size());
nSpecFiles = static_cast<int>(smryArray.size());
nParamsSpecFile.resize(nSpecFiles, 0);
// arrayInd should hold indices for each vector and runs
// n=file number, i = position in param array in file n (one array pr time step), example arrayInd[n][i] = position in keyword list (std::set)
// arrayPos std::vector of std::map, mapping position in summary file[n]
for (int i = 0; i < nSpecFiles; i++)
arrayPos.push_back({});
std::vector<std::vector<int>> arrayInd;
for (int i = 0; i < nFiles; i++){
arrayInd.push_back({});
std::map<std::string, int> keyIndex;
{
size_t m = 0;
for (auto key : keywList)
keyIndex[key] = m++;
}
int n = nFiles - 1;
int specInd = nSpecFiles - 1;
while (specInd >= 0){
while (n >= 0){
auto smry = smryArray[n];
auto smry = smryArray[specInd];
EclFile smspec(std::get<0>(smry));
smspec.loadData();
@ -241,53 +252,58 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
nJ = dimens[2];
nK = dimens[3];
nParamsSpecFile[specInd] = dimens[0];
const std::vector<std::string> keywords = smspec.get<std::string>("KEYWORDS");
const std::vector<std::string> wgnames = smspec.get<std::string>("WGNAMES");
const std::vector<int> nums = smspec.get<int>("NUMS");
const std::vector<int> tmpVect(keywords.size(), -1);
arrayInd[n]=tmpVect;
std::set<std::string>::iterator it;
for (size_t i=0; i < keywords.size(); i++) {
const std::string keyw = makeKeyString(keywords[i], wgnames[i], nums[i]);
it = std::find(keywList.begin(), keywList.end(), keyw);
if (it != keywList.end()){
arrayInd[n][i] = distance(keywList.begin(), it);
}
if (keywList.find(keyw) != keywList.end())
arrayPos[specInd][keyIndex[keyw]]=i;
}
n--;
specInd--;
}
// param array used to stor data for the object, defined in the private section of the class
param.assign(keywList.size(), {});
int fromReportStepNumber = 0;
int toReportStepNumber;
float time = 0.0;
int step = 0;
specInd = nSpecFiles - 1;
nVect = keywList.size();
n = nFiles - 1;
int index = 0;
for (const auto& keyw : keywList){
keyword.push_back(keyw);
keyword_index[keyw] = index++;
}
while (n >= 0){
vectorData.reserve(nVect);
vectorLoaded.reserve(nVect);
for (size_t n = 0; n < nVect; n ++){
vectorData.push_back({});
vectorLoaded.push_back(false);
}
int dataFileIndex = -1;
while (specInd >= 0){
int reportStepNumber = fromReportStepNumber;
if (n > 0) {
auto rstFrom = smryArray[n-1];
if (specInd > 0) {
auto rstFrom = smryArray[specInd-1];
toReportStepNumber = std::get<1>(rstFrom);
} else {
toReportStepNumber = std::numeric_limits<int>::max();
}
Opm::filesystem::path smspecFile(std::get<0>(smryArray[n]));
Opm::filesystem::path smspecFile(std::get<0>(smryArray[specInd]));
rootName = smspecFile.parent_path() / smspecFile.stem();
// check if multiple or unified result files should be used
// to import data, no information in smspec file regarding this
// if both unified and non-unified files exists, will use most recent based on
@ -295,11 +311,10 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
Opm::filesystem::path unsmryFile = rootName;
formattedVect[n] ? unsmryFile += ".FUNSMRY" : unsmryFile += ".UNSMRY";
unsmryFile += formattedFiles[specInd] ? ".FUNSMRY" : ".UNSMRY";
const bool use_unified = Opm::filesystem::exists(unsmryFile.string());
const std::vector<std::string> multFileList = checkForMultipleResultFiles(rootName, formattedVect[n]);
const std::vector<std::string> multFileList = checkForMultipleResultFiles(rootName, formattedFiles[specInd]);
std::vector<std::string> resultsFileList;
@ -323,29 +338,27 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
// make array list with reference to source files (unifed or non unified)
std::vector<std::tuple<std::string, std::string, int>> arraySourceList;
std::vector<ArrSourceEntry> arraySourceList;
for (std::string fileName : resultsFileList){
EclFile unsmry(fileName);
for (std::string fileName : resultsFileList)
{
std::vector<std::tuple <std::string, uint64_t>> arrayList;
arrayList = this->getListOfArrays(fileName, formattedFiles[specInd]);
const std::vector<EclFile::EclEntry> arrayList = unsmry.getList();
for (size_t nn = 0; nn < arrayList.size(); nn++){
std::tuple<std::string, std::string, int> t1 = std::make_tuple(std::get<0>(arrayList[nn]), fileName, static_cast<int>(nn));
for (size_t n = 0; n < arrayList.size(); n++) {
ArrSourceEntry t1 = std::make_tuple(std::get<0>(arrayList[n]), fileName, n, std::get<1>(arrayList[n]));
arraySourceList.push_back(t1);
}
}
// loop through arrays and extract symmary data from result files, arrays PARAMS
// loop through arrays and for each ministep, store data file, location of params table
//
// 2 or 3 arrays pr time step.
// If timestep is a report step: MINISTEP, PARAMS and SEQHDR
// else : MINISTEP and PARAMS
size_t i = std::get<0>(arraySourceList[0]) == "SEQHDR" ? 1 : 0 ;
std::string prevFile;
std::unique_ptr<EclFile> pEclFile;
size_t i = std::get<0>(arraySourceList[0]) == "SEQHDR" ? 1 : 0 ;
while (i < arraySourceList.size()){
@ -361,22 +374,14 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
i++;
if (std::get<1>(arraySourceList[i]) != prevFile){
pEclFile = std::make_unique<EclFile>(std::get<1>(arraySourceList[i]));
pEclFile->loadData();
prevFile = std::get<1>(arraySourceList[i]);
if (std::find(dataFileList.begin(), dataFileList.end(), std::get<1>(arraySourceList[i])) == dataFileList.end())
{
dataFileList.push_back(std::get<1>(arraySourceList[i]));
dataFileIndex++;
}
const int m = std::get<2>(arraySourceList[i]);
const std::vector<float> tmpData = pEclFile->get<float>(m);
time = tmpData[0];
if (time == 0.0) {
seqIndex.push_back(step);
}
TimeStepEntry t1 = std::make_tuple(specInd, dataFileIndex, std::get<3>(arraySourceList[i]));
timeStepList.push_back(t1);
i++;
@ -391,20 +396,6 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
seqIndex.push_back(step);
}
// adding defaut values (0.0) in case vector not found in this particular summary file
for (size_t ii = 0; ii < param.size(); ii++){
param[ii].push_back(0.0);
}
for (size_t j = 0; j < tmpData.size(); j++) {
int ind = arrayInd[n][j];
if (ind > -1) {
param[ind][step] = tmpData[j];
}
}
if (reportStepNumber >= toReportStepNumber) {
i = arraySourceList.size();
}
@ -414,14 +405,286 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
fromReportStepNumber = toReportStepNumber;
n--;
specInd--;
}
}
void ESmry::LoadData(const std::vector<std::string>& vectList) const
{
size_t nvect = vectList.size();
size_t ntstep = timeStepList.size();
std::vector<int> keywIndVect;
keywIndVect.reserve(nvect);
for (auto key : vectList){
if (!hasKey(key))
OPM_THROW(std::invalid_argument, "error loading key " + key );
auto it = keyword_index.find(key);
keywIndVect.push_back(it->second);
}
nVect = keywList.size();
for (auto ind : keywIndVect)
vectorData[ind].reserve(ntstep);
for (const auto& keyw : keywList){
keyword.push_back(keyw);
std::fstream fileH;
auto specInd = std::get<0>(timeStepList[0]);
auto dataFileIndex = std::get<1>(timeStepList[0]);
uint64_t stepFilePos = std::get<2>(timeStepList[0]);
if (formattedFiles[specInd])
fileH.open(dataFileList[dataFileIndex], std::ios::in);
else
fileH.open(dataFileList[dataFileIndex], std::ios::in | std::ios::binary);
for (auto ministep : timeStepList) {
if (dataFileIndex != std::get<1>(ministep)) {
fileH.close();
specInd = std::get<0>(ministep);
dataFileIndex = std::get<1>(ministep);
if (formattedFiles[specInd])
fileH.open(dataFileList[dataFileIndex], std::ios::in );
else
fileH.open(dataFileList[dataFileIndex], std::ios::in | std::ios::binary);
}
stepFilePos = std::get<2>(ministep);;
for (auto ind : keywIndVect) {
auto it = arrayPos[specInd].find(ind);
if (it == arrayPos[specInd].end()) {
// undefined vector in current summary file. Typically when loading
// base restart run and including base run data. Vectors can be added to restart runs
vectorData[ind].push_back(nanf(""));
} else {
int paramPos = it->second;
if (formattedFiles[specInd]) {
uint64_t elementPos = 0;
int nBlocks = paramPos /MaxBlockSizeReal;
int sizeOfLastBlock = paramPos % MaxBlockSizeReal;
if (nBlocks > 0) {
int nLinesBlock = MaxNumBlockReal / numColumnsReal;
int rest = MaxNumBlockReal % numColumnsReal;
if (rest > 0)
nLinesBlock++;
uint64_t blockSize = static_cast<uint64_t>(MaxNumBlockReal * numColumnsReal + nLinesBlock);
elementPos = static_cast<uint64_t>(nBlocks * blockSize);
}
int nLines = sizeOfLastBlock / numColumnsReal;
elementPos = stepFilePos + elementPos + static_cast<uint64_t>(sizeOfLastBlock * columnWidthReal + nLines);
fileH.seekg (elementPos, fileH.beg);
char* buffer;
size_t size = columnWidthReal;
buffer = new char [size];
fileH.read (buffer, size);
double dtmpv = std::stod(std::string(buffer, size));
vectorData[ind].push_back(static_cast<float>(dtmpv));
delete[] buffer;
} else {
uint64_t nFullBlocks = static_cast<uint64_t>(paramPos/(MaxBlockSizeReal / sizeOfReal));
uint64_t elementPos = ((2 * nFullBlocks) + 1)*static_cast<uint64_t>(sizeOfInte);
elementPos += static_cast<uint64_t>(paramPos)* static_cast<uint64_t>(sizeOfReal) + stepFilePos;
fileH.seekg (elementPos, fileH.beg);
float value;
fileH.read(reinterpret_cast<char*>(&value), sizeOfReal);
vectorData[ind].push_back(Opm::EclIO::flipEndianFloat(value));
}
}
}
}
fileH.close();
for (auto ind : keywIndVect)
vectorLoaded[ind] = true;
}
std::vector<int> ESmry::makeKeywPosVector(int specInd) const {
std::vector<int> keywpos;
keywpos.reserve(nParamsSpecFile[specInd]);
for (int n = 0; n < nParamsSpecFile[specInd]; n++){
std::string tmpstr = keywordListSpecFile[specInd][n];
auto it = keyword_index.find(tmpstr);
if (it == keyword_index.end())
keywpos.push_back(-1);
else
if (std::find(keywpos.begin(), keywpos.end(), it->second) != keywpos.end())
keywpos.push_back(-1);
else
keywpos.push_back(it->second);
}
return keywpos;
}
void ESmry::LoadData() const
{
std::fstream fileH;
auto specInd = std::get<0>(timeStepList[0]);
auto dataFileIndex = std::get<1>(timeStepList[0]);
uint64_t stepFilePos = std::get<2>(timeStepList[0]);
std::vector<int> keywpos = makeKeywPosVector(specInd);
if (formattedFiles[specInd])
fileH.open(dataFileList[dataFileIndex], std::ios::in);
else
fileH.open(dataFileList[dataFileIndex], std::ios::in | std::ios::binary);
for (auto ministep : timeStepList) {
if (dataFileIndex != std::get<1>(ministep)) {
fileH.close();
if (specInd != std::get<0>(ministep)){
specInd = std::get<0>(ministep);
keywpos = makeKeywPosVector(specInd);
}
dataFileIndex = std::get<1>(ministep);
if (formattedFiles[specInd])
fileH.open(dataFileList[dataFileIndex], std::ios::in );
else
fileH.open(dataFileList[dataFileIndex], std::ios::in | std::ios::binary);
}
stepFilePos = std::get<2>(ministep);
int maxNumberOfElements = MaxBlockSizeReal / sizeOfReal;
fileH.seekg (stepFilePos, fileH.beg);
if (formattedFiles[specInd]) {
char* buffer;
size_t size = sizeOnDiskFormatted(nParamsSpecFile[specInd], Opm::EclIO::REAL)+1;
buffer = new char [size];
fileH.read (buffer, size);
std::string fileStr = std::string(buffer, size);
size_t p = 0;
int64_t p1= 0;
for (int i=0; i< nParamsSpecFile[specInd]; i++) {
p1 = fileStr.find_first_not_of(' ',p1);
int64_t p2 = fileStr.find_first_of(' ', p1);
if (keywpos[p] > -1) {
double dtmpv = std::stod(fileStr.substr(p1, p2-p1));
vectorData[keywpos[p]].push_back(static_cast<float>(dtmpv));
}
p1 = fileStr.find_first_not_of(' ',p2);
p++;
}
delete[] buffer;
} else {
int64_t rest = static_cast<int64_t>(nParamsSpecFile[specInd]);
size_t p = 0;
while (rest > 0) {
int dhead;
fileH.read(reinterpret_cast<char*>(&dhead), sizeof(dhead));
dhead = Opm::EclIO::flipEndianInt(dhead);
int num = dhead / sizeOfInte;
if ((num > maxNumberOfElements) || (num < 0))
OPM_THROW(std::runtime_error, "??Error reading binary data, inconsistent header data or incorrect number of elements");
for (int i = 0; i < num; i++) {
float value;
fileH.read(reinterpret_cast<char*>(&value), sizeOfReal);
if (keywpos[p] > -1)
vectorData[keywpos[p]].push_back(Opm::EclIO::flipEndianFloat(value));
p++;
}
rest -= num;
if (( num < maxNumberOfElements && rest != 0) ||
(num == maxNumberOfElements && rest < 0)) {
std::string message = "Error reading binary data, incorrect number of elements";
OPM_THROW(std::runtime_error, message);
}
int dtail;
fileH.read(reinterpret_cast<char*>(&dtail), sizeof(dtail));
dtail = Opm::EclIO::flipEndianInt(dtail);
if (dhead != dtail)
OPM_THROW(std::runtime_error, "Error reading binary data, tail not matching header.");
}
}
}
for (size_t n=0; n < nVect; n++)
vectorLoaded[n] = true;
}
std::vector<std::tuple <std::string, uint64_t>>
ESmry::getListOfArrays(std::string filename, bool formatted)
{
std::vector<std::tuple <std::string, uint64_t>> resultVect;
std::fstream fileH;
if (formatted)
fileH.open(filename, std::ios::in);
else
fileH.open(filename, std::ios::in | std::ios::binary);
while (!Opm::EclIO::isEOF(&fileH)) {
std::string arrName(8,' ');
Opm::EclIO::eclArrType arrType;
int64_t num;
if (formatted)
Opm::EclIO::readFormattedHeader(fileH,arrName,num,arrType);
else
Opm::EclIO::readBinaryHeader(fileH,arrName,num,arrType);
uint64_t filePos = fileH.tellg();
std::tuple <std::string, uint64_t> t1;
t1 = std::make_tuple(Opm::EclIO::trimr(arrName), filePos);
resultVect.push_back(t1);
if (num > 0) {
if (formatted) {
uint64_t sizeOfNextArray = sizeOnDiskFormatted(num, arrType);
fileH.seekg(static_cast<std::streamoff>(sizeOfNextArray), std::ios_base::cur);
} else {
uint64_t sizeOfNextArray = sizeOnDiskBinary(num, arrType);
fileH.seekg(static_cast<std::streamoff>(sizeOfNextArray), std::ios_base::cur);
}
}
}
fileH.close();
return resultVect;
}
@ -589,7 +852,12 @@ const std::vector<float>& ESmry::get(const std::string& name) const
int ind = std::distance(keyword.begin(), it);
return param[ind];
if (!vectorLoaded[ind]){
LoadData({name});
vectorLoaded[ind]=true;
}
return vectorData[ind];
}
std::vector<float> ESmry::get_at_rstep(const std::string& name) const

View File

@ -54,174 +54,6 @@ bool isFormatted(const std::string& filename)
}
bool isEOF(std::fstream* fileH)
{
int num;
int64_t pos = fileH->tellg();
fileH->read(reinterpret_cast<char*>(&num), sizeof(num));
if (fileH->eof()) {
return true;
} else {
fileH->seekg (pos);
return false;
}
}
void readBinaryHeader(std::fstream& fileH, std::string& tmpStrName,
int& tmpSize, std::string& tmpStrType)
{
int bhead;
fileH.read(reinterpret_cast<char*>(&bhead), sizeof(bhead));
bhead = Opm::EclIO::flipEndianInt(bhead);
if (bhead != 16){
std::string message="Error reading binary header. Expected 16 bytes of header data, found " + std::to_string(bhead);
OPM_THROW(std::runtime_error, message);
}
fileH.read(&tmpStrName[0], 8);
fileH.read(reinterpret_cast<char*>(&tmpSize), sizeof(tmpSize));
tmpSize = Opm::EclIO::flipEndianInt(tmpSize);
fileH.read(&tmpStrType[0], 4);
fileH.read(reinterpret_cast<char*>(&bhead), sizeof(bhead));
bhead = Opm::EclIO::flipEndianInt(bhead);
if (bhead != 16){
std::string message="Error reading binary header. Expected 16 bytes of header data, found " + std::to_string(bhead);
OPM_THROW(std::runtime_error, message);
}
}
void readBinaryHeader(std::fstream& fileH, std::string& arrName,
int64_t& size, Opm::EclIO::eclArrType &arrType)
{
std::string tmpStrName(8,' ');
std::string tmpStrType(4,' ');
int tmpSize;
readBinaryHeader(fileH, tmpStrName, tmpSize, tmpStrType);
if (tmpStrType == "X231"){
std::string x231ArrayName = tmpStrName;
int x231exp = tmpSize * (-1);
readBinaryHeader(fileH, tmpStrName, tmpSize, tmpStrType);
if (x231ArrayName != tmpStrName)
OPM_THROW(std::runtime_error, "Invalied X231 header, name should be same in both headers'");
if (x231exp < 0)
OPM_THROW(std::runtime_error, "Invalied X231 header, size of array should be negative'");
size = static_cast<int64_t>(tmpSize) + static_cast<int64_t>(x231exp) * pow(2,31);
} else {
size = static_cast<int64_t>(tmpSize);
}
arrName = tmpStrName;
if (tmpStrType == "INTE")
arrType = Opm::EclIO::INTE;
else if (tmpStrType == "REAL")
arrType = Opm::EclIO::REAL;
else if (tmpStrType == "DOUB")
arrType = Opm::EclIO::DOUB;
else if (tmpStrType == "CHAR")
arrType = Opm::EclIO::CHAR;
else if (tmpStrType =="LOGI")
arrType = Opm::EclIO::LOGI;
else if (tmpStrType == "MESS")
arrType = Opm::EclIO::MESS;
else
OPM_THROW(std::runtime_error, "Error, unknown array type '" + tmpStrType +"'");
}
uint64_t sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrType)
{
uint64_t size = 0;
if (arrType == Opm::EclIO::MESS) {
if (num > 0) {
std::string message = "In routine calcSizeOfArray, type MESS can not have size > 0";
OPM_THROW(std::invalid_argument, message);
}
} else {
if (num > 0) {
auto sizeData = Opm::EclIO::block_size_data_binary(arrType);
int sizeOfElement = std::get<0>(sizeData);
int maxBlockSize = std::get<1>(sizeData);
int maxNumberOfElements = maxBlockSize / sizeOfElement;
auto numBlocks = static_cast<uint64_t>(num)/static_cast<uint64_t>(maxNumberOfElements);
auto rest = static_cast<uint64_t>(num) - numBlocks*static_cast<uint64_t>(maxNumberOfElements);
auto size2Inte = static_cast<uint64_t>(Opm::EclIO::sizeOfInte) * 2;
auto sizeFullBlocks = numBlocks * (static_cast<uint64_t>(maxBlockSize) + size2Inte);
uint64_t sizeLastBlock = 0;
if (rest > 0)
sizeLastBlock = rest * static_cast<uint64_t>(sizeOfElement) + size2Inte;
size = sizeFullBlocks + sizeLastBlock;
}
}
return size;
}
uint64_t sizeOnDiskFormatted(const int64_t num, Opm::EclIO::eclArrType arrType)
{
uint64_t size = 0;
if (arrType == Opm::EclIO::MESS) {
if (num > 0) {
OPM_THROW(std::invalid_argument, "In routine calcSizeOfArray, type MESS can not have size > 0");
}
} else {
auto sizeData = block_size_data_formatted(arrType);
int maxBlockSize = std::get<0>(sizeData);
int nColumns = std::get<1>(sizeData);
int columnWidth = std::get<2>(sizeData);
int nBlocks = num /maxBlockSize;
int sizeOfLastBlock = num % maxBlockSize;
size = 0;
if (nBlocks > 0) {
int nLinesBlock = maxBlockSize / nColumns;
int rest = maxBlockSize % nColumns;
if (rest > 0) {
nLinesBlock++;
}
int64_t blockSize = maxBlockSize * columnWidth + nLinesBlock;
size = nBlocks * blockSize;
}
int nLines = sizeOfLastBlock / nColumns;
int rest = sizeOfLastBlock % nColumns;
size = size + sizeOfLastBlock * columnWidth + nLines;
if (rest > 0) {
size++;
}
}
return size;
}
template<typename T, typename T2>
std::vector<T> readBinaryArray(std::fstream& fileH, const int64_t size, Opm::EclIO::eclArrType type,
std::function<T(T2)>& flip)
@ -325,48 +157,6 @@ std::vector<std::string> readBinaryCharArray(std::fstream& fileH, const int64_t
}
void readFormattedHeader(std::fstream& fileH, std::string& arrName,
int64_t &num, Opm::EclIO::eclArrType &arrType)
{
std::string line;
std::getline(fileH,line);
int p1 = line.find_first_of("'");
int p2 = line.find_first_of("'",p1+1);
int p3 = line.find_first_of("'",p2+1);
int p4 = line.find_first_of("'",p3+1);
if (p1 == -1 || p2 == -1 || p3 == -1 || p4 == -1) {
OPM_THROW(std::runtime_error, "Header name and type should be enclosed with '");
}
arrName = line.substr(p1 + 1, p2 - p1 - 1);
std::string antStr = line.substr(p2 + 1, p3 - p2 - 1);
std::string arrTypeStr = line.substr(p3 + 1, p4 - p3 - 1);
num = std::stol(antStr);
if (arrTypeStr == "INTE")
arrType = Opm::EclIO::INTE;
else if (arrTypeStr == "REAL")
arrType = Opm::EclIO::REAL;
else if (arrTypeStr == "DOUB")
arrType = Opm::EclIO::DOUB;
else if (arrTypeStr == "CHAR")
arrType = Opm::EclIO::CHAR;
else if (arrTypeStr == "LOGI")
arrType = Opm::EclIO::LOGI;
else if (arrTypeStr == "MESS")
arrType = Opm::EclIO::MESS;
else
OPM_THROW(std::runtime_error, "Error, unknown array type '" + arrTypeStr +"'");
if (arrName.size() != 8) {
OPM_THROW(std::runtime_error, "Header name should be 8 characters");
}
}
template<typename T>
std::vector<T> readFormattedArray(const std::string& file_str, const int size, int64_t fromPos,
std::function<T(const std::string&)>& process)

View File

@ -22,6 +22,8 @@
#include <algorithm>
#include <stdexcept>
#include <cmath>
#include <fstream>
int Opm::EclIO::flipEndianInt(int num)
@ -57,6 +59,20 @@ double Opm::EclIO::flipEndianDouble(double num)
return value;
}
bool Opm::EclIO::isEOF(std::fstream* fileH)
{
int num;
int64_t pos = fileH->tellg();
fileH->read(reinterpret_cast<char*>(&num), sizeof(num));
if (fileH->eof()) {
return true;
} else {
fileH->seekg (pos);
return false;
}
}
std::tuple<int, int> Opm::EclIO::block_size_data_binary(eclArrType arrType)
{
@ -128,3 +144,197 @@ std::string Opm::EclIO::trimr(const std::string &str1)
return str1.substr(0,p+1);
}
}
uint64_t Opm::EclIO::sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrType)
{
uint64_t size = 0;
if (arrType == Opm::EclIO::MESS) {
if (num > 0) {
std::string message = "In routine calcSizeOfArray, type MESS can not have size > 0";
OPM_THROW(std::invalid_argument, message);
}
} else {
if (num > 0) {
auto sizeData = Opm::EclIO::block_size_data_binary(arrType);
int sizeOfElement = std::get<0>(sizeData);
int maxBlockSize = std::get<1>(sizeData);
int maxNumberOfElements = maxBlockSize / sizeOfElement;
auto numBlocks = static_cast<uint64_t>(num)/static_cast<uint64_t>(maxNumberOfElements);
auto rest = static_cast<uint64_t>(num) - numBlocks*static_cast<uint64_t>(maxNumberOfElements);
auto size2Inte = static_cast<uint64_t>(Opm::EclIO::sizeOfInte) * 2;
auto sizeFullBlocks = numBlocks * (static_cast<uint64_t>(maxBlockSize) + size2Inte);
uint64_t sizeLastBlock = 0;
if (rest > 0)
sizeLastBlock = rest * static_cast<uint64_t>(sizeOfElement) + size2Inte;
size = sizeFullBlocks + sizeLastBlock;
}
}
return size;
}
uint64_t Opm::EclIO::sizeOnDiskFormatted(const int64_t num, Opm::EclIO::eclArrType arrType)
{
uint64_t size = 0;
if (arrType == Opm::EclIO::MESS) {
if (num > 0) {
OPM_THROW(std::invalid_argument, "In routine calcSizeOfArray, type MESS can not have size > 0");
}
} else {
auto sizeData = block_size_data_formatted(arrType);
int maxBlockSize = std::get<0>(sizeData);
int nColumns = std::get<1>(sizeData);
int columnWidth = std::get<2>(sizeData);
int nBlocks = num /maxBlockSize;
int sizeOfLastBlock = num % maxBlockSize;
size = 0;
if (nBlocks > 0) {
int nLinesBlock = maxBlockSize / nColumns;
int rest = maxBlockSize % nColumns;
if (rest > 0) {
nLinesBlock++;
}
int64_t blockSize = maxBlockSize * columnWidth + nLinesBlock;
size = nBlocks * blockSize;
}
int nLines = sizeOfLastBlock / nColumns;
int rest = sizeOfLastBlock % nColumns;
size = size + sizeOfLastBlock * columnWidth + nLines;
if (rest > 0) {
size++;
}
}
return size;
}
void Opm::EclIO::readBinaryHeader(std::fstream& fileH, std::string& tmpStrName,
int& tmpSize, std::string& tmpStrType)
{
int bhead;
fileH.read(reinterpret_cast<char*>(&bhead), sizeof(bhead));
bhead = Opm::EclIO::flipEndianInt(bhead);
if (bhead != 16){
std::string message="Error reading binary header. Expected 16 bytes of header data, found " + std::to_string(bhead);
OPM_THROW(std::runtime_error, message);
}
fileH.read(&tmpStrName[0], 8);
fileH.read(reinterpret_cast<char*>(&tmpSize), sizeof(tmpSize));
tmpSize = Opm::EclIO::flipEndianInt(tmpSize);
fileH.read(&tmpStrType[0], 4);
fileH.read(reinterpret_cast<char*>(&bhead), sizeof(bhead));
bhead = Opm::EclIO::flipEndianInt(bhead);
if (bhead != 16){
std::string message="Error reading binary header. Expected 16 bytes of header data, found " + std::to_string(bhead);
OPM_THROW(std::runtime_error, message);
}
}
void Opm::EclIO::readBinaryHeader(std::fstream& fileH, std::string& arrName,
int64_t& size, Opm::EclIO::eclArrType &arrType)
{
std::string tmpStrName(8,' ');
std::string tmpStrType(4,' ');
int tmpSize;
readBinaryHeader(fileH, tmpStrName, tmpSize, tmpStrType);
if (tmpStrType == "X231"){
std::string x231ArrayName = tmpStrName;
int x231exp = tmpSize * (-1);
readBinaryHeader(fileH, tmpStrName, tmpSize, tmpStrType);
if (x231ArrayName != tmpStrName)
OPM_THROW(std::runtime_error, "Invalied X231 header, name should be same in both headers'");
if (x231exp < 0)
OPM_THROW(std::runtime_error, "Invalied X231 header, size of array should be negative'");
size = static_cast<int64_t>(tmpSize) + static_cast<int64_t>(x231exp) * pow(2,31);
} else {
size = static_cast<int64_t>(tmpSize);
}
arrName = tmpStrName;
if (tmpStrType == "INTE")
arrType = Opm::EclIO::INTE;
else if (tmpStrType == "REAL")
arrType = Opm::EclIO::REAL;
else if (tmpStrType == "DOUB")
arrType = Opm::EclIO::DOUB;
else if (tmpStrType == "CHAR")
arrType = Opm::EclIO::CHAR;
else if (tmpStrType =="LOGI")
arrType = Opm::EclIO::LOGI;
else if (tmpStrType == "MESS")
arrType = Opm::EclIO::MESS;
else
OPM_THROW(std::runtime_error, "Error, unknown array type '" + tmpStrType +"'");
}
void Opm::EclIO::readFormattedHeader(std::fstream& fileH, std::string& arrName,
int64_t &num, Opm::EclIO::eclArrType &arrType)
{
std::string line;
std::getline(fileH,line);
int p1 = line.find_first_of("'");
int p2 = line.find_first_of("'",p1+1);
int p3 = line.find_first_of("'",p2+1);
int p4 = line.find_first_of("'",p3+1);
if (p1 == -1 || p2 == -1 || p3 == -1 || p4 == -1) {
OPM_THROW(std::runtime_error, "Header name and type should be enclosed with '");
}
arrName = line.substr(p1 + 1, p2 - p1 - 1);
std::string antStr = line.substr(p2 + 1, p3 - p2 - 1);
std::string arrTypeStr = line.substr(p3 + 1, p4 - p3 - 1);
num = std::stol(antStr);
if (arrTypeStr == "INTE")
arrType = Opm::EclIO::INTE;
else if (arrTypeStr == "REAL")
arrType = Opm::EclIO::REAL;
else if (arrTypeStr == "DOUB")
arrType = Opm::EclIO::DOUB;
else if (arrTypeStr == "CHAR")
arrType = Opm::EclIO::CHAR;
else if (arrTypeStr == "LOGI")
arrType = Opm::EclIO::LOGI;
else if (arrTypeStr == "MESS")
arrType = Opm::EclIO::MESS;
else
OPM_THROW(std::runtime_error, "Error, unknown array type '" + arrTypeStr +"'");
if (arrName.size() != 8) {
OPM_THROW(std::runtime_error, "Header name should be 8 characters");
}
}

View File

@ -335,13 +335,13 @@ void ECLRegressionTest::loadGrids()
grid1 = new EGrid(fileName1);
std::cout << " done." << std::endl;
}
if (foundEGrid2) {
std::cout << "Loading EGrid " << fileName2 << " .... ";
grid2 = new EGrid(fileName2);
std::cout << " done." << std::endl;
}
if ((not foundEGrid1) || (not foundEGrid2)) {
std::cout << "\nWarning! Both grids could not be loaded. Not possible to reference cell values to grid indices." << std::endl;
std::cout << "Grid compare may also fail. SMRY, RFT, UNRST and INIT files can be checked \n" << std::endl;
@ -352,17 +352,17 @@ void ECLRegressionTest::loadGrids()
void ECLRegressionTest::gridCompare()
{
deviations.clear();
if ((grid1) && (not grid2)){
std::string message ="test case egrid file " + rootName2 + ".EGRID could not be loaded";
std::cout << message << std::endl;
OPM_THROW(std::runtime_error, message);
}
if (grid1 && grid2) {
std::cout << "comparing grids " << std::endl;
const auto& dim1 = grid1->dimension();
const auto& dim2 = grid2->dimension();
@ -519,11 +519,11 @@ void ECLRegressionTest::gridCompare()
if (!deviations.empty()) {
printDeviationReport();
}
} else {
std::cout << "\n!Warning, grid files not found, hence not compared. \n" << std::endl;
}
}
@ -539,7 +539,7 @@ void ECLRegressionTest::results_init()
std::cout << message << std::endl;
OPM_THROW(std::runtime_error, message);
}
if (foundInit1 && foundInit2) {
EclFile init1(fileName1);
std::cout << "\nLoading INIT file " << fileName1 << " .... done" << std::endl;
@ -614,10 +614,10 @@ void ECLRegressionTest::results_init()
}
auto it = std::find(keywordsBlackList.begin(), keywordsBlackList.end(), keywords1[i]);
if (it != keywordsBlackList.end()){
std::cout << "Skipping " << keywords1[i] << std::endl;
} else {
} else {
std::cout << "Comparing " << keywords1[i] << " ... ";
if (arrayType1[i] == INTE) {
@ -658,7 +658,7 @@ void ECLRegressionTest::results_init()
} else {
std::cout << "\n!Warning, init files not found, hence not compared. \n" << std::endl;
}
}
@ -673,7 +673,7 @@ void ECLRegressionTest::results_rst()
std::cout << message << std::endl;
OPM_THROW(std::runtime_error, message);
}
if (foundRst1 && foundRst2) {
ERst rst1(fileName1);
std::cout << "\nLoading restart file " << fileName1 << " .... done" << std::endl;
@ -703,7 +703,7 @@ void ECLRegressionTest::results_rst()
seqnums2.clear();
seqnums2.push_back(spesificSequence);
} else if (onlyLastSequence) {
if (seqnums1.back() != seqnums2.back()) {
@ -754,7 +754,7 @@ void ECLRegressionTest::results_rst()
std::vector<std::string> keywords2;
std::vector<eclArrType> arrayType2;
for (const auto& array : arrays2) {
keywords2.push_back(std::get<0>(array));
arrayType2.push_back(std::get<1>(array));
@ -801,10 +801,10 @@ void ECLRegressionTest::results_rst()
}
auto it = std::find(keywordsBlackList.begin(), keywordsBlackList.end(), keywords1[i]);
if (it != keywordsBlackList.end()){
std::cout << "Skipping " << keywords1[i] << std::endl;
} else {
} else {
std::cout << "Comparing " << keywords1[i] << " ... ";
@ -868,12 +868,14 @@ void ECLRegressionTest::results_smry()
std::cout << message << std::endl;
OPM_THROW(std::runtime_error, message);
}
if (foundSmspec1 && foundSmspec2) {
ESmry smry1(fileName1, loadBaseRunData);
smry1.LoadData();
std::cout << "\nLoading summary file " << fileName1 << " .... done" << std::endl;
ESmry smry2(fileName2, loadBaseRunData);
smry2.LoadData();
std::cout << "\nLoading summary file " << fileName2 << " .... done" << std::endl;
deviations.clear();
@ -881,11 +883,11 @@ void ECLRegressionTest::results_smry()
std::string reference = "Summary file";
std::cout << "\nComparing summary files " << std::endl;
if (reportStepOnly){
std::cout << " -- Values at report steps will be compared. Time steps in between reports are ignored " << std::endl;
}
std::vector<std::string> keywords1 = smry1.keywordList();
std::vector<std::string> keywords2 = smry2.keywordList();
@ -930,10 +932,10 @@ void ECLRegressionTest::results_smry()
}
std::vector<std::string> blackListed;
for (std::vector<std::string>::iterator keywit = keywords1.begin(); keywit != keywords1.end(); ++keywit) {
auto it = std::find(keywordsBlackList.begin(), keywordsBlackList.end(), *keywit );
if (it != keywordsBlackList.end()){
blackListed.push_back(*keywit);
keywit = keywords1.erase(keywit);
@ -941,14 +943,14 @@ void ECLRegressionTest::results_smry()
--keywit;
}
}
std::cout << "\nChecking " << keywords1.size() << " vectors ... ";
for (size_t i = 0; i < keywords1.size(); i++) {
std::vector<float> vect1;
std::vector<float> vect2;
if (reportStepOnly){
vect1 = smry1.get_at_rstep( keywords1[i]);
vect2 = smry2.get_at_rstep( keywords1[i]);
@ -956,7 +958,7 @@ void ECLRegressionTest::results_smry()
vect1 = smry1.get( keywords1[i]);
vect2 = smry2.get( keywords1[i]);
}
if (vect1.size() != vect2.size()) {
OPM_THROW(std::runtime_error, "\nKeyword " << keywords1[i] << " summary vector of different length ("
<< vect1.size() << " != " << vect2.size() <<")");
@ -966,7 +968,7 @@ void ECLRegressionTest::results_smry()
}
std::cout << " done." << std::endl;
if (blackListed.size()>0){
std::cout << "Number of black listed vectors " << blackListed.size() << " (not compared) " << std::endl;
}
@ -987,7 +989,7 @@ void ECLRegressionTest::results_smry()
} else {
std::cout << "\n!Warning, summary files not found, hence not compared. \n" << std::endl;
}
}
@ -1078,10 +1080,10 @@ void ECLRegressionTest::results_rft()
eclArrType arrayType = std::get<1>(array);
auto it = std::find(keywordsBlackList.begin(), keywordsBlackList.end(), keyword);
if (it != keywordsBlackList.end()){
std::cout << "Skipping " << keyword << std::endl;
} else {
} else {
std::cout << "Comparing: " << keyword << " ... ";
if (arrayType == INTE) {

View File

@ -0,0 +1,230 @@
#include <chrono>
#include <iomanip>
#include <iostream>
#include <tuple>
#include <getopt.h>
#include <fstream>
#include <iostream>
#include <opm/io/eclipse/EclFile.hpp>
#include <opm/io/eclipse/ESmry.hpp>
using namespace Opm::EclIO;
using EclEntry = EclFile::EclEntry;
static void printHelp() {
std::cout << "\nSmall test program used to test performance for ESmry class. Two arguments needed.\n"
<< "\nfirst name of smspec file, and second is vector list:\n"
<< "\nExample\n > test_esmry_lod -p out.txt TEST.SMSPEC \"FOPR FGPR\" \n\n"
<< "\nIn addition, the program takes these options (which must be given before the arguments):\n\n"
<< "-h Print help and exit.\n"
<< "-p write selected vectors to file .\n\n";
}
std::vector<std::string> splitString(std::string str){
std::vector<std::string> res_vect;
int p1 = 0;
while (p1 != -1 ) {
p1 = str.find_first_not_of(' ', p1);
int p2 = str.find_first_of(" ", p1+1);
res_vect.push_back(str.substr(p1, p2 - p1) );
p1 = p2;
}
return res_vect;
}
int main(int argc, char **argv) {
int c = 0;
bool output = false;
bool compare = false;
bool loadOnDemand = false;
std::string outFileName = "";
std::string refFileName = "";
while ((c = getopt(argc, argv, "hp:c:l")) != -1) {
switch (c) {
case 'h':
printHelp();
return 0;
case 'p':
output=true;
outFileName = optarg;
break;
case 'c':
compare = true;
refFileName = optarg;
break;
case 'l':
loadOnDemand = true;
break;
default:
return EXIT_FAILURE;
}
}
int argOffset = optind;
if (compare) {
std::cout << "\ncompare " << argv[argOffset] << " vs ref: " << refFileName << std::endl;
std::string filename = argv[argOffset];
auto lap1 = std::chrono::system_clock::now();
ESmry smry1(filename, false);
ESmry smry2(refFileName, false);
smry1.LoadData();
smry2.LoadData();
auto kwlist1 = smry1.keywordList();
auto kwlist2 = smry2.keywordList();
if (kwlist1.size() !=kwlist2.size())
throw std::runtime_error("size of keyword lists differ");
for (size_t n = 0; n < kwlist1.size(); n++)
if (kwlist1[n] != kwlist1[n])
throw std::runtime_error("keyword element differ");
std::cout << kwlist1.size() << " vs " << kwlist2.size() << std::endl;
for (auto keyw : kwlist1){
auto v1 = smry1.get(keyw);
auto v2 = smry2.get(keyw);
if (v1.size() != v2.size())
throw std::runtime_error("size of vector differ");
for (size_t m = 0; m < v1.size(); m++) {
float absDiff = abs( v1[m]- v2[m]);
if (v2[m] > 0.0)
absDiff = absDiff / v2[m];
if (absDiff > 0.0000001) {
std::cout << "not equal. keyword: " << keyw << " v1: " << v1[m] << " vs v2: " << v2[m] << std::endl;
exit(1);
}
}
}
auto lap2 = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds2 = lap2-lap1;
std::cout << "runtime for test : " << elapsed_seconds2.count() << " seconds\n" << std::endl;
exit(0);
}
/*
do {
std::cout << '\n' << "Press a key to continue...";
} while ( std::cin.get() != '\n' );
*/
// start reading
auto start = std::chrono::system_clock::now();
std::string filename = argv[argOffset];
ESmry smry1(filename, true);
//ESmry smry1(filename, false);
auto lap1 = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds1 = lap1-start;
if (argc < 3)
throw std::invalid_argument("second argument should be a vector list, example \"FOPR FWCT\"");
std::string inputVectors(argv[argOffset+1]);
std::vector<std::string> vectKeyList = splitString(inputVectors);
if (loadOnDemand) {
std::cout << "\nloading vectors ";
for (auto key : vectKeyList)
std::cout << key << " ";
std::cout << "\n" << std::endl;
smry1.LoadData(vectKeyList);
} else {
std::cout << "\nloading all vectors \n" << std::endl;
smry1.LoadData();
}
auto lap2 = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds2 = lap2-lap1;
std::vector<std::vector<float>> dataList;
for (auto key : vectKeyList){
auto vect = smry1.get_at_rstep(key);
dataList.push_back(vect);
}
auto lap3 = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds3 = lap3-lap2;
std::cout << "runtime : " << argv[argOffset] << ": " << elapsed_seconds1.count() << " seconds\n" << std::endl;
std::cout << "runtime loading vector list: " << elapsed_seconds2.count() << " seconds\n" << std::endl;
std::cout << "runtime getting vectors vector list: " << elapsed_seconds3.count() << " seconds\n" << std::endl;
std::chrono::duration<double> elapsed_total = lap3-start;
std::cout << "runtime total: " << elapsed_total.count() << " seconds\n" << std::endl;
if (output){
int colw = 15;
std::cout << "write to file " << outFileName << std::endl;
std::ofstream outfile;
outfile.open(outFileName);
outfile << std::setw(colw) << "ts";
for (auto key : vectKeyList)
outfile << std::setw(colw) << key;
outfile << std::endl;
for (size_t n =1; n < dataList.size(); n++)
if (dataList[n].size() != dataList[n-1].size())
throw std::runtime_error("size of vectors differs ");
for (size_t t = 0; t < dataList[0].size(); t++){
outfile << std::setw(colw) << t;
for (size_t n = 0; n < dataList.size(); n++)
outfile << std::setw(colw) << std::scientific << std::setprecision(8) << dataList[n][t];
outfile << std::endl;
}
outfile.close();
}
/*
do {
std::cout << '\n' << "Press a key to exit ...";
} while ( std::cin.get() != '\n' );
*/
return 0;
}

View File

@ -153,6 +153,7 @@ BOOST_AUTO_TEST_CASE(TestESmry_1) {
getRefSmryVect(time_ref, wgpr_prod_ref, wbhp_prod_ref, wbhp_inj_ref,fgor_ref, bpr_111_ref, bpr_10103_ref);
ESmry smry1("SPE1CASE1.SMSPEC");
smry1.LoadData();
std::vector<float> smryVect = smry1.get("TIME");
BOOST_CHECK_EQUAL(smryVect==time_ref, true);
@ -229,6 +230,7 @@ BOOST_AUTO_TEST_CASE(TestESmry_2) {
// will be loaded. No data from base run (SPE1CASE1 in this case)
ESmry smry1("SPE1CASE1_RST60.SMSPEC"); // equivalent to smry1("SPE1CASE1_RST60.SMSPEC",false)
smry1.LoadData();
std::vector<float> smryVect = smry1.get("TIME");
std::vector<float> time_ref_rst60 = getFrom(time_ref,63);
@ -306,6 +308,7 @@ BOOST_AUTO_TEST_CASE(TestESmry_3) {
// vectors should be equal to reference vectors (from SPE1CASE1)
ESmry smry1("SPE1CASE1_RST60.SMSPEC",true);
smry1.LoadData();
std::vector<float> smryVect = smry1.get("TIME");
BOOST_CHECK_EQUAL(smryVect==time_ref, true);
@ -352,6 +355,7 @@ BOOST_AUTO_TEST_CASE(TestESmry_4) {
std::vector<float> time_ref = {31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396, 424, 455, 485, 516, 546, 577, 608, 638, 669, 699, 730, 761, 789, 820, 850, 881, 911, 942, 973, 1003, 1034, 1064, 1095, 1126, 1154, 1185, 1215, 1246, 1276, 1307, 1338, 1368, 1399, 1429, 1460, 1491, 1519, 1550, 1580, 1611, 1641, 1672, 1703, 1733, 1764, 1794, 1825, 1856, 1884, 1915, 1945, 1976, 2006, 2037, 2068, 2098, 2129, 2159, 2190, 2221, 2249, 2280, 2310, 2341, 2371, 2402, 2433, 2463, 2494, 2524, 2555, 2586, 2614, 2645, 2675, 2706, 2736, 2767, 2798, 2828, 2859, 2889, 2920, 2951, 2979, 3010, 3040, 3071, 3101, 3132, 3163, 3193, 3224, 3254, 3285, 3316, 3344, 3375, 3405, 3436, 3466, 3497, 3528, 3558, 3589, 3619, 3650};
ESmry smry1("SPE1CASE1.SMSPEC");
smry1.LoadData();
std::vector<float> smryVect = smry1.get("TIME");
std::vector<float> smryVect_rstep = smry1.get_at_rstep("TIME");
@ -365,6 +369,7 @@ BOOST_AUTO_TEST_CASE(TestESmry_4) {
namespace fs = Opm::filesystem;
BOOST_AUTO_TEST_CASE(TestCreateRSM) {
ESmry smry1("SPE1CASE1.SMSPEC");
smry1.LoadData();
smry1.write_rsm_file();
BOOST_CHECK(fs::exists("SPE1CASE1.RSM"));
@ -375,6 +380,7 @@ BOOST_AUTO_TEST_CASE(TestCreateRSM) {
BOOST_AUTO_TEST_CASE(TestUnits) {
ESmry smry("SPE1CASE1.SMSPEC");
smry.LoadData();
BOOST_CHECK_THROW( smry.get_unit("NO_SUCH_KEY"), std::out_of_range);
BOOST_CHECK_EQUAL( smry.get_unit("TIME"), "DAYS");