Adding python bindings for C++ class ERft
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <src/opm/io/eclipse/ERst.cpp>
|
||||
#include <src/opm/io/eclipse/ESmry.cpp>
|
||||
#include <src/opm/io/eclipse/EGrid.cpp>
|
||||
#include <src/opm/io/eclipse/ERft.cpp>
|
||||
|
||||
#include <opm/common/utility/numeric/calculateCellVol.hpp>
|
||||
|
||||
@@ -191,11 +192,62 @@ py::array get_cellvolumes(Opm::EclIO::EGrid * file_ptr)
|
||||
return get_cellvolumes_mask(file_ptr, mask);
|
||||
}
|
||||
|
||||
npArray get_rft_vector_WellDate(Opm::EclIO::ERft * file_ptr,const std::string& name,
|
||||
const std::string& well, int y, int m, int d)
|
||||
{
|
||||
auto arrList = file_ptr->listOfRftArrays(well, y, m, d);
|
||||
size_t array_index = get_array_index(arrList, name, 0);
|
||||
Opm::EclIO::eclArrType array_type = std::get<1>(arrList[array_index]);
|
||||
|
||||
if (array_type == Opm::EclIO::INTE)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<int>(name, well, y, m, d) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::REAL)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<float>(name, well, y, m, d) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::DOUB)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<double>(name, well, y, m, d) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::CHAR)
|
||||
return std::make_tuple (convert::numpy_string_array( file_ptr->getRft<std::string>(name, well, y, m, d) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::LOGI)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<bool>(name, well, y, m, d) ), array_type);
|
||||
|
||||
throw std::logic_error("Data type not supported");
|
||||
}
|
||||
|
||||
npArray get_rft_vector_Index(Opm::EclIO::ERft * file_ptr,const std::string& name, int reportIndex)
|
||||
{
|
||||
auto arrList = file_ptr->listOfRftArrays(reportIndex);
|
||||
size_t array_index = get_array_index(arrList, name, 0);
|
||||
Opm::EclIO::eclArrType array_type = std::get<1>(arrList[array_index]);
|
||||
|
||||
if (array_type == Opm::EclIO::INTE)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<int>(name, reportIndex) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::REAL)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<float>(name, reportIndex) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::DOUB)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<double>(name, reportIndex) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::CHAR)
|
||||
return std::make_tuple (convert::numpy_string_array( file_ptr->getRft<std::string>(name, reportIndex) ), array_type);
|
||||
|
||||
if (array_type == Opm::EclIO::LOGI)
|
||||
return std::make_tuple (convert::numpy_array( file_ptr->getRft<bool>(name, reportIndex) ), array_type);
|
||||
|
||||
throw std::logic_error("Data type not supported");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void python::common::export_IO(py::module& m) {
|
||||
|
||||
py::enum_<Opm::EclIO::eclArrType>(m, "eclArrType", py::arithmetic())
|
||||
@@ -250,4 +302,25 @@ void python::common::export_IO(py::module& m) {
|
||||
.def("xyz_from_active_index", &get_xyz_from_active_index)
|
||||
.def("cellvolumes", &get_cellvolumes)
|
||||
.def("cellvolumes", &get_cellvolumes_mask);
|
||||
|
||||
py::class_<Opm::EclIO::ERft>(m, "ERft")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("__get_list_of_rfts", &Opm::EclIO::ERft::listOfRftReports)
|
||||
|
||||
.def("__get_list_of_arrays", (std::vector< std::tuple<std::string, Opm::EclIO::eclArrType, long int> >
|
||||
(Opm::EclIO::ERft::*)(int) const) &Opm::EclIO::ERft::listOfRftArrays)
|
||||
|
||||
.def("__get_list_of_arrays", (std::vector< std::tuple<std::string, Opm::EclIO::eclArrType, long int> >
|
||||
(Opm::EclIO::ERft::*)(const std::string&, int, int, int) const)
|
||||
&Opm::EclIO::ERft::listOfRftArrays)
|
||||
|
||||
.def("__get_data", &get_rft_vector_WellDate)
|
||||
.def("__get_data", &get_rft_vector_Index)
|
||||
|
||||
.def("__has_rft", (bool (Opm::EclIO::ERft::*)(const std::string&, int, int, int) const) &Opm::EclIO::ERft::hasRft)
|
||||
.def("__has_array", (bool (Opm::EclIO::ERft::*)(const std::string&, int) const) &Opm::EclIO::ERft::hasArray)
|
||||
.def("__has_array", (bool (Opm::EclIO::ERft::*)(const std::string&, const std::string&, const
|
||||
std::tuple<int,int,int>&) const) &Opm::EclIO::ERft::hasArray)
|
||||
|
||||
.def("__len__", &Opm::EclIO::ERft::numberOfReports);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ from .libopmcommon_python import EclFile, eclArrType
|
||||
from .libopmcommon_python import ERst
|
||||
from .libopmcommon_python import ESmry
|
||||
from .libopmcommon_python import EGrid
|
||||
from .libopmcommon_python import ERft
|
||||
from .libopmcommon_python import SummaryState
|
||||
|
||||
#from .schedule import Well, Connection, Schedule
|
||||
|
||||
@@ -3,6 +3,7 @@ from opm._common import EclFile
|
||||
from opm._common import ERst
|
||||
from opm._common import ESmry
|
||||
from opm._common import EGrid
|
||||
from opm._common import ERft
|
||||
|
||||
import sys
|
||||
import datetime
|
||||
@@ -119,6 +120,63 @@ def getitem_esmry(self, arg):
|
||||
return self.__get_all(arg)
|
||||
|
||||
|
||||
def contains_erft(self, arg):
|
||||
|
||||
if isinstance(arg, tuple):
|
||||
if len(arg) == 4:
|
||||
return self.__has_rft(arg[0], arg[1], arg[2], arg[3])
|
||||
elif len(arg) == 5:
|
||||
return self.__has_array(arg[0], arg[1], (arg[2], arg[3], arg[4]))
|
||||
elif len(arg) == 2:
|
||||
return self.__has_array(arg[0], arg[1])
|
||||
else:
|
||||
raise ValueError("expecting tuple (wellname, year, month, day) or \
|
||||
(arrayName, wellname, year, month, day) or (arrayName, report_index)")
|
||||
else:
|
||||
raise ValueError("expecting tuple (wellname, year, month, day) or \
|
||||
(arrayName, wellname, year, month, day) or (arrayName, report_index)")
|
||||
|
||||
@property
|
||||
def erft_list_of_rfts(self):
|
||||
|
||||
if sys.version_info.major==2:
|
||||
data = self.__get_list_of_rfts()
|
||||
return [ ( x[0].encode("utf-8"), x[1], x[2] ) for x in data ]
|
||||
else:
|
||||
return self.__get_list_of_rfts()
|
||||
|
||||
|
||||
def erft_list_of_arrays(self, arg1, arg2 = None):
|
||||
|
||||
if not arg2:
|
||||
data = self.__get_list_of_arrays(int(arg1))
|
||||
else:
|
||||
data = self.__get_list_of_arrays(str(arg1), int(arg2[0]), int(arg2[1]), int(arg2[2]))
|
||||
|
||||
if sys.version_info.major==2:
|
||||
return [ ( x[0].encode("utf-8"), x[1], x[2] ) for x in data ]
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
def getitem_erft(self, arg):
|
||||
|
||||
if isinstance(arg, tuple):
|
||||
if len(arg) == 2:
|
||||
data, array_type = self.__get_data(arg[0], arg[1])
|
||||
elif len(arg) == 5:
|
||||
data, array_type = self.__get_data(arg[0], arg[1], arg[2], arg[3], arg[4])
|
||||
else:
|
||||
raise ValueError("ERft.__getitem__, expecting tuple (name, index) or (name, well, y, m, d)")
|
||||
else:
|
||||
raise ValueError("ERft.__getitem__, expecting tuple (name, index) or (name, well, y, m, d)")
|
||||
|
||||
if array_type == eclArrType.CHAR:
|
||||
return np.array([ x.decode("utf-8") for x in data ])
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
setattr(EclFile, "__getitem__", getitem_eclfile)
|
||||
setattr(EclFile, "arrays", eclfile_get_list_of_arrays)
|
||||
|
||||
@@ -129,3 +187,8 @@ setattr(ERst, "__getitem__", getitem_erst)
|
||||
setattr(ESmry, "start_date", esmry_start_date)
|
||||
setattr(ESmry, "end_date", esmry_end_date)
|
||||
setattr(ESmry, "__getitem__", getitem_esmry)
|
||||
|
||||
setattr(ERft, "__contains__", contains_erft)
|
||||
setattr(ERft, "list_of_rfts", erft_list_of_rfts)
|
||||
setattr(ERft, "arrays", erft_list_of_arrays)
|
||||
setattr(ERft, "__getitem__",getitem_erft)
|
||||
|
||||
Binary file not shown.
Executable
+177
@@ -0,0 +1,177 @@
|
||||
import unittest
|
||||
import sys
|
||||
import numpy as np
|
||||
import datetime
|
||||
|
||||
from opm.io.ecl import ERft, eclArrType
|
||||
try:
|
||||
from tests.utils import test_path
|
||||
except ImportError:
|
||||
from utils import test_path
|
||||
|
||||
|
||||
|
||||
class TestEclFile(unittest.TestCase):
|
||||
|
||||
def test_content(self):
|
||||
|
||||
refContent = [ ('PROD', (2015, 1, 1), 0.0),
|
||||
('INJ', (2015, 1, 1), 0.0),
|
||||
('A-1H', (2015, 9, 1), 243.0),
|
||||
('B-2H', (2016, 5, 31), 516.0),
|
||||
('PROD', (2017, 7, 31), 942.0) ]
|
||||
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
ERft("/file/that/does_not_exists")
|
||||
|
||||
rft1 = ERft(test_path("data/SPE1CASE1.RFT"))
|
||||
self.assertEqual(len(rft1), 5)
|
||||
|
||||
self.assertTrue( ("PROD", 2015, 1, 1) in rft1 )
|
||||
self.assertFalse( ("XXX", 2015, 1, 1) in rft1 )
|
||||
|
||||
self.assertTrue( ("PRESSURE", "PROD", 2015, 1, 1) in rft1 )
|
||||
self.assertFalse( ("XXX", "PROD", 2015, 1, 1) in rft1 )
|
||||
|
||||
self.assertTrue( ("PRESSURE", 0) in rft1 )
|
||||
self.assertTrue( ("PRESSURE", 1) in rft1 )
|
||||
|
||||
self.assertFalse( ("XXX", 0) in rft1 )
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
self.assertTrue( ("PRESSURE", "XX", "XX") in rft1 )
|
||||
|
||||
rftlist = rft1.list_of_rfts
|
||||
|
||||
self.assertEqual(len(rftlist), 5)
|
||||
|
||||
for n, rftdata in enumerate(rftlist):
|
||||
self.assertEqual(rftdata[0], refContent[n][0])
|
||||
self.assertEqual(rftdata[1], refContent[n][1])
|
||||
self.assertEqual(rftdata[2], refContent[n][2])
|
||||
|
||||
|
||||
def test_list_of_rfts(self):
|
||||
|
||||
ref_rftlist = []
|
||||
ref_rftlist.append(('PROD', (2015, 1, 1), 0.0))
|
||||
ref_rftlist.append(('INJ', (2015, 1, 1), 0.0))
|
||||
ref_rftlist.append(('A-1H', (2015, 9, 1), 243.0))
|
||||
ref_rftlist.append(('B-2H', (2016, 5, 31), 516.0))
|
||||
ref_rftlist.append(('PROD', (2017, 7, 31), 942.0))
|
||||
|
||||
rft1 = ERft(test_path("data/SPE1CASE1.RFT"))
|
||||
|
||||
for n, element in enumerate(rft1.list_of_rfts):
|
||||
self.assertEqual(element, ref_rftlist[n])
|
||||
|
||||
|
||||
def test_list_of_array(self):
|
||||
|
||||
refArrList = ["TIME", "DATE", "WELLETC", "CONIPOS", "CONJPOS", "CONKPOS", "HOSTGRID", "DEPTH", "PRESSURE",
|
||||
"SWAT", "SGAS"]
|
||||
|
||||
rft1 = ERft(test_path("data/SPE1CASE1.RFT"))
|
||||
|
||||
rft_date = (2016, 5, 31)
|
||||
arrList1 = rft1.arrays( "B-2H", rft_date )
|
||||
arrList2 = rft1.arrays( 3 )
|
||||
|
||||
self.assertEqual(len(arrList1), len(refArrList))
|
||||
|
||||
for n, (name, arrType, arrSize) in enumerate(arrList1):
|
||||
|
||||
self.assertEqual(name, refArrList[n])
|
||||
|
||||
if arrType != eclArrType.MESS:
|
||||
array = rft1[name, "B-2H", 2016, 5, 31]
|
||||
self.assertEqual(len(array), arrSize)
|
||||
|
||||
if arrType == eclArrType.INTE:
|
||||
self.assertEqual(array.dtype, "int32")
|
||||
elif arrType == eclArrType.REAL:
|
||||
self.assertEqual(array.dtype, "float32")
|
||||
elif arrType == eclArrType.DOUB:
|
||||
self.assertEqual(array.dtype, "float64")
|
||||
elif arrType == eclArrType.LOGI:
|
||||
self.assertEqual(array.dtype, "bool")
|
||||
elif arrType == eclArrType.CHAR:
|
||||
self.assertTrue(array.dtype.kind in {'U', 'S'})
|
||||
|
||||
|
||||
self.assertEqual(len(arrList2), len(refArrList))
|
||||
|
||||
for n, (name, arrType, arrSize) in enumerate(arrList2):
|
||||
|
||||
self.assertEqual(name, refArrList[n])
|
||||
|
||||
if arrType != eclArrType.MESS:
|
||||
array = rft1[name, "B-2H", 2016, 5, 31 ]
|
||||
self.assertEqual(len(array), arrSize)
|
||||
|
||||
if arrType == eclArrType.INTE:
|
||||
self.assertEqual(array.dtype, "int32")
|
||||
elif arrType == eclArrType.REAL:
|
||||
self.assertEqual(array.dtype, "float32")
|
||||
elif arrType == eclArrType.DOUB:
|
||||
self.assertEqual(array.dtype, "float64")
|
||||
elif arrType == eclArrType.LOGI:
|
||||
self.assertEqual(array.dtype, "bool")
|
||||
elif arrType == eclArrType.CHAR:
|
||||
self.assertTrue(array.dtype.kind in {'U', 'S'})
|
||||
|
||||
|
||||
def test_get(self):
|
||||
|
||||
pref = [0.57886104E+04, 0.57946934E+04, 0.58056177E+04]
|
||||
refI = [9, 9, 9]
|
||||
refJ = [4, 4, 4]
|
||||
refK = [1, 2, 3]
|
||||
|
||||
rft1 = ERft(test_path("data/SPE1CASE1.RFT"))
|
||||
|
||||
pres1a = rft1["PRESSURE", "A-1H", 2015, 9, 1 ]
|
||||
pres1b = rft1["PRESSURE", 2 ]
|
||||
|
||||
self.assertEqual(len(pres1a), len(pref))
|
||||
self.assertEqual(len(pres1b), len(pref))
|
||||
|
||||
for ref, v1, v2 in zip(pref, pres1a, pres1b):
|
||||
self.assertAlmostEqual(ref, v1, 4)
|
||||
self.assertAlmostEqual(ref, v2, 4)
|
||||
|
||||
conI_1a = rft1["CONIPOS", "B-2H", 2016, 5, 31]
|
||||
conJ_1a = rft1["CONJPOS", "B-2H", 2016, 5, 31]
|
||||
conK_1a = rft1["CONKPOS", "B-2H", 2016, 5, 31]
|
||||
|
||||
conI_1b = rft1["CONIPOS", 3]
|
||||
conJ_1b = rft1["CONJPOS", 3]
|
||||
conK_1b = rft1["CONKPOS", 3]
|
||||
|
||||
self.assertEqual(len(refI), len(conI_1a))
|
||||
self.assertEqual(len(refI), len(conI_1b))
|
||||
|
||||
self.assertEqual(len(refJ), len(conJ_1a))
|
||||
self.assertEqual(len(refJ), len(conJ_1b))
|
||||
|
||||
self.assertEqual(len(refK), len(conK_1a))
|
||||
self.assertEqual(len(refK), len(conK_1b))
|
||||
|
||||
for ref, v1, v2 in zip(refI, conI_1a, conI_1b):
|
||||
self.assertEqual(ref, v1)
|
||||
self.assertEqual(ref, v2)
|
||||
|
||||
for ref, v1, v2 in zip(refJ, conJ_1a, conJ_1b):
|
||||
self.assertEqual(ref, v1)
|
||||
self.assertEqual(ref, v2)
|
||||
|
||||
for ref, v1, v2 in zip(refK, conK_1a, conK_1b):
|
||||
self.assertEqual(ref, v1)
|
||||
self.assertEqual(ref, v2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user