added some config classes, refactored out files

This commit is contained in:
Pål Grønås Drange
2017-01-13 12:52:50 +01:00
parent afb28c00c2
commit 39fa96b02f
8 changed files with 256 additions and 149 deletions

View File

@@ -6,6 +6,9 @@ target_link_libraries( sunbeam ${Boost_LIBRARIES} ${opm-parser_LIBRARIES} )
set(PYTHON_SOURCES
__init__.py
sunbeam.py)
sunbeam.py
config.py
properties.py
schedule.py)
add_python_package(sunbeam sunbeam "${PYTHON_SOURCES}")

View File

@@ -1,6 +1,7 @@
from .sunbeam import parse
from .sunbeam import Well
from .schedule import Well
from .libsunbeam import action
from .properties import parse
from .config import EclipseConfig
__version__ = '0.0.1'
__license__ = 'GNU General Public License version 3'

13
python/sunbeam/config.py Normal file
View File

@@ -0,0 +1,13 @@
from os.path import isfile
import libsunbeam as lib
from .sunbeam import delegate
@delegate(lib.SummaryConfig)
class SummaryConfig(object):
def __repr__(self):
return 'SummaryConfig()'
@delegate(lib.EclipseConfig)
class EclipseConfig(object):
def __repr__(self):
return 'EclipseConfig()'

View File

@@ -0,0 +1,77 @@
from os.path import isfile
import libsunbeam as lib
from .sunbeam import delegate
from .schedule import Schedule
from .config import EclipseConfig
@delegate(lib.EclipseState)
class EclipseState(object):
def __repr__(self):
return 'EclipseState(title = "%s")' % self.title
@property
def schedule(self):
return Schedule(self._schedule())
def props(self):
return Eclipse3DProperties(self._props())
def grid(self):
return EclipseGrid(self._grid())
def cfg(self):
return EclipseConfig(self._cfg())
@delegate(lib.Eclipse3DProperties)
class Eclipse3DProperties(object):
def __repr__(self):
return 'Eclipse3DProperties()'
@delegate(lib.EclipseGrid)
class EclipseGrid(object):
def getNX(self):
return self._getXYZ()[0]
def getNY(self):
return self._getXYZ()[1]
def getNZ(self):
return self._getXYZ()[2]
def __repr__(self):
x,y,z = self._getXYZ()
g = self.cartesianSize()
na = self.nactive()
cnt = '(%d, %d, %d)' % (x,y,z)
if na != g:
cnt += ', active = %s' % na
return 'EclipseGrid(%s)' % cnt
def _parse_context(actions):
ctx = lib.ParseContext()
if actions is None:
return ctx
# this might be a single tuple, in which case we unpack it and repack it
# into a list. If it's not a tuple we assume it's an iterable and just
# carry on
try:
key, action = actions
except ValueError:
pass
else:
actions = [(key, action)]
for key, action in actions:
ctx.update(key, action)
return ctx
def parse(deck, actions = None):
"""deck may be a deck string, or a file path"""
if isfile(deck):
return EclipseState(lib.parse(deck, _parse_context(actions)))
return EclipseState(lib.parseData(deck, _parse_context(actions)))

View File

