Merge pull request #2096 from tskille/io_c0nn

Update of EclIO classes.
This commit is contained in:
Joakim Hove 2020-11-11 08:18:26 +01:00 committed by GitHub
commit 71b5dea35e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1037 additions and 167 deletions

View File

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

View File

@ -472,6 +472,10 @@ if(ENABLE_ECL_INPUT)
list (APPEND TEST_DATA_FILES
tests/ECLFILE.INIT
tests/ECLFILE.FINIT
tests/ECLFILE.FINIT
tests/MODEL1_IX.INIT
tests/MODEL1_IX.SMSPEC
tests/MODEL1_IX.UNSMRY
tests/SPE1CASE1.EGRID
tests/SPE1CASE1.RFT
tests/SPE1_TESTCASE.UNRST

View File

@ -36,7 +36,7 @@ class EclFile
{
public:
explicit EclFile(const std::string& filename, bool preload = false);
bool formattedInput() { return formatted; }
bool formattedInput() const { return formatted; }
void loadData(); // load all data
void loadData(const std::string& arrName); // load all arrays with array name equal to arrName
@ -55,6 +55,8 @@ public:
using EclEntry = std::tuple<std::string, eclArrType, int64_t>;
std::vector<EclEntry> getList() const;
const std::vector<int>& getElementSizeList() const { return array_element_size; }
template <typename T>
const std::vector<T>& get(int arrIndex);
@ -66,6 +68,7 @@ public:
const std::vector<std::string>& arrayNames() const { return array_name; }
std::size_t size() const;
bool is_ix() const;
protected:
bool formatted;
@ -80,6 +83,7 @@ protected:
std::vector<std::string> array_name;
std::vector<eclArrType> array_type;
std::vector<int64_t> array_size;
std::vector<int> array_element_size;
std::vector<uint64_t> ifStreamPos;
@ -111,6 +115,9 @@ private:
void loadBinaryArray(std::fstream& fileH, std::size_t arrIndex);
void loadFormattedArray(const std::string& fileStr, std::size_t arrIndex, int64_t fromPos);
std::vector<unsigned int> get_bin_logi_raw_values(int arrIndex) const;
std::vector<std::string> get_fmt_real_raw_str_values(int arrIndex) const;
};
}} // namespace Opm::EclIO

View File

@ -26,13 +26,15 @@ namespace Opm { namespace EclIO {
// type MESS have no assisiated data
enum eclArrType {
INTE, REAL, DOUB, CHAR, LOGI, MESS
INTE, REAL, DOUB, CHAR, LOGI, MESS, C0NN
};
// named constants related to binary file format
const unsigned int true_value = 0xffffffff;
const unsigned int true_value_ecl = 0xffffffff;
const unsigned int true_value_ix = 0x1000000;
const unsigned int false_value = 0x00000000;
const int sizeOfInte = 4; // number of bytes pr integer (inte) element
const int sizeOfReal = 4; // number of bytes pr float (real) element
const int sizeOfDoub = 8; // number of bytes pr double (doub) element

View File

@ -47,59 +47,71 @@ public:
const std::vector<T>& data)
{
eclArrType arrType = MESS;
int element_size = 4;
if (typeid(T) == typeid(int))
arrType = INTE;
else if (typeid(T) == typeid(float))
arrType = REAL;
else if (typeid(T) == typeid(double))
else if (typeid(T) == typeid(double)){
arrType = DOUB;
else if (typeid(T) == typeid(bool))
element_size = 8;
} else if (typeid(T) == typeid(bool))
arrType = LOGI;
else if (typeid(T) == typeid(char))
arrType = MESS;
if (isFormatted)
{
writeFormattedHeader(name, data.size(), arrType);
writeFormattedHeader(name, data.size(), arrType, element_size);
if (arrType != MESS)
writeFormattedArray(data);
}
else
{
writeBinaryHeader(name, data.size(), arrType);
writeBinaryHeader(name, data.size(), arrType, element_size);
if (arrType != MESS)
writeBinaryArray(data);
}
}
// when this function is used array type will be assumed C0NN (not CHAR).
// Also in cases where element size is 8 or less, element size will be 8.
void write(const std::string& name, const std::vector<std::string>& data, int element_size);
void message(const std::string& msg);
void flushStream();
void set_ix() { ix_standard = true; }
friend class OutputStream::Restart;
friend class OutputStream::SummarySpecification;
private:
void writeBinaryHeader(const std::string& arrName, int64_t size, eclArrType arrType);
void writeBinaryHeader(const std::string& arrName, int64_t size, eclArrType arrType, int element_size);
template <typename T>
void writeBinaryArray(const std::vector<T>& data);
void writeBinaryCharArray(const std::vector<std::string>& data);
void writeBinaryCharArray(const std::vector<std::string>& data, int element_size);
void writeBinaryCharArray(const std::vector<PaddedOutputString<8>>& data);
void writeFormattedHeader(const std::string& arrName, int size, eclArrType arrType);
void writeFormattedHeader(const std::string& arrName, int size, eclArrType arrType, int element_size);
template <typename T>
void writeFormattedArray(const std::vector<T>& data);
void writeFormattedCharArray(const std::vector<std::string>& data);
void writeFormattedCharArray(const std::vector<std::string>& data, int element_size);
void writeFormattedCharArray(const std::vector<PaddedOutputString<8>>& data);
void writeArrayType(const eclArrType arrType);
std::string make_real_string(float value) const;
std::string make_doub_string(double value) const;
std::string make_real_string_ecl(float value) const;
std::string make_real_string_ix(float value) const;
std::string make_doub_string_ecl(double value) const;
std::string make_doub_string_ix(double value) const;
bool isFormatted;
bool isFormatted, ix_standard;
std::ofstream ofileH;
};

View File

@ -41,35 +41,42 @@ namespace Opm { namespace EclIO {
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);
uint64_t sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrType, int elementSize);
uint64_t sizeOnDiskFormatted(const int64_t num, Opm::EclIO::eclArrType arrType, int elementSize);
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);
int64_t& size, Opm::EclIO::eclArrType &arrType, int& elementSize);
void readFormattedHeader(std::fstream& fileH, std::string& arrName,
int64_t &num, Opm::EclIO::eclArrType &arrType);
int64_t &num, Opm::EclIO::eclArrType &arrType, int& elementSize);
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);
std::function<T(T2)>& flip, int elementSize);
std::vector<int> readBinaryInteArray(std::fstream &fileH, const int64_t size);
std::vector<float> readBinaryRealArray(std::fstream& fileH, const int64_t size);
std::vector<double> readBinaryDoubArray(std::fstream& fileH, const int64_t size);
std::vector<bool> readBinaryLogiArray(std::fstream &fileH, const int64_t size);
std::vector<unsigned int> readBinaryRawLogiArray(std::fstream &fileH, const int64_t size);
std::vector<std::string> readBinaryCharArray(std::fstream& fileH, const int64_t size);
std::vector<std::string> readBinaryC0nnArray(std::fstream& fileH, const int64_t size, int elementSize);
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);
std::vector<int> readFormattedInteArray(const std::string& file_str, const int64_t size, int64_t fromPos);
std::vector<std::string> readFormattedCharArray(const std::string& file_str, const int64_t size, int64_t fromPos);
std::vector<std::string> readFormattedCharArray(const std::string& file_str, const int64_t size,
int64_t fromPos, int elementSize);
std::vector<float> readFormattedRealArray(const std::string& file_str, const int64_t size, int64_t fromPos);
std::vector<std::string> readFormattedRealRawStrings(const std::string& file_str, const int64_t size, int64_t fromPos);
std::vector<bool> readFormattedLogiArray(const std::string& file_str, const int64_t size, int64_t fromPos);
std::vector<double> readFormattedDoubArray(const std::string& file_str, const int64_t size, int64_t fromPos);

View File

