new python bindings class EModel
This commit is contained in:
106
python/cxx/emodel_util.cpp
Normal file
106
python/cxx/emodel_util.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/numpy.h>
|
||||
|
||||
#include <opm/utility/EModel.hpp>
|
||||
|
||||
#include "export.hpp"
|
||||
#include "converters.hpp"
|
||||
|
||||
#include <opm/common/utility/numeric/calculateCellVol.hpp>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
using EclEntry = std::tuple<std::string, Opm::EclIO::eclArrType, int>;
|
||||
|
||||
|
||||
Opm::EclIO::eclArrType getArrayType(EModel * file_ptr, std::string key){
|
||||
|
||||
std::vector<std::string> inteVect = {"I", "J", "K", "ROW", "COLUMN", "LAYER"};
|
||||
|
||||
if(std::find(inteVect.begin(), inteVect.end(), key) != inteVect.end()) {
|
||||
return Opm::EclIO::INTE;
|
||||
}
|
||||
|
||||
auto arrayList = file_ptr->getListOfParameters();
|
||||
|
||||
size_t n = 0;
|
||||
|
||||
while (n < arrayList.size() ){
|
||||
|
||||
if (std::get<0>(arrayList[n]) == key){
|
||||
return std::get<1>(arrayList[n]);
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
throw std::logic_error("Array not found in EModel");
|
||||
}
|
||||
|
||||
|
||||
py::array get_param(EModel * file_ptr, std::string key)
|
||||
{
|
||||
Opm::EclIO::eclArrType arrType = getArrayType(file_ptr, key);
|
||||
|
||||
if (arrType == Opm::EclIO::REAL){
|
||||
std::vector<float> vect = file_ptr->getParam<float>(key);
|
||||
return py::array(py::dtype("f"), {vect.size()}, {}, &vect[0]);
|
||||
} else if (arrType == Opm::EclIO::INTE){
|
||||
std::vector<int> vect = file_ptr->getParam<int>(key);
|
||||
return py::array(py::dtype("i"), {vect.size()}, {}, &vect[0]);
|
||||
} else
|
||||
throw std::logic_error("Data type not supported");
|
||||
}
|
||||
|
||||
|
||||
void add_int_filter_1value(EModel * file_ptr, std::string key, std::string opr, int value)
|
||||
{
|
||||
file_ptr->addFilter<int>(key, opr, value);
|
||||
}
|
||||
|
||||
void add_float_filter_1value(EModel * file_ptr, std::string key, std::string opr, float value)
|
||||
{
|
||||
file_ptr->addFilter<float>(key, opr, value);
|
||||
}
|
||||
|
||||
void add_int_filter_2values(EModel * file_ptr, std::string key, std::string opr, int value1, int value2)
|
||||
{
|
||||
file_ptr->addFilter<int>(key, opr, value1, value2);
|
||||
}
|
||||
|
||||
void add_float_filter_2values(EModel * file_ptr, std::string key, std::string opr, float value1, float value2)
|
||||
{
|
||||
file_ptr->addFilter<float>(key, opr, value1, value2);
|
||||
}
|
||||
|
||||
} // name space
|
||||
|
||||
|
||||
void python::common::export_EModel(py::module& m) {
|
||||
|
||||
m.def("calc_cell_vol",calculateCellVol);
|
||||
|
||||
py::class_<EModel>(m, "EModel")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("__contains__", &EModel::hasParameter)
|
||||
.def("grid_dims", &EModel::gridDims)
|
||||
.def("active_cells", &EModel::getNumberOfActiveCells)
|
||||
.def("set_depth_fwl", &EModel::setDepthfwl)
|
||||
.def("add_hc_filter", &EModel::addHCvolFilter)
|
||||
.def("get_list_of_arrays", &EModel::getListOfParameters)
|
||||
.def("active_report_step", &EModel::getActiveReportStep)
|
||||
.def("get_report_steps", &EModel::getListOfReportSteps)
|
||||
.def("has_report_step", &EModel::hasReportStep)
|
||||
.def("set_report_step", &EModel::setReportStep)
|
||||
.def("reset_filter", &EModel::resetFilter)
|
||||
.def("get", &get_param)
|
||||
.def("__add_filter", &add_int_filter_1value)
|
||||
.def("__add_filter", &add_float_filter_1value)
|
||||
.def("__add_filter", &add_int_filter_2values)
|
||||
.def("__add_filter", &add_float_filter_2values);
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ void python::common::export_all(py::module& module) {
|
||||
export_UnitSystem(module);
|
||||
export_Log(module);
|
||||
export_IO(module);
|
||||
export_EModel(module);
|
||||
export_SummaryState(module);
|
||||
export_ParserKeywords(module);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ void export_TableManager(py::module& module);
|
||||
void export_Well(py::module& module);
|
||||
void export_Log(py::module& module);
|
||||
void export_IO(py::module& module);
|
||||
void export_EModel(py::module& module);
|
||||
void export_SummaryState(py::module& module);
|
||||
|
||||
// The export_ParserKeywords() function is implemented in the source file
|
||||
|
||||
@@ -26,6 +26,8 @@ from .libopmcommon_python import ESmry
|
||||
from .libopmcommon_python import EGrid
|
||||
from .libopmcommon_python import ERft
|
||||
from .libopmcommon_python import EclOutput
|
||||
from .libopmcommon_python import EModel
|
||||
from .libopmcommon_python import calc_cell_vol
|
||||
from .libopmcommon_python import SummaryState
|
||||
|
||||
#from .schedule import Well, Connection, Schedule
|
||||
|
||||
34
python/opm/util/__init__.py
Normal file
34
python/opm/util/__init__.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from opm._common import EModel, eclArrType
|
||||
from opm._common import calc_cell_vol
|
||||
|
||||
def emodel_add_filter(self, key, operator, val1, val2 = None):
|
||||
|
||||
if key in ["I", "J", "K", "ROW", "COLUMN", "LAYER"]:
|
||||
arrType=eclArrType.INTE
|
||||
else:
|
||||
arrList = self.get_list_of_arrays()
|
||||
arrNameList = [item[0] for item in arrList]
|
||||
arrTypeList = [item[1] for item in arrList]
|
||||
|
||||
if key not in arrNameList:
|
||||
raise ValueError("{} array not found in EModel".format(key))
|
||||
|
||||
ind = arrNameList.index(key)
|
||||
|
||||
arrType = arrTypeList[ind]
|
||||
|
||||
if not val2:
|
||||
if arrType == eclArrType.INTE:
|
||||
self.__add_filter(key, operator, int(val1))
|
||||
elif arrType == eclArrType.REAL:
|
||||
self.__add_filter(key, operator, float(val1))
|
||||
else:
|
||||
if arrType == eclArrType.INTE:
|
||||
self.__add_filter(key, operator, int(val1), int(val2))
|
||||
elif arrType == eclArrType.REAL:
|
||||
self.__add_filter(key, operator, float(val1), float(val2))
|
||||
|
||||
|
||||
setattr(EModel, "add_filter", emodel_add_filter)
|
||||
@@ -60,8 +60,9 @@ ext_modules = [
|
||||
'cxx/summary_state.cpp',
|
||||
'cxx/table_manager.cpp',
|
||||
'cxx/well.cpp',
|
||||
'cxx/export.cpp',
|
||||
'cxx/builtin_pybind11.cpp'
|
||||
'cxx/emodel_util.cpp',
|
||||
'cxx/builtin_pybind11.cpp',
|
||||
'cxx/export.cpp'
|
||||
],
|
||||
libraries=libs,
|
||||
language='c++',
|
||||
@@ -92,7 +93,8 @@ setup(
|
||||
'opm.io.parser',
|
||||
'opm.io.schedule',
|
||||
'opm.io.ecl',
|
||||
'opm.tools'
|
||||
'opm.tools',
|
||||
'opm.util'
|
||||
],
|
||||
ext_modules=ext_modules,
|
||||
include_package_data=True,
|
||||
|
||||
BIN
python/tests/data/9_EDITNNC.UNRST
Normal file
BIN
python/tests/data/9_EDITNNC.UNRST
Normal file
Binary file not shown.
184
python/tests/test_emodel.py
Executable file
184
python/tests/test_emodel.py
Executable file
@@ -0,0 +1,184 @@
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
from opm.util import EModel
|
||||
try:
|
||||
from tests.utils import test_path
|
||||
except ImportError:
|
||||
from utils import test_path
|
||||
|
||||
|
||||
class TestEModel(unittest.TestCase):
|
||||
|
||||
def test_open_model(self):
|
||||
|
||||
refArrList = ["PORV", "CELLVOL", "DEPTH", "DX", "DY", "DZ", "PORO", "PERMX", "PERMY", "PERMZ", "NTG", "TRANX",
|
||||
"TRANY", "TRANZ", "ACTNUM", "ENDNUM", "EQLNUM", "FIPNUM", "FLUXNUM", "IMBNUM", "PVTNUM",
|
||||
"SATNUM", "SWL", "SWCR", "SGL", "SGU", "ISWL", "ISWCR", "ISGL", "ISGU", "PPCW", "PRESSURE",
|
||||
"RS", "RV", "SGAS", "SWAT", "SOMAX", "SGMAX"]
|
||||
|
||||
|
||||
self.assertRaises(RuntimeError, EModel, "/file/that/does_not_exists")
|
||||
|
||||
self.assertRaises(ValueError, EModel, test_path("data/9_EDITNNC.EGRID"))
|
||||
self.assertRaises(ValueError, EModel, test_path("data/9_EDITNNC.UNRST"))
|
||||
|
||||
mod1 = EModel(test_path("data/9_EDITNNC.INIT"))
|
||||
|
||||
arrayList = mod1.get_list_of_arrays()
|
||||
|
||||
for n, element in enumerate(arrayList):
|
||||
self.assertEqual(element[0], refArrList[n])
|
||||
|
||||
celvol1 = mod1.get("CELLVOL")
|
||||
self.assertEqual(len(celvol1), 2794)
|
||||
|
||||
|
||||
def test_add_filter(self):
|
||||
|
||||
mod1 = EModel(test_path("data/9_EDITNNC.INIT"))
|
||||
|
||||
celvol1 = mod1.get("CELLVOL")
|
||||
depth1 = mod1.get("DEPTH")
|
||||
|
||||
self.assertTrue(isinstance(celvol1, np.ndarray))
|
||||
self.assertEqual(celvol1.dtype, "float32")
|
||||
|
||||
refVol1 = 2.79083e8
|
||||
|
||||
self.assertTrue( abs((sum(celvol1) - refVol1)/refVol1) < 1.0e-5)
|
||||
|
||||
mod1.add_filter("EQLNUM","eq", 1);
|
||||
mod1.add_filter("DEPTH","lt", 2645.21);
|
||||
|
||||
refVol2 = 1.08876e8
|
||||
refPorvVol2 = 2.29061e7
|
||||
|
||||
porv2 = mod1.get("PORV")
|
||||
celvol2 = mod1.get("CELLVOL")
|
||||
|
||||
self.assertTrue( abs((sum(celvol2) - refVol2)/refVol2) < 1.0e-5)
|
||||
self.assertTrue( abs((sum(porv2) - refPorvVol2)/refPorvVol2) < 1.0e-5)
|
||||
|
||||
mod1.reset_filter()
|
||||
mod1.add_filter("EQLNUM","eq", 2);
|
||||
mod1.add_filter("DEPTH","in", 2584.20, 2685.21);
|
||||
|
||||
refPorvVol3 = 3.34803e7
|
||||
porv3 = mod1.get("PORV")
|
||||
|
||||
self.assertTrue( abs((sum(porv3) - refPorvVol3)/refPorvVol3) < 1.0e-5)
|
||||
|
||||
mod1.reset_filter()
|
||||
mod1.add_filter("I","lt", 10);
|
||||
mod1.add_filter("J","between", 3, 15);
|
||||
mod1.add_filter("K","between", 2, 9);
|
||||
|
||||
poro = mod1.get("PORO")
|
||||
|
||||
self.assertEqual(len(poro), 495)
|
||||
|
||||
|
||||
def test_paramers(self):
|
||||
|
||||
mod1 = EModel(test_path("data/9_EDITNNC.INIT"))
|
||||
|
||||
self.assertFalse("XXX" in mod1)
|
||||
self.assertTrue("PORV" in mod1)
|
||||
self.assertTrue("PRESSURE" in mod1)
|
||||
self.assertTrue("RS" in mod1)
|
||||
self.assertTrue("RV" in mod1)
|
||||
|
||||
self.assertEqual(mod1.active_report_step(), 0)
|
||||
|
||||
|
||||
rsteps = mod1.get_report_steps()
|
||||
self.assertEqual(rsteps, [0, 4, 7, 10, 15, 20, 27, 32, 36, 39])
|
||||
|
||||
mod1.set_report_step(7)
|
||||
|
||||
# parameter RS and RV is missing in report step number 7
|
||||
|
||||
self.assertFalse("RS" in mod1)
|
||||
self.assertFalse("RV" in mod1)
|
||||
|
||||
mod1.set_report_step(15)
|
||||
|
||||
self.assertTrue("RS" in mod1)
|
||||
self.assertTrue("RV" in mod1)
|
||||
|
||||
arrayList = mod1.get_list_of_arrays()
|
||||
|
||||
|
||||
def test_rsteps_steps(self):
|
||||
|
||||
pres_ref_4_1_10 = [272.608, 244.461, 228.503, 214.118, 201.147, 194.563, 178.02, 181.839, 163.465, 148.677]
|
||||
|
||||
mod1 = EModel(test_path("data/9_EDITNNC.INIT"))
|
||||
|
||||
mod1.add_filter("I","eq", 4);
|
||||
mod1.add_filter("J","eq", 1);
|
||||
mod1.add_filter("K","eq", 10);
|
||||
|
||||
self.assertTrue(mod1.has_report_step(4))
|
||||
self.assertFalse(mod1.has_report_step(2))
|
||||
|
||||
rsteps = mod1.get_report_steps()
|
||||
|
||||
for n, step in enumerate(rsteps):
|
||||
mod1.set_report_step(step)
|
||||
pres = mod1.get("PRESSURE")
|
||||
|
||||
self.assertTrue(abs(pres[0] - pres_ref_4_1_10[n])/pres_ref_4_1_10[n] < 1.0e-5)
|
||||
|
||||
|
||||
def test_grid_props(self):
|
||||
|
||||
mod1 = EModel(test_path("data/9_EDITNNC.INIT"))
|
||||
nI,nJ,nK = mod1.grid_dims()
|
||||
|
||||
self.assertEqual((nI,nJ,nK), (13, 22, 11))
|
||||
|
||||
nAct = mod1.active_cells()
|
||||
self.assertEqual(nAct, 2794)
|
||||
|
||||
|
||||
def test_hc_filter(self):
|
||||
|
||||
nAct_hc_eqln1 = 1090
|
||||
nAct_hc_eqln2 = 1694
|
||||
|
||||
mod1 = EModel(test_path("data/9_EDITNNC.INIT"))
|
||||
|
||||
porv = mod1.get("PORV")
|
||||
|
||||
mod1.set_depth_fwl([2645.21, 2685.21])
|
||||
|
||||
mod1.add_hc_filter()
|
||||
|
||||
porv = mod1.get("PORV")
|
||||
self.assertEqual(len(porv), nAct_hc_eqln1 + nAct_hc_eqln2)
|
||||
|
||||
mod1.reset_filter()
|
||||
mod1.add_filter("EQLNUM","eq", 1);
|
||||
mod1.add_filter("DEPTH","lt", 2645.21);
|
||||
|
||||
porv1 = mod1.get("PORV")
|
||||
self.assertEqual(len(porv1), nAct_hc_eqln1)
|
||||
|
||||
mod1.reset_filter()
|
||||
mod1.add_filter("EQLNUM","eq", 2);
|
||||
mod1.add_filter("DEPTH","lt", 2685.21);
|
||||
|
||||
porv2 = mod1.get("PORV")
|
||||
self.assertEqual(len(porv2), nAct_hc_eqln2)
|
||||
|
||||
ivect = mod1.get("I")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user