@@ -0,0 +1,79 @@
import libsunbeam as lib
from .sunbeam import delegate
@delegate(lib.Schedule)
class Schedule(object):
def __repr__(self):
lt = len(self.timesteps)
lw = len(self.wells)
return 'Schedule(timesteps: %d, wells: %d)' % (lt, lw)
@property
def wells(self):
return map(Well, self._wells)
def group(self, name):
return Group(self._group(name), self)
@property
def groups(self):
def mk(x): return Group(x, self)
def not_field(x): return x.name != 'FIELD'
return map(mk, filter(not_field, self._groups))
@delegate(lib.Well)
class Well(object):
def pos(self, timestep = None):
if timestep is None:
return self.I(), self.J(), self.ref()
return self.I(timestep), self.J(timestep), self.ref(timestep)
def __repr__(self):
return 'Well(name = "%s")' % self.name
@staticmethod
def defined(timestep):
def fn(well): return well.isdefined(timestep)
return fn
@staticmethod
def injector(timestep):
def fn(well): return well.isinjector(timestep)
return fn
@staticmethod
def producer(timestep):
def fn(well): return well.isproducer(timestep)
return fn
# using the names flowing and closed for functions that test if a well is
# opened or closed at some point, because we might want to use the more
# imperative words 'open' and 'close' (or 'shut') for *changing* the status
# later
@staticmethod
def flowing(timestep):
def fn(well): return well.status(timestep) == 'OPEN'
return fn
@staticmethod
def closed(timestep):
def fn(well): return well.status(timestep) == 'SHUT'
return fn
@staticmethod
def auto(timestep):
def fn(well): return well.status(timestep) == 'AUTO'
return fn
@delegate(lib.Group)
class Group(object):
def __init__(self, _, schedule):
self._schedule = schedule
def wells(self, timestep):
names = self._wellnames(timestep)
wells = { well.name: well for well in self._schedule.wells }
return map(wells.__getitem__, filter(wells.__contains__, names))

View File