@ -3,13 +3,13 @@
namespace convert {
py::array numpy_string_array(const std::vector<std::string>& input) {
const std::size_t target_length = 8;
const std::size_t target_length = 99;
using numpy_string_t = char[target_length];
auto output = py::array_t<numpy_string_t>(input.size());
auto output_ptr = reinterpret_cast<numpy_string_t *>(output.request().ptr);
for (std::size_t index = 0; index < input.size(); index++) {
if (input[index].size() > target_length)
throw std::invalid_argument("Current implementation only works with 8 character strings");
throw std::invalid_argument("Current implementation only works with 99 character strings");
std::size_t length = input[index].size();
std::strncpy(output_ptr[index], input[index].c_str(), length);

View File

@ -43,6 +43,11 @@ public:
m_output->flushStream();
}
void writeC0nnArray(const std::string& name, const std::vector<std::string>& data, int element_size){
m_output->write(name, data, element_size);
m_output->flushStream();
}
void writeMessage(const std::string& name)
{
m_output->message(name);
@ -70,7 +75,7 @@ npArray get_vector_index(Opm::EclIO::EclFile * file_ptr, std::size_t array_index
if (array_type == Opm::EclIO::LOGI)
return std::make_tuple (convert::numpy_array( file_ptr->get<bool>(array_index)), array_type);
if (array_type == Opm::EclIO::CHAR)
if ((array_type == Opm::EclIO::CHAR) || (array_type == Opm::EclIO::C0NN))
return std::make_tuple (convert::numpy_string_array( file_ptr->get<std::string>(array_index)), array_type);
throw std::logic_error("Data type not supported");
@ -305,6 +310,7 @@ void python::common::export_IO(py::module& m) {
.value("REAL", Opm::EclIO::REAL)
.value("DOUB", Opm::EclIO::DOUB)
.value("CHAR", Opm::EclIO::CHAR)
.value("C0nn", Opm::EclIO::C0NN)
.value("LOGI", Opm::EclIO::LOGI)
.value("MESS", Opm::EclIO::MESS)
.export_values();
@ -384,6 +390,9 @@ void python::common::export_IO(py::module& m) {
.def("write_message", &EclOutputBind::writeMessage)
.def("__write_char_array", (void (EclOutputBind::*)(const std::string&,
const std::vector<std::string>&)) &EclOutputBind::writeArray)
.def("__write_c0nn_array", &EclOutputBind::writeC0nnArray)
.def("__write_logi_array", (void (EclOutputBind::*)(const std::string&,
const std::vector<bool>&)) &EclOutputBind::writeArray)
.def("__write_inte_array", (void (EclOutputBind::*)(const std::string&,

View File

@ -33,7 +33,7 @@ def getitem_eclfile(self, arg):
else:
data, array_type = self.__get_data(arg)
if array_type == eclArrType.CHAR:
if array_type == eclArrType.CHAR or array_type == eclArrType.C0nn:
return [ x.decode("utf-8") for x in data ]
return data
@ -63,7 +63,7 @@ def getitem_erst(self, arg):
else:
raise ValueError("expecting tuple argument with 2 or 3 argumens: (index, rstep), (name, rstep) or (name, rstep, occurrence) ")
if array_type == eclArrType.CHAR:
if array_type == eclArrType.CHAR or array_type == eclArrType.C0nn:
return [ x.decode("utf-8") for x in data ]
return data
@ -169,7 +169,7 @@ def getitem_erft(self, arg):
(CHAR, LOGI, INTE)
'''
def ecloutput_write(self, name, array):
def ecloutput_write(self, name, array, C0nn=False):
if isinstance(array, list):
if all(isinstance(element, str) for element in array):
@ -197,8 +197,11 @@ def ecloutput_write(self, name, array):
self.__write_doub_array(name, array)
elif array.dtype == "bool":
self.__write_logi_array(name, array)
elif array.dtype.kind in {'U', 'S'}:
elif array.dtype.kind in {'U', 'S'} and not C0nn:
self.__write_char_array(name, array)
elif array.dtype.kind in {'U', 'S'} and C0nn:
maxStrLength = max([len(x) for x in array])
self.__write_c0nn_array(name, array, max([maxStrLength, 8]))
else:
raise ValueError("unknown array type for array {}".format(name))

View File

@ -271,6 +271,137 @@ class TestEclOutput(unittest.TestCase):
os.remove(testFile)
def test_write_strings_binary(self):
testFile = test_path("data/TMP1.INIT")
shortWelNames = ["PROD-1", "PROD-2", "PROD-3", "PROD-4", "PROD-5"]
longWelNames = ["PRODUCER-1", "PRODUCER-2", "PRODUCER-13", "PRODUCER-4"]
out1 = EclOutput(testFile)
out1.write("WGNAME", shortWelNames)
file1 = EclFile(testFile)
array = file1["WGNAME"]
self.assertEqual(len(array), len(shortWelNames))
for v1,v2 in zip (array, shortWelNames):
self.assertEqual(v1, v2)
arrayList = file1.arrays
name, arr_type, num = arrayList[0]
self.assertEqual(name, "WGNAME")
self.assertEqual(arr_type, eclArrType.CHAR)
self.assertEqual(num, len(shortWelNames))
out2 = EclOutput(testFile)
out2.write("NAMES", longWelNames)
file2 = EclFile(testFile)
array = file2["NAMES"]
self.assertEqual(len(array), len(longWelNames))
for v1,v2 in zip (array, longWelNames):
self.assertEqual(v1, v2)
arrayList = file2.arrays
name, arr_type, num = arrayList[0]
self.assertEqual(name, "NAMES")
self.assertEqual(arr_type, eclArrType.C0nn)
self.assertEqual(num, len(longWelNames))
out3 = EclOutput(testFile, formatted=False)
out3.write("NAMES", shortWelNames, C0nn=True)
file3 = EclFile(testFile)
array = file3["NAMES"]
self.assertEqual(len(array), len(shortWelNames))
for v1,v2 in zip (array, shortWelNames):
self.assertEqual(v1, v2)
arrayList = file3.arrays
name, arr_type, num = arrayList[0]
self.assertEqual(name, "NAMES")
self.assertEqual(arr_type, eclArrType.C0nn)
self.assertEqual(num, len(shortWelNames))
if os.path.isfile(testFile):
os.remove(testFile)
def test_write_strings_formattede(self):
testFile = test_path("data/TMP1.FINIT")
shortWelNames = ["PROD-1", "PROD-2", "PROD-3", "PROD-4", "PROD-5"]
longWelNames = ["PRODUCER-1", "PRODUCER-2", "PRODUCER-13", "PRODUCER-4"]
out1 = EclOutput(testFile, formatted=True)
out1.write("WGNAME", shortWelNames)
file1 = EclFile(testFile)
array = file1["WGNAME"]
self.assertEqual(len(array), len(shortWelNames))
for v1,v2 in zip (array, shortWelNames):
self.assertEqual(v1, v2)
arrayList = file1.arrays
name, arr_type, num = arrayList[0]
self.assertEqual(name, "WGNAME")
self.assertEqual(arr_type, eclArrType.CHAR)
self.assertEqual(num, len(shortWelNames))
out2 = EclOutput(testFile, formatted=True)
out2.write("NAMES", longWelNames)
file2 = EclFile(testFile)
array = file2["NAMES"]
self.assertEqual(len(array), len(longWelNames))
for v1,v2 in zip (array, longWelNames):
self.assertEqual(v1, v2)
arrayList = file2.arrays
name, arr_type, num = arrayList[0]
self.assertEqual(name, "NAMES")
self.assertEqual(arr_type, eclArrType.C0nn)
self.assertEqual(num, len(longWelNames))
out3 = EclOutput(testFile, formatted=True)
out3.write("NAMES", shortWelNames, C0nn=True)
file3 = EclFile(testFile)
array = file3["NAMES"]
self.assertEqual(len(array), len(shortWelNames))
for v1,v2 in zip (array, shortWelNames):
self.assertEqual(v1, v2)
arrayList = file3.arrays
name, arr_type, num = arrayList[0]
self.assertEqual(name, "NAMES")
self.assertEqual(arr_type, eclArrType.C0nn)
self.assertEqual(num, len(shortWelNames))
if os.path.isfile(testFile):
os.remove(testFile)
if __name__ == "__main__":

View File

@ -158,7 +158,13 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<std::string> restartArray = smspecList.back().get<std::string>("RESTART");
const std::vector<std::string> keywords = smspecList.back().get<std::string>("KEYWORDS");
const std::vector<std::string> wgnames = smspecList.back().get<std::string>("WGNAMES");
std::vector<std::string> wgnames;
if (smspecList.back().hasKey("WGNAMES"))
wgnames = smspecList.back().get<std::string>("WGNAMES");
else
wgnames = smspecList.back().get<std::string>("NAMES");
const std::vector<int> nums = smspecList.back().get<int>("NUMS");
const std::vector<std::string> units = smspecList.back().get<std::string>("UNITS");
@ -223,7 +229,13 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> dimens = smspecList.back().get<int>("DIMENS");
const std::vector<std::string> restartArray = smspecList.back().get<std::string>("RESTART");
const std::vector<std::string> keywords = smspecList.back().get<std::string>("KEYWORDS");
const std::vector<std::string> wgnames = smspecList.back().get<std::string>("WGNAMES");
std::vector<std::string> wgnames;
if (smspecList.back().hasKey("WGNAMES"))
wgnames = smspecList.back().get<std::string>("WGNAMES");
else
wgnames = smspecList.back().get<std::string>("NAMES");
const std::vector<int> nums = smspecList.back().get<int>("NUMS");
const std::vector<std::string> units = smspecList.back().get<std::string>("UNITS");
@ -285,7 +297,13 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
nParamsSpecFile[specInd] = dimens[0];
const std::vector<std::string> keywords = smspecList[specInd].get<std::string>("KEYWORDS");
const std::vector<std::string> wgnames = smspecList[specInd].get<std::string>("WGNAMES");
std::vector<std::string> wgnames;
if (smspecList.back().hasKey("WGNAMES"))
wgnames = smspecList.back().get<std::string>("WGNAMES");
else
wgnames = smspecList.back().get<std::string>("NAMES");
const std::vector<int> nums = smspecList[specInd].get<int>("NUMS");
for (size_t i=0; i < keywords.size(); i++) {
@ -457,15 +475,16 @@ void ESmry::inspect_lodsmry()
std::string arrName;
int64_t arr_size;
Opm::EclIO::eclArrType arrType;
int sizeOfElement;
std::fstream fileH;
if (formattedFiles[0]) {
fileH.open(lodFileName, std::ios::in);
Opm::EclIO::readFormattedHeader(fileH, arrName, arr_size, arrType);
Opm::EclIO::readFormattedHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
} else {
fileH.open(lodFileName, std::ios::in | std::ios::binary);
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType);
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
}
if ((arrName != "KEYCHECK") or (arrType != Opm::EclIO::CHAR))
@ -474,10 +493,10 @@ void ESmry::inspect_lodsmry()
std::vector<std::string> keycheck;
if (formattedFiles[0]) {
uint64_t size = Opm::EclIO::sizeOnDiskFormatted(arr_size, Opm::EclIO::CHAR) + 1;
uint64_t size = Opm::EclIO::sizeOnDiskFormatted(arr_size, Opm::EclIO::CHAR, sizeOfChar) + 1;
std::string fileStr = read_string_from_disk(fileH, size);
keycheck = Opm::EclIO::readFormattedCharArray(fileStr, arr_size, 0);
keycheck = Opm::EclIO::readFormattedCharArray(fileStr, arr_size, 0, sizeOfChar);
} else {
keycheck = Opm::EclIO::readBinaryCharArray(fileH, arr_size);
}
@ -501,9 +520,9 @@ void ESmry::inspect_lodsmry()
}
if (formattedFiles[0])
Opm::EclIO::readFormattedHeader(fileH, arrName, arr_size, arrType);
Opm::EclIO::readFormattedHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
else
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType);
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
if ((arrName != "RSTEP ") or (arrType != Opm::EclIO::LOGI))
OPM_THROW(std::invalid_argument, "reading rstep, invalid lod file");
@ -511,7 +530,7 @@ void ESmry::inspect_lodsmry()
std::vector<bool> rstep;
if (formattedFiles[0]) {
uint64_t size = Opm::EclIO::sizeOnDiskFormatted(arr_size, Opm::EclIO::LOGI) + 1;
uint64_t size = Opm::EclIO::sizeOnDiskFormatted(arr_size, Opm::EclIO::LOGI, sizeOfLogi) + 1;
std::string fileStr = read_string_from_disk(fileH, size);
rstep = Opm::EclIO::readFormattedLogiArray(fileStr, arr_size, 0);
@ -527,9 +546,9 @@ void ESmry::inspect_lodsmry()
nTstep = rstep.size();
if (formattedFiles[0])
lod_arr_size = sizeOnDiskFormatted(nTstep, Opm::EclIO::REAL);
lod_arr_size = sizeOnDiskFormatted(nTstep, Opm::EclIO::REAL, sizeOfReal);
else
lod_arr_size = sizeOnDiskBinary(nTstep, Opm::EclIO::REAL);
lod_arr_size = sizeOnDiskBinary(nTstep, Opm::EclIO::REAL, sizeOfReal);
fileH.close();
}
@ -558,6 +577,7 @@ void ESmry::Load_from_lodsmry(const std::vector<int>& keywIndVect) const
std::string arrName;
int64_t size;
Opm::EclIO::eclArrType arrType;
int sizeOfElement;
uint64_t pos = lod_offset + lod_arr_size*static_cast<uint64_t>(ind);
@ -569,9 +589,9 @@ void ESmry::Load_from_lodsmry(const std::vector<int>& keywIndVect) const
fileH.seekg (pos, fileH.beg);
if (formattedFiles[0])
readFormattedHeader(fileH, arrName, size, arrType);
readFormattedHeader(fileH, arrName, size, arrType, sizeOfElement);
else
readBinaryHeader(fileH, arrName, size, arrType);
readBinaryHeader(fileH, arrName, size, arrType, sizeOfElement);
arrName = Opm::EclIO::trimr(arrName);
@ -777,7 +797,7 @@ void ESmry::LoadData() const
if (formattedFiles[specInd]) {
char* buffer;
size_t size = sizeOnDiskFormatted(nParamsSpecFile[specInd], Opm::EclIO::REAL)+1;
size_t size = sizeOnDiskFormatted(nParamsSpecFile[specInd], Opm::EclIO::REAL, sizeOfReal) + 1;
buffer = new char [size];
fileH.read (buffer, size);
@ -932,10 +952,10 @@ ESmry::getListOfArrays(std::string filename, bool formatted)
if (num > 0) {
if (formatted) {
uint64_t sizeOfNextArray = sizeOnDiskFormatted(num, arrType);
uint64_t sizeOfNextArray = sizeOnDiskFormatted(num, arrType, 4);
fseek(ptr, static_cast<long int>(sizeOfNextArray), SEEK_CUR);
} else {
uint64_t sizeOfNextArray = sizeOnDiskBinary(num, arrType);
uint64_t sizeOfNextArray = sizeOnDiskBinary(num, arrType, 4);
fseek(ptr, static_cast<long int>(sizeOfNextArray), SEEK_CUR);
}
}

View File

@ -64,17 +64,19 @@ EclFile::EclFile(const std::string& filename, bool preload) : inputFilename(file
std::string arrName(8,' ');
eclArrType arrType;
int64_t num;
int sizeOfElement;
if (formatted) {
readFormattedHeader(fileH,arrName,num,arrType);
readFormattedHeader(fileH,arrName,num,arrType, sizeOfElement);
} else {
readBinaryHeader(fileH,arrName,num,arrType);
readBinaryHeader(fileH,arrName,num, arrType, sizeOfElement);
}
array_size.push_back(num);
array_type.push_back(arrType);
array_name.push_back(trimr(arrName));
array_element_size.push_back(sizeOfElement);
array_index[array_name[n]] = n;
uint64_t pos = fileH.tellg();
@ -84,15 +86,14 @@ EclFile::EclFile(const std::string& filename, bool preload) : inputFilename(file
if (num > 0){
if (formatted) {
uint64_t sizeOfNextArray = sizeOnDiskFormatted(num, arrType);
uint64_t sizeOfNextArray = sizeOnDiskFormatted(num, arrType, sizeOfElement);
fileH.seekg(static_cast<std::streamoff>(sizeOfNextArray), std::ios_base::cur);
} else {
uint64_t sizeOfNextArray = sizeOnDiskBinary(num, arrType);
uint64_t sizeOfNextArray = sizeOnDiskBinary(num, arrType, sizeOfElement);
fileH.seekg(static_cast<std::streamoff>(sizeOfNextArray), std::ios_base::cur);
}
}
n++;
};
@ -125,6 +126,9 @@ void EclFile::loadBinaryArray(std::fstream& fileH, std::size_t arrIndex)
case CHAR:
char_array[arrIndex] = readBinaryCharArray(fileH, array_size[arrIndex]);
break;
case C0NN:
char_array[arrIndex] = readBinaryC0nnArray(fileH, array_size[arrIndex], array_element_size[arrIndex]);
break;
case MESS:
break;
default:
@ -152,7 +156,10 @@ void EclFile::loadFormattedArray(const std::string& fileStr, std::size_t arrInde
logi_array[arrIndex] = readFormattedLogiArray(fileStr, array_size[arrIndex], fromPos);
break;
case CHAR:
char_array[arrIndex] = readFormattedCharArray(fileStr, array_size[arrIndex], fromPos);
char_array[arrIndex] = readFormattedCharArray(fileStr, array_size[arrIndex], fromPos, sizeOfChar);
break;
case C0NN:
char_array[arrIndex] = readFormattedCharArray(fileStr, array_size[arrIndex], fromPos, array_element_size[arrIndex]);
break;
case MESS:
break;
@ -208,7 +215,7 @@ void EclFile::loadData(const std::string& name)
inFile.seekg(ifStreamPos[arrIndex]);
char* buffer;
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex])+1;
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex])+1;
buffer = new char [size];
inFile.read (buffer, size);
@ -253,7 +260,7 @@ void EclFile::loadData(const std::vector<int>& arrIndex)
inFile.seekg(ifStreamPos[ind]);
char* buffer;
size_t size = sizeOnDiskFormatted(array_size[ind], array_type[ind])+1;
size_t size = sizeOnDiskFormatted(array_size[ind], array_type[ind], array_element_size[ind])+1;
buffer = new char [size];
inFile.read (buffer, size);
@ -284,7 +291,6 @@ void EclFile::loadData(const std::vector<int>& arrIndex)
void EclFile::loadData(int arrIndex)
{
if (formatted) {
std::ifstream inFile(inputFilename);
@ -292,7 +298,7 @@ void EclFile::loadData(int arrIndex)
inFile.seekg(ifStreamPos[arrIndex]);
char* buffer;
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex])+1;
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex])+1;
buffer = new char [size];
inFile.read (buffer, size);
@ -318,6 +324,109 @@ void EclFile::loadData(int arrIndex)
}
}
bool EclFile::is_ix() const
{
// assuming that array data type C0nn only are used in IX. This may change in future.
// Formatted files,
// >> use real arrays. Example Ecl = '0.70000000E-01', IX = '7.0000000E-02'
// Binary files,
// >> if logi array exists in file, look for IX spes binary representation of true value
if (formatted) {
for (size_t n=0; n < array_type.size(); n++) {
if (array_type[n] == Opm::EclIO::C0NN) {
return true;
} else if (array_type[n] == Opm::EclIO::REAL) {
auto realStr = get_fmt_real_raw_str_values(n);
int p, first;
for (auto val : realStr) {
double dtmpv = abs(std::stod(val));
if (dtmpv > 0.0) {
p = val.find_first_of(".");
first = abs(std::stoi(val.substr(0, p)));
if (first > 0)
return true;
else
return false;
}
}
}
}
} else {
for (size_t n=0; n < array_type.size(); n++) {
if (array_type[n] == Opm::EclIO::C0NN) {
return true;
} else if (array_type[n] == Opm::EclIO::LOGI) {
auto raw_logi_values = get_bin_logi_raw_values(n);
for (unsigned int val : raw_logi_values) {
if (val == Opm::EclIO::true_value_ix)
return true;
}
}
}
return false;
}
return false;
}
std::vector<unsigned int> EclFile::get_bin_logi_raw_values(int arrIndex) const
{
if (array_type[arrIndex] != Opm::EclIO::LOGI)
OPM_THROW(std::runtime_error, "Error, selected array is not of type LOGI");
std::fstream fileH;
fileH.open(inputFilename, std::ios::in | std::ios::binary);
if (!fileH) {
std::string message="Could not open file: '" + inputFilename +"'";
OPM_THROW(std::runtime_error, message);
}
fileH.seekg (ifStreamPos[arrIndex], fileH.beg);
std::vector<unsigned int> raw_logi = readBinaryRawLogiArray(fileH, array_size[arrIndex]);
return raw_logi;
}
std::vector<std::string> EclFile::get_fmt_real_raw_str_values(int arrIndex) const
{
std::vector<std::string> real_vect;
if (array_type[arrIndex] != Opm::EclIO::REAL)
OPM_THROW(std::runtime_error, "Error, selected array is not of type REAL");
std::ifstream inFile(inputFilename);
if (!inFile) {
std::string message="Could not open file: '" + inputFilename +"'";
OPM_THROW(std::runtime_error, message);
}
inFile.seekg(ifStreamPos[arrIndex]);
char* buffer;
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex])+1;
buffer = new char [size];
inFile.read (buffer, size);
std::string fileStr = std::string(buffer, size);
std::vector<std::string> real_vect_str;
real_vect_str = readFormattedRealRawStrings(fileStr, array_size[arrIndex], 0);
delete buffer;
return real_vect_str;
}
std::vector<EclFile::EclEntry> EclFile::getList() const
{
std::vector<EclEntry> list;
@ -362,7 +471,12 @@ const std::vector<bool>& EclFile::get<bool>(int arrIndex)
template<>
const std::vector<std::string>& EclFile::get<std::string>(int arrIndex)
{
return getImpl(arrIndex, CHAR, char_array, "string");
if ((array_type[arrIndex] != Opm::EclIO::C0NN) && (array_type[arrIndex] != Opm::EclIO::CHAR)){
std::string message = "Array with index " + std::to_string(arrIndex) + " is not of type " + "std::string";
OPM_THROW(std::runtime_error, message);
}
return getImpl(arrIndex, array_type[arrIndex], char_array, "string");
}
@ -498,7 +612,12 @@ const std::vector<std::string>& EclFile::get<std::string>(const std::string &nam
OPM_THROW(std::invalid_argument, message);
}
return getImpl(search->second, CHAR, char_array, "string");
if ((array_type[search->second] != Opm::EclIO::C0NN) && (array_type[search->second] != Opm::EclIO::CHAR)){
std::string message = "Array with index " + std::to_string(search->second) + " is not of type " + "std::string";
OPM_THROW(std::runtime_error, message);
}
return getImpl(search->second, array_type[search->second], char_array, "string");
}

View File

@ -41,6 +41,7 @@ EclOutput::EclOutput(const std::string& filename,
: isFormatted{formatted}
{
const auto binmode = mode | std::ios_base::binary;
ix_standard = false;
this->ofileH.open(filename, this->isFormatted ? mode : binmode);
}
@ -50,15 +51,79 @@ template<>
void EclOutput::write<std::string>(const std::string& name,
const std::vector<std::string>& data)
{
// array type will be assumed CHAR if maximum string length is 8 or less
// If maximum string length is > 8, C0nn will be used with element size equal to
// maximum string length
int maximum_length = 8;
if (data.size() > 0) {
auto it = std::max_element(data.begin(), data.end(), []
(const std::string& str1, const std::string& str2)
{
return str2.size() > str1.size();
});
maximum_length = it->size();
}
if (isFormatted)
{
writeFormattedHeader(name, data.size(), CHAR);
writeFormattedCharArray(data);
if (maximum_length > sizeOfChar){
writeFormattedHeader(name, data.size(), C0NN, maximum_length);
writeFormattedCharArray(data, maximum_length);
} else {
writeFormattedHeader(name, data.size(), CHAR, sizeOfChar);
writeFormattedCharArray(data, sizeOfChar);
}
}
else
{
writeBinaryHeader(name, data.size(), CHAR);
writeBinaryCharArray(data);
if (maximum_length > sizeOfChar){
writeBinaryHeader(name, data.size(), C0NN, maximum_length);
writeBinaryCharArray(data, maximum_length);
} else {
writeBinaryHeader(name, data.size(), CHAR, sizeOfChar);
writeBinaryCharArray(data, sizeOfChar);
}
}
}
void EclOutput::write(const std::string& name, const std::vector<std::string>& data, int element_size)
{
// array type will be assumed C0NN (not CHAR). Also in cases where element size is 8 or less
if (data.size() > 0) {
auto it = std::max_element(data.begin(), data.end(), []
(const std::string& str1, const std::string& str2)
{
return str2.size() > str1.size();
});
if (it->size() > static_cast<size_t>(element_size))
OPM_THROW(std::runtime_error, "specified element size for type C0NN less than maximum string length in ouput data");
}
if (isFormatted)
{
if (element_size > sizeOfChar){
writeFormattedHeader(name, data.size(), C0NN, element_size);
writeFormattedCharArray(data, element_size);
} else {
writeFormattedHeader(name, data.size(), C0NN, sizeOfChar);
writeFormattedCharArray(data, sizeOfChar);
}
}
else
{
if (element_size > sizeOfChar){
writeBinaryHeader(name, data.size(), C0NN, element_size);
writeBinaryCharArray(data, element_size);
} else {
writeBinaryHeader(name, data.size(), C0NN, sizeOfChar);
writeBinaryCharArray(data, sizeOfChar);
}
}
}
@ -68,11 +133,11 @@ void EclOutput::write<PaddedOutputString<8>>
const std::vector<PaddedOutputString<8>>& data)
{
if (this->isFormatted) {
writeFormattedHeader(name, data.size(), CHAR);
writeFormattedHeader(name, data.size(), CHAR, sizeOfChar);
writeFormattedCharArray(data);
}
else {
writeBinaryHeader(name, data.size(), CHAR);
writeBinaryHeader(name, data.size(), CHAR, sizeOfChar);
writeBinaryCharArray(data);
}
}
@ -91,7 +156,7 @@ void EclOutput::flushStream()
this->ofileH.flush();
}
void EclOutput::writeBinaryHeader(const std::string&arrName, int64_t size, eclArrType arrType)
void EclOutput::writeBinaryHeader(const std::string&arrName, int64_t size, eclArrType arrType, int element_size)
{
int bhead = flipEndianInt(16);
std::string name = arrName + std::string(8 - arrName.size(),' ');
@ -119,6 +184,14 @@ void EclOutput::writeBinaryHeader(const std::string&arrName, int64_t size, eclAr
ofileH.write(name.c_str(), 8);
ofileH.write(reinterpret_cast<char*>(&flippedSize), sizeof(flippedSize));
std::string c0nn_str;
if (arrType == C0NN){
std::ostringstream ss;
ss << "C" << std::setw(3) << std::setfill('0') << element_size;
c0nn_str = ss.str();
}
switch(arrType) {
case INTE:
ofileH.write("INTE", 4);
@ -135,6 +208,9 @@ void EclOutput::writeBinaryHeader(const std::string&arrName, int64_t size, eclAr
case CHAR:
ofileH.write("CHAR", 4);
break;
case C0NN:
ofileH.write(c0nn_str.c_str(), 4);
break;
case MESS:
ofileH.write("MESS", 4);
break;
@ -178,6 +254,8 @@ void EclOutput::writeBinaryArray(const std::vector<T>& data)
OPM_THROW(std::runtime_error, "fstream fileH not open for writing");
}
int logi_true_val = ix_standard ? true_value_ix : true_value_ecl;
rest = size * static_cast<int64_t>(sizeOfElement);
while (rest > 0) {
if (rest > maxBlockSize) {
@ -203,7 +281,7 @@ void EclOutput::writeBinaryArray(const std::vector<T>& data)
value_d = flipEndianDouble(data[n]);
ofileH.write(reinterpret_cast<char*>(&value_d), sizeof(value_d));
} else if (arrType == LOGI) {
intVal = data[n] ? true_value : false_value;
intVal = data[n] ? logi_true_val : false_value;
ofileH.write(reinterpret_cast<char*>(&intVal), sizeOfElement);
} else {
std::cerr << "type not supported in write binaryarray\n";
@ -225,7 +303,7 @@ template void EclOutput::writeBinaryArray<bool>(const std::vector<bool>& data);
template void EclOutput::writeBinaryArray<char>(const std::vector<char>& data);
void EclOutput::writeBinaryCharArray(const std::vector<std::string>& data)
void EclOutput::writeBinaryCharArray(const std::vector<std::string>& data, int element_size)
{
int num,dhead;
@ -234,6 +312,11 @@ void EclOutput::writeBinaryCharArray(const std::vector<std::string>& data)
auto sizeData = block_size_data_binary(CHAR);
if (element_size > sizeOfChar){
std::get<1>(sizeData)= std::get<1>(sizeData) / std::get<0>(sizeData) * element_size;
std::get<0>(sizeData) = element_size;
}
int sizeOfElement = std::get<0>(sizeData);
int maxBlockSize = std::get<1>(sizeData);
int maxNumberOfElements = maxBlockSize / sizeOfElement;
@ -258,7 +341,7 @@ void EclOutput::writeBinaryCharArray(const std::vector<std::string>& data)
ofileH.write(reinterpret_cast<char*>(&dhead), sizeof(dhead));
for (int i = 0; i < num; i++) {
std::string tmpStr = data[n] + std::string(8 - data[n].size(),' ');
std::string tmpStr = data[n] + std::string(sizeOfElement - data[n].size(),' ');
ofileH.write(tmpStr.c_str(), sizeOfElement);
n++;
}
@ -303,12 +386,21 @@ void EclOutput::writeBinaryCharArray(const std::vector<PaddedOutputString<8>>& d
}
}
void EclOutput::writeFormattedHeader(const std::string& arrName, int size, eclArrType arrType)
void EclOutput::writeFormattedHeader(const std::string& arrName, int size, eclArrType arrType, int element_size)
{
std::string name = arrName + std::string(8 - arrName.size(),' ');
ofileH << " '" << name << "' " << std::setw(11) << size;
std::string c0nn_str;
if (arrType == C0NN){
std::ostringstream ss;
ss << "C" << std::setw(3) << std::setfill('0') << element_size;
c0nn_str = ss.str();
}
switch (arrType) {
case INTE:
ofileH << " 'INTE'" << std::endl;
@ -325,6 +417,9 @@ void EclOutput::writeFormattedHeader(const std::string& arrName, int size, eclAr
case CHAR:
ofileH << " 'CHAR'" << std::endl;
break;
case C0NN:
ofileH << " '" << c0nn_str << "'" << std::endl;
break;
case MESS:
ofileH << " 'MESS'" << std::endl;
break;
@ -332,7 +427,7 @@ void EclOutput::writeFormattedHeader(const std::string& arrName, int size, eclAr
}
std::string EclOutput::make_real_string(float value) const
std::string EclOutput::make_real_string_ecl(float value) const
{
char buffer [15];
std::sprintf (buffer, "%10.7E", value);
@ -367,8 +462,32 @@ std::string EclOutput::make_real_string(float value) const
}
}
std::string EclOutput::make_real_string_ix(float value) const
{
char buffer [15];
std::sprintf (buffer, "%10.7E", value);
std::string EclOutput::make_doub_string(double value) const
if (value == 0.0) {
return " 0.0000000E+00";
} else {
if (std::isnan(value))
return "NAN";
if (std::isinf(value)) {
if (value > 0)
return "INF";
else
return "-INF";
}
std::string tmpstr(buffer);
return tmpstr;
}
}
std::string EclOutput::make_doub_string_ecl(double value) const
{
char buffer [21];
std::sprintf (buffer, "%19.13E", value);
@ -409,6 +528,30 @@ std::string EclOutput::make_doub_string(double value) const
}
}
std::string EclOutput::make_doub_string_ix(double value) const
{
char buffer [21];
std::sprintf (buffer, "%19.13E", value);
if (value == 0.0) {
return " 0.0000000000000E+00";
} else {
if (std::isnan(value))
return "NAN";
if (std::isinf(value)) {
if (value > 0)
return "INF";
else
return "-INF";
}
std::string tmpstr(buffer);
return tmpstr;
}
}
template <typename T>
void EclOutput::writeFormattedArray(const std::vector<T>& data)
@ -427,6 +570,7 @@ void EclOutput::writeFormattedArray(const std::vector<T>& data)
arrType = LOGI;
}
auto sizeData = block_size_data_formatted(arrType);
int maxBlockSize = std::get<0>(sizeData);
@ -441,10 +585,16 @@ void EclOutput::writeFormattedArray(const std::vector<T>& data)
ofileH << std::setw(columnWidth) << data[i];
break;
case REAL:
ofileH << std::setw(columnWidth) << make_real_string(data[i]);
if (ix_standard)
ofileH << std::setw(columnWidth) << make_real_string_ix(data[i]);
else
ofileH << std::setw(columnWidth) << make_real_string_ecl(data[i]);
break;
case DOUB:
ofileH << std::setw(columnWidth) << make_doub_string(data[i]);
if (ix_standard)
ofileH << std::setw(columnWidth) << make_doub_string_ix(data[i]);
else
ofileH << std::setw(columnWidth) << make_doub_string_ecl(data[i]);
break;
case LOGI:
if (data[i]) {
@ -479,18 +629,34 @@ template void EclOutput::writeFormattedArray<bool>(const std::vector<bool>& data
template void EclOutput::writeFormattedArray<char>(const std::vector<char>& data);
void EclOutput::writeFormattedCharArray(const std::vector<std::string>& data)
void EclOutput::writeFormattedCharArray(const std::vector<std::string>& data, int element_size)
{
auto sizeData = block_size_data_formatted(CHAR);
int maxBlockSize = std::get<0>(sizeData);
int nColumns = std::get<1>(sizeData);
int nColumns;
int size = data.size();
if (element_size < 9)
{
element_size = 8;
nColumns = std::get<1>(sizeData);
} else
nColumns = 80 / (element_size + 3);
int rest = data.size();
int n = 0;
while (rest > 0) {
int size = rest;
if (size > maxBlockSize)
size = maxBlockSize;
for (int i = 0; i < size; i++) {
std::string str1(8,' ');
str1 = data[i] + std::string(8 - data[i].size(),' ');
std::string str1(element_size,' ');
str1 = data[n] + std::string(element_size - data[n].size(),' ');
n++;
ofileH << " '" << str1 << "'";
if ((i+1) % nColumns == 0) {
@ -501,7 +667,11 @@ void EclOutput::writeFormattedCharArray(const std::vector<std::string>& data)
if ((size % nColumns) != 0) {
ofileH << std::endl;
}
rest = (rest > maxBlockSize) ? rest - maxBlockSize : 0;
}
}
void EclOutput::writeFormattedCharArray(const std::vector<PaddedOutputString<8>>& data)
{

View File

@ -27,6 +27,8 @@
#include <fstream>
#include <cstring>
//temporary
#include <iostream>
int Opm::EclIO::flipEndianInt(int num)
{
@ -111,6 +113,9 @@ std::tuple<int, int> Opm::EclIO::block_size_data_binary(eclArrType arrType)
case CHAR:
return BlockSizeTuple{sizeOfChar, MaxBlockSizeChar};
break;
case C0NN:
return BlockSizeTuple{sizeOfChar, MaxBlockSizeChar};
break;
case MESS:
OPM_THROW(std::invalid_argument, "Type 'MESS' have no associated data");
break;
@ -141,6 +146,9 @@ std::tuple<int, int, int> Opm::EclIO::block_size_data_formatted(eclArrType arrTy
case CHAR:
return BlockSizeTuple{MaxNumBlockChar,numColumnsChar, columnWidthChar};
break;
case C0NN:
return BlockSizeTuple{MaxNumBlockChar,numColumnsChar, columnWidthChar};
break;
case MESS:
OPM_THROW(std::invalid_argument, "Type 'MESS' have no associated data") ;
break;
@ -162,7 +170,7 @@ std::string Opm::EclIO::trimr(const std::string &str1)
}
}
uint64_t Opm::EclIO::sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrType)
uint64_t Opm::EclIO::sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrType, int elementSize)
{
uint64_t size = 0;
@ -175,6 +183,11 @@ uint64_t Opm::EclIO::sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrTyp
if (num > 0) {
auto sizeData = Opm::EclIO::block_size_data_binary(arrType);
if (arrType == Opm::EclIO::C0NN){
std::get<1>(sizeData)= std::get<1>(sizeData) / std::get<0>(sizeData) * elementSize;
std::get<0>(sizeData) = elementSize;
}
int sizeOfElement = std::get<0>(sizeData);
int maxBlockSize = std::get<1>(sizeData);
int maxNumberOfElements = maxBlockSize / sizeOfElement;
@ -197,7 +210,7 @@ uint64_t Opm::EclIO::sizeOnDiskBinary(int64_t num, Opm::EclIO::eclArrType arrTyp
return size;
}
uint64_t Opm::EclIO::sizeOnDiskFormatted(const int64_t num, Opm::EclIO::eclArrType arrType)
uint64_t Opm::EclIO::sizeOnDiskFormatted(const int64_t num, Opm::EclIO::eclArrType arrType, int elementSize)
{
uint64_t size = 0;
@ -208,6 +221,11 @@ uint64_t Opm::EclIO::sizeOnDiskFormatted(const int64_t num, Opm::EclIO::eclArrTy
} else {
auto sizeData = block_size_data_formatted(arrType);
if (arrType == Opm::EclIO::C0NN){
std::get<2>(sizeData) = elementSize + 3;
std::get<1>(sizeData) = 80 / std::get<2>(sizeData);
}
int maxBlockSize = std::get<0>(sizeData);
int nColumns = std::get<1>(sizeData);
int columnWidth = std::get<2>(sizeData);
@ -272,7 +290,7 @@ void Opm::EclIO::readBinaryHeader(std::fstream& fileH, std::string& tmpStrName,
}
void Opm::EclIO::readBinaryHeader(std::fstream& fileH, std::string& arrName,
int64_t& size, Opm::EclIO::eclArrType &arrType)
int64_t& size, Opm::EclIO::eclArrType &arrType, int& elementSize)
{
std::string tmpStrName(8,' ');
std::string tmpStrType(4,' ');
@ -297,15 +315,25 @@ void Opm::EclIO::readBinaryHeader(std::fstream& fileH, std::string& arrName,
size = static_cast<int64_t>(tmpSize);
}
elementSize = 4;
arrName = tmpStrName;
if (tmpStrType == "INTE")
arrType = Opm::EclIO::INTE;
else if (tmpStrType == "REAL")
arrType = Opm::EclIO::REAL;
else if (tmpStrType == "DOUB")
else if (tmpStrType == "DOUB"){
arrType = Opm::EclIO::DOUB;
else if (tmpStrType == "CHAR")
elementSize = 8;
}
else if (tmpStrType == "CHAR"){
arrType = Opm::EclIO::CHAR;
elementSize = 8;
}
else if (tmpStrType.substr(0,1)=="C"){
arrType = Opm::EclIO::C0NN;
elementSize = std::stoi(tmpStrType.substr(1,3));
}
else if (tmpStrType =="LOGI")
arrType = Opm::EclIO::LOGI;
else if (tmpStrType == "MESS")
@ -316,7 +344,7 @@ void Opm::EclIO::readBinaryHeader(std::fstream& fileH, std::string& arrName,
void Opm::EclIO::readFormattedHeader(std::fstream& fileH, std::string& arrName,
int64_t &num, Opm::EclIO::eclArrType &arrType)
int64_t &num, Opm::EclIO::eclArrType &arrType, int& elementSize)
{
std::string line;
std::getline(fileH,line);
@ -336,14 +364,24 @@ void Opm::EclIO::readFormattedHeader(std::fstream& fileH, std::string& arrName,
num = std::stol(antStr);
elementSize = 4;
if (arrTypeStr == "INTE")
arrType = Opm::EclIO::INTE;
else if (arrTypeStr == "REAL")
arrType = Opm::EclIO::REAL;
else if (arrTypeStr == "DOUB")
else if (arrTypeStr == "DOUB"){
arrType = Opm::EclIO::DOUB;
else if (arrTypeStr == "CHAR")
elementSize = 8;
}
else if (arrTypeStr == "CHAR"){
arrType = Opm::EclIO::CHAR;
elementSize = 8;
}
else if (arrTypeStr.substr(0,1)=="C"){
arrType = Opm::EclIO::C0NN;
elementSize = std::stoi(arrTypeStr.substr(1,3));
}
else if (arrTypeStr == "LOGI")
arrType = Opm::EclIO::LOGI;
else if (arrTypeStr == "MESS")
@ -358,11 +396,17 @@ void Opm::EclIO::readFormattedHeader(std::fstream& fileH, std::string& arrName,
template<typename T, typename T2>
std::vector<T> Opm::EclIO::readBinaryArray(std::fstream& fileH, const int64_t size, Opm::EclIO::eclArrType type,
std::function<T(T2)>& flip)
std::function<T(T2)>& flip, int elementSize)
{
std::vector<T> arr;
auto sizeData = block_size_data_binary(type);
if (type == Opm::EclIO::C0NN){
std::get<1>(sizeData)= std::get<1>(sizeData) / std::get<0>(sizeData) * elementSize;
std::get<0>(sizeData) = elementSize;
}
int sizeOfElement = std::get<0>(sizeData);
int maxBlockSize = std::get<1>(sizeData);
int maxNumberOfElements = maxBlockSize / sizeOfElement;
@ -370,11 +414,11 @@ std::vector<T> Opm::EclIO::readBinaryArray(std::fstream& fileH, const int64_t si
arr.reserve(size);
int64_t rest = size;
while (rest > 0) {
int dhead;
fileH.read(reinterpret_cast<char*>(&dhead), sizeof(dhead));
dhead = Opm::EclIO::flipEndianInt(dhead);
int num = dhead / sizeOfElement;
if ((num > maxNumberOfElements) || (num < 0)) {
@ -383,7 +427,13 @@ std::vector<T> Opm::EclIO::readBinaryArray(std::fstream& fileH, const int64_t si
for (int i = 0; i < num; i++) {
T2 value;
if constexpr (std::is_same_v<T2, std::string>) {
value.resize(sizeOfElement) ;
fileH.read(&value[0], sizeOfElement);
} else
fileH.read(reinterpret_cast<char*>(&value), sizeOfElement);
arr.push_back(flip(value));
}
@ -411,21 +461,21 @@ std::vector<T> Opm::EclIO::readBinaryArray(std::fstream& fileH, const int64_t si
std::vector<int> Opm::EclIO::readBinaryInteArray(std::fstream &fileH, const int64_t size)
{
std::function<int(int)> f = Opm::EclIO::flipEndianInt;
return readBinaryArray<int,int>(fileH, size, Opm::EclIO::INTE, f);
return readBinaryArray<int,int>(fileH, size, Opm::EclIO::INTE, f, sizeOfInte);
}
std::vector<float> Opm::EclIO::readBinaryRealArray(std::fstream& fileH, const int64_t size)
{
std::function<float(float)> f = Opm::EclIO::flipEndianFloat;
return readBinaryArray<float,float>(fileH, size, Opm::EclIO::REAL, f);
return readBinaryArray<float,float>(fileH, size, Opm::EclIO::REAL, f, sizeOfReal);
}
std::vector<double> Opm::EclIO::readBinaryDoubArray(std::fstream& fileH, const int64_t size)
{
std::function<double(double)> f = Opm::EclIO::flipEndianDouble;
return readBinaryArray<double,double>(fileH, size, Opm::EclIO::DOUB, f);
return readBinaryArray<double,double>(fileH, size, Opm::EclIO::DOUB, f, sizeOfDoub);
}
std::vector<bool> Opm::EclIO::readBinaryLogiArray(std::fstream &fileH, const int64_t size)
@ -433,17 +483,28 @@ std::vector<bool> Opm::EclIO::readBinaryLogiArray(std::fstream &fileH, const int
std::function<bool(unsigned int)> f = [](unsigned int intVal)
{
bool value;
if (intVal == Opm::EclIO::true_value) {
if (intVal == Opm::EclIO::true_value_ecl) {
value = true;
} else if (intVal == Opm::EclIO::false_value) {
value = false;
} else if (intVal == Opm::EclIO::true_value_ix) {
value = true;
} else {
OPM_THROW(std::runtime_error, "Error reading logi value");
}
return value;
};
return readBinaryArray<bool,unsigned int>(fileH, size, Opm::EclIO::LOGI, f);
return readBinaryArray<bool,unsigned int>(fileH, size, Opm::EclIO::LOGI, f, sizeOfLogi);
}
std::vector<unsigned int> Opm::EclIO::readBinaryRawLogiArray(std::fstream &fileH, const int64_t size)
{
std::function<unsigned int(unsigned int)> f = [](unsigned int intVal)
{
return intVal;
};
return readBinaryArray<unsigned int, unsigned int>(fileH, size, Opm::EclIO::LOGI, f, sizeOfLogi);
}
@ -455,7 +516,18 @@ std::vector<std::string> Opm::EclIO::readBinaryCharArray(std::fstream& fileH, co
std::string res(val.begin(), val.end());
return Opm::EclIO::trimr(res);
};
return readBinaryArray<std::string,Char8>(fileH, size, Opm::EclIO::CHAR, f);
return readBinaryArray<std::string,Char8>(fileH, size, Opm::EclIO::CHAR, f, sizeOfChar);
}
std::vector<std::string> Opm::EclIO::readBinaryC0nnArray(std::fstream& fileH, const int64_t size, int elementSize)
{
std::function<std::string(std::string)> f = [](const std::string& val)
{
return Opm::EclIO::trimr(val);
};
return readBinaryArray<std::string,std::string>(fileH, size, Opm::EclIO::C0NN, f, elementSize);
}
@ -479,7 +551,6 @@ std::vector<T> Opm::EclIO::readFormattedArray(const std::string& file_str, const
}
return arr;
}
@ -495,7 +566,8 @@ std::vector<int> Opm::EclIO::readFormattedInteArray(const std::string& file_str,
}
std::vector<std::string> Opm::EclIO::readFormattedCharArray(const std::string& file_str, const int64_t size, int64_t fromPos)
std::vector<std::string> Opm::EclIO::readFormattedCharArray(const std::string& file_str, const int64_t size,
int64_t fromPos, int elementSize)
{
std::vector<std::string> arr;
arr.reserve(size);
@ -504,7 +576,7 @@ std::vector<std::string> Opm::EclIO::readFormattedCharArray(const std::string& f
for (int i=0; i< size; i++) {
p1 = file_str.find_first_of('\'',p1);
std::string value = file_str.substr(p1 + 1, 8);
std::string value = file_str.substr(p1 + 1, elementSize);
if (value == " ") {
arr.push_back("");
@ -512,7 +584,7 @@ std::vector<std::string> Opm::EclIO::readFormattedCharArray(const std::string& f
arr.push_back(Opm::EclIO::trimr(value));
}
p1 = p1+10;
p1 = p1 + elementSize + 2;
}
return arr;
@ -533,6 +605,18 @@ std::vector<float> Opm::EclIO::readFormattedRealArray(const std::string& file_st
return readFormattedArray<float>(file_str, size, fromPos, f);
}
std::vector<std::string> Opm::EclIO::readFormattedRealRawStrings(const std::string& file_str, const int64_t size, int64_t fromPos)
{
std::function<std::string(const std::string&)> f = [](const std::string& val)
{
return val;
};
return readFormattedArray<std::string>(file_str, size, fromPos, f);
}
std::vector<bool> Opm::EclIO::readFormattedLogiArray(const std::string& file_str, const int64_t size, int64_t fromPos)
{
@ -559,15 +643,18 @@ std::vector<double> Opm::EclIO::readFormattedDoubArray(const std::string& file_s
{
auto p1 = val.find_first_of("D");
if (p1 == std::string::npos) {
auto p2 = val.find_first_of("-+", 1);
if (p2 != std::string::npos) {
val = val.insert(p2,"E");
}
} else {
if (p1 != std::string::npos) {
val.replace(p1,1,"E");
}
p1 = val.find_first_of("E");
if (p1 == std::string::npos) {
auto p2 = val.find_first_of("-+", 1);
if (p2 != std::string::npos)
val = val.insert(p2,"E");
}
return std::stod(val);
};

View File

@ -50,6 +50,8 @@ void writeArray(std::string name, eclArrType arrType, T& file1, int index, EclOu
write<bool>(outFile, file1, name, index);
} else if (arrType == CHAR) {
write<std::string>(outFile, file1, name, index);
} else if (arrType == C0NN) {
write<std::string>(outFile, file1, name, index);
} else if (arrType == MESS) {
outFile.message(name);
} else {
@ -58,6 +60,7 @@ void writeArray(std::string name, eclArrType arrType, T& file1, int index, EclOu
}
}
template <typename T>
void writeArray(std::string name, eclArrType arrType, T& file1, int index, int reportStepNumber, EclOutput& outFile) {
@ -79,11 +82,23 @@ void writeArray(std::string name, eclArrType arrType, T& file1, int index, int r
}
}
void writeArrayList(std::vector<EclEntry>& arrayList, EclFile file1, EclOutput& outFile) {
void writeC0nnArray(std::string name, int elementSize, EclFile& file1, int index, EclOutput& outFile)
{
auto vect = file1.get<std::string>(index);
outFile.write(name, vect, elementSize);
}
void writeArrayList(std::vector<EclEntry>& arrayList, std::vector<int>& elementSizeList, EclFile file1, EclOutput& outFile) {
for (size_t index = 0; index < arrayList.size(); index++) {
std::string name = std::get<0>(arrayList[index]);
eclArrType arrType = std::get<1>(arrayList[index]);
if (arrType == Opm::EclIO::C0NN){
writeC0nnArray(name, elementSizeList[index], file1, index, outFile);
} else
writeArray(name, arrType, file1, index, outFile);
}
}
@ -102,8 +117,9 @@ static void printHelp() {
std::cout << "\nconvertECL needs one argument which is the input file to be converted. If this is a binary file the output file will be formatted. If the input file is formatted the output will be binary. \n"
<< "\nIn addition, the program takes these options (which must be given before the arguments):\n\n"
<< "-h Print help and exit.\n"
<< "-l list report step numbers in the selected restart file.\n"
<< "-r extract and convert a spesific report time step number from a unified restart file. \n\n";
<< "-l List report step numbers in the selected restart file.\n"
<< "-i Enforce IX standard on output file.\n"
<< "-r Extract and convert a spesific report time step number from a unified restart file. \n\n";
}
int main(int argc, char **argv) {
@ -112,8 +128,9 @@ int main(int argc, char **argv) {
int reportStepNumber = -1;
bool specificReportStepNumber = false;
bool listProperties = false;
bool enforce_ix_output = false;
while ((c = getopt(argc, argv, "hr:l")) != -1) {
while ((c = getopt(argc, argv, "hr:li")) != -1) {
switch (c) {
case 'h':
printHelp();
@ -121,6 +138,9 @@ int main(int argc, char **argv) {
case 'l':
listProperties=true;
break;
case 'i':
enforce_ix_output=true;
break;
case 'r':
specificReportStepNumber=true;
reportStepNumber = atoi(optarg);
@ -215,6 +235,11 @@ int main(int argc, char **argv) {
EclOutput outFile(resFile, formattedOutput);
if ((file1.is_ix()) || (enforce_ix_output)) {
std::cout << "setting IX flag on output file \n";
outFile.set_ix();
}
if (specificReportStepNumber) {
if (extension!=".UNRST") {
@ -239,8 +264,8 @@ int main(int argc, char **argv) {
file1.loadData();
auto arrayList = file1.getList();
writeArrayList(arrayList, file1, outFile);
std::vector<int> elementSizeList = file1.getElementSizeList();
writeArrayList(arrayList, elementSizeList, file1, outFile);
}
auto end = std::chrono::system_clock::now();

View File

@ -0,0 +1,102 @@
/*
Copyright 2019 Equinor 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 <cmath>
#include <iomanip>
#include <iostream>
#include <tuple>
#include <getopt.h>
#include <sstream>
#include <stdexcept>
#include <opm/io/eclipse/EclFile.hpp>
#include <opm/io/eclipse/EclOutput.hpp>
static void printHelp() {
std::cout << "\rewriteEclFile needs a minimum of one arguments which is the input file name. \n"
<< "\nIn addition, the program takes these options (which must be given before the arguments):\n\n"
<< "-h Print help and exit.\n\n";
}
int main(int argc, char **argv) {
int c = 0;
while ((c = getopt(argc, argv, "h")) != -1) {
switch (c) {
case 'h':
printHelp();
return 0;
default:
return EXIT_FAILURE;
}
}
int argOffset = optind;
Opm::EclIO::EclFile reffile(argv[argOffset]);
auto arrayList = reffile.getList();
std::string outputFile=std::string(argv[argOffset]);
int p1 = outputFile.find_last_of(".");
std::string ext = outputFile.substr(p1+1);
outputFile = outputFile.substr(0,p1) + "_REWRITE." + ext;
Opm::EclIO::EclOutput outFile(outputFile, reffile.formattedInput());
if (reffile.is_ix())
outFile.set_ix();
reffile.loadData();
std::vector<int> elementSizeList = reffile.getElementSizeList();
for (size_t n = 0; n < arrayList.size(); n++){
std::string name = std::get<0>(arrayList[n]);
auto arrType = std::get<1>(arrayList[n]);
if (arrType == Opm::EclIO::INTE) {
auto data = reffile.get<int>(n);
outFile.write(name, data);
} else if (arrType == Opm::EclIO::CHAR) {
auto data = reffile.get<std::string>(n);
outFile.write(name, data);
} else if (arrType == Opm::EclIO::C0NN) {
auto data = reffile.get<std::string>(n);
outFile.write(name, data, elementSizeList[n]);
} else if (arrType == Opm::EclIO::REAL) {
auto data = reffile.get<float>(n);
outFile.write(name, data);
} else if (arrType == Opm::EclIO::DOUB) {
auto data = reffile.get<double>(n);
outFile.write(name, data);
} else if (arrType == Opm::EclIO::LOGI) {
auto data = reffile.get<bool>(n);
outFile.write(name, data);
} else if (arrType == Opm::EclIO::MESS) {
outFile.message(name);
}
}
return 0;
}

View File

@ -26,7 +26,6 @@
#include <opm/io/eclipse/ESmry.hpp>
static void printHelp() {
std::cout << "\nsummary needs a minimum of two arguments. First is smspec filename and then list of vectors \n"
@ -36,26 +35,32 @@ static void printHelp() {
<< "-r extract data only for report steps. \n\n";
}
void printHeader(const std::vector<std::string>& keyList){
void printHeader(const std::vector<std::string>& keyList, const std::vector<int>& width){
std::cout << "--" << std::setw(14) << keyList[0];
std::cout << std::endl;
for (size_t n= 1; n < keyList.size(); n++){
for (size_t n= 0; n < keyList.size(); n++){
if (width[n] < 14)
std::cout << std::setw(16) << keyList[n];
else
std::cout << std::setw(width[n] + 2) << keyList[n];
}
std::cout << std::endl;
}
std::string formatString(float data){
std::string formatString(float data, int width){
std::stringstream stream;
if (std::fabs(data) < 1e6){
if (std::fabs(data) < 1e6)
if (width < 14)
stream << std::fixed << std::setw(16) << std::setprecision(6) << data;
} else {
else
stream << std::fixed << std::setw(width + 2) << std::setprecision(6) << data;
else
stream << std::scientific << std::setw(16) << std::setprecision(6) << data;
}
return stream.str();
}
@ -128,20 +133,27 @@ int main(int argc, char **argv) {
}
std::vector<std::vector<float>> smryData;
std::vector<int> width;
for (auto name : smryList)
width.push_back(name.size());
for (auto key : smryList) {
std::vector<float> vect = reportStepsOnly ? smryFile.get_at_rstep(key) : smryFile.get(key);
smryData.push_back(vect);
}
printHeader(smryList);
printHeader(smryList, width);
for (size_t s=0; s<smryData[0].size(); s++){
for (size_t n=0; n < smryData.size(); n++){
std::cout << formatString(smryData[n][s]);
std::cout << formatString(smryData[n][s], width[n]);
}
std::cout << std::endl;
}
std::cout << std::endl;
return 0;
}

BIN
tests/MODEL1_IX.INIT Normal file

Binary file not shown.

BIN
tests/MODEL1_IX.SMSPEC Normal file

Binary file not shown.

BIN
tests/MODEL1_IX.UNSMRY Normal file

Binary file not shown.

View File

@ -366,6 +366,35 @@ BOOST_AUTO_TEST_CASE(TestESmry_4) {
}
BOOST_AUTO_TEST_CASE(TestESmry_5) {
// file MODEL1_IX.SMSPEC and MODEL1_IX.UNSMRY are output from comercial simulator ix with
// BASE_MODEL_1.DATA in opm-tests
// array WGNAME (of type CHAR) in Eclipse and Flow smspec files, is replaced with
// array NAMES (of type C0NN) in IX smspec files
ESmry smry1("MODEL1_IX.SMSPEC");
smry1.LoadData();
std::vector<float> report_timesteps = {31.0, 60.0, 91.0, 121.0, 152.0, 182.0, 213.0, 244.0, 274.0, 305.0, 335.0, 364.0};
std::vector<float> qoil_p2 = { 1160.149902, 1199.301147, 1199.304932, 1199.147583, 1199.120239, 1199.040405, 1198.917725,
1198.765381, 1198.627930, 1198.406616, 1198.143555, 1197.853760 };
std::vector<float> timeVect = smry1.get_at_rstep("TIME");
std::vector<float> wopr_prod2 = smry1.get_at_rstep("WOPR:PROD-2");
for (size_t n = 0; n < timeVect.size() ; n ++)
BOOST_CHECK_CLOSE(timeVect[n], report_timesteps[n], 1e-6);
for (size_t n = 0; n < wopr_prod2.size() ; n ++)
BOOST_CHECK_CLOSE(wopr_prod2[n], qoil_p2[n], 1e-6);
}
namespace fs = Opm::filesystem;
BOOST_AUTO_TEST_CASE(TestCreateRSM) {
ESmry smry1("SPE1CASE1.SMSPEC");

View File

@ -87,7 +87,6 @@ void write_header(std::ofstream& ofileH, std::string& arrName, int size, std::st
ofileH.write(reinterpret_cast<char*>(&bhead), sizeof(bhead));
}
BOOST_AUTO_TEST_CASE(TestEclFile_X231) {
std::string filename = "TEST.DAT";
@ -193,6 +192,7 @@ BOOST_AUTO_TEST_CASE(TestEclFile_BINARY) {
BOOST_CHECK_EQUAL(vect5b.size(), 312U);
}
BOOST_AUTO_TEST_CASE(TestEclFile_FORMATTED) {
std::string testFile1="ECLFILE.INIT";
@ -238,6 +238,31 @@ BOOST_AUTO_TEST_CASE(TestEclFile_FORMATTED) {
}
BOOST_AUTO_TEST_CASE(TestEclFile_IX) {
// file MODEL1_IX.INIT is output from comercial simulator ix with
// BASE_MODEL_1.DATA in opm-tests
// binary representation of true value for data type LOGI is different
// compared with output from Eclipse and OPM-Flow
std::string testInitFile="MODEL1_IX.INIT";
EclFile file1(testInitFile);
file1.loadData();
std::vector<bool> refLogihead = {true, true, false, false, true, false, false, false, false, false, false,
false, false, false, false, false, true, false, true, false };
auto logih = file1.get<bool>("LOGIHEAD");
for (size_t n = 0 ; n < refLogihead.size(); n++)
BOOST_CHECK_EQUAL(refLogihead[n], logih[n]);
}
BOOST_AUTO_TEST_CASE(TestEcl_Write_binary) {
std::string inputFile="ECLFILE.INIT";
@ -391,26 +416,128 @@ BOOST_AUTO_TEST_CASE(TestEcl_getList) {
BOOST_AUTO_TEST_CASE(TestEcl_Write_CHAR) {
std::string testFile="TEST.FDAT";
std::vector<std::string> refStrList = {"This", "is", "a test.", "", "charact", "er >'<", "can be", "part of", "a string"};
std::string testFile1="TEST.FDAT";
std::string testFile2="TEST2.DAT";
std::vector<std::string> refStrList1 = {"This", "is", "a test.", "", "charact", "er >'<", "can be", "part of", "a string"};
std::vector<std::string> refStrList2 = {"strings with length", "beyone 8 character","is also possible", "will use type C0nn"};
{
EclOutput eclTest(testFile, true);
eclTest.write("TEST",refStrList);
EclOutput eclTest(testFile1, true);
eclTest.write("TEST1",refStrList1);
}
{
EclFile file1(testFile);
std::vector<std::string> strList=file1.get<std::string>("TEST");
EclFile file1(testFile1);
std::vector<std::string> strList=file1.get<std::string>("TEST1");
for (size_t n = 0; n < refStrList.size(); n++) {
BOOST_CHECK(refStrList[n] == strList[n]);
}
for (size_t n = 0; n < refStrList1.size(); n++) {
BOOST_CHECK(refStrList1[n] == strList[n]);
}
if (remove(testFile.c_str())==-1) {
auto arrayList =file1.getList();
BOOST_CHECK(std::get<1>(arrayList[0]) == Opm::EclIO::CHAR);
}
// the next should automatically use C019
{
EclOutput eclTest(testFile1, true);
eclTest.write("TEST2",refStrList2);
}
{
EclFile file1(testFile1);
std::vector<std::string> strList=file1.get<std::string>("TEST2");
for (size_t n = 0; n < refStrList2.size(); n++) {
BOOST_CHECK(refStrList2[n] == strList[n]);
}
auto arrayList =file1.getList();
BOOST_CHECK(std::get<1>(arrayList[0]) == Opm::EclIO::C0NN);
}
// the next should automatically use C008 (and not CHAR)
// will use C0nn since element size is specified in function call
{
EclOutput eclTest(testFile1, true);
eclTest.write("TEST3",refStrList1, 8);
}
{
EclFile file1(testFile1);
std::vector<std::string> strList=file1.get<std::string>("TEST3");
for (size_t n = 0; n < refStrList1.size(); n++) {
BOOST_CHECK(refStrList1[n] == strList[n]);
}
auto arrayList =file1.getList();
BOOST_CHECK(std::get<1>(arrayList[0]) == Opm::EclIO::C0NN);
}
// testing binary CHAR/C0nn format
{
EclOutput eclTest(testFile2, false);
eclTest.write("TEST4",refStrList1);
}
{
EclFile file1(testFile2);
std::vector<std::string> strList=file1.get<std::string>("TEST4");
for (size_t n = 0; n < refStrList1.size(); n++) {
BOOST_CHECK(refStrList1[n] == strList[n]);
}
auto arrayList =file1.getList();
BOOST_CHECK(std::get<1>(arrayList[0]) == Opm::EclIO::CHAR);
}
// the next should automatically use C019
{
EclOutput eclTest(testFile2, false);
eclTest.write("TEST5",refStrList2);
}
{
EclFile file1(testFile2);
std::vector<std::string> strList=file1.get<std::string>("TEST5");
for (size_t n = 0; n < refStrList2.size(); n++) {
BOOST_CHECK(refStrList2[n] == strList[n]);
}
auto arrayList =file1.getList();
BOOST_CHECK(std::get<1>(arrayList[0]) == Opm::EclIO::C0NN);
}
// the next should automatically use C008 (and not CHAR)
// will use C0nn since element size is specified in function call
{
EclOutput eclTest(testFile2, false);
eclTest.write("TEST6",refStrList1, 8);
}
{
EclFile file1(testFile2);
std::vector<std::string> strList=file1.get<std::string>("TEST6");
for (size_t n = 0; n < refStrList1.size(); n++) {
BOOST_CHECK(refStrList1[n] == strList[n]);
}
auto arrayList =file1.getList();
BOOST_CHECK(std::get<1>(arrayList[0]) == Opm::EclIO::C0NN);
}
if (remove(testFile1.c_str())==-1) {
std::cout << " > Warning! temporary file was not deleted" << std::endl;
};
if (remove(testFile2.c_str())==-1) {
std::cout << " > Warning! temporary file was not deleted" << std::endl;
};
}