mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
* Move case loading commands from Commands to project and case * Major refactor * Fix problems with Python examples * Add ability to export snapshot from just one view + fixup * Case comments and black * Make all modules pass pylint test
This commit is contained in:
parent
00eb02ccec
commit
a2bad82391
@ -832,7 +832,7 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments( cvf::Progr
|
||||
// 2016-11-09 : Location of snapshot folder was previously located in 'snapshot' folder
|
||||
// relative to current working folder. Now harmonized to behave as RiuMainWindow::slotSnapshotAllViewsToFile()
|
||||
QString absolutePathToSnapshotDir = createAbsolutePathFromProjectRelativePath( "snapshots" );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder( absolutePathToSnapshotDir );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir );
|
||||
|
||||
mainWnd->loadWinGeoAndDockToolBarLayout();
|
||||
}
|
||||
@ -1799,7 +1799,7 @@ void RiaGuiApplication::runMultiCaseSnapshots( const QString& templateProj
|
||||
bool loadOk = loadProject( templateProjectFileName, PLA_NONE, &modifier );
|
||||
if ( loadOk )
|
||||
{
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder( snapshotFolderName );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( snapshotFolderName );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ void RiaRegressionTestRunner::runRegressionTest()
|
||||
resizePlotWindows();
|
||||
|
||||
QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath( generatedFolderName );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder( fullPathGeneratedFolder );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( fullPathGeneratedFolder );
|
||||
|
||||
RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder( fullPathGeneratedFolder );
|
||||
|
||||
|
@ -135,3 +135,25 @@ RimEclipseView* RicfApplicationTools::viewFromCaseIdAndViewName( int caseId, con
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseView* RicfApplicationTools::viewFromCaseIdAndViewId( int caseId, int viewId )
|
||||
{
|
||||
for ( RimEclipseCase* c : RiaApplication::instance()->project()->eclipseCases() )
|
||||
{
|
||||
if ( c->caseId() == caseId )
|
||||
{
|
||||
for ( auto v : c->views() )
|
||||
{
|
||||
auto eclipseView = dynamic_cast<RimEclipseView*>( v );
|
||||
if ( eclipseView && eclipseView->id() == viewId )
|
||||
{
|
||||
return eclipseView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
static std::vector<RimWellPath*> wellPathsFromNames( const QStringList& wellPathNames, QStringList* wellsNotFound );
|
||||
static RimEclipseCase* caseFromId( int caseId );
|
||||
static RimEclipseView* viewFromCaseIdAndViewName( int caseId, const QString& viewName );
|
||||
static RimEclipseView* viewFromCaseIdAndViewId( int caseId, int viewId );
|
||||
|
||||
static std::vector<QString> toStringVector( const QStringList& stringList );
|
||||
static QStringList toQStringList( const std::vector<QString>& v );
|
||||
|
@ -48,6 +48,7 @@ CAF_PDM_SOURCE_INIT( RicfExportPropertyInViews, "exportPropertyInViews" );
|
||||
RicfExportPropertyInViews::RicfExportPropertyInViews()
|
||||
{
|
||||
RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" );
|
||||
RICF_InitField( &m_viewIds, "viewIds", std::vector<int>(), "View IDs", "", "", "" );
|
||||
RICF_InitField( &m_viewNames, "viewNames", std::vector<QString>(), "View Names", "", "", "" );
|
||||
RICF_InitField( &m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", "" );
|
||||
}
|
||||
@ -74,22 +75,35 @@ RicfCommandResponse RicfExportPropertyInViews::execute()
|
||||
RimEclipseView* view = dynamic_cast<RimEclipseView*>( v );
|
||||
if ( !view ) continue;
|
||||
|
||||
if ( m_viewNames().empty() )
|
||||
if ( m_viewNames().empty() && m_viewIds().empty() )
|
||||
{
|
||||
viewsForExport.push_back( view );
|
||||
}
|
||||
else
|
||||
{
|
||||
bool matchingName = false;
|
||||
for ( const auto& viewName : m_viewNames() )
|
||||
bool matchingIdOrName = false;
|
||||
|
||||
for ( auto viewId : m_viewIds() )
|
||||
{
|
||||
if ( view->name().compare( viewName, Qt::CaseInsensitive ) == 0 )
|
||||
if ( view->id() == viewId )
|
||||
{
|
||||
matchingName = true;
|
||||
matchingIdOrName = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( matchingName )
|
||||
if ( !matchingIdOrName )
|
||||
{
|
||||
for ( const auto& viewName : m_viewNames() )
|
||||
{
|
||||
if ( view->name().compare( viewName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
matchingIdOrName = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( matchingIdOrName )
|
||||
{
|
||||
viewsForExport.push_back( view );
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
|
||||
private:
|
||||
caf::PdmField<int> m_caseId;
|
||||
caf::PdmField<std::vector<int>> m_viewIds;
|
||||
caf::PdmField<std::vector<QString>> m_viewNames;
|
||||
caf::PdmField<double> m_undefinedValue;
|
||||
};
|
||||
|
@ -45,6 +45,7 @@ CAF_PDM_SOURCE_INIT( RicfExportSimWellFractureCompletions, "exportSimWellFractur
|
||||
RicfExportSimWellFractureCompletions::RicfExportSimWellFractureCompletions()
|
||||
{
|
||||
RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" );
|
||||
RICF_InitField( &m_viewId, "viewId", -1, "View ID", "", "", "" );
|
||||
RICF_InitField( &m_viewName, "viewName", QString( "" ), "View Name", "", "", "" );
|
||||
RICF_InitField( &m_timeStep, "timeStep", -1, "Time Step Index", "", "", "" );
|
||||
RICF_InitField( &m_simWellNames, "simulationWellNames", std::vector<QString>(), "Simulation Well Names", "", "", "" );
|
||||
@ -94,17 +95,19 @@ RicfCommandResponse RicfExportSimWellFractureCompletions::execute()
|
||||
for ( Rim3dView* v : exportSettings->caseToApply->views() )
|
||||
{
|
||||
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>( v );
|
||||
if ( eclipseView && eclipseView->name() == m_viewName() )
|
||||
if ( eclipseView && ( eclipseView->id() == m_viewId() || eclipseView->name() == m_viewName() ) )
|
||||
{
|
||||
views.push_back( eclipseView );
|
||||
}
|
||||
}
|
||||
if ( views.empty() )
|
||||
{
|
||||
QString error = QString(
|
||||
"exportSimWellCompletions: Could not find any views named \"%1\" in the case with ID %2" )
|
||||
.arg( m_viewName )
|
||||
.arg( m_caseId() );
|
||||
QString error =
|
||||
QString(
|
||||
"exportSimWellCompletions: Could not find any views with id %1 or named \"%2\" in the case with ID %3" )
|
||||
.arg( m_viewId )
|
||||
.arg( m_viewName )
|
||||
.arg( m_caseId() );
|
||||
RiaLogging::error( error );
|
||||
return RicfCommandResponse( RicfCommandResponse::COMMAND_ERROR, error );
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
|
||||
private:
|
||||
caf::PdmField<int> m_caseId;
|
||||
caf::PdmField<int> m_viewId;
|
||||
caf::PdmField<QString> m_viewName;
|
||||
caf::PdmField<int> m_timeStep;
|
||||
caf::PdmField<std::vector<QString>> m_simWellNames;
|
||||
|
@ -52,6 +52,7 @@ RicfExportSnapshots::RicfExportSnapshots()
|
||||
RICF_InitField( &m_type, "type", RicfExportSnapshots::SnapshotsTypeEnum(), "Type", "", "", "" );
|
||||
RICF_InitField( &m_prefix, "prefix", QString(), "Prefix", "", "", "" );
|
||||
RICF_InitField( &m_caseId, "caseId", -1, "Case Id", "", "", "" );
|
||||
RICF_InitField( &m_viewId, "viewId", -1, "View Id", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -80,9 +81,10 @@ RicfCommandResponse RicfExportSnapshots::execute()
|
||||
}
|
||||
if ( m_type == RicfExportSnapshots::VIEWS || m_type == RicfExportSnapshots::ALL )
|
||||
{
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder( absolutePathToSnapshotDir,
|
||||
m_prefix,
|
||||
m_caseId() );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir,
|
||||
m_prefix,
|
||||
m_caseId(),
|
||||
m_viewId() );
|
||||
}
|
||||
if ( m_type == RicfExportSnapshots::PLOTS || m_type == RicfExportSnapshots::ALL )
|
||||
{
|
||||
|
@ -51,4 +51,5 @@ private:
|
||||
caf::PdmField<SnapshotsTypeEnum> m_type;
|
||||
caf::PdmField<QString> m_prefix;
|
||||
caf::PdmField<int> m_caseId;
|
||||
caf::PdmField<int> m_viewId;
|
||||
};
|
||||
|
@ -64,6 +64,7 @@ void AppEnum<RicfExportVisibleCells::ExportKeyword>::setUp()
|
||||
RicfExportVisibleCells::RicfExportVisibleCells()
|
||||
{
|
||||
RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" );
|
||||
RICF_InitField( &m_viewId, "viewId", -1, "View ID", "", "", "" );
|
||||
RICF_InitField( &m_viewName, "viewName", QString(), "View Name", "", "", "" );
|
||||
RICF_InitField( &m_exportKeyword,
|
||||
"exportKeyword",
|
||||
@ -82,18 +83,27 @@ RicfExportVisibleCells::RicfExportVisibleCells()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicfCommandResponse RicfExportVisibleCells::execute()
|
||||
{
|
||||
if ( m_caseId < 0 || m_viewName().isEmpty() )
|
||||
if ( m_caseId < 0 || ( m_viewName().isEmpty() && m_viewId() < 0 ) )
|
||||
{
|
||||
QString error( "exportVisibleCells: CaseId or view name not specified" );
|
||||
QString error( "exportVisibleCells: CaseId or view name or view id not specified" );
|
||||
RiaLogging::error( error );
|
||||
return RicfCommandResponse( RicfCommandResponse::COMMAND_ERROR, error );
|
||||
}
|
||||
|
||||
auto eclipseView = RicfApplicationTools::viewFromCaseIdAndViewName( m_caseId, m_viewName );
|
||||
RimEclipseView* eclipseView = nullptr;
|
||||
if ( m_viewId() >= 0 )
|
||||
{
|
||||
eclipseView = RicfApplicationTools::viewFromCaseIdAndViewId( m_caseId, m_viewId() );
|
||||
}
|
||||
else
|
||||
{
|
||||
eclipseView = RicfApplicationTools::viewFromCaseIdAndViewName( m_caseId, m_viewName );
|
||||
}
|
||||
if ( !eclipseView )
|
||||
{
|
||||
QString error(
|
||||
QString( "exportVisibleCells: Could not find view '%1' in case ID %2" ).arg( m_viewName ).arg( m_caseId ) );
|
||||
QString error( QString( "exportVisibleCells: Could not find view of id %1 or named '%2' in case ID %3" )
|
||||
.arg( m_viewId )
|
||||
.arg( m_viewName )
|
||||
.arg( m_caseId ) );
|
||||
RiaLogging::error( error );
|
||||
return RicfCommandResponse( RicfCommandResponse::COMMAND_ERROR, error );
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ private:
|
||||
void buildExportSettings( const QString& exportFolder, RicSaveEclipseInputVisibleCellsUi* exportSettings );
|
||||
|
||||
caf::PdmField<int> m_caseId;
|
||||
caf::PdmField<int> m_viewId;
|
||||
caf::PdmField<QString> m_viewName;
|
||||
caf::PdmField<caf::AppEnum<ExportKeyword>> m_exportKeyword;
|
||||
caf::PdmField<int> m_visibleActiveCellsValue;
|
||||
|
@ -35,6 +35,7 @@ CAF_PDM_SOURCE_INIT( RicfSetTimeStep, "setTimeStep" );
|
||||
RicfSetTimeStep::RicfSetTimeStep()
|
||||
{
|
||||
RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" );
|
||||
RICF_InitField( &m_viewId, "viewId", -1, "View ID", "", "", "" );
|
||||
RICF_InitField( &m_timeStepIndex, "timeStep", -1, "Time Step Index", "", "", "" );
|
||||
}
|
||||
|
||||
@ -46,6 +47,14 @@ void RicfSetTimeStep::setCaseId( int caseId )
|
||||
m_caseId = caseId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicfSetTimeStep::setViewId( int viewId )
|
||||
{
|
||||
m_viewId = viewId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -93,8 +102,11 @@ RicfCommandResponse RicfSetTimeStep::execute()
|
||||
|
||||
for ( Rim3dView* view : eclipseCase->views() )
|
||||
{
|
||||
view->setCurrentTimeStepAndUpdate( m_timeStepIndex );
|
||||
view->createDisplayModelAndRedraw();
|
||||
if ( m_viewId() == -1 || view->id() == m_viewId() )
|
||||
{
|
||||
view->setCurrentTimeStepAndUpdate( m_timeStepIndex );
|
||||
view->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
return RicfCommandResponse();
|
||||
|
@ -35,11 +35,13 @@ public:
|
||||
RicfSetTimeStep();
|
||||
|
||||
void setCaseId( int caseId );
|
||||
void setViewId( int viewId );
|
||||
void setTimeStepIndex( int timeStepIndex );
|
||||
|
||||
RicfCommandResponse execute() override;
|
||||
|
||||
private:
|
||||
caf::PdmField<int> m_caseId;
|
||||
caf::PdmField<int> m_viewId;
|
||||
caf::PdmField<int> m_timeStepIndex;
|
||||
};
|
||||
|
@ -60,18 +60,19 @@ void RicSnapshotAllViewsToFileFeature::saveAllViews()
|
||||
// Save images in snapshot catalog relative to project directory
|
||||
QString snapshotFolderName = app->createAbsolutePathFromProjectRelativePath( "snapshots" );
|
||||
|
||||
exportSnapshotOfAllViewsIntoFolder( snapshotFolderName );
|
||||
exportSnapshotOfViewsIntoFolder( snapshotFolderName );
|
||||
|
||||
QString text = QString( "Exported snapshots to folder : \n%1" ).arg( snapshotFolderName );
|
||||
RiaLogging::info( text );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Export all snapshots of a given case (or caseId == -1 for all cases)
|
||||
/// Export snapshots of a given view (or viewId == -1 for all views) for the given case (or caseId == -1 for all cases)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder( const QString& snapshotFolderName,
|
||||
const QString& prefix /*= ""*/,
|
||||
int caseId /*= -1*/ )
|
||||
void RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( const QString& snapshotFolderName,
|
||||
const QString& prefix /*= ""*/,
|
||||
int caseId /*= -1*/,
|
||||
int viewId /*= -1*/ )
|
||||
{
|
||||
RimProject* project = RiaApplication::instance()->project();
|
||||
|
||||
@ -104,7 +105,7 @@ void RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder( const
|
||||
{
|
||||
Rim3dView* riv = views[j];
|
||||
|
||||
if ( riv && riv->viewer() )
|
||||
if ( riv && riv->viewer() && ( viewId == -1 || viewId == riv->id() ) )
|
||||
{
|
||||
RiaApplication::instance()->setActiveReservoirView( riv );
|
||||
|
||||
|
@ -32,9 +32,10 @@ class RicSnapshotAllViewsToFileFeature : public caf::CmdFeature
|
||||
public:
|
||||
static void saveAllViews();
|
||||
|
||||
static void exportSnapshotOfAllViewsIntoFolder( const QString& snapshotFolderName,
|
||||
const QString& prefix = "",
|
||||
int caseId = -1 );
|
||||
static void exportSnapshotOfViewsIntoFolder( const QString& snapshotFolderName,
|
||||
const QString& prefix = "",
|
||||
int caseId = -1,
|
||||
int viewId = -1 );
|
||||
|
||||
protected:
|
||||
// Overrides
|
||||
|
@ -85,7 +85,7 @@ set(PROTO_FILES
|
||||
"Commands"
|
||||
"App"
|
||||
"Properties"
|
||||
"Grid"
|
||||
"grid"
|
||||
)
|
||||
|
||||
set(GRPC_PYTHON_SOURCE_PATH "${CMAKE_CURRENT_LIST_DIR}/Python")
|
||||
@ -162,15 +162,13 @@ if (RESINSIGHT_GRPC_PYTHON_EXECUTABLE)
|
||||
list(APPEND GRPC_PYTHON_SOURCES
|
||||
"rips/generated/RiaVersionInfo.py"
|
||||
"rips/__init__.py"
|
||||
"rips/Case.py"
|
||||
"rips/Commands.py"
|
||||
"rips/Grid.py"
|
||||
"rips/GridCaseGroup.py"
|
||||
"rips/Project.py"
|
||||
"rips/Properties.py"
|
||||
"rips/Instance.py"
|
||||
"rips/PdmObject.py"
|
||||
"rips/View.py"
|
||||
"rips/case.py"
|
||||
"rips/grid.py"
|
||||
"rips/gridcasegroup.py"
|
||||
"rips/project.py"
|
||||
"rips/instance.py"
|
||||
"rips/pdmobject.py"
|
||||
"rips/view.py"
|
||||
"rips/PythonExamples/InstanceExample.py"
|
||||
"rips/PythonExamples/CommandExample.py"
|
||||
"rips/PythonExamples/CaseGridGroup.py"
|
||||
@ -191,7 +189,6 @@ if (RESINSIGHT_GRPC_PYTHON_EXECUTABLE)
|
||||
"rips/PythonExamples/SoilAverageSync.py"
|
||||
"rips/PythonExamples/ViewExample.py"
|
||||
"rips/tests/test_cases.py"
|
||||
"rips/tests/test_commands.py"
|
||||
"rips/tests/test_grids.py"
|
||||
"rips/tests/test_properties.py"
|
||||
"rips/tests/test_project.py"
|
||||
|
@ -53,6 +53,7 @@ message ExportSnapshotsRequest
|
||||
SnapshotType type = 1;
|
||||
string prefix = 2;
|
||||
int32 caseId = 3;
|
||||
int32 viewId = 4;
|
||||
}
|
||||
|
||||
message ExportPropertyRequest
|
||||
@ -67,9 +68,9 @@ message ExportPropertyRequest
|
||||
|
||||
message ExportPropertyInViewsRequest
|
||||
{
|
||||
int32 caseId = 1;
|
||||
repeated string viewNames = 2;
|
||||
double undefinedValue = 3;
|
||||
int32 caseId = 1;
|
||||
repeated int32 viewIds = 2;
|
||||
double undefinedValue = 3;
|
||||
}
|
||||
|
||||
enum CompdatExportSplit
|
||||
@ -89,7 +90,7 @@ enum CompdatExportType
|
||||
enum CompdatCombinationMode
|
||||
{
|
||||
INDIVIDUALLY = 0;
|
||||
caCOMBINED = 1;
|
||||
COMBINED = 1;
|
||||
}
|
||||
|
||||
message ExportWellPathCompRequest
|
||||
@ -108,7 +109,7 @@ message ExportWellPathCompRequest
|
||||
message ExportSimWellPathFracRequest
|
||||
{
|
||||
int32 caseId = 1;
|
||||
string viewName = 2;
|
||||
int32 viewId = 2;
|
||||
int32 timeStep = 3;
|
||||
repeated string simulationWellNames = 4;
|
||||
CompdatExportSplit fileSplit = 5;
|
||||
@ -130,7 +131,7 @@ message ExportWellPathRequest
|
||||
message ExportVisibleCellsRequest
|
||||
{
|
||||
int32 caseId = 1;
|
||||
string viewName = 2;
|
||||
int32 viewId = 2;
|
||||
string exportKeyword = 3;
|
||||
int32 visibleActiveCellsValue = 4;
|
||||
int32 hiddenActiveCellsValue = 5;
|
||||
@ -175,7 +176,8 @@ message ComputeCaseGroupStatRequest
|
||||
message SetTimeStepParams
|
||||
{
|
||||
int32 caseId = 1;
|
||||
int32 timeStep = 2;
|
||||
int32 viewId = 2;
|
||||
int32 timeStep = 3;
|
||||
}
|
||||
|
||||
message ScaleFractureTemplateRequest
|
||||
|
@ -1,188 +0,0 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
from rips.Commands import Commands
|
||||
from rips.Grid import Grid
|
||||
from rips.Properties import Properties
|
||||
from rips.PdmObject import PdmObject
|
||||
from rips.View import View
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
import Case_pb2
|
||||
import Case_pb2_grpc
|
||||
import PdmObject_pb2
|
||||
|
||||
class Case (PdmObject):
|
||||
"""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 (str): Case name
|
||||
groupId (int): Case Group id
|
||||
"""
|
||||
def __init__(self, channel, id):
|
||||
self.channel = channel
|
||||
self.stub = Case_pb2_grpc.CaseStub(channel)
|
||||
self.id = id
|
||||
info = self.stub.GetCaseInfo(Case_pb2.CaseRequest(id=self.id))
|
||||
self.name = info.name
|
||||
self.group_id = info.group_id
|
||||
self.type = info.type
|
||||
self.properties = Properties(self)
|
||||
self.request = Case_pb2.CaseRequest(id=self.id)
|
||||
PdmObject.__init__(self, self.stub.GetPdmObject(self.request), self.channel)
|
||||
|
||||
def grid_count(self):
|
||||
"""Get number of grids in the case"""
|
||||
try:
|
||||
return self.stub.GetGridCount(self.request).count
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
return 0
|
||||
print("ERROR: ", e)
|
||||
return 0
|
||||
|
||||
def grid_path(self):
|
||||
return self.get_value("CaseFileName")
|
||||
|
||||
def grid(self, index):
|
||||
"""Get Grid of a given index. Returns a rips Grid object
|
||||
|
||||
Arguments:
|
||||
index (int): The grid index
|
||||
|
||||
Returns: Grid object
|
||||
"""
|
||||
return Grid(index, self)
|
||||
|
||||
def grids(self):
|
||||
"""Get a list of all rips Grid objects in the case"""
|
||||
grid_list = []
|
||||
for i in range(0, self.grid_count()):
|
||||
grid_list.append(Grid(i, self))
|
||||
return grid_list
|
||||
|
||||
def cell_count(self, porosity_model='MATRIX_MODEL'):
|
||||
"""Get a cell count object containing number of active cells and
|
||||
total number of cells
|
||||
|
||||
Arguments:
|
||||
porosity_model (str): 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
|
||||
"""
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Case_pb2.CellInfoRequest(case_request=self.request,
|
||||
porosity_model=porosity_model_enum)
|
||||
return self.stub.GetCellCount(request)
|
||||
|
||||
def cell_info_for_active_cells_async(self, porosity_model='MATRIX_MODEL'):
|
||||
"""Get Stream of cell info objects for current case
|
||||
|
||||
Arguments:
|
||||
porosity_model(str): String representing an enum.
|
||||
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
|
||||
Returns:
|
||||
Stream of **CellInfo** objects
|
||||
|
||||
See cell_info_for_active_cells() for detalis on the **CellInfo** class.
|
||||
"""
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Case_pb2.CellInfoRequest(case_request=self.request,
|
||||
porosity_model=porosity_model_enum)
|
||||
return self.stub.GetCellInfoForActiveCells(request)
|
||||
|
||||
def cell_info_for_active_cells(self, porosity_model='MATRIX_MODEL'):
|
||||
"""Get list of cell info objects for current case
|
||||
|
||||
Arguments:
|
||||
porosity_model(str): String representing an enum.
|
||||
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
|
||||
Returns:
|
||||
List of **CellInfo** objects
|
||||
|
||||
### CellInfo class description
|
||||
|
||||
Parameter | Description | Type
|
||||
------------------------- | --------------------------------------------- | -----
|
||||
grid_index | Index to grid | Integer
|
||||
parent_grid_index | Index to parent grid | Integer
|
||||
coarsening_box_index | Index to coarsening box | Integer
|
||||
local_ijk | Cell index in IJK directions of local grid | Vec3i
|
||||
parent_ijk | Cell index in IJK directions of parent grid | Vec3i
|
||||
|
||||
### Vec3i class description
|
||||
|
||||
Parameter | Description | Type
|
||||
---------------- | -------------------------------------------- | -----
|
||||
i | I grid index | Integer
|
||||
j | J grid index | Integer
|
||||
k | K grid index | Integer
|
||||
|
||||
"""
|
||||
active_cell_info_chunks = self.cell_info_for_active_cells_async()
|
||||
received_active_cells = []
|
||||
for active_cell_chunk in active_cell_info_chunks:
|
||||
for active_cell in active_cell_chunk.data:
|
||||
received_active_cells.append(active_cell)
|
||||
return received_active_cells
|
||||
|
||||
def time_steps(self):
|
||||
"""Get a list containing all time steps
|
||||
|
||||
The time steps are defined by the class **TimeStepDate** :
|
||||
|
||||
Type | Name
|
||||
--------- | ----------
|
||||
int | year
|
||||
int | month
|
||||
int | day
|
||||
int | hour
|
||||
int | minute
|
||||
int | second
|
||||
|
||||
|
||||
"""
|
||||
return self.stub.GetTimeSteps(self.request).dates
|
||||
|
||||
def days_since_start(self):
|
||||
"""Get a list of decimal values representing days since the start of the simulation"""
|
||||
return self.stub.GetDaysSinceStart(self.request).day_decimals
|
||||
|
||||
def views(self):
|
||||
"""Get a list of views belonging to a case"""
|
||||
pdm_objects = self.children("ReservoirViews")
|
||||
view_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
view_list.append(View(pdm_object))
|
||||
return view_list
|
||||
|
||||
def view(self, id):
|
||||
"""Get a particular view belonging to a case by providing view id
|
||||
Arguments:
|
||||
id(int): view id
|
||||
|
||||
Returns: a view object
|
||||
|
||||
"""
|
||||
views = self.views()
|
||||
for view_object in views:
|
||||
if view_object.id == id:
|
||||
return view_object
|
||||
return None
|
||||
|
||||
def create_view(self):
|
||||
"""Create a new view in the current case"""
|
||||
view_id = Commands(self.channel).create_view(self.id)
|
||||
return self.view(view_id)
|
||||
|
@ -1,311 +0,0 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
from Definitions_pb2 import Empty
|
||||
import Commands_pb2 as Cmd
|
||||
import Commands_pb2_grpc as CmdRpc
|
||||
import rips.Case
|
||||
|
||||
class Commands:
|
||||
"""Command executor which can run ResInsight Command File commands nearly verbatim. See
|
||||
[ Command File Interface ]({{< ref "commandfile.md" >}})
|
||||
|
||||
The differences are:
|
||||
|
||||
- Enum values have to be provided as strings. I.e. "ALL" instead of ALL.
|
||||
- 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, **command_params):
|
||||
return self.commands.Execute(Cmd.CommandParams(**command_params))
|
||||
|
||||
########################
|
||||
# Case Control Commands
|
||||
########################
|
||||
|
||||
def open_project(self, path):
|
||||
"""Open a project
|
||||
|
||||
Arguments:
|
||||
path (str): path to project file
|
||||
|
||||
|
||||
"""
|
||||
return self.__execute(openProject=Cmd.FilePathRequest(path=path))
|
||||
|
||||
def close_project(self):
|
||||
"""Close the current project (and reopen empty one)"""
|
||||
return self.__execute(closeProject=Empty())
|
||||
|
||||
def set_start_dir(self, path):
|
||||
"""Set current start directory
|
||||
|
||||
Arguments:
|
||||
path (str): path to directory
|
||||
|
||||
"""
|
||||
return self.__execute(setStartDir=Cmd.FilePathRequest(path=path))
|
||||
|
||||
def load_case(self, path):
|
||||
"""Load a case
|
||||
|
||||
Arguments:
|
||||
path (str): path to EGRID file
|
||||
|
||||
Returns:
|
||||
A Case object
|
||||
|
||||
"""
|
||||
command_reply = self.__execute(loadCase=Cmd.FilePathRequest(path=path))
|
||||
return rips.Case(self.channel, command_reply.loadCaseResult.id)
|
||||
|
||||
def replace_case(self, new_grid_file, case_id=0):
|
||||
"""Replace the given case with a new case loaded from file
|
||||
|
||||
Arguments:
|
||||
new_grid_file (str): path to EGRID file
|
||||
case_id (int): case Id to replace
|
||||
|
||||
"""
|
||||
return self.__execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=new_grid_file,
|
||||
caseId=case_id))
|
||||
|
||||
def replace_source_cases(self, grid_list_file, case_group_id=0):
|
||||
"""Replace all source cases within a case group
|
||||
|
||||
Arguments:
|
||||
grid_list_file (str): path to file containing a list of cases
|
||||
case_group_id (int): id of the case group to replace
|
||||
|
||||
"""
|
||||
return self.__execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=grid_list_file,
|
||||
caseGroupId=case_group_id))
|
||||
|
||||
def create_grid_case_group(self, case_paths):
|
||||
"""Create a Grid Case Group from a list of cases
|
||||
|
||||
Arguments:
|
||||
case_paths (list): list of file path strings
|
||||
|
||||
Returns:
|
||||
A case group id and name
|
||||
"""
|
||||
commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=case_paths))
|
||||
return (commandReply.createGridCaseGroupResult.groupId, commandReply.createGridCaseGroupResult.groupName)
|
||||
|
||||
def create_statistics_case(self, case_group_id):
|
||||
"""Create a Statistics case in a Grid Case Group
|
||||
|
||||
Arguments:
|
||||
case_group_id (int): id of the case group
|
||||
|
||||
Returns:
|
||||
A case id for the new case
|
||||
"""
|
||||
commandReply = self.__execute(createStatisticsCase=Cmd.CreateStatisticsCaseRequest(caseGroupId=case_group_id))
|
||||
return commandReply.createStatisticsCaseResult.caseId
|
||||
|
||||
##################
|
||||
# Export Commands
|
||||
##################
|
||||
|
||||
def export_multi_case_snapshots(self, grid_list_file):
|
||||
"""Export snapshots for a set of cases
|
||||
|
||||
Arguments:
|
||||
grid_list_file (str): Path to a file containing a list of grids to export snapshot for
|
||||
|
||||
"""
|
||||
return self.__execute(exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(gridListFile=grid_list_file))
|
||||
|
||||
def export_snapshots(self, type = 'ALL', prefix='', case_id = -1):
|
||||
""" Export snapshots of a given type
|
||||
|
||||
Arguments:
|
||||
type (str): Enum string ('ALL', 'VIEWS' or 'PLOTS')
|
||||
prefix (str): Exported file name prefix
|
||||
case_id (int): the case Id to export for. The default of -1 will export all cases
|
||||
|
||||
"""
|
||||
return self.__execute(exportSnapshots=Cmd.ExportSnapshotsRequest(type=type,
|
||||
prefix=prefix,
|
||||
caseId=case_id))
|
||||
|
||||
def export_property(self, case_id, time_step, property, eclipse_keyword=property, undefined_value=0.0, export_file=property):
|
||||
""" Export an Eclipse property
|
||||
|
||||
Arguments:
|
||||
case_id (int): case id
|
||||
time_step (int): time step index
|
||||
property (str): property to export
|
||||
eclipse_keyword (str): Eclipse keyword used as text in export header. Defaults to the value of property parameter.
|
||||
undefined_value (double): Value to use for undefined values. Defaults to 0.0
|
||||
export_file (str): File name for export. Defaults to the value of property parameter
|
||||
"""
|
||||
return self.__execute(exportProperty=Cmd.ExportPropertyRequest(caseId=case_id,
|
||||
timeStep=time_step,
|
||||
property=property,
|
||||
eclipseKeyword=eclipse_keyword,
|
||||
undefinedValue=undefined_value,
|
||||
exportFile=export_file))
|
||||
|
||||
def export_property_in_views(self, case_id, view_names, undefined_value):
|
||||
""" Export the current Eclipse property from the given views
|
||||
|
||||
Arguments:
|
||||
case_id (int): case id
|
||||
view_names (list): list of views
|
||||
undefined_value (double): Value to use for undefined values. Defaults to 0.0
|
||||
"""
|
||||
if isinstance(view_names, str):
|
||||
view_names = [view_names]
|
||||
|
||||
return self.__execute(exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(caseId=case_id,
|
||||
viewNames=view_names,
|
||||
undefinedValue=undefined_value))
|
||||
|
||||
def export_well_path_completions(self, case_id, time_step, well_path_names, file_split,
|
||||
compdat_export, include_perforations, include_fishbones,
|
||||
exclude_main_bore_for_fishbones, combination_mode):
|
||||
if (isinstance(well_path_names, str)):
|
||||
well_path_names = [well_path_names]
|
||||
return self.__execute(exportWellPathCompletions=Cmd.ExportWellPathCompRequest(caseId=case_id,
|
||||
timeStep=time_step,
|
||||
wellPathNames=well_path_names,
|
||||
fileSplit=file_split,
|
||||
compdatExport=compdat_export,
|
||||
includePerforations=include_perforations,
|
||||
includeFishbones=include_fishbones,
|
||||
excludeMainBoreForFishbones=exclude_main_bore_for_fishbones,
|
||||
combinationMode=combination_mode))
|
||||
|
||||
def export_sim_well_fracture_completions(self, case_id, view_name, time_step, simulation_well_names, file_split, compdat_export):
|
||||
if(isinstance(simulation_well_names, str)):
|
||||
simulation_well_names = [simulation_well_names]
|
||||
return self.__execute(exportSimWellFractureCompletions=Cmd.ExportSimWellPathFraqRequest(caseId=case_id,
|
||||
viewName=view_name,
|
||||
timeStep=time_step,
|
||||
simulationWellNames=simulation_well_names,
|
||||
fileSplit=file_split,
|
||||
compdatExport=compdat_export))
|
||||
|
||||
def export_msw(self, case_id, well_path):
|
||||
return self.__execute(exportMsw=Cmd.ExportMswRequest(caseId=case_id,
|
||||
wellPath=well_path))
|
||||
|
||||
def export_well_paths(self, well_paths=[], md_step_size=5.0):
|
||||
if isinstance(well_paths, str):
|
||||
well_paths = [well_paths]
|
||||
return self.__execute(exportWellPaths=Cmd.ExportWellPathRequest(wellPathNames=well_paths, mdStepSize=md_step_size))
|
||||
|
||||
def export_visible_cells(self, case_id, view_name, export_keyword='FLUXNUM', visible_active_cells_value=1, hidden_active_cells_value=0, inactive_cells_value=0):
|
||||
return self.__execute(exportVisibleCells=Cmd.ExportVisibleCellsRequest(caseId=case_id,
|
||||
viewName=view_name,
|
||||
exportKeyword=export_keyword,
|
||||
visibleActiveCellsValue=visible_active_cells_value,
|
||||
hiddenActiveCellsValue=hidden_active_cells_value,
|
||||
inactiveCellsValue=inactive_cells_value))
|
||||
def set_export_folder(self, type, path, create_folder=False):
|
||||
return self.__execute(setExportFolder=Cmd.SetExportFolderRequest(type=type,
|
||||
path=path,
|
||||
createFolder=create_folder))
|
||||
|
||||
def run_octave_script(self, path, cases):
|
||||
caseIds = []
|
||||
for case in cases:
|
||||
caseIds.append(case.id)
|
||||
return self.__execute(runOctaveScript=Cmd.RunOctaveScriptRequest(path=path,
|
||||
caseIds=caseIds))
|
||||
|
||||
def set_main_window_size(self, width, height):
|
||||
return self.__execute(setMainWindowSize=Cmd.SetMainWindowSizeParams(width=width, height=height))
|
||||
|
||||
def compute_case_group_statistics(self, case_ids = [], case_group_id = -1):
|
||||
return self.__execute(computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(caseIds=case_ids,
|
||||
caseGroupId=case_group_id))
|
||||
|
||||
def set_time_step(self, case_id, time_step):
|
||||
return self.__execute(setTimeStep=Cmd.SetTimeStepParams(caseId=case_id, timeStep=time_step))
|
||||
|
||||
def scale_fracture_template(self, id, half_length, height, dfactor, conductivity):
|
||||
return self.__execute(scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(id=id,
|
||||
halfLength=half_length,
|
||||
height=height,
|
||||
dFactor=dfactor,
|
||||
conductivity=conductivity))
|
||||
|
||||
def set_fracture_containment(self, id, top_layer, base_layer):
|
||||
return self.__execute(setFractureContainment=Cmd.SetFracContainmentRequest(id=id,
|
||||
topLayer=top_layer,
|
||||
baseLayer=base_layer))
|
||||
|
||||
def create_multiple_fractures(self, case_id, template_id, well_path_names, min_dist_from_well_td,
|
||||
max_fractures_per_well, top_layer, base_layer, spacing, action):
|
||||
if isinstance(well_path_names, str):
|
||||
well_path_names = [well_path_names]
|
||||
return self.__execute(createMultipleFractures=Cmd.MultipleFracAction(caseId=case_id,
|
||||
templateId=template_id,
|
||||
wellPathNames=well_path_names,
|
||||
minDistFromWellTd=min_dist_from_well_td,
|
||||
maxFracturesPerWell=max_fractures_per_well,
|
||||
topLayer=top_layer,
|
||||
baseLayer=base_layer,
|
||||
spacing=spacing,
|
||||
action=action))
|
||||
|
||||
def create_lgr_for_completion(self, case_id, time_step, well_path_names, refinement_i, refinement_j, refinement_k, split_type):
|
||||
if isinstance(well_path_names, str):
|
||||
well_path_names = [well_path_names]
|
||||
return self.__execute(createLgrForCompletions=Cmd.CreateLgrForCompRequest(caseId=case_id,
|
||||
timeStep=time_step,
|
||||
wellPathNames=well_path_names,
|
||||
refinementI=refinement_i,
|
||||
refinementJ=refinement_j,
|
||||
refinementK=refinement_k,
|
||||
splitType=split_type))
|
||||
|
||||
def create_saturation_pressure_plots(self, case_ids):
|
||||
if isinstance(case_ids, int):
|
||||
case_ids = [case_ids]
|
||||
return self.__execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=case_ids))
|
||||
|
||||
def export_flow_characteristics(self, case_id, time_steps, injectors, producers, file_name, minimum_communication=0.0, aquifer_cell_threshold=0.1):
|
||||
""" Export Flow Characteristics data to text file in CSV format
|
||||
|
||||
Parameter | Description | Type
|
||||
------------------------- | --------------------------------------------- | -----
|
||||
case_id | ID of case | Integer
|
||||
time_steps | Time step indices | List of Integer
|
||||
injectors | Injector names | List of Strings
|
||||
producers | Producer names | List of Strings
|
||||
file_name | Export file name | Integer
|
||||
minimum_communication | Minimum Communication, defaults to 0.0 | Integer
|
||||
aquifer_cell_threshold | Aquifer Cell Threshold, defaults to 0.1 | Integer
|
||||
|
||||
"""
|
||||
if isinstance(time_steps, int):
|
||||
time_steps = [time_steps]
|
||||
if isinstance(injectors, str):
|
||||
injectors = [injectors]
|
||||
if isinstance(producers, str):
|
||||
producers = [producers]
|
||||
return self.__execute(exportFlowCharacteristics=Cmd.ExportFlowInfoRequest(caseId=case_id,
|
||||
timeSteps=time_steps,
|
||||
injectors=injectors,
|
||||
producers=producers,
|
||||
fileName=file_name,
|
||||
minimumCommunication = minimum_communication,
|
||||
aquiferCellThreshold = aquifer_cell_threshold))
|
||||
|
||||
def create_view(self, case_id):
|
||||
return self.__execute(createView=Cmd.CreateViewRequest(caseId=case_id)).createViewResult.viewId
|
||||
|
||||
def clone_view(self, view_id):
|
||||
return self.__execute(cloneView=Cmd.CloneViewRequest(viewId=view_id)).createViewResult.viewId
|
@ -1,27 +0,0 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
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
|
||||
|
@ -1,48 +0,0 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
from rips.PdmObject import PdmObject
|
||||
from rips.View import View
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
import PdmObject_pb2
|
||||
|
||||
class GridCaseGroup (PdmObject):
|
||||
"""ResInsight Grid Case Group class
|
||||
|
||||
Operate on a ResInsight case group specified by a Case Group Id integer.
|
||||
|
||||
Attributes:
|
||||
group_id (int): Grid Case Group Id corresponding to case group Id in ResInsight project.
|
||||
"""
|
||||
def __init__(self, pdm_object):
|
||||
self.group_id = pdm_object.get_value("GroupId")
|
||||
PdmObject.__init__(self, pdm_object.pb2Object, pdm_object.channel)
|
||||
|
||||
def statistics_cases(self):
|
||||
"""Get a list of all statistics cases in the Grid Case Group"""
|
||||
stat_case_collection = self.children("StatisticsCaseCollection")[0]
|
||||
return stat_case_collection.children("Reservoirs")
|
||||
|
||||
def views(self):
|
||||
"""Get a list of views belonging to a grid case group"""
|
||||
pdm_objects = self.descendants("ReservoirView")
|
||||
view_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
view_list.append(View(pdm_object))
|
||||
return view_list
|
||||
|
||||
def view(self, id):
|
||||
"""Get a particular view belonging to a case group by providing view id
|
||||
Arguments:
|
||||
id(int): view id
|
||||
|
||||
Returns: a view object
|
||||
|
||||
"""
|
||||
views = self.views()
|
||||
for view_object in views:
|
||||
if view_object.id == id:
|
||||
return view_object
|
||||
return None
|
@ -1,196 +0,0 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
import logging
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
import App_pb2
|
||||
import App_pb2_grpc
|
||||
from Definitions_pb2 import Empty
|
||||
|
||||
import RiaVersionInfo
|
||||
|
||||
from rips.Commands import Commands
|
||||
from rips.Project import Project
|
||||
|
||||
class Instance:
|
||||
"""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.
|
||||
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):
|
||||
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(resinsight_executable = '', console = False, launch_port = -1, command_line_parameters=[]):
|
||||
""" Launch a new Instance of ResInsight. This requires the environment variable
|
||||
RESINSIGHT_EXECUTABLE to be set or the parameter resinsight_executable to be provided.
|
||||
The RESINSIGHT_GRPC_PORT environment variable can be set to an alternative port number.
|
||||
|
||||
Args:
|
||||
resinsight_executable (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.
|
||||
launch_port(int): If -1 will use the default port of 50051 or look for RESINSIGHT_GRPC_PORT
|
||||
if anything else, ResInsight will try to launch with this port
|
||||
command_line_parameters(list): Additional command line parameters as string entries in the list.
|
||||
Returns:
|
||||
Instance: an instance object if it worked. None if not.
|
||||
"""
|
||||
|
||||
port = 50051
|
||||
port_env = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if port_env:
|
||||
port = int(port_env)
|
||||
if launch_port is not -1:
|
||||
port = launch_port
|
||||
|
||||
if not resinsight_executable:
|
||||
resinsight_executable = os.environ.get('RESINSIGHT_EXECUTABLE')
|
||||
if not resinsight_executable:
|
||||
print('ERROR: Could not launch ResInsight because the environment variable'
|
||||
' RESINSIGHT_EXECUTABLE is not set')
|
||||
return None
|
||||
|
||||
while Instance.__is_port_in_use(port):
|
||||
port += 1
|
||||
|
||||
print('Port ' + str(port))
|
||||
print('Trying to launch', resinsight_executable)
|
||||
|
||||
if isinstance(command_line_parameters, str):
|
||||
command_line_parameters = [str]
|
||||
|
||||
parameters = ["ResInsight", "--server", str(port)] + command_line_parameters
|
||||
if console:
|
||||
print("Launching as console app")
|
||||
parameters.append("--console")
|
||||
|
||||
# Stringify all parameters
|
||||
for i in range(0, len(parameters)):
|
||||
parameters[i] = str(parameters[i])
|
||||
|
||||
pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters)
|
||||
if pid:
|
||||
instance = Instance(port=port, launched=True)
|
||||
return instance
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def find(start_port = 50051, end_port = 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:
|
||||
start_port (int): start searching from this port
|
||||
end_port (int): search up to but not including this port
|
||||
"""
|
||||
port_env = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if port_env:
|
||||
start_port = int(port_env)
|
||||
end_port = start_port + 20
|
||||
|
||||
for try_port in range(start_port, end_port):
|
||||
if Instance.__is_port_in_use(try_port):
|
||||
return Instance(port=try_port)
|
||||
|
||||
print('Error: Could not find any ResInsight instances responding between ports ' + str(start_port) + ' and ' + str(end_port))
|
||||
return None
|
||||
|
||||
def __check_version(self):
|
||||
try:
|
||||
major_version_ok = self.major_version() == int(RiaVersionInfo.RESINSIGHT_MAJOR_VERSION)
|
||||
minor_version_ok = self.minor_version() == int(RiaVersionInfo.RESINSIGHT_MINOR_VERSION)
|
||||
return True, major_version_ok and minor_version_ok
|
||||
except:
|
||||
return False, False
|
||||
|
||||
def __init__(self, port = 50051, launched = False):
|
||||
""" 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, options=[('grpc.enable_http_proxy', False)])
|
||||
self.launched = launched
|
||||
|
||||
# Main version check package
|
||||
self.app = self.app = App_pb2_grpc.AppStub(self.channel)
|
||||
|
||||
connection_ok = False
|
||||
version_ok = False
|
||||
|
||||
if self.launched:
|
||||
for i in range(0, 10):
|
||||
connection_ok, version_ok = self.__check_version()
|
||||
if connection_ok:
|
||||
break
|
||||
time.sleep(1.0)
|
||||
else:
|
||||
connection_ok, version_ok = self.__check_version()
|
||||
|
||||
if not connection_ok:
|
||||
if self.launched:
|
||||
raise Exception('Error: Could not connect to resinsight at ', location, ' after trying 10 times with 1 second apart')
|
||||
else:
|
||||
raise Exception('Error: Could not connect to resinsight at ', location)
|
||||
exit(1)
|
||||
if not version_ok:
|
||||
raise Exception('Error: Wrong Version of ResInsight at ', location)
|
||||
|
||||
# Service packages
|
||||
self.commands = Commands(self.channel)
|
||||
self.project = Project(self.channel)
|
||||
|
||||
path = os.getcwd()
|
||||
self.commands.set_start_dir(path=path)
|
||||
|
||||
def __version_message(self):
|
||||
return self.app.GetVersion(Empty())
|
||||
|
||||
def major_version(self):
|
||||
"""Get an integer with the major version number"""
|
||||
return self.__version_message().major_version
|
||||
|
||||
def minor_version(self):
|
||||
"""Get an integer with the minor version number"""
|
||||
return self.__version_message().minor_version
|
||||
|
||||
def patch_version(self):
|
||||
"""Get an integer with the patch version number"""
|
||||
return self.__version_message().patch_version
|
||||
|
||||
def version_string(self):
|
||||
"""Get a full version string, i.e. 2019.04.01"""
|
||||
return str(self.major_version()) + "." + str(self.minor_version()) + "." + str(self.patch_version())
|
||||
|
||||
def exit(self):
|
||||
"""Tell ResInsight instance to quit"""
|
||||
print("Telling ResInsight to Exit")
|
||||
return self.app.Exit(Empty())
|
||||
|
||||
def is_console(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 is_gui(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')
|
@ -1,149 +0,0 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
|
||||
from rips.Case import Case
|
||||
from rips.Commands import Commands
|
||||
from rips.GridCaseGroup import GridCaseGroup
|
||||
from rips.PdmObject import PdmObject
|
||||
from rips.View import View
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
from Definitions_pb2 import Empty
|
||||
import Project_pb2
|
||||
import Project_pb2_grpc
|
||||
|
||||
class Project (PdmObject):
|
||||
"""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)
|
||||
PdmObject.__init__(self, self.project.GetPdmObject(Empty()), self.channel)
|
||||
|
||||
def open(self, path):
|
||||
"""Open a new project from the given path
|
||||
|
||||
Arguments:
|
||||
path(str): path to project file
|
||||
|
||||
"""
|
||||
Commands(self.channel).open_project(path)
|
||||
return self
|
||||
|
||||
def close(self):
|
||||
"""Close the current project (and open new blank project)"""
|
||||
Commands(self.channel).close_project()
|
||||
|
||||
def selected_cases(self):
|
||||
"""Get a list of all cases selected in the project tree
|
||||
|
||||
Returns:
|
||||
A list of rips Case objects
|
||||
"""
|
||||
case_infos = self.project.GetSelectedCases(Empty())
|
||||
cases = []
|
||||
for case_info in case_infos.data:
|
||||
cases.append(Case(self.channel, case_info.id))
|
||||
return cases
|
||||
|
||||
def cases(self):
|
||||
"""Get a list of all cases in the project
|
||||
|
||||
Returns:
|
||||
A list of rips Case objects
|
||||
"""
|
||||
try:
|
||||
case_infos = self.project.GetAllCases(Empty())
|
||||
|
||||
cases = []
|
||||
for case_info in case_infos.data:
|
||||
cases.append(Case(self.channel, case_info.id))
|
||||
return cases
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
return []
|
||||
else:
|
||||
print("ERROR: ", e)
|
||||
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
|
||||
except grpc.RpcError as e:
|
||||
return None
|
||||
|
||||
def load_case(self, path):
|
||||
"""Load a new case from the given file path
|
||||
|
||||
Arguments:
|
||||
path(str): file path to case
|
||||
Returns:
|
||||
A rips Case object
|
||||
"""
|
||||
return Commands(self.channel).load_case(path)
|
||||
|
||||
def views(self):
|
||||
"""Get a list of views belonging to a project"""
|
||||
pdm_objects = self.descendants("ReservoirView")
|
||||
view_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
view_list.append(View(pdm_object))
|
||||
return view_list
|
||||
|
||||
def view(self, id):
|
||||
"""Get a particular view belonging to a case by providing view id
|
||||
Arguments:
|
||||
id(int): view id
|
||||
|
||||
Returns: a view object
|
||||
|
||||
"""
|
||||
views = self.views()
|
||||
for view_object in views:
|
||||
if view_object.id == id:
|
||||
return view_object
|
||||
return None
|
||||
|
||||
def grid_case_groups(self):
|
||||
"""Get a list of all grid case groups in the project"""
|
||||
case_groups = self.descendants("RimIdenticalGridCaseGroup")
|
||||
|
||||
case_group_list = []
|
||||
for pdm_group in case_groups:
|
||||
case_group_list.append(GridCaseGroup(pdm_group))
|
||||
return case_group_list
|
||||
|
||||
def grid_case_group(self, group_id):
|
||||
"""Get a particular grid case group belonging to a project
|
||||
Arguments:
|
||||
groupId(int): group id
|
||||
|
||||
Returns: a grid case group object
|
||||
"""
|
||||
case_groups = self.grid_case_groups()
|
||||
for case_group in case_groups:
|
||||
if case_group.groupId == group_id:
|
||||
return case_group
|
||||
return None
|
||||
|
||||
def create_grid_case_group(self, case_paths):
|
||||
"""Create a new grid case group from the provided case paths
|
||||
Arguments:
|
||||
casePaths(list): a list of paths to the cases to be loaded and included in the group
|
||||
Returns:
|
||||
A new grid case group object
|
||||
"""
|
||||
group_id, group_name = Commands(self.channel).create_grid_case_group(case_paths)
|
||||
return self.grid_case_group(group_id)
|
@ -1,239 +0,0 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
import Properties_pb2
|
||||
import Properties_pb2_grpc
|
||||
import Case_pb2
|
||||
import Case_pb2_grpc
|
||||
from Definitions_pb2 import ClientToServerStreamReply
|
||||
|
||||
class Properties:
|
||||
""" Class for streaming properties to and from ResInsight
|
||||
|
||||
Attributes:
|
||||
chunkSize(int): The size of each chunk during value streaming.
|
||||
A good chunk size is 64KiB = 65536B.
|
||||
Meaning the ideal number of doubles would be 8192.
|
||||
However we need overhead space, so the default is 8160.
|
||||
This leaves 256B for overhead.
|
||||
"""
|
||||
def __init__(self, case):
|
||||
"""
|
||||
Arguments:
|
||||
case(Case): A rips case to handle properties for
|
||||
"""
|
||||
self.case = case
|
||||
self._properties_stub = Properties_pb2_grpc.PropertiesStub(self.case.channel)
|
||||
self.chunk_size = 8160
|
||||
|
||||
|
||||
def __generate_property_input_iterator(self, values_iterator, parameters):
|
||||
chunk = Properties_pb2.PropertyInputChunk()
|
||||
chunk.params.CopyFrom(parameters)
|
||||
yield chunk
|
||||
|
||||
for values in values_iterator:
|
||||
valmsg = Properties_pb2.PropertyChunk(values = values)
|
||||
chunk.values.CopyFrom(valmsg)
|
||||
yield chunk
|
||||
|
||||
def __generate_property_input_chunks(self, array, parameters):
|
||||
|
||||
index = -1
|
||||
while index < len(array):
|
||||
chunk = Properties_pb2.PropertyInputChunk()
|
||||
if index is -1:
|
||||
chunk.params.CopyFrom(parameters)
|
||||
index += 1
|
||||
else:
|
||||
actual_chunk_size = min(len(array) - index + 1, self.chunk_size)
|
||||
chunk.values.CopyFrom(Properties_pb2.PropertyChunk(values = array[index:index+actual_chunk_size]))
|
||||
index += actual_chunk_size
|
||||
|
||||
yield chunk
|
||||
# Final empty message to signal completion
|
||||
chunk = Properties_pb2.PropertyInputChunk()
|
||||
yield chunk
|
||||
|
||||
def available(self, property_type, porosity_model = 'MATRIX_MODEL'):
|
||||
"""Get a list of available properties
|
||||
|
||||
Arguments:
|
||||
property_type (str): string corresponding to property_type enum. Can be one of the following:
|
||||
- DYNAMIC_NATIVE
|
||||
- STATIC_NATIVE
|
||||
- SOURSIMRL
|
||||
- GENERATED
|
||||
- INPUT_PROPERTY
|
||||
- FORMATION_NAMES
|
||||
- FLOW_DIAGNOSTICS
|
||||
- INJECTION_FLOODING
|
||||
|
||||
porosity_model(str): 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
"""
|
||||
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.AvailablePropertiesRequest (case_request = Case_pb2.CaseRequest(id=self.case.id),
|
||||
property_type = property_type_enum,
|
||||
porosity_model = porosity_model_enum)
|
||||
return self._properties_stub.GetAvailableProperties(request).property_names
|
||||
|
||||
def active_cell_property_async(self, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'):
|
||||
"""Get a cell property for all active cells. Async, so returns an iterator
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): 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.
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(case_request = Case_pb2.CaseRequest(id=self.case.id),
|
||||
property_type = property_type_enum,
|
||||
property_name = property_name,
|
||||
time_step = time_step,
|
||||
porosity_model = porosity_model_enum)
|
||||
for chunk in self._properties_stub.GetActiveCellProperty(request):
|
||||
yield chunk
|
||||
|
||||
def active_cell_property(self, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'):
|
||||
"""Get a cell property for all active cells. Sync, so returns a list
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): string enum. See available()
|
||||
|
||||
Returns:
|
||||
A list containing double values
|
||||
You first loop through the chunks and then the values within the chunk to get all values.
|
||||
"""
|
||||
all_values = []
|
||||
generator = self.active_cell_property_async(property_type, property_name, time_step, porosity_model)
|
||||
for chunk in generator:
|
||||
for value in chunk.values:
|
||||
all_values.append(value)
|
||||
return all_values
|
||||
|
||||
def grid_property_async(self, property_type, property_name, time_step, gridIndex = 0, porosity_model = 'MATRIX_MODEL'):
|
||||
"""Get a cell property for all grid cells. Async, so returns an iterator
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
gridIndex(int): index to the grid we're getting values for
|
||||
porosity_model(str): 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.
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
property_type = property_type_enum,
|
||||
property_name = property_name,
|
||||
time_step = time_step,
|
||||
grid_index = gridIndex,
|
||||
porosity_model = porosity_model_enum)
|
||||
for chunk in self._properties_stub.GetGridProperty(request):
|
||||
yield chunk
|
||||
|
||||
def grid_property(self, property_type, property_name, time_step, grid_index = 0, porosity_model = 'MATRIX_MODEL'):
|
||||
"""Get a cell property for all grid cells. Synchronous, so returns a list
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
grid_index(int): index to the grid we're getting values for
|
||||
porosity_model(str): string enum. See available()
|
||||
|
||||
Returns:
|
||||
A list of double values
|
||||
"""
|
||||
all_values = []
|
||||
generator = self.grid_property_async(property_type, property_name, time_step, grid_index, porosity_model)
|
||||
for chunk in generator:
|
||||
for value in chunk.values:
|
||||
all_values.append(value)
|
||||
return all_values
|
||||
|
||||
def set_active_cell_property_async(self, values_iterator, property_type, property_name, time_step, porosity_model = '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
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): string enum. See available()
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
property_type = property_type_enum,
|
||||
property_name = property_name,
|
||||
time_step = time_step,
|
||||
porosity_model = porosity_model_enum)
|
||||
|
||||
request_iterator = self.__generate_property_input_iterator(values_iterator, request)
|
||||
self._properties_stub.SetActiveCellProperty(request_iterator)
|
||||
|
||||
def set_active_cell_property(self, values, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'):
|
||||
"""Set a cell property for all active cells.
|
||||
|
||||
Arguments:
|
||||
values(list): a list of double precision floating point numbers
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): string enum. See available()
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
property_type = property_type_enum,
|
||||
property_name = property_name,
|
||||
time_step = time_step,
|
||||
porosity_model = porosity_model_enum)
|
||||
request_iterator = self.__generate_property_input_chunks(values, request)
|
||||
reply = self._properties_stub.SetActiveCellProperty(request_iterator)
|
||||
if reply.accepted_value_count < len(values):
|
||||
raise IndexError
|
||||
|
||||
def set_grid_property(self, values, property_type, property_name, time_step, grid_index = 0, porosity_model = 'MATRIX_MODEL'):
|
||||
"""Set a cell property for all grid cells.
|
||||
|
||||
Arguments:
|
||||
values(list): a list of double precision floating point numbers
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
grid_index(int): index to the grid we're setting values for
|
||||
porosity_model(str): string enum. See available()
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(case_request = self.case.request,
|
||||
property_type = property_type_enum,
|
||||
property_name = property_name,
|
||||
time_step = time_step,
|
||||
grid_index = grid_index,
|
||||
porosity_model = porosity_model_enum)
|
||||
request_iterator = self.__generate_property_input_chunks(values, request)
|
||||
reply = self._properties_stub.SetGridProperty(request_iterator)
|
||||
if reply.accepted_value_count < len(values):
|
||||
raise IndexError
|
||||
|
@ -6,8 +6,8 @@ resinsight = rips.Instance.find()
|
||||
case_paths = []
|
||||
case_paths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID")
|
||||
case_paths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID")
|
||||
for casePath in case_paths:
|
||||
assert os.path.exists(casePath), "You need to set valid case paths for this script to work"
|
||||
for case_path in case_paths:
|
||||
assert os.path.exists(case_path), "You need to set valid case paths for this script to work"
|
||||
|
||||
case_group = resinsight.project.create_grid_case_group(case_paths=case_paths)
|
||||
|
||||
@ -20,7 +20,7 @@ case_group.print_object_info()
|
||||
# stat_case.update()
|
||||
# case_ids.append(stat_case.get_value("CaseId"))
|
||||
|
||||
resinsight.commands.compute_case_group_statistics(case_group_id=case_group.group_id)
|
||||
case_group.compute_statistics()
|
||||
|
||||
view = case_group.views()[0]
|
||||
cell_result = view.set_cell_result()
|
||||
|
@ -9,7 +9,7 @@ import rips
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
# Get the case with id == 0. This will fail if your project doesn't have a case with id == 0
|
||||
case = resinsight.project.case(id = 0)
|
||||
case = resinsight.project.case(id=0)
|
||||
|
||||
# Get the cell count object
|
||||
cell_counts = case.cell_count()
|
||||
|
@ -1,7 +1,5 @@
|
||||
###############################################################################
|
||||
# This example will run a few ResInsight command file commands
|
||||
# .. which are exposed in the Python interface.
|
||||
# Including setting time step, window size and export snapshots and properties
|
||||
# This example will show setting time step, window size and export snapshots and properties
|
||||
###############################################################################
|
||||
import os
|
||||
import tempfile
|
||||
@ -10,9 +8,24 @@ import rips
|
||||
# Load instance
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
# Run a couple of commands
|
||||
resinsight.commands.set_time_step(case_id=0, time_step=3)
|
||||
resinsight.commands.set_main_window_size(width=800, height=500)
|
||||
# Set window size
|
||||
resinsight.set_main_window_size(width=800, height=500)
|
||||
|
||||
# Retrieve first case
|
||||
case = resinsight.project.cases()[0]
|
||||
|
||||
# Get a view
|
||||
view1 = case.view(view_id=0)
|
||||
|
||||
# Clone the view
|
||||
view2 = view1.clone()
|
||||
|
||||
# Set the time step for view1 only
|
||||
view1.set_time_step(time_step=2)
|
||||
|
||||
# Set cell result to SOIL
|
||||
view1.apply_cell_result(result_type='DYNAMIC_NATIVE', result_variable='SOIL')
|
||||
|
||||
|
||||
# Create a temporary directory which will disappear at the end of this script
|
||||
# If you want to keep the files, provide a good path name instead of tmpdirname
|
||||
@ -20,23 +33,23 @@ with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
|
||||
print("Temporary folder: ", tmpdirname)
|
||||
|
||||
# Set export folder for snapshots and properties
|
||||
resinsight.commands.set_export_folder(type='SNAPSHOTS', path=tmpdirname)
|
||||
resinsight.commands.set_export_folder(type='PROPERTIES', path=tmpdirname)
|
||||
resinsight.set_export_folder(export_type='SNAPSHOTS', path=tmpdirname)
|
||||
resinsight.set_export_folder(export_type='PROPERTIES', path=tmpdirname)
|
||||
|
||||
# Export snapshots
|
||||
resinsight.commands.export_snapshots()
|
||||
# Export all snapshots
|
||||
resinsight.project.export_snapshots()
|
||||
|
||||
assert(len(os.listdir(tmpdirname)) > 0)
|
||||
|
||||
# Export properties in the view
|
||||
view1.export_property()
|
||||
|
||||
# Check that the exported file exists
|
||||
expected_file_name = case.name + "-" + str("3D_View") + "-" + "T2" + "-SOIL"
|
||||
full_path = tmpdirname + "/" + expected_file_name
|
||||
|
||||
# Print contents of temporary folder
|
||||
print(os.listdir(tmpdirname))
|
||||
|
||||
assert(len(os.listdir(tmpdirname)) > 0)
|
||||
case = resinsight.project.case(id=0)
|
||||
|
||||
# Export properties in the view
|
||||
resinsight.commands.export_property_in_views(0, "3D View", 0)
|
||||
|
||||
# Check that the exported file exists
|
||||
expected_file_name = case.name + "-" + str("3D_View") + "-" + "T3" + "-SOIL"
|
||||
full_path = tmpdirname + "/" + expected_file_name
|
||||
assert(os.path.exists(full_path))
|
||||
|
||||
|
@ -16,14 +16,14 @@ try:
|
||||
except grpc.RpcError as e:
|
||||
print("Expected Server Exception Received: ", e)
|
||||
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
if case is not None:
|
||||
results = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0)
|
||||
results = case.active_cell_property('STATIC_NATIVE', 'PORO', 0)
|
||||
active_cell_count = len(results)
|
||||
|
||||
# Send the results back to ResInsight inside try / except construct
|
||||
try:
|
||||
case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0)
|
||||
case.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0)
|
||||
print("Everything went well as expected")
|
||||
except: # Match any exception, but it should not happen
|
||||
print("Ooops!")
|
||||
@ -33,7 +33,7 @@ if case is not None:
|
||||
|
||||
# This time we should get a grpc.RpcError exception, which is a server side error.
|
||||
try:
|
||||
case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0)
|
||||
case.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0)
|
||||
print("Everything went well??")
|
||||
except grpc.RpcError as e:
|
||||
print("Expected Server Exception Received: ", e)
|
||||
@ -43,10 +43,10 @@ if case is not None:
|
||||
# With a chunk size exactly matching the active cell count the server will not
|
||||
# be able to see any error as it will successfully close the stream after receiving
|
||||
# the correct number of values, even if the python client has more chunks to send
|
||||
case.properties.chunk_size = active_cell_count
|
||||
case.chunk_size = active_cell_count
|
||||
|
||||
try:
|
||||
case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0)
|
||||
case.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0)
|
||||
print("Everything went well??")
|
||||
except grpc.RpcError as e:
|
||||
print("Got unexpected server exception", e, "This should not happen now")
|
||||
|
@ -10,13 +10,15 @@ resinsight = rips.Instance.find()
|
||||
cases = resinsight.project.cases()
|
||||
|
||||
# Set main window size
|
||||
resinsight.commands.set_main_window_size(width=800, height=500)
|
||||
resinsight.set_main_window_size(width=800, height=500)
|
||||
|
||||
n = 5 # every n-th time_step for snapshot
|
||||
property_list = ['SOIL', 'PRESSURE'] # list of parameter for snapshot
|
||||
|
||||
print ("Looping through cases")
|
||||
for case in cases:
|
||||
print("Case name: ", case.name)
|
||||
print("Case id: ", case.case_id)
|
||||
# Get grid path and its folder name
|
||||
case_path = case.grid_path()
|
||||
folder_name = os.path.dirname(case_path)
|
||||
@ -28,16 +30,14 @@ for case in cases:
|
||||
os.mkdir(dirname)
|
||||
|
||||
print ("Exporting to folder: " + dirname)
|
||||
resinsight.commands.set_export_folder(type='SNAPSHOTS', path=dirname)
|
||||
resinsight.set_export_folder(export_type='SNAPSHOTS', path=dirname)
|
||||
|
||||
time_steps = case.time_steps()
|
||||
tss_snapshot = range(0, len(time_steps), n)
|
||||
print(case.name, case.id, 'Number of time_steps: ' + str(len(time_steps)))
|
||||
print('Number of time_steps for snapshoting: ' + str(len(tss_snapshot)))
|
||||
print('Number of time_steps: ' + str(len(time_steps)))
|
||||
|
||||
view = case.views()[0]
|
||||
for property in property_list:
|
||||
view.apply_cell_result(result_type='DYNAMIC_NATIVE', result_variable=property)
|
||||
for ts_snapshot in tss_snapshot:
|
||||
resinsight.commands.set_time_step(case_id = case.id, time_step = ts_snapshot)
|
||||
resinsight.commands.export_snapshots(type='VIEWS', case_id=case.id) # ‘ALL’, ‘VIEWS’ or ‘PLOTS’ default is 'ALL'
|
||||
for time_step in range(0, len(time_steps), 10):
|
||||
view.set_time_step(time_step = time_step)
|
||||
view.export_snapshot()
|
||||
|
@ -19,17 +19,17 @@ def create_result(poro_chunks, permx_chunks):
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
start = time.time()
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
|
||||
# Get a generator for the poro results. The generator will provide a chunk each time it is iterated
|
||||
poro_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORO', 0)
|
||||
poro_chunks = case.active_cell_property_async('STATIC_NATIVE', 'PORO', 0)
|
||||
# Get a generator for the permx results. The generator will provide a chunk each time it is iterated
|
||||
permx_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0)
|
||||
permx_chunks = case.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0)
|
||||
|
||||
# Send back the result with the result provided by a generator object.
|
||||
# Iterating the result generator will cause the script to read from the poro and permx generators
|
||||
# And return the result of each iteration
|
||||
case.properties.set_active_cell_property_async(create_result(poro_chunks, permx_chunks),
|
||||
case.set_active_cell_property_async(create_result(poro_chunks, permx_chunks),
|
||||
'GENERATED', 'POROPERMXAS', 0)
|
||||
|
||||
end = time.time()
|
||||
|
@ -9,12 +9,12 @@ import grpc
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
start = time.time()
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
|
||||
# Read poro result into list
|
||||
poro_results = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0)
|
||||
poro_results = case.active_cell_property('STATIC_NATIVE', 'PORO', 0)
|
||||
# Read permx result into list
|
||||
permx_results = case.properties.active_cell_property('STATIC_NATIVE', 'PERMX', 0)
|
||||
permx_results = case.active_cell_property('STATIC_NATIVE', 'PERMX', 0)
|
||||
|
||||
# Generate output result
|
||||
results = []
|
||||
@ -23,7 +23,7 @@ for (poro, permx) in zip(poro_results, permx_results):
|
||||
|
||||
try:
|
||||
# Send back output result
|
||||
case.properties.set_active_cell_property(results, 'GENERATED', 'POROPERMXSY', 0)
|
||||
case.set_active_cell_property(results, 'GENERATED', 'POROPERMXSY', 0)
|
||||
except grpc.RpcError as e:
|
||||
print("Exception Received: ", e)
|
||||
|
||||
|
@ -14,7 +14,7 @@ if resinsight is not None:
|
||||
print ("Got " + str(len(cases)) + " cases: ")
|
||||
for case in cases:
|
||||
print(case.name)
|
||||
for property in case.properties.available('DYNAMIC_NATIVE'):
|
||||
for property in case.available_properties('DYNAMIC_NATIVE'):
|
||||
print(property)
|
||||
|
||||
|
||||
|
@ -5,5 +5,5 @@ import rips
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
view = resinsight.project.view(0)
|
||||
view.apply_cell_result(resultType='STATIC_NATIVE', resultVariable='DX')
|
||||
view = resinsight.project.view(view_id=0)
|
||||
view.apply_cell_result(result_type='STATIC_NATIVE', result_variable='DX')
|
||||
|
@ -7,7 +7,7 @@ import rips
|
||||
# Connect to ResInsight instance
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
view = resinsight.project.view(0)
|
||||
view = resinsight.project.view(view_id=0)
|
||||
#view.apply_flow_diagnostics_cell_result(result_variable='Fraction',
|
||||
# selection_mode='FLOW_TR_INJ_AND_PROD')
|
||||
|
||||
|
@ -5,7 +5,7 @@ import rips
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
total_cell_count = case.cell_count().reservoir_cell_count
|
||||
|
||||
values = []
|
||||
@ -13,5 +13,5 @@ for i in range(0, total_cell_count):
|
||||
values.append(i % 2 * 0.75);
|
||||
|
||||
print("Applying values to full grid")
|
||||
case.properties.set_grid_property(values, 'DYNAMIC_NATIVE', 'SOIL', 0)
|
||||
case.set_grid_property(values, 'DYNAMIC_NATIVE', 'SOIL', 0)
|
||||
|
||||
|
@ -11,7 +11,7 @@ resinsight = rips.Instance.find()
|
||||
start = time.time()
|
||||
|
||||
# Get the case with case id 0
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
|
||||
# Get a list of all time steps
|
||||
timeSteps = case.time_steps()
|
||||
@ -20,7 +20,7 @@ averages = []
|
||||
for i in range(0, len(timeSteps)):
|
||||
# Get the results from time step i asynchronously
|
||||
# It actually returns a generator object almost immediately
|
||||
result_chunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
result_chunks = case.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
mysum = 0.0
|
||||
count = 0
|
||||
# Loop through and append the average. each time we loop resultChunks
|
||||
|
@ -8,10 +8,9 @@ import time
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
start = time.time()
|
||||
case = resinsight.project.case(id=0)
|
||||
|
||||
# Get the case with case id 0
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
|
||||
# Get a list of all time steps
|
||||
time_steps = case.time_steps()
|
||||
@ -19,7 +18,7 @@ time_steps = case.time_steps()
|
||||
averages = []
|
||||
for i in range(0, len(time_steps)):
|
||||
# Get a list of all the results for time step i
|
||||
results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
mysum = sum(results)
|
||||
averages.append(mysum/len(results))
|
||||
|
||||
|
@ -18,11 +18,11 @@ def create_result(soil_chunks, porv_chunks):
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
start = time.time()
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
timeStepInfo = case.time_steps()
|
||||
|
||||
# Get a generator for the porv results. The generator will provide a chunk each time it is iterated
|
||||
porv_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORV', 0)
|
||||
porv_chunks = case.active_cell_property_async('STATIC_NATIVE', 'PORV', 0)
|
||||
|
||||
# Read the static result into an array, so we don't have to transfer it for each iteration
|
||||
# Note we use the async method even if we synchronise here, because we need the values chunked
|
||||
@ -33,11 +33,11 @@ for porv_chunk in porv_chunks:
|
||||
|
||||
for i in range (0, len(timeStepInfo)):
|
||||
# Get a generator object for the SOIL property for time step i
|
||||
soil_chunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
soil_chunks = case.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
# Create the generator object for the SOIL * PORV derived result
|
||||
result_generator = create_result(soil_chunks, iter(porv_array))
|
||||
# Send back the result asynchronously with a generator object
|
||||
case.properties.set_active_cell_property_async(result_generator, 'GENERATED', 'SOILPORVAsync', i)
|
||||
case.set_active_cell_property_async(result_generator, 'GENERATED', 'SOILPORVAsync', i)
|
||||
|
||||
end = time.time()
|
||||
print("Time elapsed: ", end - start)
|
||||
|
@ -7,15 +7,15 @@ import time
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
start = time.time()
|
||||
case = resinsight.project.case(id=0)
|
||||
case = resinsight.project.case(case_id=0)
|
||||
|
||||
# Read the full porv result
|
||||
porv_results = case.properties.active_cell_property('STATIC_NATIVE', 'PORV', 0)
|
||||
porv_results = case.active_cell_property('STATIC_NATIVE', 'PORV', 0)
|
||||
time_step_info = case.time_steps()
|
||||
|
||||
for i in range (0, len(time_step_info)):
|
||||
# Read the full SOIl result for time step i
|
||||
soil_results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
soil_results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i)
|
||||
|
||||
# Generate the result by looping through both lists in order
|
||||
results = []
|
||||
@ -23,7 +23,7 @@ for i in range (0, len(time_step_info)):
|
||||
results.append(soil * porv)
|
||||
|
||||
# Send back result
|
||||
case.properties.set_active_cell_property(results, 'GENERATED', 'SOILPORVSync', i)
|
||||
case.set_active_cell_property(results, 'GENERATED', 'SOILPORVSync', i)
|
||||
|
||||
end = time.time()
|
||||
print("Time elapsed: ", end - start)
|
||||
|
@ -1,9 +1,12 @@
|
||||
name = "rips"
|
||||
from rips.Case import Case
|
||||
from rips.Grid import Grid
|
||||
from rips.Properties import Properties
|
||||
from rips.Instance import Instance
|
||||
from rips.Commands import Commands
|
||||
from rips.PdmObject import PdmObject
|
||||
from rips.View import View
|
||||
from rips.Project import Project
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
from rips.case import Case
|
||||
from rips.grid import Grid
|
||||
from rips.instance import Instance
|
||||
from rips.pdmobject import PdmObject
|
||||
from rips.view import View
|
||||
from rips.project import Project
|
719
ApplicationCode/GrpcInterface/Python/rips/case.py
Normal file
719
ApplicationCode/GrpcInterface/Python/rips/case.py
Normal file
@ -0,0 +1,719 @@
|
||||
# pylint: disable=no-member
|
||||
# pylint: disable=too-many-arguments
|
||||
# pylint: disable=too-many-public-methods
|
||||
# pylint: disable=no-self-use
|
||||
|
||||
"""
|
||||
Module containing the Case class
|
||||
"""
|
||||
|
||||
import grpc
|
||||
|
||||
import rips.generated.Case_pb2 as Case_pb2
|
||||
import rips.generated.Case_pb2_grpc as Case_pb2_grpc
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
import rips.generated.Properties_pb2 as Properties_pb2
|
||||
import rips.generated.Properties_pb2_grpc as Properties_pb2_grpc
|
||||
|
||||
from rips.grid import Grid
|
||||
from rips.pdmobject import PdmObject
|
||||
from rips.view import View
|
||||
|
||||
class Case(PdmObject):
|
||||
"""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, selectedCasesq
|
||||
|
||||
Attributes:
|
||||
id (int): Case Id corresponding to case Id in ResInsight project.
|
||||
name (str): Case name
|
||||
group_id (int): Case Group id
|
||||
chunkSize(int): The size of each chunk during value streaming.
|
||||
A good chunk size is 64KiB = 65536B.
|
||||
Meaning the ideal number of doubles would be 8192.
|
||||
However we need overhead space, so the default is 8160.
|
||||
This leaves 256B for overhead.
|
||||
"""
|
||||
def __init__(self, channel, case_id):
|
||||
# Private properties
|
||||
self.__channel = channel
|
||||
self.__case_stub = Case_pb2_grpc.CaseStub(channel)
|
||||
self.__request = Case_pb2.CaseRequest(id=case_id)
|
||||
|
||||
info = self.__case_stub.GetCaseInfo(self.__request)
|
||||
self.__properties_stub = Properties_pb2_grpc.PropertiesStub(
|
||||
self.__channel)
|
||||
PdmObject.__init__(self, self.__case_stub.GetPdmObject(self.__request),
|
||||
self.__channel)
|
||||
|
||||
# Public properties
|
||||
self.case_id = case_id
|
||||
self.name = info.name
|
||||
self.chunk_size = 8160
|
||||
|
||||
def __grid_count(self):
|
||||
"""Get number of grids in the case"""
|
||||
try:
|
||||
return self.__case_stub.GetGridCount(self.__request).count
|
||||
except grpc.RpcError as exception:
|
||||
if exception.code() == grpc.StatusCode.NOT_FOUND:
|
||||
return 0
|
||||
print("ERROR: ", exception)
|
||||
return 0
|
||||
|
||||
def __generate_property_input_iterator(self, values_iterator, parameters):
|
||||
chunk = Properties_pb2.PropertyInputChunk()
|
||||
chunk.params.CopyFrom(parameters)
|
||||
yield chunk
|
||||
|
||||
for values in values_iterator:
|
||||
valmsg = Properties_pb2.PropertyChunk(values=values)
|
||||
chunk.values.CopyFrom(valmsg)
|
||||
yield chunk
|
||||
|
||||
def __generate_property_input_chunks(self, array, parameters):
|
||||
index = -1
|
||||
while index < len(array):
|
||||
chunk = Properties_pb2.PropertyInputChunk()
|
||||
if index is -1:
|
||||
chunk.params.CopyFrom(parameters)
|
||||
index += 1
|
||||
else:
|
||||
actual_chunk_size = min(len(array) - index + 1, self.chunk_size)
|
||||
chunk.values.CopyFrom(
|
||||
Properties_pb2.PropertyChunk(values=array[index:index +
|
||||
actual_chunk_size]))
|
||||
index += actual_chunk_size
|
||||
|
||||
yield chunk
|
||||
# Final empty message to signal completion
|
||||
chunk = Properties_pb2.PropertyInputChunk()
|
||||
yield chunk
|
||||
|
||||
def grid_path(self):
|
||||
"""Get path of the current grid case
|
||||
|
||||
Returns: path string
|
||||
"""
|
||||
return self.get_value("CaseFileName")
|
||||
|
||||
def grid(self, index):
|
||||
"""Get Grid of a given index. Returns a rips Grid object
|
||||
|
||||
Arguments:
|
||||
index (int): The grid index
|
||||
|
||||
Returns: Grid object
|
||||
"""
|
||||
return Grid(index, self, self.__channel)
|
||||
|
||||
def grids(self):
|
||||
"""Get a list of all rips Grid objects in the case"""
|
||||
grid_list = []
|
||||
for i in range(0, self.__grid_count()):
|
||||
grid_list.append(Grid(i, self, self.__channel))
|
||||
return grid_list
|
||||
|
||||
def replace(self, new_grid_file):
|
||||
"""Replace the current case grid with a new grid loaded from file
|
||||
|
||||
Arguments:
|
||||
new_egrid_file (str): path to EGRID file
|
||||
"""
|
||||
self._execute_command(replaceCase=Cmd.ReplaceCaseRequest(
|
||||
newGridFile=new_grid_file, caseId=self.case_id))
|
||||
self.__init__(self.__channel, self.case_id)
|
||||
|
||||
def cell_count(self, porosity_model="MATRIX_MODEL"):
|
||||
"""Get a cell count object containing number of active cells and
|
||||
total number of cells
|
||||
|
||||
Arguments:
|
||||
porosity_model (str): 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
|
||||
"""
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Case_pb2.CellInfoRequest(case_request=self.__request,
|
||||
porosity_model=porosity_model_enum)
|
||||
return self.__case_stub.GetCellCount(request)
|
||||
|
||||
def cell_info_for_active_cells_async(self, porosity_model="MATRIX_MODEL"):
|
||||
"""Get Stream of cell info objects for current case
|
||||
|
||||
Arguments:
|
||||
porosity_model(str): String representing an enum.
|
||||
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
|
||||
Returns:
|
||||
Stream of **CellInfo** objects
|
||||
|
||||
See cell_info_for_active_cells() for detalis on the **CellInfo** class.
|
||||
"""
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Case_pb2.CellInfoRequest(case_request=self.__request,
|
||||
porosity_model=porosity_model_enum)
|
||||
return self.__case_stub.GetCellInfoForActiveCells(request)
|
||||
|
||||
def cell_info_for_active_cells(self, porosity_model="MATRIX_MODEL"):
|
||||
"""Get list of cell info objects for current case
|
||||
|
||||
Arguments:
|
||||
porosity_model(str): String representing an enum.
|
||||
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
|
||||
Returns:
|
||||
List of **CellInfo** objects
|
||||
|
||||
### CellInfo class description
|
||||
|
||||
Parameter | Description | Type
|
||||
------------------------- | --------------------------------------------- | -----
|
||||
grid_index | Index to grid | Integer
|
||||
parent_grid_index | Index to parent grid | Integer
|
||||
coarsening_box_index | Index to coarsening box | Integer
|
||||
local_ijk | Cell index in IJK directions of local grid | Vec3i
|
||||
parent_ijk | Cell index in IJK directions of parent grid | Vec3i
|
||||
|
||||
### Vec3i class description
|
||||
|
||||
Parameter | Description | Type
|
||||
---------------- | -------------------------------------------- | -----
|
||||
i | I grid index | Integer
|
||||
j | J grid index | Integer
|
||||
k | K grid index | Integer
|
||||
|
||||
"""
|
||||
active_cell_info_chunks = self.cell_info_for_active_cells_async(
|
||||
porosity_model=porosity_model)
|
||||
received_active_cells = []
|
||||
for active_cell_chunk in active_cell_info_chunks:
|
||||
for active_cell in active_cell_chunk.data:
|
||||
received_active_cells.append(active_cell)
|
||||
return received_active_cells
|
||||
|
||||
def time_steps(self):
|
||||
"""Get a list containing all time steps
|
||||
|
||||
The time steps are defined by the class **TimeStepDate** :
|
||||
|
||||
Type | Name
|
||||
--------- | ----------
|
||||
int | year
|
||||
int | month
|
||||
int | day
|
||||
int | hour
|
||||
int | minute
|
||||
int | second
|
||||
|
||||
|
||||
"""
|
||||
return self.__case_stub.GetTimeSteps(self.__request).dates
|
||||
|
||||
def days_since_start(self):
|
||||
"""Get a list of decimal values representing days since the start of the simulation"""
|
||||
return self.__case_stub.GetDaysSinceStart(self.__request).day_decimals
|
||||
|
||||
def views(self):
|
||||
"""Get a list of views belonging to a case"""
|
||||
pdm_objects = self.children("ReservoirViews")
|
||||
view_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
view_list.append(View(pdm_object))
|
||||
return view_list
|
||||
|
||||
def view(self, view_id):
|
||||
"""Get a particular view belonging to a case by providing view id
|
||||
Arguments:
|
||||
view_id(int): view id
|
||||
|
||||
Returns: a view object
|
||||
|
||||
"""
|
||||
views = self.views()
|
||||
for view_object in views:
|
||||
if view_object.view_id == view_id:
|
||||
return view_object
|
||||
return None
|
||||
|
||||
def create_view(self):
|
||||
"""Create a new view in the current case"""
|
||||
return self.view(
|
||||
self._execute_command(createView=Cmd.CreateViewRequest(
|
||||
caseId=self.case_id)).createViewResult.viewId)
|
||||
|
||||
def export_snapshots_of_all_views(self, prefix=""):
|
||||
""" Export snapshots for all views in the case
|
||||
|
||||
Arguments:
|
||||
prefix (str): Exported file name prefix
|
||||
|
||||
"""
|
||||
return self._execute_command(
|
||||
exportSnapshots=Cmd.ExportSnapshotsRequest(
|
||||
type="VIEWS", prefix=prefix, caseId=self.case_id, viewId=-1))
|
||||
|
||||
def export_well_path_completions(
|
||||
self,
|
||||
time_step,
|
||||
well_path_names,
|
||||
file_split,
|
||||
compdat_export="TRANSMISSIBILITIES",
|
||||
include_perforations=True,
|
||||
include_fishbones=True,
|
||||
fishbones_exclude_main_bore=True,
|
||||
combination_mode="INDIVIDUALLY",
|
||||
):
|
||||
"""
|
||||
Export well path completions for the current case to file
|
||||
|
||||
Parameter | Description | Type
|
||||
----------------------------| ------------------------------------------------ | -----
|
||||
time_step | Time step to export for | Integer
|
||||
well_path_names | List of well path names | List
|
||||
file_split | Split type:
|
||||
<ul>
|
||||
<li>'UNIFIED_FILE'</li>
|
||||
<li>'SPLIT_ON_WELL'</li>
|
||||
<li>'SPLIT_ON_WELL_AND_COMPLETION_TYPE'</li>
|
||||
</ul> | String enum
|
||||
compdat_export | Compdat export type:
|
||||
<ul>
|
||||
<li>'TRANSMISSIBILITIES'</li>
|
||||
<li>'WPIMULT_AND_DEFAULT_CONNECTION_FACTORS'</li>
|
||||
</ul> | String enum
|
||||
include_perforations | Export perforations? | bool
|
||||
include_fishbones | Export fishbones? | bool
|
||||
fishbones_exclude_main_bore | Exclude main bore when exporting fishbones? | bool
|
||||
combination_mode | Combination mode:
|
||||
<ul>
|
||||
<li>'INDIVIDUALLY'</li>
|
||||
<li>'COMBINED'</li>
|
||||
</ul> | String enum
|
||||
"""
|
||||
if isinstance(well_path_names, str):
|
||||
well_path_names = [well_path_names]
|
||||
return self._execute_command(
|
||||
exportWellPathCompletions=Cmd.ExportWellPathCompRequest(
|
||||
caseId=self.case_id,
|
||||
timeStep=time_step,
|
||||
wellPathNames=well_path_names,
|
||||
fileSplit=file_split,
|
||||
compdatExport=compdat_export,
|
||||
includePerforations=include_perforations,
|
||||
includeFishbones=include_fishbones,
|
||||
excludeMainBoreForFishbones=fishbones_exclude_main_bore,
|
||||
combinationMode=combination_mode,
|
||||
))
|
||||
|
||||
def export_msw(self, well_path):
|
||||
"""
|
||||
Export Eclipse Multi-segment-well model to file
|
||||
|
||||
Arguments:
|
||||
well_path(str): Well path name
|
||||
"""
|
||||
return self._execute_command(exportMsw=Cmd.ExportMswRequest(
|
||||
caseId=self.case_id, wellPath=well_path))
|
||||
|
||||
def create_multiple_fractures(
|
||||
self,
|
||||
template_id,
|
||||
well_path_names,
|
||||
min_dist_from_well_td,
|
||||
max_fractures_per_well,
|
||||
top_layer,
|
||||
base_layer,
|
||||
spacing,
|
||||
action,
|
||||
):
|
||||
"""
|
||||
Create Multiple Fractures in one go
|
||||
|
||||
Parameter | Description | Type
|
||||
-----------------------| ---------------------------------- -| -----
|
||||
template_id | Id of the template | Integer
|
||||
well_path_names | List of well path names | List of Strings
|
||||
min_dist_from_well_td | Minimum distance from well TD | Double
|
||||
max_fractures_per_well | Max number of fractures per well | Integer
|
||||
top_layer | Top grid k-level for fractures | Integer
|
||||
base_layer | Base grid k-level for fractures | Integer
|
||||
spacing | Spacing between fractures | Double
|
||||
action | 'APPEND_FRACTURES' or 'REPLACE_FRACTURES' | String enum
|
||||
"""
|
||||
if isinstance(well_path_names, str):
|
||||
well_path_names = [well_path_names]
|
||||
return self._execute_command(
|
||||
createMultipleFractures=Cmd.MultipleFracRequest(
|
||||
caseId=self.case_id,
|
||||
templateId=template_id,
|
||||
wellPathNames=well_path_names,
|
||||
minDistFromWellTd=min_dist_from_well_td,
|
||||
maxFracturesPerWell=max_fractures_per_well,
|
||||
topLayer=top_layer,
|
||||
baseLayer=base_layer,
|
||||
spacing=spacing,
|
||||
action=action,
|
||||
))
|
||||
|
||||
def create_lgr_for_completion(
|
||||
self,
|
||||
time_step,
|
||||
well_path_names,
|
||||
refinement_i,
|
||||
refinement_j,
|
||||
refinement_k,
|
||||
split_type,
|
||||
):
|
||||
"""
|
||||
Create a local grid refinement for the completions on the given well paths
|
||||
|
||||
Parameter | Description | Type
|
||||
--------------- | -------------------------------------- | -----
|
||||
time_steps | Time step index | Integer
|
||||
well_path_names | List of well path names | List of Strings
|
||||
refinement_i | Refinment in x-direction | Integer
|
||||
refinement_j | Refinment in y-direction | Integer
|
||||
refinement_k | Refinment in z-direction | Integer
|
||||
split_type | Type of LGR split:
|
||||
<ul>
|
||||
<li>'LGR_PER_CELL'</li>
|
||||
<li>'LGR_PER_COMPLETION'</li>
|
||||
<li>'LGR_PER_WELL'</li>
|
||||
</ul> | String enum
|
||||
"""
|
||||
if isinstance(well_path_names, str):
|
||||
well_path_names = [well_path_names]
|
||||
return self._execute_command(
|
||||
createLgrForCompletions=Cmd.CreateLgrForCompRequest(
|
||||
caseId=self.case_id,
|
||||
timeStep=time_step,
|
||||
wellPathNames=well_path_names,
|
||||
refinementI=refinement_i,
|
||||
refinementJ=refinement_j,
|
||||
refinementK=refinement_k,
|
||||
splitType=split_type,
|
||||
))
|
||||
|
||||
def create_saturation_pressure_plots(self):
|
||||
"""
|
||||
Create saturation pressure plots for the current case
|
||||
"""
|
||||
case_ids = [self.case_id]
|
||||
return self._execute_command(
|
||||
createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(
|
||||
caseIds=case_ids))
|
||||
|
||||
def export_flow_characteristics(
|
||||
self,
|
||||
time_steps,
|
||||
injectors,
|
||||
producers,
|
||||
file_name,
|
||||
minimum_communication=0.0,
|
||||
aquifer_cell_threshold=0.1,
|
||||
):
|
||||
""" Export Flow Characteristics data to text file in CSV format
|
||||
|
||||
Parameter | Description | Type
|
||||
------------------------- | --------------------------------------------- | -----
|
||||
time_steps | Time step indices | List of Integer
|
||||
injectors | Injector names | List of Strings
|
||||
producers | Producer names | List of Strings
|
||||
file_name | Export file name | Integer
|
||||
minimum_communication | Minimum Communication, defaults to 0.0 | Integer
|
||||
aquifer_cell_threshold | Aquifer Cell Threshold, defaults to 0.1 | Integer
|
||||
|
||||
"""
|
||||
if isinstance(time_steps, int):
|
||||
time_steps = [time_steps]
|
||||
if isinstance(injectors, str):
|
||||
injectors = [injectors]
|
||||
if isinstance(producers, str):
|
||||
producers = [producers]
|
||||
return self._execute_command(
|
||||
exportFlowCharacteristics=Cmd.ExportFlowInfoRequest(
|
||||
caseId=self.case_id,
|
||||
timeSteps=time_steps,
|
||||
injectors=injectors,
|
||||
producers=producers,
|
||||
fileName=file_name,
|
||||
minimumCommunication=minimum_communication,
|
||||
aquiferCellThreshold=aquifer_cell_threshold,
|
||||
))
|
||||
|
||||
def available_properties(self,
|
||||
property_type,
|
||||
porosity_model="MATRIX_MODEL"):
|
||||
"""Get a list of available properties
|
||||
|
||||
Arguments:
|
||||
property_type (str): string corresponding to property_type enum. Choices:
|
||||
- DYNAMIC_NATIVE
|
||||
- STATIC_NATIVE
|
||||
- SOURSIMRL
|
||||
- GENERATED
|
||||
- INPUT_PROPERTY
|
||||
- FORMATION_NAMES
|
||||
- FLOW_DIAGNOSTICS
|
||||
- INJECTION_FLOODING
|
||||
|
||||
porosity_model(str): 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
|
||||
"""
|
||||
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.AvailablePropertiesRequest(
|
||||
case_request=self.__request,
|
||||
property_type=property_type_enum,
|
||||
porosity_model=porosity_model_enum,
|
||||
)
|
||||
return self.__properties_stub.GetAvailableProperties(
|
||||
request).property_names
|
||||
|
||||
def active_cell_property_async(self,
|
||||
property_type,
|
||||
property_name,
|
||||
time_step,
|
||||
porosity_model="MATRIX_MODEL"):
|
||||
"""Get a cell property for all active cells. Async, so returns an iterator
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): string enum. See available()
|
||||
|
||||
Returns:
|
||||
An iterator to a chunk object containing an array of double values
|
||||
Loop through the chunks and then the values within the chunk to get all values.
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(
|
||||
case_request=self.__request,
|
||||
property_type=property_type_enum,
|
||||
property_name=property_name,
|
||||
time_step=time_step,
|
||||
porosity_model=porosity_model_enum,
|
||||
)
|
||||
for chunk in self.__properties_stub.GetActiveCellProperty(request):
|
||||
yield chunk
|
||||
|
||||
def active_cell_property(self,
|
||||
property_type,
|
||||
property_name,
|
||||
time_step,
|
||||
porosity_model="MATRIX_MODEL"):
|
||||
"""Get a cell property for all active cells. Sync, so returns a list
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): string enum. See available()
|
||||
|
||||
Returns:
|
||||
A list containing double values
|
||||
Loop through the chunks and then the values within the chunk to get all values.
|
||||
"""
|
||||
all_values = []
|
||||
generator = self.active_cell_property_async(property_type,
|
||||
property_name, time_step,
|
||||
porosity_model)
|
||||
for chunk in generator:
|
||||
for value in chunk.values:
|
||||
all_values.append(value)
|
||||
return all_values
|
||||
|
||||
def grid_property_async(
|
||||
self,
|
||||
property_type,
|
||||
property_name,
|
||||
time_step,
|
||||
grid_index=0,
|
||||
porosity_model="MATRIX_MODEL",
|
||||
):
|
||||
"""Get a cell property for all grid cells. Async, so returns an iterator
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
gridIndex(int): index to the grid we're getting values for
|
||||
porosity_model(str): string enum. See available()
|
||||
|
||||
Returns:
|
||||
An iterator to a chunk object containing an array of double values
|
||||
Loop through the chunks and then the values within the chunk to get all values.
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(
|
||||
case_request=self.__request,
|
||||
property_type=property_type_enum,
|
||||
property_name=property_name,
|
||||
time_step=time_step,
|
||||
grid_index=grid_index,
|
||||
porosity_model=porosity_model_enum,
|
||||
)
|
||||
for chunk in self.__properties_stub.GetGridProperty(request):
|
||||
yield chunk
|
||||
|
||||
def grid_property(
|
||||
self,
|
||||
property_type,
|
||||
property_name,
|
||||
time_step,
|
||||
grid_index=0,
|
||||
porosity_model="MATRIX_MODEL",
|
||||
):
|
||||
"""Get a cell property for all grid cells. Synchronous, so returns a list
|
||||
|
||||
Arguments:
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
grid_index(int): index to the grid we're getting values for
|
||||
porosity_model(str): string enum. See available()
|
||||
|
||||
Returns:
|
||||
A list of double values
|
||||
"""
|
||||
all_values = []
|
||||
generator = self.grid_property_async(property_type, property_name,
|
||||
time_step, grid_index,
|
||||
porosity_model)
|
||||
for chunk in generator:
|
||||
for value in chunk.values:
|
||||
all_values.append(value)
|
||||
return all_values
|
||||
|
||||
def set_active_cell_property_async(
|
||||
self,
|
||||
values_iterator,
|
||||
property_type,
|
||||
property_name,
|
||||
time_step,
|
||||
porosity_model="MATRIX_MODEL",
|
||||
):
|
||||
"""Set cell property for all active cells Async. Takes an iterator to the input values
|
||||
|
||||
Arguments:
|
||||
values_iterator(iterator): an iterator to the properties to be set
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): string enum. See available()
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(
|
||||
case_request=self.__request,
|
||||
property_type=property_type_enum,
|
||||
property_name=property_name,
|
||||
time_step=time_step,
|
||||
porosity_model=porosity_model_enum,
|
||||
)
|
||||
|
||||
request_iterator = self.__generate_property_input_iterator(
|
||||
values_iterator, request)
|
||||
self.__properties_stub.SetActiveCellProperty(request_iterator)
|
||||
|
||||
def set_active_cell_property(
|
||||
self,
|
||||
values,
|
||||
property_type,
|
||||
property_name,
|
||||
time_step,
|
||||
porosity_model="MATRIX_MODEL",
|
||||
):
|
||||
"""Set a cell property for all active cells.
|
||||
|
||||
Arguments:
|
||||
values(list): a list of double precision floating point numbers
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
porosity_model(str): string enum. See available()
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(
|
||||
case_request=self.__request,
|
||||
property_type=property_type_enum,
|
||||
property_name=property_name,
|
||||
time_step=time_step,
|
||||
porosity_model=porosity_model_enum,
|
||||
)
|
||||
request_iterator = self.__generate_property_input_chunks(
|
||||
values, request)
|
||||
reply = self.__properties_stub.SetActiveCellProperty(request_iterator)
|
||||
if reply.accepted_value_count < len(values):
|
||||
raise IndexError
|
||||
|
||||
def set_grid_property(
|
||||
self,
|
||||
values,
|
||||
property_type,
|
||||
property_name,
|
||||
time_step,
|
||||
grid_index=0,
|
||||
porosity_model="MATRIX_MODEL",
|
||||
):
|
||||
"""Set a cell property for all grid cells.
|
||||
|
||||
Arguments:
|
||||
values(list): a list of double precision floating point numbers
|
||||
property_type(str): string enum. See available()
|
||||
property_name(str): name of an Eclipse property
|
||||
time_step(int): the time step for which to get the property for
|
||||
grid_index(int): index to the grid we're setting values for
|
||||
porosity_model(str): string enum. See available()
|
||||
"""
|
||||
property_type_enum = Properties_pb2.PropertyType.Value(property_type)
|
||||
porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model)
|
||||
request = Properties_pb2.PropertyRequest(
|
||||
case_request=self.__request,
|
||||
property_type=property_type_enum,
|
||||
property_name=property_name,
|
||||
time_step=time_step,
|
||||
grid_index=grid_index,
|
||||
porosity_model=porosity_model_enum,
|
||||
)
|
||||
request_iterator = self.__generate_property_input_chunks(
|
||||
values, request)
|
||||
reply = self.__properties_stub.SetGridProperty(request_iterator)
|
||||
if reply.accepted_value_count < len(values):
|
||||
raise IndexError
|
||||
|
||||
def export_property(
|
||||
self,
|
||||
time_step,
|
||||
property_name,
|
||||
eclipse_keyword=property,
|
||||
undefined_value=0.0,
|
||||
export_file=property,
|
||||
):
|
||||
""" Export an Eclipse property
|
||||
|
||||
Arguments:
|
||||
time_step (int): time step index
|
||||
property_name (str): property to export
|
||||
eclipse_keyword (str): Keyword used in export header. Defaults: value of property
|
||||
undefined_value (double): Value to use for undefined values. Defaults to 0.0
|
||||
export_file (str): File name for export. Defaults to the value of property parameter
|
||||
"""
|
||||
return self._execute_command(exportProperty=Cmd.ExportPropertyRequest(
|
||||
caseId=self.case_id,
|
||||
timeStep=time_step,
|
||||
property=property_name,
|
||||
eclipseKeyword=eclipse_keyword,
|
||||
undefinedValue=undefined_value,
|
||||
exportFile=export_file,
|
||||
))
|
33
ApplicationCode/GrpcInterface/Python/rips/grid.py
Normal file
33
ApplicationCode/GrpcInterface/Python/rips/grid.py
Normal file
@ -0,0 +1,33 @@
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
"""
|
||||
Module containing the Grid class, containing information
|
||||
about Case grids.
|
||||
"""
|
||||
|
||||
import rips.generated.Case_pb2 as Case_pb2
|
||||
import rips.generated.Grid_pb2 as Grid_pb2
|
||||
import rips.generated.Grid_pb2_grpc as 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, channel):
|
||||
self.__channel = channel
|
||||
self.__stub = Grid_pb2_grpc.GridStub(self.__channel)
|
||||
|
||||
self.case = case
|
||||
self.index = index
|
||||
|
||||
def dimensions(self):
|
||||
"""The dimensions in i, j, k direction
|
||||
|
||||
Returns:
|
||||
Vec3i: class with integer attributes i, j, k giving extent in all three dimensions.
|
||||
"""
|
||||
case_request = Case_pb2.CaseRequest(id=self.case.case_id)
|
||||
return self.__stub.GetDimensions(
|
||||
Grid_pb2.GridRequest(case_request=case_request,
|
||||
grid_index=self.index)).dimensions
|
73
ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py
Normal file
73
ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py
Normal file
@ -0,0 +1,73 @@
|
||||
"""
|
||||
Grid Case Group statistics module
|
||||
"""
|
||||
|
||||
from rips.pdmobject import PdmObject
|
||||
from rips.view import View
|
||||
from rips.case import Case
|
||||
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
|
||||
class GridCaseGroup(PdmObject):
|
||||
"""ResInsight Grid Case Group class
|
||||
|
||||
Operate on a ResInsight case group specified by a Case Group Id integer.
|
||||
|
||||
Attributes:
|
||||
group_id (int): Grid Case Group Id corresponding to case group Id in ResInsight project.
|
||||
"""
|
||||
def __init__(self, pdm_object):
|
||||
self.group_id = pdm_object.get_value("GroupId")
|
||||
PdmObject.__init__(self, pdm_object._pb2_object, pdm_object._channel)
|
||||
|
||||
def create_statistics_case(self):
|
||||
"""Create a Statistics case in the Grid Case Group
|
||||
|
||||
Returns:
|
||||
A new Case
|
||||
"""
|
||||
command_reply = self._execute_command(
|
||||
createStatisticsCase=Cmd.CreateStatisticsCaseRequest(
|
||||
caseGroupId=self.group_id))
|
||||
return Case(self.channel,
|
||||
command_reply.createStatisticsCaseResult.caseId)
|
||||
|
||||
def statistics_cases(self):
|
||||
"""Get a list of all statistics cases in the Grid Case Group"""
|
||||
stat_case_collection = self.children("StatisticsCaseCollection")[0]
|
||||
return stat_case_collection.children("Reservoirs")
|
||||
|
||||
def views(self):
|
||||
"""Get a list of views belonging to a grid case group"""
|
||||
pdm_objects = self.descendants("ReservoirView")
|
||||
view_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
view_list.append(View(pdm_object))
|
||||
return view_list
|
||||
|
||||
def view(self, view_id):
|
||||
"""Get a particular view belonging to a case group by providing view id
|
||||
Arguments:
|
||||
id(int): view id
|
||||
|
||||
Returns: a view object
|
||||
|
||||
"""
|
||||
views = self.views()
|
||||
for view_object in views:
|
||||
if view_object.id == view_id:
|
||||
return view_object
|
||||
return None
|
||||
|
||||
def compute_statistics(self, case_ids=None):
|
||||
""" Compute statistics for the given case ids
|
||||
|
||||
Arguments:
|
||||
case_ids(list): list of case ids. If this is None all cases in group are included
|
||||
|
||||
"""
|
||||
if case_ids is None:
|
||||
case_ids = []
|
||||
return self._execute_command(
|
||||
computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(
|
||||
caseIds=case_ids, caseGroupId=self.group_id))
|
269
ApplicationCode/GrpcInterface/Python/rips/instance.py
Normal file
269
ApplicationCode/GrpcInterface/Python/rips/instance.py
Normal file
@ -0,0 +1,269 @@
|
||||
# pylint: disable=no-self-use
|
||||
"""
|
||||
The main entry point for ResInsight connections
|
||||
The Instance class contained have static methods launch and find for
|
||||
creating connections to ResInsight
|
||||
"""
|
||||
|
||||
import os
|
||||
import socket
|
||||
import logging
|
||||
import time
|
||||
|
||||
import grpc
|
||||
|
||||
import rips.generated.App_pb2 as App_pb2
|
||||
import rips.generated.App_pb2_grpc as App_pb2_grpc
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
import rips.generated.Commands_pb2_grpc as CmdRpc
|
||||
from rips.generated.Definitions_pb2 import Empty
|
||||
|
||||
import rips.generated.RiaVersionInfo as RiaVersionInfo
|
||||
|
||||
from rips.project import Project
|
||||
|
||||
|
||||
class Instance:
|
||||
"""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.
|
||||
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):
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as my_socket:
|
||||
my_socket.settimeout(0.2)
|
||||
return my_socket.connect_ex(('localhost', port)) == 0
|
||||
|
||||
@staticmethod
|
||||
def launch(resinsight_executable='',
|
||||
console=False,
|
||||
launch_port=-1,
|
||||
command_line_parameters=None):
|
||||
""" Launch a new Instance of ResInsight. This requires the environment variable
|
||||
RESINSIGHT_EXECUTABLE to be set or the parameter resinsight_executable to be provided.
|
||||
The RESINSIGHT_GRPC_PORT environment variable can be set to an alternative port number.
|
||||
|
||||
Args:
|
||||
resinsight_executable (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.
|
||||
launch_port(int): If -1 will use the default port 50051 or RESINSIGHT_GRPC_PORT
|
||||
if anything else, ResInsight will try to launch with this port
|
||||
command_line_parameters(list): Additional parameters as string entries in the list.
|
||||
Returns:
|
||||
Instance: an instance object if it worked. None if not.
|
||||
"""
|
||||
|
||||
port = 50051
|
||||
port_env = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if port_env:
|
||||
port = int(port_env)
|
||||
if launch_port is not -1:
|
||||
port = launch_port
|
||||
|
||||
if not resinsight_executable:
|
||||
resinsight_executable = os.environ.get('RESINSIGHT_EXECUTABLE')
|
||||
if not resinsight_executable:
|
||||
print(
|
||||
'ERROR: Could not launch ResInsight because the environment variable'
|
||||
' RESINSIGHT_EXECUTABLE is not set')
|
||||
return None
|
||||
|
||||
while Instance.__is_port_in_use(port):
|
||||
port += 1
|
||||
|
||||
print('Port ' + str(port))
|
||||
print('Trying to launch', resinsight_executable)
|
||||
|
||||
if command_line_parameters is None:
|
||||
command_line_parameters = []
|
||||
elif isinstance(command_line_parameters, str):
|
||||
command_line_parameters = [str]
|
||||
|
||||
parameters = ["ResInsight", "--server",
|
||||
str(port)] + command_line_parameters
|
||||
if console:
|
||||
print("Launching as console app")
|
||||
parameters.append("--console")
|
||||
|
||||
# Stringify all parameters
|
||||
for i in enumerate(parameters):
|
||||
parameters[i] = str(parameters[i])
|
||||
|
||||
pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters)
|
||||
if pid:
|
||||
instance = Instance(port=port, launched=True)
|
||||
return instance
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def find(start_port=50051, end_port=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:
|
||||
start_port (int): start searching from this port
|
||||
end_port (int): search up to but not including this port
|
||||
"""
|
||||
port_env = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if port_env:
|
||||
start_port = int(port_env)
|
||||
end_port = start_port + 20
|
||||
|
||||
for try_port in range(start_port, end_port):
|
||||
if Instance.__is_port_in_use(try_port):
|
||||
return Instance(port=try_port)
|
||||
|
||||
print(
|
||||
'Error: Could not find any ResInsight instances responding between ports '
|
||||
+ str(start_port) + ' and ' + str(end_port))
|
||||
return None
|
||||
|
||||
def __execute_command(self, **command_params):
|
||||
return self.commands.Execute(Cmd.CommandParams(**command_params))
|
||||
|
||||
def __check_version(self):
|
||||
try:
|
||||
major_version_ok = self.major_version() == int(
|
||||
RiaVersionInfo.RESINSIGHT_MAJOR_VERSION)
|
||||
minor_version_ok = self.minor_version() == int(
|
||||
RiaVersionInfo.RESINSIGHT_MINOR_VERSION)
|
||||
return True, major_version_ok and minor_version_ok
|
||||
except grpc.RpcError:
|
||||
return False, False
|
||||
|
||||
def __init__(self, port=50051, launched=False):
|
||||
""" 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,
|
||||
options=[
|
||||
('grpc.enable_http_proxy',
|
||||
False)
|
||||
])
|
||||
self.launched = launched
|
||||
self.commands = CmdRpc.CommandsStub(self.channel)
|
||||
|
||||
# Main version check package
|
||||
self.app = self.app = App_pb2_grpc.AppStub(self.channel)
|
||||
|
||||
connection_ok = False
|
||||
version_ok = False
|
||||
|
||||
if self.launched:
|
||||
for _ in range(0, 10):
|
||||
connection_ok, version_ok = self.__check_version()
|
||||
if connection_ok:
|
||||
break
|
||||
time.sleep(1.0)
|
||||
else:
|
||||
connection_ok, version_ok = self.__check_version()
|
||||
|
||||
if not connection_ok:
|
||||
if self.launched:
|
||||
raise Exception('Error: Could not connect to resinsight at ',
|
||||
location,
|
||||
' after trying 10 times with 1 second apart')
|
||||
raise Exception('Error: Could not connect to resinsight at ', location)
|
||||
if not version_ok:
|
||||
raise Exception('Error: Wrong Version of ResInsight at ', location,
|
||||
self.version_string(), " ",
|
||||
self.client_version_string())
|
||||
|
||||
# Service packages
|
||||
self.project = Project(self.channel)
|
||||
|
||||
path = os.getcwd()
|
||||
self.set_start_dir(path=path)
|
||||
|
||||
def __version_message(self):
|
||||
return self.app.GetVersion(Empty())
|
||||
|
||||
def set_start_dir(self, path):
|
||||
"""Set current start directory
|
||||
|
||||
Arguments:
|
||||
path (str): path to directory
|
||||
|
||||
"""
|
||||
return self.__execute_command(setStartDir=Cmd.FilePathRequest(path=path))
|
||||
|
||||
def set_export_folder(self, export_type, path, create_folder=False):
|
||||
"""
|
||||
Set the export folder used for all export functions
|
||||
|
||||
Parameter | Description | Type
|
||||
---------------- | -------------------------------------------- | -----
|
||||
export_type | Type of export: 'COMPLETIONS', 'SNAPSHOTS'
|
||||
'PROPERTIES' or 'STATISTICS' | String
|
||||
path | Path to folder | String
|
||||
create_folder | Create folder if it doesn't exist? | Boolean
|
||||
"""
|
||||
return self.__execute_command(setExportFolder=Cmd.SetExportFolderRequest(
|
||||
type=export_type, path=path, createFolder=create_folder))
|
||||
|
||||
def set_main_window_size(self, width, height):
|
||||
"""
|
||||
Set the main window size in pixels
|
||||
Parameter | Description | Type
|
||||
--------- | ---------------- | -----
|
||||
width | Width in pixels | Integer
|
||||
height | Height in pixels | Integer
|
||||
"""
|
||||
return self.__execute_command(setMainWindowSize=Cmd.SetMainWindowSizeParams(
|
||||
width=width, height=height))
|
||||
|
||||
def major_version(self):
|
||||
"""Get an integer with the major version number"""
|
||||
return self.__version_message().major_version
|
||||
|
||||
def minor_version(self):
|
||||
"""Get an integer with the minor version number"""
|
||||
return self.__version_message().minor_version
|
||||
|
||||
def patch_version(self):
|
||||
"""Get an integer with the patch version number"""
|
||||
return self.__version_message().patch_version
|
||||
|
||||
def version_string(self):
|
||||
"""Get a full version string, i.e. 2019.04.01"""
|
||||
return str(self.major_version()) + "." + str(
|
||||
self.minor_version()) + "." + str(self.patch_version())
|
||||
|
||||
def client_version_string(self):
|
||||
"""Get a full version string, i.e. 2019.04.01"""
|
||||
version_string = RiaVersionInfo.RESINSIGHT_MAJOR_VERSION + "."
|
||||
version_string += RiaVersionInfo.RESINSIGHT_MINOR_VERSION + "."
|
||||
version_string += RiaVersionInfo.RESINSIGHT_PATCH_VERSION
|
||||
return version_string
|
||||
|
||||
def exit(self):
|
||||
"""Tell ResInsight instance to quit"""
|
||||
print("Telling ResInsight to Exit")
|
||||
return self.app.Exit(Empty())
|
||||
|
||||
def is_console(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 is_gui(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')
|
@ -1,18 +1,27 @@
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
# pylint: disable=no-self-use
|
||||
"""
|
||||
ResInsight caf::PdmObject connection module
|
||||
"""
|
||||
import rips.generated.PdmObject_pb2 as PdmObject_pb2
|
||||
import rips.generated.PdmObject_pb2_grpc as PdmObject_pb2_grpc
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
import rips.generated.Commands_pb2_grpc as CmdRpc
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
|
||||
|
||||
from Definitions_pb2 import Empty
|
||||
import PdmObject_pb2
|
||||
import PdmObject_pb2_grpc
|
||||
|
||||
class PdmObject:
|
||||
"""
|
||||
Generic ResInsight object. Corresponds to items in the Project Tree
|
||||
"""
|
||||
|
||||
def _execute_command(self, **command_params):
|
||||
return self._commands.Execute(Cmd.CommandParams(**command_params))
|
||||
|
||||
def __init__(self, pb2_object, channel):
|
||||
self.pb2_object = pb2_object
|
||||
self.channel = channel
|
||||
self.pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self.channel)
|
||||
self._pb2_object = pb2_object
|
||||
self._channel = channel
|
||||
self._pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(
|
||||
self._channel)
|
||||
self._commands = CmdRpc.CommandsStub(channel)
|
||||
|
||||
def address(self):
|
||||
"""Get the unique address of the PdmObject
|
||||
@ -21,57 +30,56 @@ class PdmObject:
|
||||
A 64-bit unsigned integer address
|
||||
"""
|
||||
|
||||
return self.pb2_object.address
|
||||
return self._pb2_object.address
|
||||
|
||||
def class_keyword(self):
|
||||
"""Get the class keyword in the ResInsight Data Model for the given PdmObject"""
|
||||
return self.pb2_object.class_keyword
|
||||
return self._pb2_object.class_keyword
|
||||
|
||||
def keywords(self):
|
||||
"""Get a list of all parameter keywords available in the object"""
|
||||
list_of_keywords = []
|
||||
for keyword in self.pb2_object.parameters:
|
||||
for keyword in self._pb2_object.parameters:
|
||||
list_of_keywords.append(keyword)
|
||||
return list_of_keywords
|
||||
|
||||
def print_object_info(self):
|
||||
"""Print the structure and data content of the PdmObject"""
|
||||
print ("Class Keyword: " + self.class_keyword())
|
||||
print("Class Keyword: " + self.class_keyword())
|
||||
for keyword in self.keywords():
|
||||
print(keyword + " [" + type(self.get_value(keyword)).__name__ + "]: " + str(self.get_value(keyword)))
|
||||
print(keyword + " [" + type(self.get_value(keyword)).__name__ +
|
||||
"]: " + str(self.get_value(keyword)))
|
||||
|
||||
def __to_value(self, value):
|
||||
if value.lower() == 'false':
|
||||
return False
|
||||
elif value.lower() == 'true':
|
||||
return False
|
||||
if value.lower() == 'true':
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
int_val = int(value)
|
||||
return int_val
|
||||
except ValueError:
|
||||
try:
|
||||
int_val = int(value)
|
||||
return int_val
|
||||
float_val = float(value)
|
||||
return float_val
|
||||
except ValueError:
|
||||
try:
|
||||
float_val = float(value)
|
||||
return float_val
|
||||
except ValueError:
|
||||
# We may have a string. Strip internal start and end quotes
|
||||
value = value.strip('\"')
|
||||
if self.__islist(value):
|
||||
return self.__makelist(value)
|
||||
return value
|
||||
# We may have a string. Strip internal start and end quotes
|
||||
value = value.strip('\"')
|
||||
if self.__islist(value):
|
||||
return self.__makelist(value)
|
||||
return value
|
||||
|
||||
def __from_value(self, value):
|
||||
if isinstance(value, bool):
|
||||
if value:
|
||||
return "true"
|
||||
else:
|
||||
return "false"
|
||||
elif isinstance(value, list):
|
||||
return "false"
|
||||
if isinstance(value, list):
|
||||
list_of_strings = []
|
||||
for val in value:
|
||||
list_of_strings.append(self.__from_value('\"' + val + '\"'))
|
||||
return "[" + ", ".join(list_of_strings) + "]"
|
||||
else:
|
||||
return str(value)
|
||||
return str(value)
|
||||
|
||||
def get_value(self, keyword):
|
||||
"""Get the value associated with the provided keyword
|
||||
@ -81,7 +89,7 @@ class PdmObject:
|
||||
Returns:
|
||||
The value of the parameter. Can be int, str or list.
|
||||
"""
|
||||
value = self.pb2_object.parameters[keyword]
|
||||
value = self._pb2_object.parameters[keyword]
|
||||
return self.__to_value(value)
|
||||
|
||||
def __islist(self, value):
|
||||
@ -104,7 +112,7 @@ class PdmObject:
|
||||
See keyword documentation and/or print_object_info() to find
|
||||
the correct data type.
|
||||
"""
|
||||
self.pb2_object.parameters[keyword] = self.__from_value(value)
|
||||
self._pb2_object.parameters[keyword] = self.__from_value(value)
|
||||
|
||||
def descendants(self, class_keyword):
|
||||
"""Get a list of all project tree descendants matching the class keyword
|
||||
@ -114,11 +122,13 @@ class PdmObject:
|
||||
Returns:
|
||||
A list of PdmObjects matching the keyword provided
|
||||
"""
|
||||
request = PdmObject_pb2.PdmDescendantObjectRequest(object=self.pb2_object, child_keyword=class_keyword)
|
||||
object_list = self.pdm_object_stub.GetDescendantPdmObjects(request).objects
|
||||
request = PdmObject_pb2.PdmDescendantObjectRequest(
|
||||
object=self._pb2_object, child_keyword=class_keyword)
|
||||
object_list = self._pdm_object_stub.GetDescendantPdmObjects(
|
||||
request).objects
|
||||
child_list = []
|
||||
for object in object_list:
|
||||
child_list.append(PdmObject(object, self.channel))
|
||||
for pdm_object in object_list:
|
||||
child_list.append(PdmObject(pdm_object, self._channel))
|
||||
return child_list
|
||||
|
||||
def children(self, child_field):
|
||||
@ -128,11 +138,12 @@ class PdmObject:
|
||||
Returns:
|
||||
A list of PdmObjects inside the child_field
|
||||
"""
|
||||
request = PdmObject_pb2.PdmChildObjectRequest(object=self.pb2_object, child_field=child_field)
|
||||
object_list = self.pdm_object_stub.GetChildPdmObjects(request).objects
|
||||
request = PdmObject_pb2.PdmChildObjectRequest(object=self._pb2_object,
|
||||
child_field=child_field)
|
||||
object_list = self._pdm_object_stub.GetChildPdmObjects(request).objects
|
||||
child_list = []
|
||||
for object in object_list:
|
||||
child_list.append(PdmObject(object, self.channel))
|
||||
for pdm_object in object_list:
|
||||
child_list.append(PdmObject(pdm_object, self._channel))
|
||||
return child_list
|
||||
|
||||
def ancestor(self, class_keyword):
|
||||
@ -140,13 +151,11 @@ class PdmObject:
|
||||
Arguments:
|
||||
class_keyword[str]: A class keyword matching the type of class wanted
|
||||
"""
|
||||
request = PdmObject_pb2.PdmParentObjectRequest(object=self.pb2_object, parent_keyword=class_keyword)
|
||||
return PdmObject(self.pdm_object_stub.GetAncestorPdmObject(request), self.channel)
|
||||
request = PdmObject_pb2.PdmParentObjectRequest(
|
||||
object=self._pb2_object, parent_keyword=class_keyword)
|
||||
return PdmObject(self._pdm_object_stub.GetAncestorPdmObject(request),
|
||||
self._channel)
|
||||
|
||||
def update(self):
|
||||
"""Sync all fields from the Python Object to ResInsight"""
|
||||
self.pdm_object_stub.UpdateExistingPdmObject(self.pb2_object)
|
||||
|
||||
# def createChild(self, child_field, childClassKeyword):
|
||||
# childRequest = PdmObject_pb2.CreatePdmChildObjectRequest(object=self.pb2Object, child_field=child_field, child_class=childClassKeyword)
|
||||
# return PdmObject(self.pdmObjectStub.CreateChildPdmObject(childRequest), self.channel)
|
||||
self._pdm_object_stub.UpdateExistingPdmObject(self._pb2_object)
|
209
ApplicationCode/GrpcInterface/Python/rips/project.py
Normal file
209
ApplicationCode/GrpcInterface/Python/rips/project.py
Normal file
@ -0,0 +1,209 @@
|
||||
# pylint: disable=too-many-arguments
|
||||
# pylint: disable=no-member
|
||||
"""
|
||||
The ResInsight project module
|
||||
"""
|
||||
import grpc
|
||||
|
||||
from rips.case import Case
|
||||
from rips.gridcasegroup import GridCaseGroup
|
||||
from rips.pdmobject import PdmObject
|
||||
from rips.view import View
|
||||
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
from rips.generated.Definitions_pb2 import Empty
|
||||
import rips.generated.Project_pb2_grpc as Project_pb2_grpc
|
||||
|
||||
|
||||
class Project(PdmObject):
|
||||
"""ResInsight project. Not intended to be created separately.
|
||||
|
||||
Automatically created and assigned to Instance.
|
||||
"""
|
||||
def __init__(self, channel):
|
||||
self._project_stub = Project_pb2_grpc.ProjectStub(channel)
|
||||
PdmObject.__init__(self, self._project_stub.GetPdmObject(Empty()),
|
||||
channel)
|
||||
|
||||
def open(self, path):
|
||||
"""Open a new project from the given path
|
||||
|
||||
Arguments:
|
||||
path(str): path to project file
|
||||
|
||||
"""
|
||||
self._execute_command(openProject=Cmd.FilePathRequest(path=path))
|
||||
return self
|
||||
|
||||
def close(self):
|
||||
"""Close the current project (and open new blank project)"""
|
||||
self._execute_command(closeProject=Empty())
|
||||
|
||||
def load_case(self, path):
|
||||
"""Load a new case from the given file path
|
||||
|
||||
Arguments:
|
||||
path(str): file path to case
|
||||
Returns:
|
||||
A rips Case object
|
||||
"""
|
||||
command_reply = self._execute_command(loadCase=Cmd.FilePathRequest(
|
||||
path=path))
|
||||
return Case(self._channel, command_reply.loadCaseResult.id)
|
||||
|
||||
def selected_cases(self):
|
||||
"""Get a list of all cases selected in the project tree
|
||||
|
||||
Returns:
|
||||
A list of rips Case objects
|
||||
"""
|
||||
case_infos = self._project_stub.GetSelectedCases(Empty())
|
||||
cases = []
|
||||
for case_info in case_infos.data:
|
||||
cases.append(Case(self._channel, case_info.id))
|
||||
return cases
|
||||
|
||||
def cases(self):
|
||||
"""Get a list of all cases in the project
|
||||
|
||||
Returns:
|
||||
A list of rips Case objects
|
||||
"""
|
||||
try:
|
||||
case_infos = self._project_stub.GetAllCases(Empty())
|
||||
|
||||
cases = []
|
||||
for case_info in case_infos.data:
|
||||
cases.append(Case(self._channel, case_info.id))
|
||||
return cases
|
||||
except grpc.RpcError as rpc_error:
|
||||
if rpc_error.code() == grpc.StatusCode.NOT_FOUND:
|
||||
return []
|
||||
print("ERROR: ", rpc_error)
|
||||
return []
|
||||
|
||||
def case(self, case_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, case_id)
|
||||
return case
|
||||
except grpc.RpcError:
|
||||
return None
|
||||
|
||||
def replace_source_cases(self, grid_list_file, case_group_id=0):
|
||||
"""Replace all source cases within a case group
|
||||
Arguments:
|
||||
grid_list_file (str): path to file containing a list of cases
|
||||
case_group_id (int): id of the case group to replace
|
||||
"""
|
||||
return self._execute_command(
|
||||
replaceSourceCases=Cmd.ReplaceSourceCasesRequest(
|
||||
gridListFile=grid_list_file, caseGroupId=case_group_id))
|
||||
|
||||
def create_grid_case_group(self, case_paths):
|
||||
"""Create a Grid Case Group from a list of cases
|
||||
Arguments:
|
||||
case_paths (list): list of file path strings
|
||||
Returns:
|
||||
A case group id and name
|
||||
"""
|
||||
command_reply = self._execute_command(
|
||||
createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(
|
||||
casePaths=case_paths))
|
||||
return self.grid_case_group(
|
||||
command_reply.createGridCaseGroupResult.groupId)
|
||||
|
||||
def views(self):
|
||||
"""Get a list of views belonging to a project"""
|
||||
pdm_objects = self.descendants("ReservoirView")
|
||||
view_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
view_list.append(View(pdm_object))
|
||||
return view_list
|
||||
|
||||
def view(self, view_id):
|
||||
"""Get a particular view belonging to a case by providing view id
|
||||
Arguments:
|
||||
id(int): view id
|
||||
Returns: a view object
|
||||
"""
|
||||
views = self.views()
|
||||
for view_object in views:
|
||||
if view_object.view_id == view_id:
|
||||
return view_object
|
||||
return None
|
||||
|
||||
def grid_case_groups(self):
|
||||
"""Get a list of all grid case groups in the project"""
|
||||
case_groups = self.descendants("RimIdenticalGridCaseGroup")
|
||||
|
||||
case_group_list = []
|
||||
for pdm_group in case_groups:
|
||||
case_group_list.append(GridCaseGroup(pdm_group))
|
||||
return case_group_list
|
||||
|
||||
def grid_case_group(self, group_id):
|
||||
"""Get a particular grid case group belonging to a project
|
||||
Arguments:
|
||||
groupId(int): group id
|
||||
|
||||
Returns: a grid case group object
|
||||
"""
|
||||
case_groups = self.grid_case_groups()
|
||||
for case_group in case_groups:
|
||||
if case_group.group_id == group_id:
|
||||
return case_group
|
||||
return None
|
||||
|
||||
def export_multi_case_snapshots(self, grid_list_file):
|
||||
"""Export snapshots for a set of cases
|
||||
Arguments:
|
||||
grid_list_file (str): Path to a file containing a list of grids to export snapshot for
|
||||
"""
|
||||
return self._execute_command(
|
||||
exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(
|
||||
gridListFile=grid_list_file))
|
||||
|
||||
def export_snapshots(self, snapshot_type='ALL', prefix=''):
|
||||
""" Export all snapshots of a given type
|
||||
Arguments:
|
||||
snapshot_type (str): Enum string ('ALL', 'VIEWS' or 'PLOTS')
|
||||
prefix (str): Exported file name prefix
|
||||
"""
|
||||
return self._execute_command(
|
||||
exportSnapshots=Cmd.ExportSnapshotsRequest(
|
||||
type=snapshot_type, prefix=prefix, caseId=-1))
|
||||
|
||||
def export_well_paths(self, well_paths=None, md_step_size=5.0):
|
||||
""" Export a set of well paths
|
||||
Arguments:
|
||||
well_paths(list): List of strings of well paths. If none, export all.
|
||||
md_step_size(double): resolution of the exported well path
|
||||
"""
|
||||
if well_paths is None:
|
||||
well_paths = []
|
||||
elif isinstance(well_paths, str):
|
||||
well_paths = [well_paths]
|
||||
return self._execute_command(exportWellPaths=Cmd.ExportWellPathRequest(
|
||||
wellPathNames=well_paths, mdStepSize=md_step_size))
|
||||
|
||||
def scale_fracture_template(self, template_id, half_length, height, dfactor,
|
||||
conductivity):
|
||||
return self._execute_command(
|
||||
scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(
|
||||
id=template_id,
|
||||
halfLength=half_length,
|
||||
height=height,
|
||||
dFactor=dfactor,
|
||||
conductivity=conductivity))
|
||||
|
||||
def set_fracture_containment(self, fracture_id, top_layer, base_layer):
|
||||
return self._execute_command(
|
||||
setFractureContainment=Cmd.SetFracContainmentRequest(
|
||||
id=fracture_id, topLayer=top_layer, baseLayer=base_layer))
|
@ -1,6 +1,8 @@
|
||||
import sys
|
||||
import os
|
||||
import pytest
|
||||
import grpc
|
||||
import tempfile
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../../'))
|
||||
import rips
|
||||
@ -17,7 +19,7 @@ def test_EmptyProject(rips_instance, initialize_test):
|
||||
def test_OneCase(rips_instance, initialize_test):
|
||||
case = rips_instance.project.load_case(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID")
|
||||
assert(case.name == "TEST10K_FLT_LGR_NNC")
|
||||
assert(case.id == 0)
|
||||
assert(case.case_id == 0)
|
||||
cases = rips_instance.project.cases()
|
||||
assert(len(cases) is 1)
|
||||
|
||||
@ -41,7 +43,7 @@ def test_MultipleCases(rips_instance, initialize_test):
|
||||
def test_10k(rips_instance, initialize_test):
|
||||
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=case_path)
|
||||
assert(case.grid_count() == 2)
|
||||
assert(len(case.grids()) == 2)
|
||||
cell_count_info = case.cell_count()
|
||||
assert(cell_count_info.active_cell_count == 11125)
|
||||
assert(cell_count_info.reservoir_cell_count == 316224)
|
||||
@ -53,17 +55,17 @@ def test_10k(rips_instance, initialize_test):
|
||||
def test_PdmObject(rips_instance, initialize_test):
|
||||
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=case_path)
|
||||
assert(case.id == 0)
|
||||
assert(case.case_id == 0)
|
||||
assert(case.address() is not 0)
|
||||
assert(case.class_keyword() == "EclipseCase")
|
||||
case_id = case.get_value('CaseId')
|
||||
assert(case_id == case.id)
|
||||
assert(case_id == case.case_id)
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux")
|
||||
def test_brugge_0010(rips_instance, initialize_test):
|
||||
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID"
|
||||
case = rips_instance.project.load_case(path=case_path)
|
||||
assert(case.grid_count() == 1)
|
||||
assert(len(case.grids()) == 1)
|
||||
cellCountInfo = case.cell_count()
|
||||
assert(cellCountInfo.active_cell_count == 43374)
|
||||
assert(cellCountInfo.reservoir_cell_count == 60048)
|
||||
@ -76,16 +78,36 @@ def test_brugge_0010(rips_instance, initialize_test):
|
||||
def test_replaceCase(rips_instance, initialize_test):
|
||||
project = rips_instance.project.open(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/10KWithWellLog.rsp")
|
||||
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
|
||||
case = project.case(id=0)
|
||||
case = project.case(case_id=0)
|
||||
assert(case is not None)
|
||||
assert(case.name == "TEST10K_FLT_LGR_NNC")
|
||||
assert(case.id == 0)
|
||||
assert(case.case_id == 0)
|
||||
cases = rips_instance.project.cases()
|
||||
assert(len(cases) is 1)
|
||||
|
||||
rips_instance.commands.replace_case(new_grid_file=case_path, case_id=case.id)
|
||||
case.replace(new_grid_file=case_path)
|
||||
# Check that the case object has been changed
|
||||
assert(case.name == "Real0--BRUGGE_0000.EGRID")
|
||||
assert(case.case_id == 0)
|
||||
|
||||
cases = rips_instance.project.cases()
|
||||
assert(len(cases) is 1)
|
||||
case = project.case(id=0)
|
||||
# Check that retrieving the case object again will yield the changed object
|
||||
case = project.case(case_id=0)
|
||||
assert(case.name == "Real0--BRUGGE_0000.EGRID")
|
||||
assert(case.id == 0)
|
||||
assert(case.case_id == 0)
|
||||
|
||||
def test_loadNonExistingCase(rips_instance, initialize_test):
|
||||
case_path = "Nonsense/Nonsense/Nonsense"
|
||||
with pytest.raises(grpc.RpcError):
|
||||
assert rips_instance.project.load_case(case_path)
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux")
|
||||
def test_exportFlowCharacteristics(rips_instance, initialize_test):
|
||||
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
|
||||
case = rips_instance.project.load_case(case_path)
|
||||
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
|
||||
print("Temporary folder: ", tmpdirname)
|
||||
file_name = tmpdirname + "/exportFlowChar.txt"
|
||||
case.export_flow_characteristics(time_steps=8, producers=[], injectors = "I01", file_name = file_name)
|
||||
|
||||
|
@ -9,50 +9,3 @@ import rips
|
||||
|
||||
import dataroot
|
||||
|
||||
def test_exportSnapshots(rips_instance, initialize_test):
|
||||
if not rips_instance.is_gui():
|
||||
pytest.skip("Cannot run test without a GUI")
|
||||
|
||||
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
rips_instance.project.load_case(case_path)
|
||||
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
|
||||
print("Temporary folder: ", tmpdirname)
|
||||
rips_instance.commands.set_export_folder(type='SNAPSHOTS', path=tmpdirname)
|
||||
rips_instance.commands.export_snapshots()
|
||||
print(os.listdir(tmpdirname))
|
||||
assert(len(os.listdir(tmpdirname)) > 0)
|
||||
for fileName in os.listdir(tmpdirname):
|
||||
assert(os.path.splitext(fileName)[1] == '.png')
|
||||
|
||||
def test_exportPropertyInView(rips_instance, initialize_test):
|
||||
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
rips_instance.project.load_case(case_path)
|
||||
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
|
||||
print("Temporary folder: ", tmpdirname)
|
||||
rips_instance.commands.set_export_folder(type='PROPERTIES', path=tmpdirname)
|
||||
case = rips_instance.project.case(id=0)
|
||||
rips_instance.commands.export_property_in_views(0, "3D View", 0)
|
||||
expected_file_name = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL"
|
||||
full_path = tmpdirname + "/" + expected_file_name
|
||||
assert(os.path.exists(full_path))
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux")
|
||||
def test_loadGridCaseGroup(rips_instance, initialize_test):
|
||||
case_paths = []
|
||||
case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID")
|
||||
case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID")
|
||||
group_id, group_name = rips_instance.commands.create_grid_case_group(case_paths=case_paths)
|
||||
print(group_id, group_name)
|
||||
|
||||
def test_exportFlowCharacteristics(rips_instance, initialize_test):
|
||||
case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"
|
||||
rips_instance.project.load_case(case_path)
|
||||
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
|
||||
print("Temporary folder: ", tmpdirname)
|
||||
file_name = tmpdirname + "/exportFlowChar.txt"
|
||||
rips_instance.commands.export_flow_characteristics(case_id=0, time_steps=8, producers=[], injectors = "I01", file_name = file_name)
|
||||
|
||||
def test_loadNonExistingCase(rips_instance, initialize_test):
|
||||
case_path = "Nonsense/Nonsense/Nonsense"
|
||||
with pytest.raises(grpc.RpcError):
|
||||
assert rips_instance.project.load_case(case_path)
|
||||
|
@ -9,7 +9,7 @@ import dataroot
|
||||
def test_10k(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
assert(case.grid_count() == 2)
|
||||
assert(len(case.grids()) == 2)
|
||||
grid = case.grid(index=0)
|
||||
dimensions = grid.dimensions()
|
||||
assert(dimensions.i == 90)
|
||||
|
@ -1,6 +1,8 @@
|
||||
import sys
|
||||
import os
|
||||
import pytest
|
||||
import grpc
|
||||
import tempfile
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../../'))
|
||||
import rips
|
||||
@ -9,9 +11,32 @@ import dataroot
|
||||
|
||||
def test_loadProject(rips_instance, initialize_test):
|
||||
project = rips_instance.project.open(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/10KWithWellLog.rsp")
|
||||
case = project.case(id=0)
|
||||
case = project.case(case_id=0)
|
||||
assert(case is not None)
|
||||
assert(case.name == "TEST10K_FLT_LGR_NNC")
|
||||
assert(case.id == 0)
|
||||
assert(case.case_id == 0)
|
||||
cases = rips_instance.project.cases()
|
||||
assert(len(cases) is 1)
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux")
|
||||
def test_loadGridCaseGroup(rips_instance, initialize_test):
|
||||
case_paths = []
|
||||
case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID")
|
||||
case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID")
|
||||
grid_case_group = rips_instance.project.create_grid_case_group(case_paths=case_paths)
|
||||
assert(grid_case_group is not None and grid_case_group.group_id == 0)
|
||||
|
||||
def test_exportSnapshots(rips_instance, initialize_test):
|
||||
if not rips_instance.is_gui():
|
||||
pytest.skip("Cannot run test without a GUI")
|
||||
|
||||
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
rips_instance.project.load_case(case_path)
|
||||
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
|
||||
print("Temporary folder: ", tmpdirname)
|
||||
rips_instance.set_export_folder(export_type='SNAPSHOTS', path=tmpdirname)
|
||||
rips_instance.project.export_snapshots()
|
||||
print(os.listdir(tmpdirname))
|
||||
assert(len(os.listdir(tmpdirname)) > 0)
|
||||
for fileName in os.listdir(tmpdirname):
|
||||
assert(os.path.splitext(fileName)[1] == '.png')
|
||||
|
@ -2,6 +2,7 @@ import sys
|
||||
import os
|
||||
import grpc
|
||||
import pytest
|
||||
import tempfile
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../../'))
|
||||
import rips
|
||||
@ -12,7 +13,7 @@ def test_10kAsync(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
|
||||
resultChunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
resultChunks = case.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
mysum = 0.0
|
||||
count = 0
|
||||
for chunk in resultChunks:
|
||||
@ -27,7 +28,7 @@ def test_10kSync(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
|
||||
results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
mysum = sum(results)
|
||||
average = mysum / len(results)
|
||||
assert(mysum == pytest.approx(621.768, abs=0.001))
|
||||
@ -38,27 +39,27 @@ def test_10k_set(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
|
||||
results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1)
|
||||
results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
case.set_active_cell_property(results, 'GENERATED', 'SOIL', 1)
|
||||
|
||||
def test_10k_set_out_of_bounds(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
|
||||
results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
results.append(5.0)
|
||||
with pytest.raises(grpc.RpcError):
|
||||
assert case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1)
|
||||
assert case.set_active_cell_property(results, 'GENERATED', 'SOIL', 1)
|
||||
|
||||
def test_10k_set_out_of_bounds_client(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
|
||||
results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
case.properties.chunk_size = len(results)
|
||||
results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1)
|
||||
case.chunk_size = len(results)
|
||||
results.append(5.0)
|
||||
with pytest.raises(IndexError):
|
||||
assert case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1)
|
||||
assert case.set_active_cell_property(results, 'GENERATED', 'SOIL', 1)
|
||||
|
||||
def createResult(poroChunks, permxChunks):
|
||||
for (poroChunk, permxChunk) in zip(poroChunks, permxChunks):
|
||||
@ -76,16 +77,26 @@ def test_10k_PoroPermX(rips_instance, initialize_test):
|
||||
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
case = rips_instance.project.load_case(path=casePath)
|
||||
|
||||
poroChunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORO', 0)
|
||||
permxChunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0)
|
||||
poroChunks = case.active_cell_property_async('STATIC_NATIVE', 'PORO', 0)
|
||||
permxChunks = case.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0)
|
||||
|
||||
case.properties.set_active_cell_property_async(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0)
|
||||
case.set_active_cell_property_async(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0)
|
||||
|
||||
poro = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0)
|
||||
permx = case.properties.active_cell_property('STATIC_NATIVE', 'PERMX', 0)
|
||||
poroPermX = case.properties.active_cell_property('GENERATED', 'POROPERMXAS', 0)
|
||||
poro = case.active_cell_property('STATIC_NATIVE', 'PORO', 0)
|
||||
permx = case.active_cell_property('STATIC_NATIVE', 'PERMX', 0)
|
||||
poroPermX = case.active_cell_property('GENERATED', 'POROPERMXAS', 0)
|
||||
|
||||
checkResults(poro, permx, poroPermX)
|
||||
|
||||
|
||||
|
||||
def test_exportPropertyInView(rips_instance, initialize_test):
|
||||
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
rips_instance.project.load_case(case_path)
|
||||
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
|
||||
print("Temporary folder: ", tmpdirname)
|
||||
rips_instance.set_export_folder(export_type='PROPERTIES', path=tmpdirname)
|
||||
case = rips_instance.project.case(case_id=0)
|
||||
view = case.view(view_id=0)
|
||||
view.export_property()
|
||||
expected_file_name = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL"
|
||||
full_path = tmpdirname + "/" + expected_file_name
|
||||
assert(os.path.exists(full_path))
|
@ -1,8 +1,13 @@
|
||||
import rips.Case # Circular import of Case, which already imports View. Use full name.
|
||||
from rips.Commands import Commands
|
||||
from rips.PdmObject import PdmObject
|
||||
"""
|
||||
ResInsight 3d view module
|
||||
"""
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
|
||||
class View (PdmObject):
|
||||
import rips.case # Circular import of Case, which already imports View. Use full name.
|
||||
from rips.pdmobject import PdmObject
|
||||
|
||||
|
||||
class View(PdmObject):
|
||||
"""ResInsight view class
|
||||
|
||||
Attributes:
|
||||
@ -10,9 +15,9 @@ class View (PdmObject):
|
||||
|
||||
"""
|
||||
def __init__(self, pdm_object):
|
||||
self.id = pdm_object.get_value("ViewId")
|
||||
self.view_id = pdm_object.get_value("ViewId")
|
||||
|
||||
PdmObject.__init__(self, pdm_object.pb2_object, pdm_object.channel)
|
||||
PdmObject.__init__(self, pdm_object._pb2_object, pdm_object._channel)
|
||||
|
||||
def show_grid_box(self):
|
||||
"""Check if the grid box is meant to be shown in the view"""
|
||||
@ -54,11 +59,12 @@ class View (PdmObject):
|
||||
cell_result.set_value("ResultVariable", result_variable)
|
||||
cell_result.update()
|
||||
|
||||
def apply_flow_diagnostics_cell_result(self,
|
||||
result_variable = 'TOF',
|
||||
selection_mode = 'FLOW_TR_BY_SELECTION',
|
||||
injectors = [],
|
||||
producers = []):
|
||||
def apply_flow_diagnostics_cell_result(
|
||||
self,
|
||||
result_variable='TOF',
|
||||
selection_mode='FLOW_TR_BY_SELECTION',
|
||||
injectors=None,
|
||||
producers=None):
|
||||
"""Apply a flow diagnostics cell result
|
||||
|
||||
Arguments:
|
||||
@ -76,6 +82,10 @@ class View (PdmObject):
|
||||
producers (list): List of producer tracers (strings) to select.
|
||||
Requires selection_mode to be 'FLOW_TR_BY_SELECTION'.
|
||||
"""
|
||||
if injectors is None:
|
||||
injectors = []
|
||||
if producers is None:
|
||||
producers = []
|
||||
cell_result = self.set_cell_result()
|
||||
cell_result.set_value("ResultType", "FLOW_DIAGNOSTICS")
|
||||
cell_result.set_value("ResultVariable", result_variable)
|
||||
@ -92,9 +102,69 @@ class View (PdmObject):
|
||||
pdm_case = self.ancestor("ResInsightGeoMechCase")
|
||||
if pdm_case is None:
|
||||
return None
|
||||
return rips.Case(self.channel, pdm_case.get_value("CaseId"))
|
||||
return rips.case.Case(self._channel, pdm_case.get_value("CaseId"))
|
||||
|
||||
def clone(self):
|
||||
"""Clone the current view"""
|
||||
view_id = Commands(self.channel).clone_view(self.id)
|
||||
view_id = self._execute_command(cloneView=Cmd.CloneViewRequest(
|
||||
viewId=self.view_id)).createViewResult.viewId
|
||||
return self.case().view(view_id)
|
||||
|
||||
def set_time_step(self, time_step):
|
||||
case_id = self.case().case_id
|
||||
return self._execute_command(setTimeStep=Cmd.SetTimeStepParams(
|
||||
caseId=case_id, viewId=self.view_id, timeStep=time_step))
|
||||
|
||||
def export_sim_well_fracture_completions(self, time_step,
|
||||
simulation_well_names, file_split,
|
||||
compdat_export):
|
||||
if isinstance(simulation_well_names, str):
|
||||
simulation_well_names = [simulation_well_names]
|
||||
|
||||
case_id = self.case().case_id
|
||||
return self._execute_command(
|
||||
exportSimWellFractureCompletions=Cmd.ExportSimWellPathFracRequest(
|
||||
caseId=case_id,
|
||||
viewId=self.view_id,
|
||||
timeStep=time_step,
|
||||
simulationWellNames=simulation_well_names,
|
||||
fileSplit=file_split,
|
||||
compdatExport=compdat_export))
|
||||
|
||||
def export_visible_cells(self,
|
||||
export_keyword='FLUXNUM',
|
||||
visible_active_cells_value=1,
|
||||
hidden_active_cells_value=0,
|
||||
inactive_cells_value=0):
|
||||
case_id = self.case().case_id
|
||||
return self._execute_command(
|
||||
exportVisibleCells=Cmd.ExportVisibleCellsRequest(
|
||||
caseId=case_id,
|
||||
viewId=self.view_id,
|
||||
exportKeyword=export_keyword,
|
||||
visibleActiveCellsValue=visible_active_cells_value,
|
||||
hiddenActiveCellsValue=hidden_active_cells_value,
|
||||
inactiveCellsValue=inactive_cells_value))
|
||||
|
||||
def export_property(self, undefined_value=0.0):
|
||||
""" Export the current Eclipse property from the view
|
||||
|
||||
Arguments:
|
||||
undefined_value (double): Value to use for undefined values. Defaults to 0.0
|
||||
"""
|
||||
case_id = self.case().case_id
|
||||
return self._execute_command(
|
||||
exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(
|
||||
caseId=case_id,
|
||||
viewIds=[self.view_id],
|
||||
undefinedValue=undefined_value))
|
||||
|
||||
def export_snapshot(self, prefix=''):
|
||||
""" Export snapshot for the current view
|
||||
Arguments:
|
||||
prefix (str): Exported file name prefix
|
||||
"""
|
||||
case_id = self.case().case_id
|
||||
return self._execute_command(
|
||||
exportSnapshots=Cmd.ExportSnapshotsRequest(
|
||||
type='VIEWS', prefix=prefix, caseId=case_id, viewId=self.view_id))
|
@ -1506,7 +1506,7 @@ void RiuMainWindow::slotSnapshotAllViewsToFile()
|
||||
|
||||
// Save images in snapshot catalog relative to project directory
|
||||
QString absolutePathToSnapshotDir = app->createAbsolutePathFromProjectRelativePath( "snapshots" );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder( absolutePathToSnapshotDir );
|
||||
RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user