Update of EclIO classes.
- Enables reading of output files generated by simulator IX - Adding support for EclFile data type C0nn (string with length > 8 characters) - Update of program summary, now supporting well names with more that 8 characters - Updates of program convertECL, possible to write output files with IX "format" - updates of python bindings (EclOutput and EclFile)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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&,
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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__":
|
||||
|
||||
|
||||
Reference in New Issue
Block a user