Merge pull request #29 from pgdr/table_lookup

Table lookup
This commit is contained in:
Pål Grønås Drange
2017-02-17 18:05:17 +01:00
committed by GitHub
6 changed files with 136 additions and 5 deletions

13
examples/norne.py Normal file → Executable file
View File

@@ -1,3 +1,5 @@
#!/usr/bin/env python
import sys
from os.path import isdir, join
import sunbeam
@@ -24,6 +26,16 @@ def parse(fname):
print('Parsing took %s sec' % (e - s).seconds)
return es
def swof_krw(ecl):
assert('SWOF' in ecl.table)
krw = ecl.table['SWOF', 'KRW']
krow = ecl.table['SWOF', 'KROW']
pcow = ecl.table['SWOF', 'PCOW']
print('SWOF\tKRW\tKROW\tPCOW')
for i in range(21):
print('%.2f\t%.4f\t%.4f\t%.4f' % (i/20.0, krw(i/20.0), krow(i/20.0), pcow(i/20.0)))
def main():
es = parse(join(opmdatadir(), 'norne/NORNE_ATW2013.DATA'))
sc = es.schedule
@@ -41,6 +53,7 @@ def main():
print('pos: %s' % list(wp.pos()))
print('fault: %s' % f0)
print(' comprised of %d cells' % len(fl))
swof_krw(es)
if __name__ == '__main__':
global OPMDATA_DIR

68
examples/swofplt.py Executable file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python
import sys
from os.path import isdir, join
import sunbeam
from datetime import datetime as dt
import numpy as np
import matplotlib.pyplot as plt
def plotswof(ecl):
assert('SWOF' in ecl.table)
krw = ecl.table['SWOF', 'KRW']
krow = ecl.table['SWOF', 'KROW']
pcow = ecl.table['SWOF', 'PCOW']
swofl = [x/20.0 for x in range(21)]
krwl = [krw(x/20.0) for x in range(21)]
krowl = [krow(x/20.0) for x in range(21)]
pcowl = [pcow(x/20.0) for x in range(21)]
plt.figure(1)
plt.plot(swofl, krwl, label = 'KRW')
plt.plot(swofl, krowl, label = 'KROW')
plt.legend()
plt.show()
plt.figure(2)
plt.plot(swofl, pcowl, label = 'Water-oil capillary pressure')
plt.legend()
plt.show()
def opmdatadir():
global OPMDATA_DIR
if isdir(OPMDATA_DIR):
return OPMDATA_DIR
if len(sys.argv) < 2:
return None
d = sys.argv[1]
if isdir(d) and isdir(join(d, 'norne')):
return d
return None
def haveopmdata():
return opmdatadir() is not None
def parse(fname):
s = dt.now()
es = sunbeam.parse(fname, ('PARSE_RANDOM_SLASH', sunbeam.action.ignore))
e = dt.now()
print('Parsing took %s sec' % (e - s).seconds)
return es
def main():
es = parse(join(opmdatadir(), 'norne/NORNE_ATW2013.DATA'))
plotswof(es)
if __name__ == '__main__':
global OPMDATA_DIR
OPMDATA_DIR = '../../opm-data'
if haveopmdata():
print('Found norne, parsing ...')
main()
else:
print('Need to have path "%s" or give opm-data as argument' % OPMDATA_DIR)

View File