@@ -2,6 +2,11 @@
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseConfig.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
@@ -23,6 +28,9 @@ py::list getNNC( const EclipseState& state ) {
}
}
namespace cfg {
}
namespace grid {
py::tuple getXYZ( const EclipseGrid& grid ) {
return py::make_tuple( grid.getNX(),
@@ -172,11 +180,16 @@ py::register_exception_translator< key_error >( &key_error::translate );
py::def( "parse", parse );
py::def( "parseData", parseData );
/*
* state, grid, properties
*/
py::class_< EclipseState >( "EclipseState", py::no_init )
.add_property( "title", &EclipseState::getTitle )
.def( "_schedule", &EclipseState::getSchedule, ref() )
.def( "_props", &EclipseState::get3DProperties, ref() )
.def( "_grid", &EclipseState::getInputGrid, ref() )
.def( "_cfg", &EclipseState::cfg, ref() )
.def( "has_input_nnc", &EclipseState::hasInputNNC )
.def( "input_nnc", state::getNNC )
;
@@ -195,6 +208,45 @@ py::class_< Eclipse3DProperties >( "Eclipse3DProperties", py::no_init )
.def( "__getitem__", props::getitem )
;
/*
* config
*/
py::class_< EclipseConfig >( "EclipseConfig", py::no_init )
.def( "summary", &EclipseConfig::summary, ref())
.def( "init", &EclipseConfig::init, ref())
.def( "restart", &EclipseConfig::restart, ref())
.def( "simulation", &EclipseConfig::simulation, ref())
;
py::class_< SummaryConfig >( "SummaryConfig", py::no_init )
.def( "__contains__", &SummaryConfig::hasKeyword )
;
py::class_< InitConfig >( "InitConfig", py::no_init )
.def( "hasEquil", &InitConfig::hasEquil )
.def( "restartRequested", &InitConfig::restartRequested )
.def( "getRestartStep" , &InitConfig::getRestartStep )
;
py::class_< RestartConfig >( "RestartConfig", py::no_init )
.def( "getKeyword", &RestartConfig::getKeyword )
.def( "getFirstRestartStep", &RestartConfig::getFirstRestartStep )
.def( "getWriteRestartFile", &RestartConfig::getWriteRestartFile )
;
py::class_< SimulationConfig >( "SimulationConfig", py::no_init )
.def("hasThresholdPressure", &SimulationConfig::hasThresholdPressure )
.def("useCPR", &SimulationConfig::useCPR )
.def("hasDISGAS", &SimulationConfig::hasDISGAS )
.def("hasVAPOIL", &SimulationConfig::hasVAPOIL )
;
/*
* schedule, well, completion, group
*/
py::class_< Well >( "Well", py::no_init )
.add_property( "name", mkcopy( &Well::name ) )
.add_property( "preferred_phase", &well::preferred_phase )
@@ -242,6 +294,11 @@ py::class_< Schedule >( "Schedule", py::no_init )
.def( "_group", &Schedule::getGroup, ref() )
;
/*
* misc
*/
py::class_< ParseContext >( "ParseContext" )
.def( "update", ctx_update )
;

View File

@@ -1,4 +1,3 @@
from os.path import isfile
import libsunbeam as lib
class _delegate(object):
@@ -40,148 +39,3 @@ def delegate(delegate_cls, to = '_sun'):
return cls
return inner
@delegate(lib.Schedule)
class Schedule(object):
def __repr__(self):
lt = len(self.timesteps)
lw = len(self.wells)
return 'Schedule(timesteps: %d, wells: %d)' % (lt, lw)
@property
def wells(self):
return map(Well, self._wells)
def group(self, name):
return Group(self._group(name), self)
@property
def groups(self):
def mk(x): return Group(x, self)
def not_field(x): return x.name != 'FIELD'
return map(mk, filter(not_field, self._groups))
@delegate(lib.Eclipse3DProperties)
class Eclipse3DProperties(object):
def __repr__(self):
return 'Eclipse3DProperties()'
@delegate(lib.EclipseGrid)
class EclipseGrid(object):
def getNX(self):
return self._getXYZ()[0]
def getNY(self):
return self._getXYZ()[1]
def getNZ(self):
return self._getXYZ()[2]
def __repr__(self):
x,y,z = self._getXYZ()
g = self.cartesianSize()
na = self.nactive()
cnt = '(%d, %d, %d)' % (x,y,z)
if na != g:
cnt += ', active = %s' % na
return 'EclipseGrid(%s)' % cnt
@delegate(lib.EclipseState)
class EclipseState(object):
def __repr__(self):
return 'EclipseState(title = "%s")' % self.title
@property
def schedule(self):
return Schedule(self._schedule())
def props(self):
return Eclipse3DProperties(self._props())
def grid(self):
return EclipseGrid(self._grid())
@delegate(lib.Well)
class Well(object):
def pos(self, timestep = None):
if timestep is None:
return self.I(), self.J(), self.ref()
return self.I(timestep), self.J(timestep), self.ref(timestep)
def __repr__(self):
return 'Well(name = "%s")' % self.name
@staticmethod
def defined(timestep):
def fn(well): return well.isdefined(timestep)
return fn
@staticmethod
def injector(timestep):
def fn(well): return well.isinjector(timestep)
return fn
@staticmethod
def producer(timestep):
def fn(well): return well.isproducer(timestep)
return fn
# using the names flowing and closed for functions that test if a well is
# opened or closed at some point, because we might want to use the more
# imperative words 'open' and 'close' (or 'shut') for *changing* the status
# later
@staticmethod
def flowing(timestep):
def fn(well): return well.status(timestep) == 'OPEN'
return fn
@staticmethod
def closed(timestep):
def fn(well): return well.status(timestep) == 'SHUT'
return fn
@staticmethod
def auto(timestep):
def fn(well): return well.status(timestep) == 'AUTO'
return fn
@delegate(lib.Group)
class Group(object):
def __init__(self, _, schedule):
self._schedule = schedule
def wells(self, timestep):
names = self._wellnames(timestep)
wells = { well.name: well for well in self._schedule.wells }
return map(wells.__getitem__, filter(wells.__contains__, names))
def _parse_context(actions):
ctx = lib.ParseContext()
if actions is None:
return ctx
# this might be a single tuple, in which case we unpack it and repack it
# into a list. If it's not a tuple we assume it's an iterable and just
# carry on
try:
key, action = actions
except ValueError:
pass
else:
actions = [(key, action)]
for key, action in actions:
ctx.update(key, action)
return ctx
def parse(deck, actions = None):
"""deck may be a deck string, or a file path"""
if isfile(deck):
return EclipseState(lib.parse(deck, _parse_context(actions)))
return EclipseState(lib.parseData(deck, _parse_context(actions)))