mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Python: create PyDoc type docs, fix some inconsistencies in code and update rips module version
This commit is contained in:
parent
8f6858932b
commit
fe268cd25f
@ -10,22 +10,33 @@ import App_pb2
|
||||
import App_pb2_grpc
|
||||
|
||||
class App:
|
||||
"""ResInsight application information and control.
|
||||
Allows retrieving of information and controlling the running instance
|
||||
Not meant to be constructed manually, but exists as part of the Instance method
|
||||
"""
|
||||
def __init__(self, channel):
|
||||
self.app = App_pb2_grpc.AppStub(channel)
|
||||
def versionMessage(self):
|
||||
def __versionMessage(self):
|
||||
return self.app.GetVersion(Empty())
|
||||
def majorVersion(self):
|
||||
return self.versionMessage().major_version
|
||||
"""Get an integer with the major version number"""
|
||||
return self.__versionMessage().major_version
|
||||
def minorVersion(self):
|
||||
return self.versionMessage().minor_version
|
||||
"""Get an integer with the minor version number"""
|
||||
return self.__versionMessage().minor_version
|
||||
def patchVersion(self):
|
||||
return self.versionMessage().patch_version
|
||||
"""Get an integer with the patch version number"""
|
||||
return self.__versionMessage().patch_version
|
||||
def versionString(self):
|
||||
"""Get a full version string, i.e. 2019.04.01"""
|
||||
return str(self.majorVersion()) + "." + str(self.minorVersion()) + "." + str(self.patchVersion())
|
||||
def exit(self):
|
||||
"""Tell ResInsight instance to quit"""
|
||||
print("Telling ResInsight to Exit")
|
||||
return self.app.Exit(Empty())
|
||||
def isConsole(self):
|
||||
"""Returns true if the connected ResInsight instance is a console app"""
|
||||
return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('CONSOLE_APPLICATION')
|
||||
def isGui(self):
|
||||
"""Returns true if the connected ResInsight instance is a GUI app"""
|
||||
return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('GUI_APPLICATION')
|
||||
|
@ -10,6 +10,17 @@ import Case_pb2
|
||||
import Case_pb2_grpc
|
||||
|
||||
class Case:
|
||||
"""ResInsight case class
|
||||
|
||||
Operate on a ResInsight case specified by a Case Id integer.
|
||||
Not meant to be constructed separately but created by one of the following
|
||||
methods in Project: loadCase, case, allCases, selectedCases
|
||||
|
||||
Attributes:
|
||||
id(int): Case Id corresponding to case Id in ResInsight project.
|
||||
name(string): Case name
|
||||
groupId(int): Case Group id
|
||||
"""
|
||||
def __init__(self, channel, id):
|
||||
self.channel = channel
|
||||
self.stub = Case_pb2_grpc.CaseStub(channel)
|
||||
@ -21,8 +32,8 @@ class Case:
|
||||
self.properties = Properties(self)
|
||||
self.request = Case_pb2.CaseRequest(id=self.id)
|
||||
|
||||
# Get number of grids in the case
|
||||
def gridCount(self):
|
||||
"""Get number of grids in the case"""
|
||||
try:
|
||||
return self.stub.GetGridCount(self.request).count
|
||||
except grpc.RpcError as e:
|
||||
@ -31,32 +42,57 @@ class Case:
|
||||
print("ERROR: ", e)
|
||||
return 0
|
||||
|
||||
# Get Grid of a given index. Returns a rips Grid object
|
||||
def grid(self, index):
|
||||
"""Get Grid of a given index. Returns a rips Grid object"""
|
||||
return Grid(index, self)
|
||||
|
||||
# Get a list of all rips Grid objects in the case
|
||||
|
||||
def grids(self):
|
||||
"""Get a list of all rips Grid objects in the case"""
|
||||
gridList = []
|
||||
for i in range(0, self.gridCount()):
|
||||
gridList.append(Grid(i, self))
|
||||
return gridList
|
||||
|
||||
def cellCount(self, porosityModel='MATRIX_MODEL'):
|
||||
"""Get a cell count object containing number of active cells and
|
||||
total number of cells
|
||||
|
||||
Arguments:
|
||||
porosityModel(string): String representing an enum.
|
||||
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
Returns:
|
||||
Cell Count object with the following integer attributes:
|
||||
active_cell_count: number of active cells
|
||||
reservoir_cell_count: total number of reservoir cells
|
||||
"""
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Case_pb2.CellInfoRequest(case_request=self.request,
|
||||
porosity_model=porosityModel)
|
||||
return self.stub.GetCellCount(request)
|
||||
|
||||
def cellInfoForActiveCells(self, porosityModel='MATRIX_MODEL'):
|
||||
"""Get Stream of cell info objects for current case
|
||||
Arguments:
|
||||
porosityModel(string): String representing an enum.
|
||||
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
Returns:
|
||||
Stream of cell info objects with the following attributes:
|
||||
grid_index(int): grid the cell belongs to
|
||||
parent_grid_index(int): parent of the grid the cell belongs to
|
||||
coarsening_box_index(int): the coarsening box index
|
||||
local_ijk(Vec3i: i(int), j(int), k(int)): local cell index in i, j, k directions.
|
||||
parent_ijk(Vec3i: i(int), j(int), k(int)): cell index in parent grid in i, j, k.
|
||||
"""
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Case_pb2.CellInfoRequest(case_request=self.request,
|
||||
porosity_model=porosityModel)
|
||||
return self.stub.GetCellInfoForActiveCells(request)
|
||||
|
||||
def timeSteps(self):
|
||||
"""Get a list containing time step strings for all time steps"""
|
||||
return self.stub.GetTimeSteps(self.request).dates
|
||||
|
||||
def daysSinceStart(self):
|
||||
"""Get a list of decimal values representing days since the start of the simulation"""
|
||||
return self.stub.GetDaysSinceStart(self.request).day_decimals
|
||||
|
@ -10,11 +10,20 @@ import Commands_pb2_grpc as CmdRpc
|
||||
from .Case import Case
|
||||
|
||||
class Commands:
|
||||
"""Command executor which can run ResInsight Command File commands nearly verbatim
|
||||
|
||||
Documentation Command File Interface:
|
||||
https://resinsight.org/docs/commandfile/
|
||||
|
||||
The differences are:
|
||||
1. Enum values have to be provided as strings. I.e. "ALL" instead of ALL.
|
||||
2. Booleans have to be specified as correct Python. True instead of true.
|
||||
"""
|
||||
def __init__(self, channel):
|
||||
self.channel = channel
|
||||
self.commands = CmdRpc.CommandsStub(channel)
|
||||
|
||||
def execute(self, **commandParams):
|
||||
def __execute(self, **commandParams):
|
||||
try:
|
||||
return self.commands.Execute(Cmd.CommandParams(**commandParams))
|
||||
except grpc.RpcError as e:
|
||||
@ -28,39 +37,39 @@ class Commands:
|
||||
########################
|
||||
|
||||
def openProject(self, path):
|
||||
return self.execute(openProject=Cmd.FilePathRequest(path=path))
|
||||
return self.__execute(openProject=Cmd.FilePathRequest(path=path))
|
||||
|
||||
def closeProject(self):
|
||||
return self.execute(closeProject=Empty())
|
||||
return self.__execute(closeProject=Empty())
|
||||
|
||||
def setStartDir(self, path):
|
||||
return self.execute(setStartDir=Cmd.FilePathRequest(path=path))
|
||||
return self.__execute(setStartDir=Cmd.FilePathRequest(path=path))
|
||||
|
||||
def loadCase(self, path):
|
||||
commandReply = self.execute(loadCase=Cmd.FilePathRequest(path=path))
|
||||
commandReply = self.__execute(loadCase=Cmd.FilePathRequest(path=path))
|
||||
assert commandReply.HasField("loadCaseResult")
|
||||
return Case(self.channel, commandReply.loadCaseResult.id)
|
||||
|
||||
def replaceCase(self, path, caseId=0):
|
||||
return self.execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=path,
|
||||
return self.__execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=path,
|
||||
caseId=caseId))
|
||||
|
||||
def replaceSourceCases(self, gridListFile, caseGroupId=0):
|
||||
return self.execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=gridListFile,
|
||||
return self.__execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=gridListFile,
|
||||
caseGroupId=caseGroupId))
|
||||
##################
|
||||
# Export Commands
|
||||
##################
|
||||
|
||||
def exportMultiCaseSnapshots(self, gridListFile):
|
||||
return self.execute(exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(gridListFile=gridListFile))
|
||||
return self.__execute(exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(gridListFile=gridListFile))
|
||||
|
||||
def exportSnapshots(self, type = 'ALL', prefix=''):
|
||||
return self.execute(exportSnapshots=Cmd.ExportSnapshotsRequest(type=type,
|
||||
return self.__execute(exportSnapshots=Cmd.ExportSnapshotsRequest(type=type,
|
||||
prefix=prefix))
|
||||
|
||||
def exportProperty(self, caseId, timeStep, property, eclipseKeyword=property, undefinedValue=0.0, exportFile=property):
|
||||
return self.execute(exportProperty=Cmd.ExportPropertyRequest(caseId=caseId,
|
||||
return self.__execute(exportProperty=Cmd.ExportPropertyRequest(caseId=caseId,
|
||||
timeStep=timeStep,
|
||||
property=property,
|
||||
eclipseKeyword=eclipseKeyword,
|
||||
@ -71,7 +80,7 @@ class Commands:
|
||||
if isinstance(viewNames, str):
|
||||
viewNames = [viewNames]
|
||||
|
||||
return self.execute(exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(caseId=caseId,
|
||||
return self.__execute(exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(caseId=caseId,
|
||||
viewNames=viewNames,
|
||||
undefinedValue=undefinedValue))
|
||||
|
||||
@ -80,7 +89,7 @@ class Commands:
|
||||
excludeMainBoreForFishbones, combinationMode):
|
||||
if (isinstance(wellPathNames, str)):
|
||||
wellPathNames = [wellPathNames]
|
||||
return self.execute(exportWellPathCompletions=Cmd.ExportWellPathCompRequest(caseId=caseId,
|
||||
return self.__execute(exportWellPathCompletions=Cmd.ExportWellPathCompRequest(caseId=caseId,
|
||||
timeStep=timeStep,
|
||||
wellPathNames=wellPathNames,
|
||||
fileSplit=fileSplit,
|
||||
@ -93,7 +102,7 @@ class Commands:
|
||||
def exportSimWellFractureCompletions(self, caseId, viewName, timeStep, simulationWellNames, fileSplit, compdatExport):
|
||||
if(isinstance(simulationWellNames, str)):
|
||||
simulationWellNames = [simulationWellNames]
|
||||
return self.execute(exportSimWellFractureCompletions=Cmd.ExportSimWellPathFraqRequest(caseId=caseId,
|
||||
return self.__execute(exportSimWellFractureCompletions=Cmd.ExportSimWellPathFraqRequest(caseId=caseId,
|
||||
viewName=viewName,
|
||||
timeStep=timeStep,
|
||||
simulationWellNames=simulationWellNames,
|
||||
@ -101,23 +110,23 @@ class Commands:
|
||||
compdatExport=compdatExport))
|
||||
|
||||
def exportMsw(self, caseId, wellPath):
|
||||
return self.execute(exportMsw=Cmd.ExportMswRequest(caseId=caseId,
|
||||
return self.__execute(exportMsw=Cmd.ExportMswRequest(caseId=caseId,
|
||||
wellPath=wellPath))
|
||||
|
||||
def exportWellPaths(self, wellPaths=[], mdStepSize=5.0):
|
||||
if isinstance(wellPaths, str):
|
||||
wellPaths = [wellpaths]
|
||||
return self.execute(exportWellPaths=Cmd.ExportWellPathRequest(wellPathNames=wellPaths, mdStepSize=mdStepSize))
|
||||
return self.__execute(exportWellPaths=Cmd.ExportWellPathRequest(wellPathNames=wellPaths, mdStepSize=mdStepSize))
|
||||
|
||||
def exportVisibleCells(self, caseId, viewName, exportKeyword='FLUXNUM', visibleActiveCellsValue=1, hiddenActiveCellsValue=0, inactiveCellsValue=0):
|
||||
return self.execute(exportVisibleCells=Cmd.ExportVisibleCellsRequest(caseId=caseId,
|
||||
return self.__execute(exportVisibleCells=Cmd.ExportVisibleCellsRequest(caseId=caseId,
|
||||
viewName=viewName,
|
||||
exportKeyword=exportKeyword,
|
||||
visibleActiveCellsValue=visibleActiveCellsValue,
|
||||
hiddenActiveCellsValue=hiddenActiveCellsValue,
|
||||
inactiveCellsValue=inactiveCellsValue))
|
||||
def setExportFolder(self, type, path, createFolder=False):
|
||||
return self.execute(setExportFolder=Cmd.SetExportFolderRequest(type=type,
|
||||
return self.__execute(setExportFolder=Cmd.SetExportFolderRequest(type=type,
|
||||
path=path,
|
||||
createFolder=createFolder))
|
||||
|
||||
@ -125,29 +134,29 @@ class Commands:
|
||||
caseIds = []
|
||||
for case in cases:
|
||||
caseIds.append(case.id)
|
||||
return self.execute(runOctaveScript=Cmd.RunOctaveScriptRequest(path=path,
|
||||
return self.__execute(runOctaveScript=Cmd.RunOctaveScriptRequest(path=path,
|
||||
caseIds=caseIds))
|
||||
|
||||
def setMainWindowSize(self, width, height):
|
||||
return self.execute(setMainWindowSize=Cmd.SetMainWindowSizeParams(width=width, height=height))
|
||||
return self.__execute(setMainWindowSize=Cmd.SetMainWindowSizeParams(width=width, height=height))
|
||||
|
||||
def computeCaseGroupStatistics(self, caseIds):
|
||||
if isinstance(caseIds, int):
|
||||
caseIds = [caseIds]
|
||||
return self.execute(computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(caseIds=caseIds))
|
||||
return self.__execute(computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(caseIds=caseIds))
|
||||
|
||||
def setTimeStep(self, caseId, timeStep):
|
||||
return self.execute(setTimeStep=Cmd.SetTimeStepParams(caseId=caseId, timeStep=timeStep))
|
||||
return self.__execute(setTimeStep=Cmd.SetTimeStepParams(caseId=caseId, timeStep=timeStep))
|
||||
|
||||
def scaleFractureTemplate(self, id, halfLength, height, dFactor, conductivity):
|
||||
return self.execute(scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(id=id,
|
||||
return self.__execute(scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(id=id,
|
||||
halfLength=halfLength,
|
||||
height=height,
|
||||
dFactor=dFactor,
|
||||
conductivity=conductivity))
|
||||
|
||||
def setFractureContainment(self, id, topLayer, baseLayer):
|
||||
return self.execute(setFractureContainment=Cmd.SetFracContainmentRequest(id=id,
|
||||
return self.__execute(setFractureContainment=Cmd.SetFracContainmentRequest(id=id,
|
||||
topLayer=topLayer,
|
||||
baseLayer=baseLayer))
|
||||
|
||||
@ -155,7 +164,7 @@ class Commands:
|
||||
maxFracturesPerWell, topLayer, baseLayer, spacing, action):
|
||||
if isinstance(wellPathNames, str):
|
||||
wellPathNames = [wellPathNames]
|
||||
return self.execute(createMultipleFractures=Cmd.MultipleFracAction(caseId=caseId,
|
||||
return self.__execute(createMultipleFractures=Cmd.MultipleFracAction(caseId=caseId,
|
||||
templateId=templateId,
|
||||
wellPathNames=wellPathNames,
|
||||
minDistFromWellTd=minDistFromWellTd,
|
||||
@ -168,7 +177,7 @@ class Commands:
|
||||
def createLgrForCompletions(self, caseId, timeStep, wellPathNames, refinementI, refinementJ, refinementK, splitType):
|
||||
if isinstance(wellPathNames, str):
|
||||
wellPathNames = [wellPathNames]
|
||||
return self.execute(createLgrForCompletions=Cmd.CreateLgrForCompRequest(caseId=caseId,
|
||||
return self.__execute(createLgrForCompletions=Cmd.CreateLgrForCompRequest(caseId=caseId,
|
||||
timeStep=timeStep,
|
||||
wellPathNames=wellPathNames,
|
||||
refinementI=refinementI,
|
||||
@ -179,5 +188,5 @@ class Commands:
|
||||
def createSaturationPressurePlots(self, caseIds):
|
||||
if isinstance(caseIds, int):
|
||||
caseIds = [caseIds]
|
||||
return self.execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=caseIds))
|
||||
return self.__execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=caseIds))
|
||||
|
||||
|
@ -8,11 +8,20 @@ import Grid_pb2
|
||||
import Grid_pb2_grpc
|
||||
|
||||
class Grid:
|
||||
"""Grid Information. Not meant to be constructed separately
|
||||
|
||||
Create Grid objects using mathods on Case: Grid() and Grids()
|
||||
"""
|
||||
def __init__(self, index, case):
|
||||
self.case = case
|
||||
self.index = index
|
||||
self.stub = Grid_pb2_grpc.GridStub(self.case.channel)
|
||||
|
||||
def dimensions(self):
|
||||
"""The dimensions in i, j, k direction
|
||||
|
||||
Returns:
|
||||
Vec3i: class with integer attributes i, j, k representing the extent in all three dimensions.
|
||||
"""
|
||||
return self.stub.GetDimensions(Grid_pb2.GridRequest(case_request = self.case.request, grid_index = self.index)).dimensions
|
||||
|
||||
|
@ -14,16 +14,38 @@ from .Commands import Commands
|
||||
from .Project import Project
|
||||
|
||||
class Instance:
|
||||
launched = False
|
||||
"""The ResInsight Instance class. Use to launch or find existing ResInsight instances
|
||||
|
||||
Attributes:
|
||||
launched(bool): Tells us whether the application was launched as a new process.
|
||||
If the application was launched we may need to close it when exiting the script.
|
||||
app(App): Application information object. Set when creating an instance.
|
||||
commands(Commands): Command executor. Set when creating an instance.
|
||||
project(Project): Current project in ResInsight.
|
||||
Set when creating an instance and updated when opening/closing projects.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def is_port_in_use(port):
|
||||
def __is_port_in_use(port):
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.settimeout(0.2)
|
||||
return s.connect_ex(('localhost', port)) == 0
|
||||
|
||||
@staticmethod
|
||||
def launch(resInsightExecutable = '', console = False):
|
||||
def launch(resInsightExecutable = '', console = False):
|
||||
""" Launch a new Instance of ResInsight. This requires the environment variable
|
||||
RESINSIGHT_EXECUTABLE to be set or the parameter resInsightExecutable to be provided.
|
||||
The RESINSIGHT_GRPC_PORT environment variable can be set to an alternative port number.
|
||||
|
||||
Args:
|
||||
resInsightExecutable (str): Path to a valid ResInsight executable. If set
|
||||
will take precedence over what is provided in the RESINSIGHT_EXECUTABLE
|
||||
environment variable.
|
||||
console (bool): If True, launch as console application, without GUI.
|
||||
Returns:
|
||||
Instance: an instance object if it worked. None if not.
|
||||
"""
|
||||
|
||||
port = 50051
|
||||
portEnv = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if portEnv:
|
||||
@ -36,7 +58,7 @@ class Instance:
|
||||
' RESINSIGHT_EXECUTABLE is not set')
|
||||
return None
|
||||
|
||||
while Instance.is_port_in_use(port):
|
||||
while Instance.__is_port_in_use(port):
|
||||
port += 1
|
||||
|
||||
print('Port ' + str(port))
|
||||
@ -47,24 +69,36 @@ class Instance:
|
||||
parameters.append("--console")
|
||||
pid = os.spawnv(os.P_NOWAIT, resInsightExecutable, parameters)
|
||||
if pid:
|
||||
return Instance(port=port, launched=True)
|
||||
instance = Instance(port=port)
|
||||
instance.launched = True
|
||||
return instance
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def find(startPort = 50051, endPort = 50071):
|
||||
""" Search for an existing Instance of ResInsight by testing ports.
|
||||
|
||||
By default we search from port 50051 to 50071 or if the environment
|
||||
variable RESINSIGHT_GRPC_PORT is set we search
|
||||
RESINSIGHT_GRPC_PORT to RESINSIGHT_GRPC_PORT+20
|
||||
|
||||
Args:
|
||||
startPort(int): start searching from this port
|
||||
endPort(int): search up to but not including this port
|
||||
"""
|
||||
portEnv = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if portEnv:
|
||||
startPort = int(portEnv)
|
||||
endPort = startPort + 20
|
||||
|
||||
for tryPort in range(startPort, endPort):
|
||||
if Instance.is_port_in_use(tryPort):
|
||||
if Instance.__is_port_in_use(tryPort):
|
||||
return Instance(tryPort)
|
||||
|
||||
print('Error: Could not find any ResInsight instances responding between ports ' + str(startPort) + ' and ' + str(endPort))
|
||||
return None
|
||||
|
||||
def checkVersion(self):
|
||||
def __checkVersion(self):
|
||||
try:
|
||||
majorVersionOk = self.app.majorVersion() == int(RiaVersionInfo.RESINSIGHT_MAJOR_VERSION)
|
||||
minorVersionOk = self.app.minorVersion() == int(RiaVersionInfo.RESINSIGHT_MINOR_VERSION)
|
||||
@ -72,12 +106,17 @@ class Instance:
|
||||
except grpc.RpcError as e:
|
||||
return False, False
|
||||
|
||||
def __init__(self, port = 50051, launched = False):
|
||||
def __init__(self, port = 50051):
|
||||
""" Attempts to connect to ResInsight at aa specific port on localhost
|
||||
|
||||
Args:
|
||||
port(int): port number
|
||||
"""
|
||||
logging.basicConfig()
|
||||
location = "localhost:" + str(port)
|
||||
|
||||
self.channel = grpc.insecure_channel(location)
|
||||
self.launched = launched
|
||||
self.launched = False
|
||||
|
||||
# Main version check package
|
||||
self.app = App(self.channel)
|
||||
@ -85,14 +124,14 @@ class Instance:
|
||||
connectionOk = False
|
||||
versionOk = False
|
||||
|
||||
if launched:
|
||||
if self.launched:
|
||||
for i in range(0, 10):
|
||||
connectionOk, versionOk = self.checkVersion()
|
||||
connectionOk, versionOk = self.__checkVersion()
|
||||
if connectionOk:
|
||||
break
|
||||
time.sleep(1.0)
|
||||
else:
|
||||
connectionOk, versionOk = self.checkVersion()
|
||||
connectionOk, versionOk = self.__checkVersion()
|
||||
|
||||
if not connectionOk:
|
||||
if launched:
|
||||
|
@ -12,18 +12,34 @@ import Project_pb2
|
||||
import Project_pb2_grpc
|
||||
|
||||
class Project:
|
||||
"""ResInsight project. Not intended to be created separately.
|
||||
|
||||
Automatically created and assigned to Instance.
|
||||
"""
|
||||
def __init__(self, channel):
|
||||
self.channel = channel
|
||||
self.project = Project_pb2_grpc.ProjectStub(channel)
|
||||
|
||||
def open(self, path):
|
||||
"""Open a new project from the given path
|
||||
|
||||
Argument:
|
||||
path(string): path to project file
|
||||
|
||||
"""
|
||||
Commands(self.channel).openProject(path)
|
||||
return self
|
||||
|
||||
def close(self):
|
||||
"""Close the current project (and open new blank project)"""
|
||||
Commands(self.channel).closeProject()
|
||||
|
||||
def selectedCases(self):
|
||||
"""Get a list of all cases selected in the project tree
|
||||
|
||||
Returns:
|
||||
A list of rips Case objects
|
||||
"""
|
||||
caseInfos = self.project.GetSelectedCases(Empty())
|
||||
cases = []
|
||||
for caseInfo in caseInfos.data:
|
||||
@ -31,6 +47,11 @@ class Project:
|
||||
return cases
|
||||
|
||||
def cases(self):
|
||||
"""Get a list of all cases in the project
|
||||
|
||||
Returns:
|
||||
A list of rips Case objects
|
||||
"""
|
||||
try:
|
||||
caseInfos = self.project.GetAllCases(Empty())
|
||||
|
||||
@ -46,6 +67,13 @@ class Project:
|
||||
return []
|
||||
|
||||
def case(self, id):
|
||||
"""Get a specific case from the provided case Id
|
||||
|
||||
Arguments:
|
||||
id(int): case id
|
||||
Returns:
|
||||
A rips Case object
|
||||
"""
|
||||
try:
|
||||
case = Case(self.channel, id)
|
||||
return case
|
||||
@ -53,5 +81,12 @@ class Project:
|
||||
return None
|
||||
|
||||
def loadCase(self, path):
|
||||
"""Load a new case from the given file path
|
||||
|
||||
Arguments:
|
||||
path(string): file path to case
|
||||
Returns:
|
||||
A rips Case object
|
||||
"""
|
||||
return Commands(self.channel).loadCase(path)
|
||||
|
||||
|
@ -10,11 +10,17 @@ import Case_pb2
|
||||
import Case_pb2_grpc
|
||||
|
||||
class Properties:
|
||||
""" Class for streaming properties to and from ResInsight
|
||||
"""
|
||||
def __init__(self, case):
|
||||
"""
|
||||
Arguments:
|
||||
case(Case): A rips case to handle properties for
|
||||
"""
|
||||
self.case = case
|
||||
self.propertiesStub = Properties_pb2_grpc.PropertiesStub(self.case.channel)
|
||||
|
||||
def generatePropertyInputIterator(self, values_iterator, parameters):
|
||||
def __generatePropertyInputIterator(self, values_iterator, parameters):
|
||||
chunk = Properties_pb2.PropertyInputChunk()
|
||||
chunk.params.CopyFrom(parameters)
|
||||
yield chunk
|
||||
@ -24,7 +30,7 @@ class Properties:
|
||||
chunk.values.CopyFrom(valmsg)
|
||||
yield chunk
|
||||
|
||||
def generatePropertyInputChunks(self, array, parameters):
|
||||
def __generatePropertyInputChunks(self, array, parameters):
|
||||
# Each double is 8 bytes. A good chunk size is 64KiB = 65536B
|
||||
# Meaning ideal number of doubles would be 8192.
|
||||
# However we need overhead space, so if we choose 8160 in chunk size
|
||||
@ -47,6 +53,22 @@ class Properties:
|
||||
yield chunk
|
||||
|
||||
def available(self, propertyType, porosityModel = 'MATRIX_MODEL'):
|
||||
"""Get a list of available properties
|
||||
|
||||
Arguments:
|
||||
propertyType(string): string corresponding to propertyType enum
|
||||
Can be one of the following:
|
||||
'DYNAMIC_NATIVE'
|
||||
'STATIC_NATIVE'
|
||||
'SOURSIMRL'
|
||||
'GENERATED'
|
||||
'INPUT_PROPERTY'
|
||||
'FORMATION_NAMES'
|
||||
'FLOW_DIAGNOSTICS'
|
||||
'INJECTION_FLOODING'
|
||||
porosityModel(string): 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
"""
|
||||
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.AvailablePropertiesRequest (case_request = Case_pb2.CaseRequest(id=self.case.id),
|
||||
@ -55,6 +77,18 @@ class Properties:
|
||||
return self.propertiesStub.GetAvailableProperties(request).property_names
|
||||
|
||||
def activeCellProperty(self, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'):
|
||||
"""Get a cell property for all active cells. Async, so returns an iterator
|
||||
|
||||
Arguments:
|
||||
propertyType(string): string enum. See available()
|
||||
propertyName(string): name of an Eclipse property
|
||||
timeStep(int): the time step for which to get the property for
|
||||
porosityModel(string): string enum. See available()
|
||||
|
||||
Returns:
|
||||
An iterator to a chunk object containing an array of double values
|
||||
You first loop through the chunks and then the values within the chunk to get all values.
|
||||
"""
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.PropertyRequest(case_request = Case_pb2.CaseRequest(id=self.case.id),
|
||||
@ -66,6 +100,19 @@ class Properties:
|
||||
yield chunk
|
||||
|
||||
def gridProperty(self, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'):
|
||||
"""Get a cell property for all grid cells. Async, so returns an iterator
|
||||
|
||||
Arguments:
|
||||
propertyType(string): string enum. See available()
|
||||
propertyName(string): name of an Eclipse property
|
||||
timeStep(int): the time step for which to get the property for
|
||||
gridIndex(int): index to the grid we're getting values for
|
||||
porosityModel(string): string enum. See available()
|
||||
|
||||
Returns:
|
||||
An iterator to a chunk object containing an array of double values
|
||||
You first loop through the chunks and then the values within the chunk to get all values.
|
||||
"""
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
@ -77,17 +124,25 @@ class Properties:
|
||||
for chunk in self.propertiesStub.GetGridProperty(request):
|
||||
yield chunk
|
||||
|
||||
def setActiveCellPropertyAsync(self, values_iterator, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'):
|
||||
def setActiveCellPropertyAsync(self, values_iterator, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'):
|
||||
"""Set a cell property for all active cells. Async, and so takes an iterator to the input values
|
||||
|
||||
Arguments:
|
||||
values_iterator(iterator): an iterator to the properties to be set
|
||||
propertyType(string): string enum. See available()
|
||||
propertyName(string): name of an Eclipse property
|
||||
timeStep(int): the time step for which to get the property for
|
||||
porosityModel(string): string enum. See available()
|
||||
"""
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
property_type = propertyTypeEnum,
|
||||
property_name = propertyName,
|
||||
time_step = timeStep,
|
||||
grid_index = gridIndex,
|
||||
porosity_model = porosityModelEnum)
|
||||
try:
|
||||
reply_iterator = self.generatePropertyInputIterator(values_iterator, request)
|
||||
reply_iterator = self.__generatePropertyInputIterator(values_iterator, request)
|
||||
self.propertiesStub.SetActiveCellProperty(reply_iterator)
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
@ -95,17 +150,25 @@ class Properties:
|
||||
else:
|
||||
print("Other error", e)
|
||||
|
||||
def setActiveCellProperty(self, values, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'):
|
||||
def setActiveCellProperty(self, values, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'):
|
||||
"""Set a cell property for all active cells.
|
||||
|
||||
Arguments:
|
||||
values(list): a list of double precision floating point numbers
|
||||
propertyType(string): string enum. See available()
|
||||
propertyName(string): name of an Eclipse property
|
||||
timeStep(int): the time step for which to get the property for
|
||||
porosityModel(string): string enum. See available()
|
||||
"""
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
property_type = propertyTypeEnum,
|
||||
property_name = propertyName,
|
||||
time_step = timeStep,
|
||||
grid_index = gridIndex,
|
||||
porosity_model = porosityModelEnum)
|
||||
try:
|
||||
request_iterator = self.generatePropertyInputChunks(values, request)
|
||||
request_iterator = self.__generatePropertyInputChunks(values, request)
|
||||
self.propertiesStub.SetActiveCellProperty(request_iterator)
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
@ -114,6 +177,16 @@ class Properties:
|
||||
print("Other error", e)
|
||||
|
||||
def setGridProperty(self, values, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'):
|
||||
"""Set a cell property for all grid cells.
|
||||
|
||||
Arguments:
|
||||
values(list): a list of double precision floating point numbers
|
||||
propertyType(string): string enum. See available()
|
||||
propertyName(string): name of an Eclipse property
|
||||
timeStep(int): the time step for which to get the property for
|
||||
gridIndex(int): index to the grid we're setting values for
|
||||
porosityModel(string): string enum. See available()
|
||||
"""
|
||||
propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType)
|
||||
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
@ -123,7 +196,7 @@ class Properties:
|
||||
grid_index = gridIndex,
|
||||
porosity_model = porosityModelEnum)
|
||||
try:
|
||||
request_iterator = self.generatePropertyInputChunks(values, request)
|
||||
request_iterator = self.__generatePropertyInputChunks(values, request)
|
||||
self.propertiesStub.SetGridProperty(request_iterator)
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
|
@ -6,7 +6,7 @@ with open('README.md') as f:
|
||||
with open('LICENSE') as f:
|
||||
license = f.read()
|
||||
|
||||
RIPS_DIST_VERSION = '1'
|
||||
RIPS_DIST_VERSION = '2'
|
||||
|
||||
setup(
|
||||
name='rips',
|
||||
|
Loading…
Reference in New Issue
Block a user