Merge pull request #1141 from joakim-hove/formatted-inf

Formatted inf
This commit is contained in:
Joakim Hove
2019-10-22 08:25:16 +02:00
committed by GitHub
3 changed files with 84 additions and 53 deletions

View File

@@ -39,7 +39,7 @@ namespace {
bool fileExists(const std::string& filename){
std::ifstream fileH(filename.c_str());
return fileH.good();
return fileH.good();
}
bool isFormatted(const std::string& filename)
@@ -342,11 +342,11 @@ std::vector<T> readFormattedArray(const std::string& file_str, const int size, l
arr.reserve(size);
long int p1=fromPos;
for (int i=0; i< size; i++) {
p1 = file_str.find_first_not_of(' ',p1);
long int p2 = file_str.find_first_of(' ', p1);
arr.push_back(process(file_str.substr(p1, p2-p1)));
p1 = file_str.find_first_not_of(' ',p2);
@@ -429,24 +429,14 @@ std::vector<bool> readFormattedLogiArray(const std::string& file_str, const int
std::vector<double> readFormattedDoubArray(const std::string& file_str, const int size, long int fromPos)
{
std::function<double(const std::string&)> f = [](const std::string& value)
std::function<double(const std::string&)> f = [](std::string val)
{
std::string val(value);
int p1 = val.find_first_of("D");
auto p1 = val.find_first_of("D");
if (p1 == -1) {
p1 = val.find_first_of("-", 1);
if (p1 > -1) {
val = val.insert(p1,"E");
} else {
p1 = val.find_first_of("+", 1);
if (p1 == -1) {
std::string message="In Routine Read readFormattedDoubArray, could not convert '" + val + "' to double.";
OPM_THROW(std::invalid_argument,message);
}
val = val.insert(p1,"E");
if (p1 == std::string::npos) {
auto p2 = val.find_first_of("-+", 1);
if (p2 != std::string::npos) {
val = val.insert(p2,"E");
}
} else {
val.replace(p1,1,"E");
@@ -596,7 +586,7 @@ void EclFile::loadData()
std::iota(arrIndices.begin(), arrIndices.end(), 0);
this->loadData(arrIndices);
} else {
std::fstream fileH;
@@ -622,11 +612,11 @@ void EclFile::loadData(const std::string& name)
if (formatted) {
std::ifstream inFile(inputFilename);
for (unsigned int arrIndex = 0; arrIndex < array_name.size(); arrIndex++) {
if (array_name[arrIndex] == name) {
inFile.seekg(ifStreamPos[arrIndex]);
char* buffer;
@@ -637,7 +627,7 @@ void EclFile::loadData(const std::string& name)
std::string fileStr = std::string(buffer, size);
loadFormattedArray(fileStr, arrIndex, 0);
delete[] buffer;
}
}
@@ -671,7 +661,7 @@ void EclFile::loadData(const std::vector<int>& arrIndex)
std::ifstream inFile(inputFilename);
for (int ind : arrIndex) {
inFile.seekg(ifStreamPos[ind]);
char* buffer;
@@ -682,7 +672,7 @@ void EclFile::loadData(const std::vector<int>& arrIndex)
std::string fileStr = std::string(buffer, size);
loadFormattedArray(fileStr, ind, 0);
delete[] buffer;
}
@@ -719,9 +709,9 @@ void EclFile::loadData(int arrIndex)
inFile.read (buffer, size);
std::string fileStr = std::string(buffer, size);
loadFormattedArray(fileStr, arrIndex, 0);
delete[] buffer;

View File

@@ -324,6 +324,16 @@ std::string EclOutput::make_real_string(float value) const
if (value == 0.0) {
return "0.00000000E+00";
} else {
if (std::isnan(value))
return "NAN";
if (std::isinf(value)) {
if (value > 0)
return "INF";
else
return "-INF";
}
std::string tmpstr(buffer);
int exp = value < 0.0 ? std::stoi(tmpstr.substr(11, 3)) : std::stoi(tmpstr.substr(10, 3));
@@ -350,9 +360,18 @@ std::string EclOutput::make_doub_string(double value) const
if (value == 0.0) {
return "0.00000000000000D+00";
} else {
std::string tmpstr(buffer);
if (std::isnan(value))
return "NAN";
int exp = value < 0.0 ? std::stoi(tmpstr.substr(17, 4)) : std::stoi(tmpstr.substr(16, 4));
if (std::isinf(value)) {
if (value > 0)
return "INF";
else
return "-INF";
}
std::string tmpstr(buffer);
int exp = value < 0.0 ? std::stoi(tmpstr.substr(17, 4)) : std::stoi(tmpstr.substr(16, 4));
if (value < 0.0) {
if (std::abs(exp) < 100) {
@@ -360,8 +379,7 @@ std::string EclOutput::make_doub_string(double value) const
} else {
tmpstr = "-0." + tmpstr.substr(1, 1) + tmpstr.substr(3, 13);
}
}
else {
} else {
if (std::abs(exp) < 100) {
tmpstr = "0." + tmpstr.substr(0, 1) + tmpstr.substr(2, 13) + "D";
} else {
@@ -369,9 +387,8 @@ std::string EclOutput::make_doub_string(double value) const
}
}
std::sprintf (buffer, "%+03i", exp+1);
std::sprintf(buffer, "%+03i", exp + 1);
tmpstr = tmpstr + buffer;
return tmpstr;
}
}

View File

@@ -17,16 +17,20 @@
+ */
#include "config.h"
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <limits>
#include <tuple>
#include <cmath>
#include <opm/io/eclipse/EclFile.hpp>
#include "WorkArea.cpp"
#include <opm/io/eclipse/EclOutput.hpp>
#define BOOST_TEST_MODULE Test EclIO
@@ -99,7 +103,7 @@ BOOST_AUTO_TEST_CASE(TestEclFile_BINARY) {
BOOST_CHECK_EQUAL(file1.hasKey("PORV"), true);
BOOST_CHECK_EQUAL(file1.hasKey("XPORV"), false);
// test member functon get, use size of vector to confirm that vectror is ok
// test member functon get, use size of vector to confirm that vectror is ok
std::vector<int> vect1a=file1.get<int>(0);
std::vector<int> vect1b=file1.get<int>("ICON");
@@ -138,8 +142,8 @@ BOOST_AUTO_TEST_CASE(TestEclFile_FORMATTED) {
std::string testFile2="ECLFILE.FINIT";
// loading data both from binary and formatted file. Check that
// date vectors are identical
// date vectors are identical
EclFile file1(testFile1);
file1.loadData();
@@ -150,31 +154,30 @@ BOOST_AUTO_TEST_CASE(TestEclFile_FORMATTED) {
std::vector<int> vect1b=file2.get<int>("ICON");
BOOST_CHECK_EQUAL(vect1a.size(), vect1b.size());
BOOST_CHECK_EQUAL(vect1a==vect1b,true);
BOOST_CHECK(vect1a == vect1b);
std::vector<float> vect2a=file1.get<float>("PORV");
std::vector<float> vect2b=file2.get<float>("PORV");
BOOST_CHECK_EQUAL(vect2a.size(), vect2b.size());
BOOST_CHECK_EQUAL(vect2a==vect2b,true);
BOOST_CHECK(vect2a == vect2b);
std::vector<double> vect3a=file1.get<double>("XCON");
std::vector<double> vect3b=file2.get<double>("XCON");
BOOST_CHECK_EQUAL(vect3a.size(), vect3b.size());
BOOST_CHECK_EQUAL(vect3a==vect3b,true);
BOOST_CHECK(vect3a == vect3b);
std::vector<bool> vect4a=file1.get<bool>("LOGIHEAD");
std::vector<bool> vect4b=file2.get<bool>("LOGIHEAD");
BOOST_CHECK_EQUAL(vect4a.size(), vect4b.size());
BOOST_CHECK_EQUAL(vect4a==vect4b,true);
BOOST_CHECK(vect4a == vect4b);
std::vector<std::string> vect5a=file1.get<std::string>("KEYWORDS");
std::vector<std::string> vect5b=file2.get<std::string>("KEYWORDS");
BOOST_CHECK_EQUAL(vect5a.size(), vect5b.size());
BOOST_CHECK_EQUAL(vect5a==vect5b,true);
BOOST_CHECK(vect5a == vect5b);
}
@@ -221,7 +224,7 @@ BOOST_AUTO_TEST_CASE(TestEcl_Write_formatted) {
std::string testFile="TEST.FDAT";
// loading vectors from formatted input file and write data back to a formatted file1
// compare input and output file, and delete file.
// compare input and output file, and delete file.
EclFile file1(inputFile);
file1.loadData();
@@ -250,17 +253,38 @@ BOOST_AUTO_TEST_CASE(TestEcl_Write_formatted) {
};
}
BOOST_AUTO_TEST_CASE(TestEcl_Write_formatted_not_finite) {
WorkArea wa;
std::vector<float> float_vector{std::numeric_limits<float>::infinity() , std::numeric_limits<float>::quiet_NaN()};
std::vector<double> double_vector{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::quiet_NaN()};
{
EclOutput testfile("TEST.FINIT", true);
testfile.write("FLOAT", float_vector);
testfile.write("DOUBLE", double_vector);
}
EclFile file1("TEST.FINIT");
file1.loadData();
auto f = file1.get<float>("FLOAT");
auto d = file1.get<double>("DOUBLE");
BOOST_CHECK(std::isinf(f[0]));
BOOST_CHECK(std::isinf(d[0]));
BOOST_CHECK(std::isnan(f[1]));
BOOST_CHECK(std::isnan(d[1]));
}
BOOST_AUTO_TEST_CASE(TestEcl_getList) {
std::string inputFile="ECLFILE.INIT";
std::string testFile="TEST.DAT";
// use EclFile to read/open a binary file
// use EclFile to read/open a binary file
// Use API for class EclFile together with class EclOutput to write an
// identical eclfile
// EclFile::getList(), EclFile::get<T>(int)
// EclFile::getList(), EclFile::get<T>(int)
EclFile file1(inputFile);
file1.loadData();
@@ -316,11 +340,11 @@ BOOST_AUTO_TEST_CASE(TestEcl_Write_CHAR) {
EclOutput eclTest(testFile, true);
eclTest.write("TEST",refStrList);
}
{
EclFile file1(testFile);
std::vector<std::string> strList=file1.get<std::string>("TEST");
for (size_t n = 0; n < refStrList.size(); n++) {
BOOST_CHECK(refStrList[n] == strList[n]);
}
@@ -329,6 +353,6 @@ BOOST_AUTO_TEST_CASE(TestEcl_Write_CHAR) {
if (remove(testFile.c_str())==-1) {
std::cout << " > Warning! temporary file was not deleted" << std::endl;
};
}