Python: added class FieldProperties.
test_props.py: added check for 3d_properties/field_props extraction. cxx/eclipse_state.cpp: adding function field_props. added python class FieldProperties. python FieldProps: added __contains__. python FieldProps: added __getitem__. python field_props: images all 3dprops tests.
This commit is contained in:
@@ -190,6 +190,7 @@ if(ENABLE_ECL_INPUT)
|
||||
python/cxx/deck_keyword.cpp
|
||||
python/cxx/eclipse_io.cpp
|
||||
python/cxx/eclipse_3d_properties.cpp
|
||||
python/cxx/field_props.cpp
|
||||
python/cxx/eclipse_config.cpp
|
||||
python/cxx/eclipse_grid.cpp
|
||||
python/cxx/eclipse_state.cpp
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
bool enable3DPropsTesting();
|
||||
|
||||
template< typename > class GridProperty;
|
||||
template< typename > class GridProperties;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define FIELDPROPS_MANAGER_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
|
||||
@@ -85,14 +85,24 @@ namespace {
|
||||
return l;
|
||||
}
|
||||
|
||||
const FieldPropsManager& get_field_props(const EclipseState& state) {
|
||||
if (enable3DPropsTesting())
|
||||
return state.fieldProps();
|
||||
else
|
||||
throw std::logic_error("Field properties not implemented for this compilation.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void python::common::export_EclipseState(py::module& module) {
|
||||
|
||||
module.def("test_field_props", &enable3DPropsTesting);
|
||||
|
||||
py::class_< EclipseState >( module, "EclipseState" )
|
||||
.def(py::init<const Deck&>())
|
||||
.def_property_readonly( "title", &EclipseState::getTitle )
|
||||
.def( "props", &EclipseState::get3DProperties, ref_internal)
|
||||
.def( "ecl3d_props", &EclipseState::get3DProperties, ref_internal)
|
||||
.def( "field_props", &get_field_props, ref_internal)
|
||||
.def( "grid", &EclipseState::getInputGrid, ref_internal)
|
||||
.def( "config", &EclipseState::cfg, ref_internal)
|
||||
.def( "tables", &EclipseState::getTableManager, ref_internal)
|
||||
|
||||
@@ -13,6 +13,7 @@ void python::common::export_all(py::module& module) {
|
||||
export_Connection(module);
|
||||
export_EclipseConfig(module);
|
||||
export_Eclipse3DProperties(module);
|
||||
export_FieldProperties(module);
|
||||
export_EclipseState(module);
|
||||
export_TableManager(module);
|
||||
export_EclipseGrid(module);
|
||||
|
||||
@@ -19,6 +19,7 @@ void export_Connection(py::module& module);
|
||||
void export_Deck(py::module& module);
|
||||
void export_DeckKeyword(py::module& module);
|
||||
void export_Eclipse3DProperties(py::module& module);
|
||||
void export_FieldProperties(py::module& module);
|
||||
void export_EclipseConfig(py::module& module);
|
||||
void export_EclipseGrid(py::module& module);
|
||||
void export_EclipseState(py::module& module);
|
||||
|
||||
39
python/cxx/field_props.cpp
Normal file
39
python/cxx/field_props.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
#include "export.hpp"
|
||||
#include "converters.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
py::list getitem( const FieldPropsManager& m, const std::string& kw) {
|
||||
if (m.has<int>(kw))
|
||||
return iterable_to_pylist( m.get<int>(kw) );
|
||||
if (m.has<double>(kw))
|
||||
return iterable_to_pylist( m.get<double>(kw) );
|
||||
|
||||
throw py::key_error( "no such grid property " + kw );
|
||||
}
|
||||
|
||||
bool contains( const FieldPropsManager& manager, const std::string& kw) {
|
||||
if (manager.has<int>(kw))
|
||||
return true;
|
||||
if (manager.has<double>(kw))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void python::common::export_FieldProperties(py::module& module) {
|
||||
|
||||
py::class_< FieldPropsManager >( module, "FieldProperties")
|
||||
.def( "__contains__", &contains )
|
||||
.def( "__getitem__", &getitem )
|
||||
;
|
||||
|
||||
}
|
||||
@@ -15,6 +15,8 @@ from .libopmcommon_python import Parser, ParseContext
|
||||
from .libopmcommon_python import DeckKeyword
|
||||
|
||||
from .libopmcommon_python import EclipseState
|
||||
from .libopmcommon_python import test_field_props
|
||||
from .libopmcommon_python import FieldProperties
|
||||
from .libopmcommon_python import Schedule
|
||||
from .libopmcommon_python import OpmLog
|
||||
from .libopmcommon_python import SummaryConfig
|
||||
|
||||
@@ -1 +1 @@
|
||||
from opm._common import EclipseState
|
||||
from opm._common import EclipseState, test_field_props
|
||||
|
||||
@@ -41,6 +41,7 @@ ext_modules = [
|
||||
'cxx/deck_keyword.cpp',
|
||||
'cxx/eclipse_io.cpp',
|
||||
'cxx/eclipse_3d_properties.cpp',
|
||||
'cxx/field_props.cpp',
|
||||
'cxx/eclipse_config.cpp',
|
||||
'cxx/eclipse_grid.cpp',
|
||||
'cxx/eclipse_state.cpp',
|
||||
|
||||
73
python/tests/test_field_props.py
Normal file
73
python/tests/test_field_props.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import unittest
|
||||
import opm.io
|
||||
|
||||
from opm.io.parser import Parser
|
||||
from opm.io.ecl_state import EclipseState, test_field_props
|
||||
try:
|
||||
from tests.utils import test_path
|
||||
except ImportError:
|
||||
from utils import test_path
|
||||
|
||||
|
||||
if (test_field_props()):
|
||||
|
||||
class TestFieldProps(unittest.TestCase):
|
||||
|
||||
def assertClose(self, expected, observed, epsilon=1e-08):
|
||||
diff = abs(expected - observed)
|
||||
err_msg = '|%g - %g| = %g > %g' % (expected, observed, diff, epsilon)
|
||||
self.assertTrue(diff <= epsilon, msg=err_msg)
|
||||
|
||||
def setUp(self):
|
||||
parser = Parser()
|
||||
deck = parser.parse(test_path('spe3/SPE3CASE1.DATA'))
|
||||
self.spe3 = EclipseState(deck)
|
||||
self.props = self.spe3.field_props()
|
||||
|
||||
def test_contains(self):
|
||||
p = self.props
|
||||
self.assertTrue('PORO' in p)
|
||||
self.assertFalse('NONO' in p)
|
||||
self.assertTrue('PORV' in p)
|
||||
|
||||
def test_getitem(self):
|
||||
p = self.props
|
||||
poro = p['PORO']
|
||||
self.assertEqual(324, len(poro))
|
||||
self.assertEqual(0.13, poro[0])
|
||||
self.assertTrue( 'PERMX' in p )
|
||||
px = p['PERMX']
|
||||
print(len(px))
|
||||
self.assertEqual(324, len(px))
|
||||
|
||||
def test_permx_values(self):
|
||||
def md2si(md):
|
||||
#millidarcy->SI
|
||||
return md * 1e-3 * 9.869233e-13
|
||||
field_props = self.props
|
||||
|
||||
grid = self.spe3.grid()
|
||||
permx = field_props['PERMX']
|
||||
print('set(PERMX) = %s' % set(permx))
|
||||
# 130mD, 40mD, 20mD, and 150mD, respectively, top to bottom
|
||||
darcys = {0:md2si(130), 1:md2si(40), 2:md2si(20), 3:md2si(150)}
|
||||
for i in range(grid.nx):
|
||||
for j in range(grid.ny):
|
||||
for k in range(grid.nz):
|
||||
g_idx = grid.globalIndex(i,j,k)
|
||||
perm = permx[g_idx]
|
||||
darcy = darcys[k]
|
||||
self.assertClose(darcy, perm)
|
||||
|
||||
def test_volume(self):
|
||||
grid = self.spe3.grid()
|
||||
for i in range(grid.nx):
|
||||
for j in range(grid.ny):
|
||||
for k in range(grid.nz):
|
||||
g_idx = grid.globalIndex(i,j,k)
|
||||
exp = 293.3 * 293.3 * 30 # cubicfeet = 73 078.6084 cubic meter
|
||||
exp *= (12*0.0254)**3 # cubic feet to cubic meter
|
||||
if k == 0:
|
||||
self.assertClose(exp, grid.getCellVolume(g_idx))
|
||||
self.assertEqual(grid.getCellVolume(g_idx), grid.getCellVolume(i, j, k))
|
||||
|
||||
@@ -2,7 +2,7 @@ import unittest
|
||||
import opm.io
|
||||
|
||||
from opm.io.parser import Parser
|
||||
from opm.io.ecl_state import EclipseState
|
||||
from opm.io.ecl_state import EclipseState, test_field_props
|
||||
try:
|
||||
from tests.utils import test_path
|
||||
except ImportError:
|
||||
@@ -20,7 +20,10 @@ class TestProps(unittest.TestCase):
|
||||
parser = Parser()
|
||||
deck = parser.parse(test_path('spe3/SPE3CASE1.DATA'))
|
||||
self.spe3 = EclipseState(deck)
|
||||
self.props = self.spe3.props()
|
||||
self.props = self.spe3.ecl3d_props()
|
||||
if (not test_field_props()):
|
||||
with self.assertRaises(RuntimeError):
|
||||
self.field = self.spe3.field_props()
|
||||
|
||||
def test_contains(self):
|
||||
p = self.props
|
||||
@@ -58,7 +61,6 @@ class TestProps(unittest.TestCase):
|
||||
self.assertClose(darcy, perm)
|
||||
|
||||
def test_volume(self):
|
||||
e3dp = self.props
|
||||
grid = self.spe3.grid()
|
||||
for i in range(grid.nx):
|
||||
for j in range(grid.ny):
|
||||
|
||||
@@ -48,6 +48,19 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
/*
|
||||
This Function is used in Python to check if the
|
||||
ENABBLE_3DPROPS_TESTING macro has been set.
|
||||
*/
|
||||
#ifdef ENABLE_3DPROPS_TESTING
|
||||
bool enable3DPropsTesting() {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
bool enable3DPropsTesting() {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user