@@ -22,6 +22,10 @@ class EclipseState(object):
def cfg(self):
return EclipseConfig(self._cfg())
@property
def table(self):
return Tables(self._tables())
def faults(self):
"""Returns a map from fault names to list of (i,j,k,D) where D ~ 'X+'"""
fs = {}
@@ -43,6 +47,29 @@ class Tables(object):
def __repr__(self):
return 'Tables()'
def _eval(self, x, table, col_name, tab_idx = 0):
return self._evaluate(table, tab_idx, col_name, x)
def __getitem__(self, tab_name):
col_name = None
if isinstance(tab_name, tuple):
tab_name, col_name = tab_name
tab_name = tab_name.upper()
if not tab_name in self:
raise ValueError('Table "%s" not in deck.' % tab_name)
if col_name is None:
def t_eval(col_name, x, tab_idx = 0):
return self._eval(x, tab_name, col_name.upper(), tab_idx)
return t_eval
col_name = col_name.upper()
def t_eval(x, tab_idx = 0):
return self._eval(x, tab_name, col_name, tab_idx)
return t_eval
@delegate(lib.EclipseGrid)
class EclipseGrid(object):

View File

@@ -230,6 +230,17 @@ py::list get_groups( const Schedule& sch ) {
}
namespace tables {
double evaluate( const TableManager& tab,
std::string tab_name,
int tab_idx,
std::string col_name, double x ) try {
return tab[tab_name].getTable(tab_idx).evaluate(col_name, x);
} catch( std::invalid_argument& e ) {
throw key_error( e.what() );
}
}
EclipseState (*parse)( const std::string&, const ParseContext& ) = &Parser::parse;
EclipseState (*parseData) (const std::string &data, const ParseContext& context) = &Parser::parseData;
void (ParseContext::*ctx_update)(const std::string&, InputError::Action) = &ParseContext::update;
@@ -262,7 +273,7 @@ py::class_< EclipseState >( "EclipseState", py::no_init )
.def( "_props", &EclipseState::get3DProperties, ref() )
.def( "_grid", &EclipseState::getInputGrid, ref() )
.def( "_cfg", &EclipseState::cfg, ref() )
.def( "tables", &EclipseState::getTableManager, ref() )
.def( "_tables", &EclipseState::getTableManager, ref() )
.def( "has_input_nnc", &EclipseState::hasInputNNC )
.def( "input_nnc", state::getNNC )
.def( "faultNames", state::faultNames )
@@ -286,6 +297,7 @@ py::class_< Eclipse3DProperties >( "Eclipse3DProperties", py::no_init )
py::class_< TableManager >( "Tables", py::no_init )
.def( "__contains__", &TableManager::hasTables )
.def("_evaluate", tables::evaluate )
;
/*

View File

@@ -21,7 +21,7 @@ class TestProps(unittest.TestCase):
p = self.props
self.assertTrue('PORO' in p)
self.assertFalse('NONO' in p)
self.assertFalse('PORV' in p)
self.assertTrue('PORV' in p) # auto generated
def test_getitem(self):
p = self.props
@@ -36,7 +36,7 @@ class TestProps(unittest.TestCase):
def test_regions(self):
p = self.props
reg = p.getRegions('SATNUM')
self.assertEqual(0, len(reg))
self.assertEqual(1, len(reg)) # auto generated
def test_permx_values(self):
def md2si(md):

View File

@@ -99,15 +99,26 @@ SATNUM
self.assertTrue(sim.hasVAPOIL())
def test_tables(self):
tables = self.spe3.tables()
tables = self.spe3.table
self.assertTrue('SGOF' in tables)
self.assertTrue('SWOF' in tables)
self.assertFalse('SOF' in tables)
ct = self.cp_state.tables()
ct = self.cp_state.table
self.assertFalse('SGOF' in ct)
self.assertTrue('SWOF' in ct)
tab = 'SWOF'
col = 'KRW'
self.assertAlmostEqual(0.1345, self.spe3.table[tab](col, 0.5))
self.assertAlmostEqual(0.39, self.spe3.table[tab](col, 0.72))
self.assertAlmostEqual(0.1345, self.spe3.table[tab, col](0.5))
self.assertAlmostEqual(0.39, self.spe3.table[tab, col](0.72))
with self.assertRaises(KeyError):
self.spe3.table[tab, 'NO'](1)
def test_faults(self):
self.assertEquals([], self.spe3.faultNames())