diff --git a/ApplicationCode/Application/RiaGuiApplication.cpp b/ApplicationCode/Application/RiaGuiApplication.cpp index 88eabb6d4c..9c98a6a098 100644 --- a/ApplicationCode/Application/RiaGuiApplication.cpp +++ b/ApplicationCode/Application/RiaGuiApplication.cpp @@ -823,8 +823,8 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments(cvf::Progra // 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); + QString absolutePathToSnapshotDir = createAbsolutePathFromProjectRelativePath( "snapshots" ); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir ); mainWnd->loadWinGeoAndDockToolBarLayout(); } @@ -1787,7 +1787,7 @@ void RiaGuiApplication::runMultiCaseSnapshots(const QString& templateProje bool loadOk = loadProject(templateProjectFileName, PLA_NONE, &modifier); if (loadOk) { - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(snapshotFolderName); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( snapshotFolderName ); } } diff --git a/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp b/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp index 79285ac184..b48ddd246a 100644 --- a/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp +++ b/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp @@ -115,7 +115,7 @@ QString RiaSummaryCurveDefinition::curveDefinitionText() const { QString caseName; if (summaryCase()) - caseName = summaryCase()->caseName(); + caseName = summaryCase()->shortName(); else if (ensemble()) caseName = ensemble()->name(); diff --git a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp index 29ad82e2b3..ade720b2d1 100644 --- a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp +++ b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp @@ -201,8 +201,8 @@ void RiaRegressionTestRunner::runRegressionTest() resizePlotWindows(); - QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName); - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(fullPathGeneratedFolder); + QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath( generatedFolderName ); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( fullPathGeneratedFolder ); RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder); diff --git a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp index 35feb92961..27344f43cb 100644 --- a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp +++ b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp @@ -282,6 +282,9 @@ void RiaSummaryCurveAnalyzer::clear() m_wellCompletions.clear(); m_wellSegmentNumbers.clear(); m_blocks.clear(); + + m_quantitiesNoMatchingHistory.clear(); + m_quantitiesWithMatchingHistory.clear(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp index 5162476970..a51523ba7d 100644 --- a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp +++ b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp @@ -54,6 +54,11 @@ RiaTimeHistoryCurveResampler::RiaTimeHistoryCurveResampler() //-------------------------------------------------------------------------------------------------- void RiaTimeHistoryCurveResampler::setCurveData(const std::vector& values, const std::vector& timeSteps) { + if (values.empty() || timeSteps.empty()) + { + return; + } + CVF_ASSERT(values.size() == timeSteps.size()); clearData(); diff --git a/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp b/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp index 3944fe2b43..8e6f1704d3 100644 --- a/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp +++ b/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp @@ -133,3 +133,25 @@ RimEclipseView* RicfApplicationTools::viewFromCaseIdAndViewName(int caseId, cons } 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( v ); + if ( eclipseView && eclipseView->id() == viewId ) + { + return eclipseView; + } + } + } + } + return nullptr; +} diff --git a/ApplicationCode/CommandFileInterface/RicfApplicationTools.h b/ApplicationCode/CommandFileInterface/RicfApplicationTools.h index 182aa0d78a..c0efab4c87 100644 --- a/ApplicationCode/CommandFileInterface/RicfApplicationTools.h +++ b/ApplicationCode/CommandFileInterface/RicfApplicationTools.h @@ -34,9 +34,10 @@ class QStringList; class RicfApplicationTools { public: - static std::vector wellPathsFromNames(const QStringList& wellPathNames, QStringList* wellsNotFound); - static RimEclipseCase* caseFromId(int caseId); - static RimEclipseView* viewFromCaseIdAndViewName(int caseId, const QString& viewName); + static std::vector 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 toStringVector(const QStringList& stringList); static QStringList toQStringList(const std::vector& v); diff --git a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp index 7c95e141ef..a1e8e67f23 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp @@ -47,9 +47,10 @@ CAF_PDM_SOURCE_INIT(RicfExportPropertyInViews, "exportPropertyInViews"); //-------------------------------------------------------------------------------------------------- RicfExportPropertyInViews::RicfExportPropertyInViews() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_viewNames, "viewNames", std::vector(), "View Names", "", "", ""); - RICF_InitField(&m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", ""); + RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" ); + RICF_InitField( &m_viewIds, "viewIds", std::vector(), "View IDs", "", "", "" ); + RICF_InitField( &m_viewNames, "viewNames", std::vector(), "View Names", "", "", "" ); + RICF_InitField( &m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -74,22 +75,35 @@ RicfCommandResponse RicfExportPropertyInViews::execute() RimEclipseView* view = dynamic_cast(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->id() == viewId ) + { + matchingIdOrName = true; + break; + } + } + + if ( !matchingIdOrName ) { - if (view->name().compare(viewName, Qt::CaseInsensitive) == 0) + for ( const auto& viewName : m_viewNames() ) { - matchingName = true; + if ( view->name().compare( viewName, Qt::CaseInsensitive ) == 0 ) + { + matchingIdOrName = true; + } } } - if (matchingName) + if ( matchingIdOrName ) { viewsForExport.push_back(view); } diff --git a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h index 896d489582..8e5a60d179 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h +++ b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h @@ -44,6 +44,7 @@ class RicfExportPropertyInViews : public RicfCommandObject private: caf::PdmField m_caseId; + caf::PdmField> m_viewIds; caf::PdmField> m_viewNames; caf::PdmField m_undefinedValue; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp index 0b233c5594..0fb5e7e048 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp @@ -45,12 +45,19 @@ CAF_PDM_SOURCE_INIT(RicfExportSimWellFractureCompletions, "exportSimWellFracture //-------------------------------------------------------------------------------------------------- RicfExportSimWellFractureCompletions::RicfExportSimWellFractureCompletions() { - RICF_InitField(&m_caseId, "caseId", -1, "Case 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(), "Simulation Well Names", "", "", ""); - RICF_InitField(&m_fileSplit, "fileSplit", RicExportCompletionDataSettingsUi::ExportSplitType(), "File Split", "", "", ""); - RICF_InitField(&m_compdatExport, "compdatExport", RicExportCompletionDataSettingsUi::CompdatExportType(), "Compdat Export", "", "", ""); + 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(), "Simulation Well Names", "", "", "" ); + RICF_InitField( &m_fileSplit, "fileSplit", RicExportCompletionDataSettingsUi::ExportSplitType(), "File Split", "", "", "" ); + RICF_InitField( &m_compdatExport, + "compdatExport", + RicExportCompletionDataSettingsUi::CompdatExportType(), + "Compdat Export", + "", + "", + "" ); } //-------------------------------------------------------------------------------------------------- @@ -88,17 +95,22 @@ RicfCommandResponse RicfExportSimWellFractureCompletions::execute() std::vector views; for (Rim3dView* v : exportSettings->caseToApply->views()) { - RimEclipseView* eclipseView = dynamic_cast(v); - if (eclipseView && eclipseView->name() == m_viewName()) + RimEclipseView* eclipseView = dynamic_cast( v ); + 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()); - RiaLogging::error(error); - return RicfCommandResponse(RicfCommandResponse::COMMAND_ERROR, error); + 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 ); } RicfCommandResponse response; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h index 2b49b7d9f6..2bc202a972 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h +++ b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h @@ -40,11 +40,12 @@ class RicfExportSimWellFractureCompletions : public RicfCommandObject RicfCommandResponse execute() override; private: - caf::PdmField m_caseId; - caf::PdmField m_viewName; - caf::PdmField m_timeStep; - caf::PdmField< std::vector > m_simWellNames; - + caf::PdmField m_caseId; + caf::PdmField m_viewId; + caf::PdmField m_viewName; + caf::PdmField m_timeStep; + caf::PdmField> m_simWellNames; + caf::PdmField m_fileSplit; caf::PdmField m_compdatExport; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp index ee272ec0a1..54bdeec54c 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp @@ -49,9 +49,10 @@ void RicfExportSnapshots::SnapshotsTypeEnum::setUp() //-------------------------------------------------------------------------------------------------- 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_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", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -78,7 +79,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) { diff --git a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h index 47aa2123fa..bbad3c84ab 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h +++ b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h @@ -51,4 +51,5 @@ class RicfExportSnapshots : public RicfCommandObject caf::PdmField m_type; caf::PdmField m_prefix; caf::PdmField m_caseId; + caf::PdmField m_viewId; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp index e383e773b6..f32d1c48fe 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp @@ -63,13 +63,19 @@ void AppEnum::setUp() //-------------------------------------------------------------------------------------------------- RicfExportVisibleCells::RicfExportVisibleCells() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_viewName, "viewName", QString(), "View Name", "", "", ""); - RICF_InitField( - &m_exportKeyword, "exportKeyword", caf::AppEnum(), "Export Keyword", "", "", ""); - RICF_InitField(&m_visibleActiveCellsValue, "visibleActiveCellsValue", 1, "Visible Active Cells Value", "", "", ""); - RICF_InitField(&m_hiddenActiveCellsValue, "hiddenActiveCellsValue", 0, "Hidden Active Cells Value", "", "", ""); - RICF_InitField(&m_inactiveCellsValue, "inactiveCellsValue", 0, "Inactive Cells Value", "", "", ""); + 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", + caf::AppEnum(), + "Export Keyword", + "", + "", + "" ); + RICF_InitField( &m_visibleActiveCellsValue, "visibleActiveCellsValue", 1, "Visible Active Cells Value", "", "", "" ); + RICF_InitField( &m_hiddenActiveCellsValue, "hiddenActiveCellsValue", 0, "Hidden Active Cells Value", "", "", "" ); + RICF_InitField( &m_inactiveCellsValue, "inactiveCellsValue", 0, "Inactive Cells Value", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -77,19 +83,29 @@ 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"); - RiaLogging::error(error); - return RicfCommandResponse(RicfCommandResponse::COMMAND_ERROR, error); + 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); - if (!eclipseView) + 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)); - RiaLogging::error(error); - return RicfCommandResponse(RicfCommandResponse::COMMAND_ERROR, error); + 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 ); } QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::CELLS); diff --git a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h index 1945090d47..79cec7ce46 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h +++ b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h @@ -51,6 +51,7 @@ class RicfExportVisibleCells : public RicfCommandObject void buildExportSettings(const QString& exportFolder, RicSaveEclipseInputVisibleCellsUi* exportSettings); caf::PdmField m_caseId; + caf::PdmField m_viewId; caf::PdmField m_viewName; caf::PdmField> m_exportKeyword; caf::PdmField m_visibleActiveCellsValue; diff --git a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp index 22655a6cdc..73534e1146 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp +++ b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp @@ -34,8 +34,9 @@ CAF_PDM_SOURCE_INIT(RicfSetTimeStep, "setTimeStep"); //-------------------------------------------------------------------------------------------------- RicfSetTimeStep::RicfSetTimeStep() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_timeStepIndex, "timeStep", -1, "Time Step Index", "", "", ""); + 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", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -49,7 +50,15 @@ void RicfSetTimeStep::setCaseId(int caseId) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfSetTimeStep::setTimeStepIndex(int timeStepIndex) +void RicfSetTimeStep::setViewId( int viewId ) +{ + m_viewId = viewId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfSetTimeStep::setTimeStepIndex( int timeStepIndex ) { m_timeStepIndex = timeStepIndex; } @@ -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(); diff --git a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h index 69e7c9b89d..9d65e2309e 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h +++ b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h @@ -34,13 +34,15 @@ class RicfSetTimeStep : public RicfCommandObject public: RicfSetTimeStep(); - void setCaseId(int caseId); - void setTimeStepIndex(int timeStepIndex); + void setCaseId( int caseId ); + void setViewId( int viewId ); + void setTimeStepIndex( int timeStepIndex ); RicfCommandResponse execute() override; private: caf::PdmField m_caseId; + caf::PdmField m_viewId; caf::PdmField m_timeStepIndex; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp index b1330523c0..9872d38d52 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp +++ b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp @@ -218,7 +218,7 @@ void RicHelpOpenUsersGuideFeature::onActionTriggered(bool isChecked) { this->disableModelChangeContribution(); - QString usersGuideUrl = "http://resinsight.org/docs/home"; + QString usersGuideUrl = "https://resinsight.org/getting-started/"; if (!QDesktopServices::openUrl(usersGuideUrl)) { diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp index 269eec1081..3c329ad7fb 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp @@ -427,7 +427,7 @@ void RicExportFractureCompletionsImpl::getWellPressuresAndInitialProductionTimeS { RimSummaryCase* summaryCase = mainCollection->findSummaryCaseFromEclipseResultCase(resultCase); - if (summaryCase) + if (summaryCase && summaryCase->summaryReader()) { std::vector values; if (summaryCase->summaryReader()->values(wbhpPressureAddress, &values)) diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp index 9c6a3b5ebd..514921eab0 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp @@ -118,8 +118,12 @@ void RicEclipsePropertyFilterFeatureImpl::setDefaults(RimEclipsePropertyFilter* RimEclipseView* reservoirView = nullptr; propertyFilter->firstAncestorOrThisOfTypeAsserted(reservoirView); - propertyFilter->resultDefinition()->setEclipseCase(reservoirView->eclipseCase()); - propertyFilter->resultDefinition()->simpleCopy(reservoirView->cellResult()); + propertyFilter->resultDefinition()->setEclipseCase( reservoirView->eclipseCase() ); + + if ( !RiaDefines::isPerCellFaceResult( reservoirView->cellResult()->resultVariable() ) ) + { + propertyFilter->resultDefinition()->simpleCopy( reservoirView->cellResult() ); + } propertyFilter->resultDefinition()->loadResult(); propertyFilter->setToDefaultValues(); diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp index 6fe37816fd..223abfc03b 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp @@ -61,16 +61,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(); @@ -103,7 +106,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); diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h index 705566be1f..a0f9ea1c24 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h @@ -32,7 +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 diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp index 4d5383fe32..73e05d6680 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp @@ -142,9 +142,13 @@ QWidget* RicSummaryCurveCreatorSplitterUi::createWidget(QWidget* parent) m_firstColumnSplitter->setHandleWidth(6); m_firstColumnSplitter->setStyleSheet("QSplitter::handle { image: url(:/SplitterH.png); }"); - m_firstColumnSplitter->insertWidget(0, firstRowFrame); - m_firstColumnSplitter->insertWidget(1, secondRowFrame); - m_firstColumnSplitter->setSizes(QList() << 1 << 2); + m_firstColumnSplitter->insertWidget( 0, firstRowFrame ); + m_firstColumnSplitter->insertWidget( 1, secondRowFrame ); + + const int firstRowPixelHeight = 500; + const int secondRowPixelHeight = 300; + + m_firstColumnSplitter->setSizes( QList() << firstRowPixelHeight << secondRowPixelHeight ); m_layout->addWidget(m_firstColumnSplitter); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp index 11811f7424..89b490fa0f 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp @@ -37,7 +37,7 @@ //-------------------------------------------------------------------------------------------------- RimSummaryCurve* RicSummaryPlotFeatureImpl::addDefaultCurveToPlot(RimSummaryPlot* plot, RimSummaryCase* summaryCase) { - if (plot) + if (plot && summaryCase && summaryCase->summaryReader()) { RifEclipseSummaryAddress defaultAddressToUse; @@ -88,6 +88,9 @@ std::vector RicSummaryPlotFeatureImpl::addDefaultCurvesToPlot( { std::vector defaultCurves; + if (!plot) return defaultCurves; + if (!summaryCase || !summaryCase->summaryReader()) return defaultCurves; + QString curvesTextFilter = RiaApplication::instance()->preferences()->defaultSummaryCurvesTextFilter; QStringList curveFilters = curvesTextFilter.split(";", QString::SkipEmptyParts); diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp index 0d8771893b..461d4595cc 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp @@ -153,6 +153,32 @@ void RifEclipseOutputFileTools::timeSteps(const ecl_file_type* ecl_file, std::ve } } + bool allTimeStepsOnSameDate = true; + { + // See https://github.com/OPM/ResInsight/issues/4770 + + std::set days; + std::set months; + std::set years; + for ( int i = 0; i < numINTEHEAD; i++ ) + { + ecl_kw_type* kwINTEHEAD = ecl_file_iget_named_kw( ecl_file, INTEHEAD_KW, i ); + CVF_ASSERT( kwINTEHEAD ); + int day = 0; + int month = 0; + int year = 0; + getDayMonthYear( kwINTEHEAD, &day, &month, &year ); + + days.insert( day ); + months.insert( month ); + years.insert( year ); + } + + if ( days.size() > 1 ) allTimeStepsOnSameDate = false; + if ( months.size() > 1 ) allTimeStepsOnSameDate = false; + if ( years.size() > 1 ) allTimeStepsOnSameDate = false; + } + std::set existingTimesteps; for (int i = 0; i < numINTEHEAD; i++) @@ -167,8 +193,14 @@ void RifEclipseOutputFileTools::timeSteps(const ecl_file_type* ecl_file, std::ve QDateTime reportDateTime = RiaQDateTimeTools::createUtcDateTime(QDate(year, month, day)); CVF_ASSERT(reportDateTime.isValid()); - double dayValue = dayValues[i]; - double dayFraction = dayValue - cvf::Math::floor(dayValue); + double dayDoubleValue = dayValues[i]; + int dayValue = cvf::Math::floor( dayDoubleValue ); + if ( allTimeStepsOnSameDate ) + { + reportDateTime = reportDateTime.addDays( dayValue ); + } + + double dayFraction = dayDoubleValue - dayValue; double milliseconds = dayFraction * 24.0 * 60.0 * 60.0 * 1000.0; reportDateTime = reportDateTime.addMSecs(milliseconds); diff --git a/ApplicationCode/GrpcInterface/CMakeLists.cmake b/ApplicationCode/GrpcInterface/CMakeLists.cmake index 6271a0ad20..79a801f311 100644 --- a/ApplicationCode/GrpcInterface/CMakeLists.cmake +++ b/ApplicationCode/GrpcInterface/CMakeLists.cmake @@ -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" diff --git a/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto b/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto index 8676996ecf..7c3506bd38 100644 --- a/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto +++ b/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto @@ -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 diff --git a/ApplicationCode/GrpcInterface/Python/doc/make_and_copy.bat b/ApplicationCode/GrpcInterface/Python/doc/make_and_copy.bat new file mode 100644 index 0000000000..665d65bedc --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/doc/make_and_copy.bat @@ -0,0 +1,39 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd + +REM Copy files to deployment folder using second parameter +REM Example "d:\gitroot\ResInsight-UserDocumentation\content\scripting" +xcopy /Y build\markdown %2 \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst b/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst index 56d9a7e97b..a7b83b5caa 100644 --- a/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst +++ b/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst @@ -10,70 +10,85 @@ This pages is created based on the content in the **PythonExamples** folder loca AllCases ------- +-------- .. literalinclude:: ../../rips/PythonExamples/AllCases.py AppInfo ------- +------- .. literalinclude:: ../../rips/PythonExamples/AppInfo.py CaseGridGroup ------- +------------- .. literalinclude:: ../../rips/PythonExamples/CaseGridGroup.py CaseInfoStreamingExample ------- +------------------------ .. literalinclude:: ../../rips/PythonExamples/CaseInfoStreamingExample.py CommandExample ------- +-------------- .. literalinclude:: ../../rips/PythonExamples/CommandExample.py + ErrorHandling ------- +------------- .. literalinclude:: ../../rips/PythonExamples/ErrorHandling.py + ExportSnapshots ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/ExportSnapshots.py + GridInformation ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/GridInformation.py + InputPropTestAsync ------- +------------------ .. literalinclude:: ../../rips/PythonExamples/InputPropTestAsync.py + InputPropTestSync ------- +----------------- .. literalinclude:: ../../rips/PythonExamples/InputPropTestSync.py + InstanceExample ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/InstanceExample.py LaunchWithCommandLineOptions ------- +---------------------------- .. literalinclude:: ../../rips/PythonExamples/LaunchWithCommandLineOptions.py + SelectedCases ------- +------------- .. literalinclude:: ../../rips/PythonExamples/SelectedCases.py + SetCellResult ------- +------------- .. literalinclude:: ../../rips/PythonExamples/SetCellResult.py + SetFlowDiagnosticsResult ------- +------------------------ .. literalinclude:: ../../rips/PythonExamples/SetFlowDiagnosticsResult.py + SetGridProperties ------- +----------------- .. literalinclude:: ../../rips/PythonExamples/SetGridProperties.py + SoilAverageAsync ------- +---------------- .. literalinclude:: ../../rips/PythonExamples/SoilAverageAsync.py + SoilAverageSync ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/SoilAverageSync.py + SoilPorvAsync ------- +------------- .. literalinclude:: ../../rips/PythonExamples/SoilPorvAsync.py + SoilPorvSync ------- +------------ .. literalinclude:: ../../rips/PythonExamples/SoilPorvSync.py + ViewExample ------- +----------- .. literalinclude:: ../../rips/PythonExamples/ViewExample.py diff --git a/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst b/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst index 6e5e14daa5..a10a3a0e68 100644 --- a/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst +++ b/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst @@ -1,7 +1,7 @@ Instance Module =============== -.. autoclass:: rips.Instance +.. autoclass:: rips.instance.Instance :members: Example @@ -14,7 +14,7 @@ Example Case Module =========== -.. autoclass:: rips.Case +.. autoclass:: rips.case.Case :members: Example @@ -25,23 +25,10 @@ Example :lines: 5- :emphasize-lines: 5 -Commands Module -=============== - -.. autoclass:: rips.Commands - :members: - :undoc-members: - -Example -------- -.. literalinclude:: ../../rips/PythonExamples/CommandExample.py - :language: python - :lines: 5- - Grid Module =========== -.. autoclass:: rips.Grid +.. autoclass:: rips.grid.Grid :members: Example @@ -60,26 +47,21 @@ Example GridCaseGroup Module ==================== -.. autoclass:: rips.GridCaseGroup +.. autoclass:: rips.gridcasegroup.GridCaseGroup :members: Project Module ============== -.. autoclass:: rips.Project +.. autoclass:: rips.project.Project :members: -Properties Module -================= - -.. autoclass:: rips.Properties - :members: View Module =========== -.. autoclass:: rips.View +.. autoclass:: rips.view.View :members: Synchronous Example diff --git a/ApplicationCode/GrpcInterface/Python/rips/Case.py b/ApplicationCode/GrpcInterface/Python/rips/Case.py deleted file mode 100644 index 312bfab25d..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Case.py +++ /dev/null @@ -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.groupId = 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 gridCount(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 gridPath(self): - return self.getValue("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""" - gridList = [] - for i in range(0, self.gridCount()): - gridList.append(Grid(i, self)) - return gridList - - def cellCount(self, porosityModel='MATRIX_MODEL'): - """Get a cell count object containing number of active cells and - total number of cells - - Arguments: - porosityModel (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 - """ - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Case_pb2.CellInfoRequest(case_request=self.request, - porosity_model=porosityModel) - return self.stub.GetCellCount(request) - - def cellInfoForActiveCellsAsync(self, porosityModel='MATRIX_MODEL'): - """Get Stream of cell info objects for current case - - Arguments: - porosityModel(str): String representing an enum. - must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. - - Returns: - Stream of **CellInfo** objects - - See cellInfoForActiveCells() for detalis on the **CellInfo** class. - """ - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Case_pb2.CellInfoRequest(case_request=self.request, - porosity_model=porosityModel) - return self.stub.GetCellInfoForActiveCells(request) - - def cellInfoForActiveCells(self, porosityModel='MATRIX_MODEL'): - """Get list of cell info objects for current case - - Arguments: - porosityModel(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 - - """ - activeCellInfoChunks = self.cellInfoForActiveCellsAsync() - receivedActiveCells = [] - for activeCellChunk in activeCellInfoChunks: - for activeCell in activeCellChunk.data: - receivedActiveCells.append(activeCell) - return receivedActiveCells - - def timeSteps(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 daysSinceStart(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""" - pbmObjects = self.children("ReservoirViews") - viewList = [] - for pbmObject in pbmObjects: - viewList.append(View(pbmObject)) - return viewList - - 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 viewObject in views: - if viewObject.id == id: - return viewObject - return None - - def createView(self): - """Create a new view in the current case""" - viewId = Commands(self.channel).createView(self.id) - return self.view(viewId) - diff --git a/ApplicationCode/GrpcInterface/Python/rips/Commands.py b/ApplicationCode/GrpcInterface/Python/rips/Commands.py deleted file mode 100644 index b80d84405d..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Commands.py +++ /dev/null @@ -1,296 +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, **commandParams): - return self.commands.Execute(Cmd.CommandParams(**commandParams)) - - ######################## - # Case Control Commands - ######################## - - def openProject(self, path): - """Open a project - - Arguments: - path (str): path to project file - - - """ - return self.__execute(openProject=Cmd.FilePathRequest(path=path)) - - def closeProject(self): - """Close the current project (and reopen empty one)""" - return self.__execute(closeProject=Empty()) - - def setStartDir(self, path): - """Set current start directory - - Arguments: - path (str): path to directory - - """ - return self.__execute(setStartDir=Cmd.FilePathRequest(path=path)) - - def loadCase(self, path): - """Load a case - - Arguments: - path (str): path to EGRID file - - Returns: - A Case object - - """ - commandReply = self.__execute(loadCase=Cmd.FilePathRequest(path=path)) - return rips.Case(self.channel, commandReply.loadCaseResult.id) - - def replaceCase(self, newGridFile, caseId=0): - """Replace the given case with a new case loaded from file - - Arguments: - newGridFile (str): path to EGRID file - caseId (int): case Id to replace - - """ - return self.__execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=newGridFile, - caseId=caseId)) - - def replaceSourceCases(self, gridListFile, caseGroupId=0): - """Replace all source cases within a case group - - Arguments: - gridListFile (str): path to file containing a list of cases - caseGroupId (int): id of the case group to replace - - """ - return self.__execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=gridListFile, - caseGroupId=caseGroupId)) - - def createGridCaseGroup(self, casePaths): - """Create a Grid Case Group from a list of cases - - Arguments: - casePaths (list): list of file path strings - - Returns: - A case group id and name - """ - commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=casePaths)) - return (commandReply.createGridCaseGroupResult.groupId, commandReply.createGridCaseGroupResult.groupName) - - def createStatisticsCase(self, caseGroupId): - commandReply = self.__execute(createStatisticsCase=Cmd.CreateStatisticsCaseRequest(caseGroupId=caseGroupId)) - return commandReply.createStatisticsCaseResult.caseId; - - ################## - # Export Commands - ################## - - def exportMultiCaseSnapshots(self, gridListFile): - """Export snapshots for a set of cases - - Arguments: - gridListFile (str): Path to a file containing a list of grids to export snapshot for - - """ - return self.__execute(exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(gridListFile=gridListFile)) - - def exportSnapshots(self, type = 'ALL', prefix='', caseId = -1): - """ Export snapshots of a given type - - Arguments: - type (str): Enum string ('ALL', 'VIEWS' or 'PLOTS') - prefix (str): Exported file name prefix - caseId (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=caseId)) - - def exportProperty(self, caseId, timeStep, property, eclipseKeyword=property, undefinedValue=0.0, exportFile=property): - """ Export an Eclipse property - - Arguments: - caseId (int): case id - timeStep (int): time step index - property (str): property to export - eclipseKeyword (str): Eclipse keyword used as text in export header. Defaults to the value of property parameter. - undefinedValue (double): Value to use for undefined values. Defaults to 0.0 - exportFile (str): Filename for export. Defaults to the value of property parameter - """ - return self.__execute(exportProperty=Cmd.ExportPropertyRequest(caseId=caseId, - timeStep=timeStep, - property=property, - eclipseKeyword=eclipseKeyword, - undefinedValue=undefinedValue, - exportFile=exportFile)) - - def exportPropertyInViews(self, caseId, viewNames, undefinedValue): - if isinstance(viewNames, str): - viewNames = [viewNames] - - return self.__execute(exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(caseId=caseId, - viewNames=viewNames, - undefinedValue=undefinedValue)) - - def exportWellPathCompletions(self, caseId, timeStep, wellPathNames, fileSplit, - compdatExport, includePerforations, includeFishbones, - excludeMainBoreForFishbones, combinationMode): - if (isinstance(wellPathNames, str)): - wellPathNames = [wellPathNames] - return self.__execute(exportWellPathCompletions=Cmd.ExportWellPathCompRequest(caseId=caseId, - timeStep=timeStep, - wellPathNames=wellPathNames, - fileSplit=fileSplit, - compdatExport=compdatExport, - includePerforations=includePerforations, - includeFishbones=includeFishbones, - excludeMainBoreForFishbones=excludeMainBoreForFishbones, - combinationMode=combinationMode)) - - def exportSimWellFractureCompletions(self, caseId, viewName, timeStep, simulationWellNames, fileSplit, compdatExport): - if(isinstance(simulationWellNames, str)): - simulationWellNames = [simulationWellNames] - return self.__execute(exportSimWellFractureCompletions=Cmd.ExportSimWellPathFraqRequest(caseId=caseId, - viewName=viewName, - timeStep=timeStep, - simulationWellNames=simulationWellNames, - fileSplit=fileSplit, - compdatExport=compdatExport)) - - def exportMsw(self, caseId, wellPath): - return self.__execute(exportMsw=Cmd.ExportMswRequest(caseId=caseId, - wellPath=wellPath)) - - def exportWellPaths(self, wellPaths=[], mdStepSize=5.0): - if isinstance(wellPaths, str): - wellPaths = [wellPaths] - return self.__execute(exportWellPaths=Cmd.ExportWellPathRequest(wellPathNames=wellPaths, mdStepSize=mdStepSize)) - - def exportVisibleCells(self, caseId, viewName, exportKeyword='FLUXNUM', visibleActiveCellsValue=1, hiddenActiveCellsValue=0, inactiveCellsValue=0): - return self.__execute(exportVisibleCells=Cmd.ExportVisibleCellsRequest(caseId=caseId, - viewName=viewName, - exportKeyword=exportKeyword, - visibleActiveCellsValue=visibleActiveCellsValue, - hiddenActiveCellsValue=hiddenActiveCellsValue, - inactiveCellsValue=inactiveCellsValue)) - def setExportFolder(self, type, path, createFolder=False): - return self.__execute(setExportFolder=Cmd.SetExportFolderRequest(type=type, - path=path, - createFolder=createFolder)) - - def runOctaveScript(self, path, cases): - caseIds = [] - for case in cases: - caseIds.append(case.id) - return self.__execute(runOctaveScript=Cmd.RunOctaveScriptRequest(path=path, - caseIds=caseIds)) - - def setMainWindowSize(self, width, height): - return self.__execute(setMainWindowSize=Cmd.SetMainWindowSizeParams(width=width, height=height)) - - def computeCaseGroupStatistics(self, caseIds = [], caseGroupId = -1): - return self.__execute(computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(caseIds=caseIds, - caseGroupId=caseGroupId)) - - def setTimeStep(self, caseId, timeStep): - return self.__execute(setTimeStep=Cmd.SetTimeStepParams(caseId=caseId, timeStep=timeStep)) - - def scaleFractureTemplate(self, id, halfLength, height, dFactor, conductivity): - return self.__execute(scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(id=id, - halfLength=halfLength, - height=height, - dFactor=dFactor, - conductivity=conductivity)) - - def setFractureContainment(self, id, topLayer, baseLayer): - return self.__execute(setFractureContainment=Cmd.SetFracContainmentRequest(id=id, - topLayer=topLayer, - baseLayer=baseLayer)) - - def createMultipleFractures(self, caseId, templateId, wellPathNames, minDistFromWellTd, - maxFracturesPerWell, topLayer, baseLayer, spacing, action): - if isinstance(wellPathNames, str): - wellPathNames = [wellPathNames] - return self.__execute(createMultipleFractures=Cmd.MultipleFracAction(caseId=caseId, - templateId=templateId, - wellPathNames=wellPathNames, - minDistFromWellTd=minDistFromWellTd, - maxFracturesPerWell=maxFracturesPerWell, - topLayer=topLayer, - baseLayer=baseLayer, - spacing=spacing, - action=action)) - - def createLgrForCompletions(self, caseId, timeStep, wellPathNames, refinementI, refinementJ, refinementK, splitType): - if isinstance(wellPathNames, str): - wellPathNames = [wellPathNames] - return self.__execute(createLgrForCompletions=Cmd.CreateLgrForCompRequest(caseId=caseId, - timeStep=timeStep, - wellPathNames=wellPathNames, - refinementI=refinementI, - refinementJ=refinementJ, - refinementK=refinementK, - splitType=splitType)) - - def createSaturationPressurePlots(self, caseIds): - if isinstance(caseIds, int): - caseIds = [caseIds] - return self.__execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=caseIds)) - - def exportFlowCharacteristics(self, caseId, timeSteps, injectors, producers, fileName, minimumCommunication=0.0, aquiferCellThreshold=0.1): - """ Export Flow Characteristics data to text file in CSV format - - Parameter | Description | Type - ------------------------- | --------------------------------------------- | ----- - caseId | ID of case | Integer - timeSteps | Time step indices | List of Integer - injectors | Injector names | List of Strings - producers | Producer names | List of Strings - fileName | Export file name | Integer - minimumCommunication | Minimum Communication, defaults to 0.0 | Integer - aquiferCellThreshold | Aquifer Cell Threshold, defaults to 0.1 | Integer - - """ - if isinstance(timeSteps, int): - timeSteps = [timeSteps] - if isinstance(injectors, str): - injectors = [injectors] - if isinstance(producers, str): - producers = [producers] - return self.__execute(exportFlowCharacteristics=Cmd.ExportFlowInfoRequest(caseId=caseId, - timeSteps=timeSteps, - injectors=injectors, - producers=producers, - fileName=fileName, - minimumCommunication = minimumCommunication, - aquiferCellThreshold = aquiferCellThreshold)) - - def createView(self, caseId): - return self.__execute(createView=Cmd.CreateViewRequest(caseId=caseId)).createViewResult.viewId - - def cloneView(self, viewId): - return self.__execute(cloneView=Cmd.CloneViewRequest(viewId=viewId)).createViewResult.viewId \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/Grid.py b/ApplicationCode/GrpcInterface/Python/rips/Grid.py deleted file mode 100644 index 3a8ab8d77f..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Grid.py +++ /dev/null @@ -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 - diff --git a/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py b/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py deleted file mode 100644 index d00d2f9e40..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py +++ /dev/null @@ -1,49 +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: - id (int): Grid Case Group Id corresponding to case group Id in ResInsight project. - name (str): Case name - """ - def __init__(self, pdmObject): - self.groupId = pdmObject.getValue("GroupId") - PdmObject.__init__(self, pdmObject.pb2Object, pdmObject.channel) - - def statisticsCases(self): - """Get a list of all statistics cases in the Grid Case Group""" - statCaseCollection = self.children("StatisticsCaseCollection")[0] - return statCaseCollection.children("Reservoirs") - - def views(self): - """Get a list of views belonging to a grid case group""" - pbmObjects = self.descendants("ReservoirView") - viewList = [] - for pbmObject in pbmObjects: - viewList.append(View(pbmObject)) - return viewList - - 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 viewObject in views: - if viewObject.id == id: - return viewObject - return None diff --git a/ApplicationCode/GrpcInterface/Python/rips/Instance.py b/ApplicationCode/GrpcInterface/Python/rips/Instance.py deleted file mode 100644 index 08655f9616..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Instance.py +++ /dev/null @@ -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(resInsightExecutable = '', console = False, launchPort = -1, commandLineParameters=[]): - """ Launch a new Instance of ResInsight. This requires the environment variable - RESINSIGHT_EXECUTABLE to be set or the parameter resInsightExecutable to be provided. - The RESINSIGHT_GRPC_PORT environment variable can be set to an alternative port number. - - Args: - resInsightExecutable (str): Path to a valid ResInsight executable. If set - will take precedence over what is provided in the RESINSIGHT_EXECUTABLE - environment variable. - console (bool): If True, launch as console application, without GUI. - launchPort(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 - commandLineParameters(list): Additional command line parameters as string entries in the list. - Returns: - Instance: an instance object if it worked. None if not. - """ - - port = 50051 - portEnv = os.environ.get('RESINSIGHT_GRPC_PORT') - if portEnv: - port = int(portEnv) - if launchPort is not -1: - port = launchPort - - if not resInsightExecutable: - resInsightExecutable = os.environ.get('RESINSIGHT_EXECUTABLE') - if not resInsightExecutable: - 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', resInsightExecutable) - - if isinstance(commandLineParameters, str): - commandLineParameters = [str] - - parameters = ["ResInsight", "--server", str(port)] + commandLineParameters - 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, resInsightExecutable, parameters) - if pid: - instance = Instance(port=port, launched=True) - return instance - return None - - @staticmethod - def find(startPort = 50051, endPort = 50071): - """ Search for an existing Instance of ResInsight by testing ports. - - By default we search from port 50051 to 50071 or if the environment - variable RESINSIGHT_GRPC_PORT is set we search - RESINSIGHT_GRPC_PORT to RESINSIGHT_GRPC_PORT+20 - - Args: - startPort (int): start searching from this port - endPort (int): search up to but not including this port - """ - portEnv = os.environ.get('RESINSIGHT_GRPC_PORT') - if portEnv: - startPort = int(portEnv) - endPort = startPort + 20 - - for tryPort in range(startPort, endPort): - if Instance.__is_port_in_use(tryPort): - return Instance(port=tryPort) - - print('Error: Could not find any ResInsight instances responding between ports ' + str(startPort) + ' and ' + str(endPort)) - return None - - def __checkVersion(self): - try: - majorVersionOk = self.majorVersion() == int(RiaVersionInfo.RESINSIGHT_MAJOR_VERSION) - minorVersionOk = self.minorVersion() == int(RiaVersionInfo.RESINSIGHT_MINOR_VERSION) - return True, majorVersionOk and minorVersionOk - except grpc.RpcError as e: - 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) - - connectionOk = False - versionOk = False - - if self.launched: - for i in range(0, 10): - connectionOk, versionOk = self.__checkVersion() - if connectionOk: - break - time.sleep(1.0) - else: - connectionOk, versionOk = self.__checkVersion() - - if not connectionOk: - 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 versionOk: - 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.setStartDir(path=path) - - def __versionMessage(self): - return self.app.GetVersion(Empty()) - - def majorVersion(self): - """Get an integer with the major version number""" - return self.__versionMessage().major_version - - def minorVersion(self): - """Get an integer with the minor version number""" - return self.__versionMessage().minor_version - - def patchVersion(self): - """Get an integer with the patch version number""" - return self.__versionMessage().patch_version - - def versionString(self): - """Get a full version string, i.e. 2019.04.01""" - return str(self.majorVersion()) + "." + str(self.minorVersion()) + "." + str(self.patchVersion()) - - def exit(self): - """Tell ResInsight instance to quit""" - print("Telling ResInsight to Exit") - return self.app.Exit(Empty()) - - def isConsole(self): - """Returns true if the connected ResInsight instance is a console app""" - return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('CONSOLE_APPLICATION') - - def isGui(self): - """Returns true if the connected ResInsight instance is a GUI app""" - return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('GUI_APPLICATION') diff --git a/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py b/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py deleted file mode 100644 index e3277e6ba5..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py +++ /dev/null @@ -1,152 +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 PdmObject_pb2 -import PdmObject_pb2_grpc - -class PdmObject: - def __init__(self, pb2Object, channel): - self.pb2Object = pb2Object - self.channel = channel - self.pdmObjectStub = PdmObject_pb2_grpc.PdmObjectServiceStub(self.channel) - - def address(self): - """Get the unique address of the PdmObject - - Returns: - A 64-bit unsigned integer address - """ - - return self.pb2Object.address - - def classKeyword(self): - """Get the class keyword in the ResInsight Data Model for the given PdmObject""" - return self.pb2Object.class_keyword - - def keywords(self): - """Get a list of all parameter keywords available in the object""" - listOfKeywords = [] - for keyword in self.pb2Object.parameters: - listOfKeywords.append(keyword) - return listOfKeywords - - def printObjectInfo(self): - """Print the structure and data content of the PdmObject""" - print ("Class Keyword: " + self.classKeyword()) - for keyword in self.keywords(): - print(keyword + " [" + type(self.getValue(keyword)).__name__ + "]: " + str(self.getValue(keyword))) - - def __toValue(self, value): - if value.lower() == 'false': - return False - elif value.lower() == 'true': - return True - else: - try: - intVal = int(value) - return intVal - except ValueError: - try: - floatVal = float(value) - return floatVal - 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 - def __fromValue(self, value): - if isinstance(value, bool): - if value: - return "true" - else: - return "false" - elif isinstance(value, list): - listofstrings = [] - for val in value: - listofstrings.append(self.__fromValue('\"' + val + '\"')) - return "[" + ", ".join(listofstrings) + "]" - else: - return str(value) - - def getValue(self, keyword): - """Get the value associated with the provided keyword - Arguments: - keyword(str): A string containing the parameter keyword - - Returns: - The value of the parameter. Can be int, str or list. - """ - value = self.pb2Object.parameters[keyword] - return self.__toValue(value) - - def __islist(self, value): - return value.startswith("[") and value.endswith("]") - - def __makelist(self, liststring): - liststring = liststring.lstrip("[") - liststring = liststring.rstrip("]") - strings = liststring.split(", ") - values = [] - for string in strings: - values.append(self.__toValue(string)) - return values - - def setValue(self, keyword, value): - """Set the value associated with the provided keyword - Arguments: - keyword(str): A string containing the parameter keyword - value(varying): A value matching the type of the parameter. - See keyword documentation and/or printObjectInfo() to find - the correct data type. - """ - self.pb2Object.parameters[keyword] = self.__fromValue(value) - - def descendants(self, classKeyword): - """Get a list of all project tree descendants matching the class keyword - Arguments: - classKeyword[str]: A class keyword matching the type of class wanted - - Returns: - A list of PdmObjects matching the keyword provided - """ - request = PdmObject_pb2.PdmDescendantObjectRequest(object=self.pb2Object, child_keyword=classKeyword) - objectList = self.pdmObjectStub.GetDescendantPdmObjects(request).objects - childList = [] - for object in objectList: - childList.append(PdmObject(object, self.channel)) - return childList - - def children(self, childField): - """Get a list of all direct project tree children inside the provided childField - Arguments: - childField[str]: A field name - Returns: - A list of PdmObjects inside the childField - """ - request = PdmObject_pb2.PdmChildObjectRequest(object=self.pb2Object, child_field=childField) - objectList = self.pdmObjectStub.GetChildPdmObjects(request).objects - childList = [] - for object in objectList: - childList.append(PdmObject(object, self.channel)) - return childList - - def ancestor(self, classKeyword): - """Find the first ancestor that matches the provided classKeyword - Arguments: - classKeyword[str]: A class keyword matching the type of class wanted - """ - request = PdmObject_pb2.PdmParentObjectRequest(object=self.pb2Object, parent_keyword=classKeyword) - return PdmObject(self.pdmObjectStub.GetAncestorPdmObject(request), self.channel) - - def update(self): - """Sync all fields from the Python Object to ResInsight""" - self.pdmObjectStub.UpdateExistingPdmObject(self.pb2Object) - -# def createChild(self, childField, childClassKeyword): -# childRequest = PdmObject_pb2.CreatePdmChildObjectRequest(object=self.pb2Object, child_field=childField, child_class=childClassKeyword) -# return PdmObject(self.pdmObjectStub.CreateChildPdmObject(childRequest), self.channel) diff --git a/ApplicationCode/GrpcInterface/Python/rips/Project.py b/ApplicationCode/GrpcInterface/Python/rips/Project.py deleted file mode 100644 index 23c8e7ab2e..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Project.py +++ /dev/null @@ -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).openProject(path) - return self - - def close(self): - """Close the current project (and open new blank project)""" - Commands(self.channel).closeProject() - - def selectedCases(self): - """Get a list of all cases selected in the project tree - - Returns: - A list of rips Case objects - """ - caseInfos = self.project.GetSelectedCases(Empty()) - cases = [] - for caseInfo in caseInfos.data: - cases.append(Case(self.channel, caseInfo.id)) - return cases - - def cases(self): - """Get a list of all cases in the project - - Returns: - A list of rips Case objects - """ - try: - caseInfos = self.project.GetAllCases(Empty()) - - cases = [] - for caseInfo in caseInfos.data: - cases.append(Case(self.channel, caseInfo.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 loadCase(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).loadCase(path) - - def views(self): - """Get a list of views belonging to a project""" - pdmObjects = self.descendants("ReservoirView") - viewList = [] - for pdmObject in pdmObjects: - viewList.append(View(pdmObject)) - return viewList - - 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 viewObject in views: - if viewObject.id == id: - return viewObject - return None - - def gridCaseGroups(self): - """Get a list of all grid case groups in the project""" - caseGroups = self.descendants("RimIdenticalGridCaseGroup"); - - caseGroupList = [] - for pb2Group in caseGroups: - caseGroupList.append(GridCaseGroup(pb2Group)) - return caseGroupList - - def gridCaseGroup(self, groupId): - """Get a particular grid case group belonging to a project - Arguments: - groupId(int): group id - - Returns: a grid case group object - """ - caseGroups = self.gridCaseGroups() - for caseGroup in caseGroups: - if caseGroup.groupId == groupId: - return caseGroup - return None - - def createGridCaseGroup(self, casePaths): - """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 - """ - groupId, groupName = Commands(self.channel).createGridCaseGroup(casePaths) - return self.gridCaseGroup(groupId) \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/Properties.py b/ApplicationCode/GrpcInterface/Python/rips/Properties.py deleted file mode 100644 index 38af187e25..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Properties.py +++ /dev/null @@ -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.propertiesStub = Properties_pb2_grpc.PropertiesStub(self.case.channel) - self.chunkSize = 8160 - - - def __generatePropertyInputIterator(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 __generatePropertyInputChunks(self, array, parameters): - - index = -1 - while index < len(array): - chunk = Properties_pb2.PropertyInputChunk() - if index is -1: - chunk.params.CopyFrom(parameters) - index += 1 - else: - actualChunkSize = min(len(array) - index + 1, self.chunkSize) - chunk.values.CopyFrom(Properties_pb2.PropertyChunk(values = array[index:index+actualChunkSize])) - index += actualChunkSize - - yield chunk - # Final empty message to signal completion - chunk = Properties_pb2.PropertyInputChunk() - yield chunk - - def available(self, propertyType, porosityModel = 'MATRIX_MODEL'): - """Get a list of available properties - - Arguments: - propertyType (str): string corresponding to propertyType enum. Can be one of the following: - - DYNAMIC_NATIVE - - STATIC_NATIVE - - SOURSIMRL - - GENERATED - - INPUT_PROPERTY - - FORMATION_NAMES - - FLOW_DIAGNOSTICS - - INJECTION_FLOODING - - porosityModel(str): 'MATRIX_MODEL' or 'FRACTURE_MODEL'. - """ - - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Properties_pb2.AvailablePropertiesRequest (case_request = Case_pb2.CaseRequest(id=self.case.id), - property_type = propertyTypeEnum, - porosity_model = porosityModelEnum) - return self.propertiesStub.GetAvailableProperties(request).property_names - - def activeCellPropertyAsync(self, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): - """Get a cell property for all active cells. Async, so returns an iterator - - Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(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. - """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Properties_pb2.PropertyRequest(case_request = Case_pb2.CaseRequest(id=self.case.id), - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - porosity_model = porosityModelEnum) - for chunk in self.propertiesStub.GetActiveCellProperty(request): - yield chunk - - def activeCellProperty(self, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): - """Get a cell property for all active cells. Sync, so returns a list - - Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(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. - """ - allValues = [] - generator = self.activeCellPropertyAsync(propertyType, propertyName, timeStep, porosityModel) - for chunk in generator: - for value in chunk.values: - allValues.append(value) - return allValues - - def gridPropertyAsync(self, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'): - """Get a cell property for all grid cells. Async, so returns an iterator - - Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - gridIndex(int): index to the grid we're getting values for - porosityModel(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. - """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - grid_index = gridIndex, - porosity_model = porosityModelEnum) - for chunk in self.propertiesStub.GetGridProperty(request): - yield chunk - - def gridProperty(self, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'): - """Get a cell property for all grid cells. Synchronous, so returns a list - - Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - gridIndex(int): index to the grid we're getting values for - porosityModel(str): string enum. See available() - - Returns: - A list of double values - """ - allValues = [] - generator = self.gridPropertyAsync(propertyType, propertyName, timeStep, gridIndex, porosityModel) - for chunk in generator: - for value in chunk.values: - allValues.append(value) - return allValues - - def setActiveCellPropertyAsync(self, values_iterator, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): - """Set a cell property for all active cells. Async, and so takes an iterator to the input values - - Arguments: - values_iterator(iterator): an iterator to the properties to be set - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(str): string enum. See available() - """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - porosity_model = porosityModelEnum) - - request_iterator = self.__generatePropertyInputIterator(values_iterator, request) - self.propertiesStub.SetActiveCellProperty(request_iterator) - - def setActiveCellProperty(self, values, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): - """Set a cell property for all active cells. - - Arguments: - values(list): a list of double precision floating point numbers - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(str): string enum. See available() - """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - porosity_model = porosityModelEnum) - request_iterator = self.__generatePropertyInputChunks(values, request) - reply = self.propertiesStub.SetActiveCellProperty(request_iterator) - if reply.accepted_value_count < len(values): - raise IndexError - - def setGridProperty(self, values, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'): - """Set a cell property for all grid cells. - - Arguments: - values(list): a list of double precision floating point numbers - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - gridIndex(int): index to the grid we're setting values for - porosityModel(str): string enum. See available() - """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - grid_index = gridIndex, - porosity_model = porosityModelEnum) - request_iterator = self.__generatePropertyInputChunks(values, request) - reply = self.propertiesStub.SetGridProperty(request_iterator) - if reply.accepted_value_count < len(values): - raise IndexError - \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py index 51d07a0b44..7066682c32 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py @@ -7,17 +7,17 @@ import rips # Connect to ResInsight -resInsight = rips.Instance.find() -if resInsight is not None: +resinsight = rips.Instance.find() +if resinsight is not None: # Get a list of all cases - cases = resInsight.project.cases() + cases = resinsight.project.cases() print ("Got " + str(len(cases)) + " cases: ") for case in cases: print("Case name: " + case.name) - print("Case grid path: " + case.gridPath()) + print("Case grid path: " + case.grid_path()) - timesteps = case.timeSteps() + timesteps = case.time_steps() for t in timesteps: print("Year: " + str(t.year)) print("Month: " + str(t.month)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py index 6e83e10b59..06ee6e6a66 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py @@ -1,6 +1,6 @@ import rips -resInsight = rips.Instance.find() -if resInsight is not None: - print(resInsight.versionString()) - print("Is this a console run?", resInsight.isConsole()) +resinsight = rips.Instance.find() +if resinsight is not None: + print(resinsight.version_string()) + print("Is this a console run?", resinsight.is_console()) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py index afe8470d17..1e136c8916 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py @@ -1,29 +1,29 @@ import os import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -casePaths = [] -casePaths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") -casePaths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") -for casePath in casePaths: - assert os.path.exists(casePath), "You need to set valid case paths for this script to work" +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 case_path in case_paths: + assert os.path.exists(case_path), "You need to set valid case paths for this script to work" -caseGroup = resInsight.project.createGridCaseGroup(casePaths=casePaths) +case_group = resinsight.project.create_grid_case_group(case_paths=case_paths) -caseGroup.printObjectInfo() +case_group.print_object_info() -#statCases = caseGroup.statisticsCases() -#caseIds = [] -#for statCase in statCases: -# statCase.setValue("DynamicPropertiesToCalculate", ["SWAT"]) -# statCase.update() -# caseIds.append(statCase.getValue("CaseId")) +#stat_cases = caseGroup.statistics_cases() +#case_ids = [] +#for stat_case in stat_cases: +# stat_case.set_value("DynamicPropertiesToCalculate", ["SWAT"]) +# stat_case.update() +# case_ids.append(stat_case.get_value("CaseId")) -resInsight.commands.computeCaseGroupStatistics(caseGroupId=caseGroup.groupId) +case_group.compute_statistics() -view = caseGroup.views()[0] -cellResult = view.cellResult() -cellResult.setValue("ResultVariable", "PRESSURE_DEV") -cellResult.update() +view = case_group.views()[0] +cell_result = view.set_cell_result() +cell_result.set_value("ResultVariable", "PRESSURE_DEV") +cell_result.update() \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py index 6f81aa0693..7c839a8d14 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py @@ -6,22 +6,22 @@ import rips # Connect to ResInsight -resInsight = rips.Instance.find() +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 -cellCounts = case.cellCount() -print("Number of active cells: " + str(cellCounts.active_cell_count)) -print("Total number of reservoir cells: " + str(cellCounts.reservoir_cell_count)) +cell_counts = case.cell_count() +print("Number of active cells: " + str(cell_counts.active_cell_count)) +print("Total number of reservoir cells: " + str(cell_counts.reservoir_cell_count)) # Get information for all active cells -activeCellInfos = case.cellInfoForActiveCells() +active_cell_infos = case.cell_info_for_active_cells() # A simple check on the size of the cell info -assert(cellCounts.active_cell_count == len(activeCellInfos)) +assert(cell_counts.active_cell_count == len(active_cell_infos)) # Print information for the first active cell print("First active cell: ") -print(activeCellInfos[0]) +print(active_cell_infos[0]) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py index a32760a367..28e3839e30 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py @@ -1,18 +1,31 @@ ############################################################################### -# 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 import rips # Load instance -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() + +# 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') -# Run a couple of commands -resInsight.commands.setTimeStep(caseId=0, timeStep=3) -resInsight.commands.setMainWindowSize(width=800, height=500) # 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 @@ print("Temporary folder: ", tmpdirname) # Set export folder for snapshots and properties - resInsight.commands.setExportFolder(type='SNAPSHOTS', path=tmpdirname) - resInsight.commands.setExportFolder(type='PROPERTIES', path=tmpdirname) - - # Export snapshots - resInsight.commands.exportSnapshots() - - # Print contents of temporary folder - print(os.listdir(tmpdirname)) + resinsight.set_export_folder(export_type='SNAPSHOTS', path=tmpdirname) + resinsight.set_export_folder(export_type='PROPERTIES', path=tmpdirname) + # Export all snapshots + resinsight.project.export_snapshots() + assert(len(os.listdir(tmpdirname)) > 0) - case = resInsight.project.case(id=0) # Export properties in the view - resInsight.commands.exportPropertyInViews(0, "3D View", 0) - + view1.export_property() + # Check that the exported file exists - expectedFileName = case.name + "-" + str("3D_View") + "-" + "T3" + "-SOIL" - fullPath = tmpdirname + "/" + expectedFileName - assert(os.path.exists(fullPath)) + 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(os.path.exists(full_path)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py index d36d99f923..84866dccab 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py @@ -6,24 +6,24 @@ import rips import grpc -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() case = None # Try loading a non-existing case. We should get a grpc.RpcError exception from the server try: - case = resInsight.project.loadCase("Nonsense") + case = resinsight.project.load_case("Nonsense") 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.activeCellProperty('STATIC_NATIVE', 'PORO', 0) - activeCellCount = len(results) + 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.setActiveCellProperty(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 @@ # This time we should get a grpc.RpcError exception, which is a server side error. try: - case.properties.setActiveCellProperty(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 @@ # 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.chunkSize = activeCellCount + case.chunk_size = active_cell_count try: - case.properties.setActiveCellProperty(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") diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py index 69f71f80cc..c6e715f5f2 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py @@ -6,38 +6,38 @@ import rips # Load instance -resInsight = rips.Instance.find() -cases = resInsight.project.cases() +resinsight = rips.Instance.find() +cases = resinsight.project.cases() # Set main window size -resInsight.commands.setMainWindowSize(width=800, height=500) +resinsight.set_main_window_size(width=800, height=500) -n = 5 # every n-th timestep for snapshot +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 - casepath = case.gridPath() - foldername = os.path.dirname(casepath) + case_path = case.grid_path() + folder_name = os.path.dirname(case_path) # create a folder to hold the snapshots - dirname = os.path.join(foldername, 'snapshots') + dirname = os.path.join(folder_name, 'snapshots') if os.path.exists(dirname) is False: os.mkdir(dirname) print ("Exporting to folder: " + dirname) - resInsight.commands.setExportFolder(type='SNAPSHOTS', path=dirname) + resinsight.set_export_folder(export_type='SNAPSHOTS', path=dirname) - timeSteps = case.timeSteps() - tss_snapshot = range(0, len(timeSteps), n) - print(case.name, case.id, 'Number of timesteps: ' + str(len(timeSteps))) - print('Number of timesteps for snapshoting: ' + str(len(tss_snapshot))) + time_steps = case.time_steps() + print('Number of time_steps: ' + str(len(time_steps))) view = case.views()[0] for property in property_list: - view.applyCellResult(resultType='DYNAMIC_NATIVE', resultVariable=property) - for ts_snapshot in tss_snapshot: - resInsight.commands.setTimeStep(caseId = case.id, timeStep = ts_snapshot) - resInsight.commands.exportSnapshots(type='VIEWS', caseId=case.id) # ‘ALL’, ‘VIEWS’ or ‘PLOTS’ default is 'ALL' + view.apply_cell_result(result_type='DYNAMIC_NATIVE', result_variable=property) + for time_step in range(0, len(time_steps), 10): + view.set_time_step(time_step = time_step) + view.export_snapshot() diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py index 52ec8c3fca..ee48208960 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py @@ -4,9 +4,9 @@ import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -cases = resInsight.project.cases() +cases = resinsight.project.cases() print("Number of cases found: ", len(cases)) for case in cases: print(case.name) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py index 2db56bbf81..8b1f43dcef 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py @@ -7,9 +7,9 @@ # Internal function for creating a result from a small chunk of poro and permx results # The return value of the function is a generator for the results rather than the result itself. -def createResult(poroChunks, permxChunks): +def create_result(poro_chunks, permx_chunks): # Loop through all the chunks of poro and permx in order - for (poroChunk, permxChunk) in zip(poroChunks, permxChunks): + for (poroChunk, permxChunk) in zip(poro_chunks, permx_chunks): resultChunk = [] # Loop through all the values inside the chunks, in order for (poro, permx) in zip(poroChunk.values, permxChunk.values): @@ -17,22 +17,22 @@ def createResult(poroChunks, permxChunks): # Return a generator object that behaves like a Python iterator yield resultChunk -resInsight = rips.Instance.find() +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 -poroChunks = case.properties.activeCellPropertyAsync('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 -permxChunks = case.properties.activeCellPropertyAsync('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.setActiveCellPropertyAsync(createResult(poroChunks, permxChunks), +case.set_active_cell_property_async(create_result(poro_chunks, permx_chunks), 'GENERATED', 'POROPERMXAS', 0) end = time.time() print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'POROPERMXAS') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'POROPERMXAS') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py index 577880a1d6..a295824fd8 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py @@ -7,23 +7,23 @@ import time import grpc -resInsight = rips.Instance.find() +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 -poroResults = case.properties.activeCellProperty('STATIC_NATIVE', 'PORO', 0) +poro_results = case.active_cell_property('STATIC_NATIVE', 'PORO', 0) # Read permx result into list -permxResults = case.properties.activeCellProperty('STATIC_NATIVE', 'PERMX', 0) +permx_results = case.active_cell_property('STATIC_NATIVE', 'PERMX', 0) # Generate output result results = [] -for (poro, permx) in zip(poroResults, permxResults): +for (poro, permx) in zip(poro_results, permx_results): results.append(poro * permx) try: # Send back output result - case.properties.setActiveCellProperty(results, 'GENERATED', 'POROPERMXSY', 0) + case.set_active_cell_property(results, 'GENERATED', 'POROPERMXSY', 0) except grpc.RpcError as e: print("Exception Received: ", e) @@ -32,4 +32,4 @@ print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'POROPERMXSY') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'POROPERMXSY') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py index bf72ff22b4..f2a7517ef2 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py @@ -3,9 +3,9 @@ ####################################### import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -if resInsight is None: +if resinsight is None: print('ERROR: could not find ResInsight') else: print('Successfully connected to ResInsight') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py index ae6975408e..f6b85def3c 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py @@ -1,11 +1,11 @@ # Load ResInsight Processing Server Client Library import rips # Launch ResInsight with last project file and a Window size of 600x1000 pixels -resInsight = rips.Instance.launch(commandLineParameters=['--last', '--size', 600, 1000]) +resinsight = rips.Instance.launch(command_line_parameters=['--last', '--size', 600, 1000]) # Get a list of all cases -cases = resInsight.project.cases() +cases = resinsight.project.cases() print ("Got " + str(len(cases)) + " cases: ") for case in cases: print("Case name: " + case.name) - print("Case grid path: " + case.gridPath()) + print("Case grid path: " + case.grid_path()) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py index 80fc48d35b..1f83cee761 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py @@ -7,14 +7,14 @@ import rips -resInsight = rips.Instance.find() -if resInsight is not None: - cases = resInsight.project.selectedCases() +resinsight = rips.Instance.find() +if resinsight is not None: + cases = resinsight.project.selected_cases() 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) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py index 5eea3d07f9..1c216bed5a 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py @@ -3,7 +3,7 @@ ###################################################################### import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -view = resInsight.project.view(0) -view.applyCellResult(resultType='STATIC_NATIVE', resultVariable='DX') +view = resinsight.project.view(view_id=0) +view.apply_cell_result(result_type='STATIC_NATIVE', result_variable='DX') diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py index 9e3523f44e..521548eccc 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py @@ -5,14 +5,14 @@ # Load ResInsight Processing Server Client Library import rips # Connect to ResInsight instance -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -view = resInsight.project.view(0) -#view.applyFlowDiagnosticsCellResult(resultVariable='Fraction', -# selectionMode='FLOW_TR_INJ_AND_PROD') +view = resinsight.project.view(view_id=0) +#view.apply_flow_diagnostics_cell_result(result_variable='Fraction', +# selection_mode='FLOW_TR_INJ_AND_PROD') # Example of setting individual wells. Commented out because well names are case specific. -view.applyFlowDiagnosticsCellResult(resultVariable='Fraction', - selectionMode='FLOW_TR_BY_SELECTION', +view.apply_flow_diagnostics_cell_result(result_variable='Fraction', + selection_mode='FLOW_TR_BY_SELECTION', injectors = ['C-1H', 'C-2H', 'F-2H'], producers = ['B-1AH', 'B-3H', 'D-1H']) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py index a7f8f7878b..12f6d29449 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py @@ -3,15 +3,15 @@ ###################################################################### import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -case = resInsight.project.case(id=0) -totalCellCount = case.cellCount().reservoir_cell_count +case = resinsight.project.case(case_id=0) +total_cell_count = case.cell_count().reservoir_cell_count values = [] -for i in range(0, totalCellCount): +for i in range(0, total_cell_count): values.append(i % 2 * 0.75); print("Applying values to full grid") -case.properties.setGridProperty(values, 'DYNAMIC_NATIVE', 'SOIL', 0) +case.set_grid_property(values, 'DYNAMIC_NATIVE', 'SOIL', 0) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py index b6eccc186d..e8c5f064c9 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py @@ -6,27 +6,27 @@ import itertools import time -resInsight = rips.Instance.find() +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.timeSteps() +timeSteps = case.time_steps() averages = [] for i in range(0, len(timeSteps)): # Get the results from time step i asynchronously # It actually returns a generator object almost immediately - resultChunks = case.properties.activeCellPropertyAsync('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 # We will trigger a read of the input data, meaning the script will start # Calculating averages before the whole resultValue for this time step has been received - for chunk in resultChunks: + for chunk in result_chunks: mysum += sum(chunk.values) count += len(chunk.values) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py index 7b3b879689..92b763c8be 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py @@ -5,21 +5,20 @@ import itertools import time -resInsight = rips.Instance.find() +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 -timeSteps = case.timeSteps() +time_steps = case.time_steps() averages = [] -for i in range(0, len(timeSteps)): +for i in range(0, len(time_steps)): # Get a list of all the results for time step i - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', i) + results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i) mysum = sum(results) averages.append(mysum/len(results)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py index 2c8bd954de..531a8c1b10 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py @@ -7,41 +7,41 @@ # Internal function for creating a result from a small chunk of soil and porv results # The return value of the function is a generator for the results rather than the result itself. -def createResult(soilChunks, porvChunks): - for (soilChunk, porvChunk) in zip(soilChunks, porvChunks): +def create_result(soil_chunks, porv_chunks): + for (soil_chunk, porv_chunk) in zip(soil_chunks, porv_chunks): resultChunk = [] number = 0 - for (soilValue, porvValue) in zip(soilChunk.values, porvChunk.values): - resultChunk.append(soilValue * porvValue) + for (soil_value, porv_value) in zip(soil_chunk.values, porv_chunk.values): + resultChunk.append(soil_value * porv_value) # Return a Python generator yield resultChunk -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() start = time.time() -case = resInsight.project.case(id=0) -timeStepInfo = case.timeSteps() +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 -porvChunks = case.properties.activeCellPropertyAsync('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 # ... to match the soil chunks -porvArray = [] -for porvChunk in porvChunks: - porvArray.append(porvChunk) +porv_array = [] +for porv_chunk in porv_chunks: + porv_array.append(porv_chunk) for i in range (0, len(timeStepInfo)): # Get a generator object for the SOIL property for time step i - soilChunks = case.properties.activeCellPropertyAsync('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 = createResult(soilChunks, iter(porvArray)) + result_generator = create_result(soil_chunks, iter(porv_array)) # Send back the result asynchronously with a generator object - case.properties.setActiveCellPropertyAsync(result_generator, 'GENERATED', 'SOILPORVAsync', i) + case.set_active_cell_property_async(result_generator, 'GENERATED', 'SOILPORVAsync', i) end = time.time() print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'SOILPORVAsync') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'SOILPORVAsync') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py index 53684a211b..13a51f0d97 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py @@ -5,29 +5,29 @@ import rips import time -resInsight = rips.Instance.find() +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 -porvResults = case.properties.activeCellProperty('STATIC_NATIVE', 'PORV', 0) -timeStepInfo = case.timeSteps() +porv_results = case.active_cell_property('STATIC_NATIVE', 'PORV', 0) +time_step_info = case.time_steps() -for i in range (0, len(timeStepInfo)): +for i in range (0, len(time_step_info)): # Read the full SOIl result for time step i - soilResults = case.properties.activeCellProperty('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 = [] - for (soil, porv) in zip(soilResults, porvResults): + for (soil, porv) in zip(soil_results, porv_results): results.append(soil * porv) # Send back result - case.properties.setActiveCellProperty(results, 'GENERATED', 'SOILPORVSync', i) + case.set_active_cell_property(results, 'GENERATED', 'SOILPORVSync', i) end = time.time() print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'SOILPORVSync') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'SOILPORVSync') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py index 3b03154125..99a1e0a5b8 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py @@ -5,23 +5,23 @@ ############################################################# import rips # Connect to ResInsight instance -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() # Check if connection worked -if resInsight is not None: +if resinsight is not None: # Get a list of all cases - cases = resInsight.project.cases() + cases = resinsight.project.cases() for case in cases: # Get a list of all views views = case.views() for view in views: # Set some parameters for the view - view.setShowGridBox(not view.showGridBox()) - view.setBackgroundColor("#3388AA") + view.set_show_grid_box(not view.show_grid_box()) + view.set_background_color("#3388AA") # Update the view in ResInsight view.update() # Clone the first view - newView = views[0].clone() - view.setShowGridBox(False) - newView.setBackgroundColor("#FFAA33") - newView.update() \ No newline at end of file + new_view = views[0].clone() + view.set_show_grid_box(False) + new_view.set_background_color("#FFAA33") + new_view.update() diff --git a/ApplicationCode/GrpcInterface/Python/rips/View.py b/ApplicationCode/GrpcInterface/Python/rips/View.py deleted file mode 100644 index 5e55cda7e9..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/View.py +++ /dev/null @@ -1,100 +0,0 @@ -import rips.Case # Circular import of Case, which already imports View. Use full name. -from rips.Commands import Commands -from rips.PdmObject import PdmObject - -class View (PdmObject): - """ResInsight view class - - Attributes: - id(int): View Id corresponding to the View Id in ResInsight project. - - """ - def __init__(self, pbmObject): - self.id = pbmObject.getValue("ViewId") - - PdmObject.__init__(self, pbmObject.pb2Object, pbmObject.channel) - - def showGridBox(self): - """Check if the grid box is meant to be shown in the view""" - return self.getValue("ShowGridBox") - - def setShowGridBox(self, value): - """Set if the grid box is meant to be shown in the view""" - self.setValue("ShowGridBox", value) - - def backgroundColor(self): - """Get the current background color in the view""" - return self.getValue("ViewBackgroundColor") - - def setBackgroundColor(self, bgColor): - """Set the background color in the view""" - self.setValue("ViewBackgroundColor", bgColor) - - def cellResult(self): - """Retrieve the current cell results""" - return self.children("GridCellResult")[0] - - def applyCellResult(self, resultType, resultVariable): - """Apply a regular cell result - - Arguments: - resultType (str): String representing the result category. The valid values are - - DYNAMIC_NATIVE - - STATIC_NATIVE - - SOURSIMRL - - GENERATED - - INPUT_PROPERTY - - FORMATION_NAMES - - FLOW_DIAGNOSTICS - - INJECTION_FLOODING - resultVariable (str): String representing the result variable. - """ - cellResult = self.cellResult() - cellResult.setValue("ResultType", resultType) - cellResult.setValue("ResultVariable", resultVariable) - cellResult.update() - - def applyFlowDiagnosticsCellResult(self, - resultVariable = 'TOF', - selectionMode = 'FLOW_TR_BY_SELECTION', - injectors = [], - producers = []): - """Apply a flow diagnostics cell result - - Arguments: - resultVariable (str): String representing the result value - The valid values are 'TOF', 'Fraction', 'MaxFractionTracer' and 'Communication'. - selectionMode (str): String specifying which tracers to select. - The valid values are - - FLOW_TR_INJ_AND_PROD (all injector and producer tracers), - - FLOW_TR_PRODUCERS (all producers) - - FLOW_TR_INJECTORS (all injectors), - - FLOW_TR_BY_SELECTION (specify individual tracers in the - injectorTracers and producerTracers variables) - injectorTracers (list): List of injector names (strings) to select. - Requires selectionMode to be 'FLOW_TR_BY_SELECTION'. - producerTracers (list): List of producer tracers (strings) to select. - Requires selectionMode to be 'FLOW_TR_BY_SELECTION'. - """ - cellResult = self.cellResult() - cellResult.setValue("ResultType", "FLOW_DIAGNOSTICS") - cellResult.setValue("ResultVariable", resultVariable) - cellResult.setValue("FlowTracerSelectionMode", selectionMode) - if selectionMode == 'FLOW_TR_BY_SELECTION': - cellResult.setValue("SelectedInjectorTracers", injectors) - cellResult.setValue("SelectedProducerTracers", producers) - cellResult.update() - - def case(self): - """Get the case the view belongs to""" - pdmCase = self.ancestor("EclipseCase") - if pdmCase is None: - pdmCase = self.ancestor("ResInsightGeoMechCase") - if pdmCase is None: - return None - return rips.Case(self.channel, pdmCase.getValue("CaseId")) - - def clone(self): - """Clone the current view""" - viewId = Commands(self.channel).cloneView(self.id) - return self.case().view(viewId) \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/__init__.py b/ApplicationCode/GrpcInterface/Python/rips/__init__.py index 1988c72ad2..f004c2a2a3 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/__init__.py +++ b/ApplicationCode/GrpcInterface/Python/rips/__init__.py @@ -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 \ No newline at end of file + +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 \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/case.py b/ApplicationCode/GrpcInterface/Python/rips/case.py new file mode 100644 index 0000000000..0384b91369 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/case.py @@ -0,0 +1,734 @@ +# 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 | Controls how export data is split into files | String enum + compdat_export | Compdat export type | 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 | Settings for multiple completions in same cell | String Enum + + ##### Enum file_split + + Option | Description + ----------------------------------- | ------------ + "UNIFIED_FILE" | A single file with all combined transmissibilities + "SPLIT_ON_WELL" | One file for each well with combined transmissibilities + "SPLIT_ON_WELL_AND_COMPLETION_TYPE" | One file for each completion type for each well + + ##### Enum compdat_export + + Option | Description + ------------------------------------------- | ------------ + "TRANSMISSIBILITIES" | Direct export of transmissibilities + "WPIMULT_AND_DEFAULT_CONNECTION_FACTORS" | Include WPIMULT in addition to transmissibilities + + ##### Enum combination_mode + + Option | Description + ------------------- | ------------ + "INDIVIDUALLY" | Exports the different completion types into separate sections + "COMBINED" | Export one combined transmissibility for each cell + + """ + 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 | Defines how to split LGRS | String enum + + ##### Enum split_type + + Option | Description + ------------------------| ------------ + "LGR_PER_CELL" | One LGR for each completed cell + "LGR_PER_COMPLETION" | One LGR for each completion (fracture, perforation, ...) + "LGR_PER_WELL" | One LGR for each well + + """ + 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, + )) diff --git a/ApplicationCode/GrpcInterface/Python/rips/grid.py b/ApplicationCode/GrpcInterface/Python/rips/grid.py new file mode 100644 index 0000000000..ba306d932e --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/grid.py @@ -0,0 +1,34 @@ +# 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 diff --git a/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py new file mode 100644 index 0000000000..d2fe59fb3b --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py @@ -0,0 +1,75 @@ +""" +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 of integers): 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)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/instance.py b/ApplicationCode/GrpcInterface/Python/rips/instance.py new file mode 100644 index 0000000000..2b03a0caae --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/instance.py @@ -0,0 +1,279 @@ +# 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 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 __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 | String specifying what to export | String + path | Path to folder | String + create_folder | Create folder if it doesn't exist? | Boolean + + ##### Enum export_type + + Option | Description + --------------- | ------------ + "COMPLETIONS" | + "SNAPSHOTS" | + "PROPERTIES" | + "STATISTICS" | + + """ + 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') diff --git a/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py new file mode 100644 index 0000000000..2d8f9cdc0c --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py @@ -0,0 +1,169 @@ +# 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 + + +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._commands = CmdRpc.CommandsStub(channel) + + def pb2_object(self): + """ Private method""" + return self._pb2_object + + def channel(self): + """ Private method""" + return self._channel + + def address(self): + """Get the unique address of the PdmObject + + Returns: + A 64-bit unsigned integer 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 + + def keywords(self): + """Get a list of all parameter keywords available in the object""" + list_of_keywords = [] + 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()) + for keyword in self.keywords(): + print(keyword + " [" + type(self.get_value(keyword)).__name__ + + "]: " + str(self.get_value(keyword))) + + def __to_value(self, value): + if value.lower() == 'false': + return False + if value.lower() == 'true': + return True + try: + int_val = int(value) + return int_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 + + def __from_value(self, value): + if isinstance(value, bool): + if value: + return "true" + 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) + "]" + return str(value) + + def get_value(self, keyword): + """Get the value associated with the provided keyword + Arguments: + keyword(str): A string containing the parameter keyword + + Returns: + The value of the parameter. Can be int, str or list. + """ + value = self._pb2_object.parameters[keyword] + return self.__to_value(value) + + def __islist(self, value): + return value.startswith("[") and value.endswith("]") + + def __makelist(self, list_string): + list_string = list_string.lstrip("[") + list_string = list_string.rstrip("]") + strings = list_string.split(", ") + values = [] + for string in strings: + values.append(self.__to_value(string)) + return values + + def set_value(self, keyword, value): + """Set the value associated with the provided keyword + Arguments: + keyword(str): A string containing the parameter keyword + value(varying): A value matching the type of the parameter. + See keyword documentation and/or print_object_info() to find + the correct data type. + """ + 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 + Arguments: + class_keyword[str]: A class keyword matching the type of class wanted + + 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 + child_list = [] + for pdm_object in object_list: + child_list.append(PdmObject(pdm_object, self._channel)) + return child_list + + def children(self, child_field): + """Get a list of all direct project tree children inside the provided child_field + Arguments: + child_field[str]: A field name + 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 + child_list = [] + for pdm_object in object_list: + child_list.append(PdmObject(pdm_object, self._channel)) + return child_list + + def ancestor(self, class_keyword): + """Find the first ancestor that matches the provided class_keyword + 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) + + def update(self): + """Sync all fields from the Python Object to ResInsight""" + self._pdm_object_stub.UpdateExistingPdmObject(self._pb2_object) diff --git a/ApplicationCode/GrpcInterface/Python/rips/project.py b/ApplicationCode/GrpcInterface/Python/rips/project.py new file mode 100644 index 0000000000..a13c703201 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/project.py @@ -0,0 +1,232 @@ +# 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, + d_factor, conductivity): + """ Scale fracture template parameters + + Arguments: + template_id(int): ID of fracture template + half_length (double): Half Length scale factor + height (double): Height scale factor + d_factor (double): D-factor scale factor + conductivity (double): Conductivity scale factor + """ + return self._execute_command( + scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest( + id=template_id, + halfLength=half_length, + height=height, + dFactor=d_factor, + conductivity=conductivity)) + + def set_fracture_containment(self, template_id, top_layer, base_layer): + """ Set fracture template containment parameters + + Arguments: + template_id(int): ID of fracture template + top_layer (int): Top layer containment + base_layer (int): Base layer containment + """ + return self._execute_command( + setFractureContainment=Cmd.SetFracContainmentRequest( + id=template_id, topLayer=top_layer, baseLayer=base_layer)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py b/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py index b9d1efb2f3..ab02a62b6f 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py @@ -13,9 +13,9 @@ def rips_instance(): return _rips_instance @pytest.fixture -def initializeTest(): +def initialize_test(): _rips_instance.project.close() # make sure ResInsight is clean before execution of test - yield initializeTest + yield initialize_test _rips_instance.project.close() # make sure ResInsight is clean after test def pytest_addoption(parser): diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py index 76e198ce05..257ab20fb0 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py @@ -1,91 +1,113 @@ import sys import os import pytest +import grpc +import tempfile sys.path.insert(1, os.path.join(sys.path[0], '../../')) import rips import dataroot -def test_Launch(rips_instance, initializeTest): +def test_Launch(rips_instance, initialize_test): assert(rips_instance is not None) -def test_EmptyProject(rips_instance, initializeTest): +def test_EmptyProject(rips_instance, initialize_test): cases = rips_instance.project.cases() assert(len(cases) is 0) -def test_OneCase(rips_instance, initializeTest): - case = rips_instance.project.loadCase(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") +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) -def test_MultipleCases(rips_instance, initializeTest): - casePaths = [] - casePaths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") - casePaths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") - casePaths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") +def test_MultipleCases(rips_instance, initialize_test): + case_paths = [] + case_paths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") + case_paths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") + case_paths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") - caseNames = [] - for casePath in casePaths: - caseName = os.path.splitext(os.path.basename(casePath))[0] - caseNames.append(caseName) - rips_instance.project.loadCase(path=casePath) + case_names = [] + for case_path in case_paths: + case_name = os.path.splitext(os.path.basename(case_path))[0] + case_names.append(case_name) + rips_instance.project.load_case(path=case_path) cases = rips_instance.project.cases() - assert(len(cases) == len(caseNames)) - for i, caseName in enumerate(caseNames): - assert(caseName == cases[i].name) + assert(len(cases) == len(case_names)) + for i, case_name in enumerate(case_names): + assert(case_name == cases[i].name) -def test_10k(rips_instance, initializeTest): - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) - assert(case.gridCount() == 2) - cellCountInfo = case.cellCount() - assert(cellCountInfo.active_cell_count == 11125) - assert(cellCountInfo.reservoir_cell_count == 316224) - timeSteps = case.timeSteps() - assert(len(timeSteps) == 9) - daysSinceStart = case.daysSinceStart() - assert(len(daysSinceStart) == 9) +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(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) + time_steps = case.time_steps() + assert(len(time_steps) == 9) + days_since_start = case.days_since_start() + assert(len(days_since_start) == 9) -def test_PdmObject(rips_instance, initializeTest): - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) - assert(case.id == 0) +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.case_id == 0) assert(case.address() is not 0) - assert(case.classKeyword() == "EclipseCase") - caseId = case.getValue('CaseId') - assert(caseId == case.id) + assert(case.class_keyword() == "EclipseCase") + case_id = case.get_value('CaseId') + 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, initializeTest): - casePath = dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID" - case = rips_instance.project.loadCase(path=casePath) - assert(case.gridCount() == 1) - cellCountInfo = case.cellCount() +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(len(case.grids()) == 1) + cellCountInfo = case.cell_count() assert(cellCountInfo.active_cell_count == 43374) assert(cellCountInfo.reservoir_cell_count == 60048) - timeSteps = case.timeSteps() - assert(len(timeSteps) == 11) - daysSinceStart = case.daysSinceStart() - assert(len(daysSinceStart) == 11) + time_steps = case.time_steps() + assert(len(time_steps) == 11) + days_since_start = case.days_since_start() + assert(len(days_since_start) == 11) @pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") -def test_replaceCase(rips_instance, initializeTest): +def test_replaceCase(rips_instance, initialize_test): project = rips_instance.project.open(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/10KWithWellLog.rsp") - casePath = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" - case = project.case(id=0) + case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" + 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.replaceCase(newGridFile=casePath, caseId=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) + diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py index 184b0e42e6..5fdef57c34 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py @@ -9,50 +9,3 @@ import dataroot -def test_exportSnapshots(rips_instance, initializeTest): - if not rips_instance.isGui(): - pytest.skip("Cannot run test without a GUI") - - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - rips_instance.project.loadCase(casePath) - with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: - print("Temporary folder: ", tmpdirname) - rips_instance.commands.setExportFolder(type='SNAPSHOTS', path=tmpdirname) - rips_instance.commands.exportSnapshots() - 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, initializeTest): - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - rips_instance.project.loadCase(casePath) - with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: - print("Temporary folder: ", tmpdirname) - rips_instance.commands.setExportFolder(type='PROPERTIES', path=tmpdirname) - case = rips_instance.project.case(id=0) - rips_instance.commands.exportPropertyInViews(0, "3D View", 0) - expectedFileName = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL" - fullPath = tmpdirname + "/" + expectedFileName - assert(os.path.exists(fullPath)) - -@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") -def test_loadGridCaseGroup(rips_instance, initializeTest): - casePaths = [] - casePaths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") - casePaths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") - groupId, groupName = rips_instance.commands.createGridCaseGroup(casePaths=casePaths) - print(groupId, groupName) - -def test_exportFlowCharacteristics(rips_instance, initializeTest): - casePath = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" - rips_instance.project.loadCase(casePath) - with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: - print("Temporary folder: ", tmpdirname) - fileName = tmpdirname + "/exportFlowChar.txt" - rips_instance.commands.exportFlowCharacteristics(caseId=0, timeSteps=8, producers=[], injectors = "I01", fileName = fileName) - -def test_loadNonExistingCase(rips_instance, initializeTest): - casePath = "Nonsense/Nonsense/Nonsense" - with pytest.raises(grpc.RpcError): - assert rips_instance.project.loadCase(casePath) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py index 52556d94da..80ad582d16 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py @@ -6,10 +6,10 @@ import dataroot -def test_10k(rips_instance, initializeTest): +def test_10k(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) - assert(case.gridCount() == 2) + case = rips_instance.project.load_case(path=casePath) + assert(len(case.grids()) == 2) grid = case.grid(index=0) dimensions = grid.dimensions() assert(dimensions.i == 90) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py index 9595923d4b..592142bd0a 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py @@ -1,17 +1,42 @@ import sys import os -import pytest +import pytest +import grpc +import tempfile sys.path.insert(1, os.path.join(sys.path[0], '../../')) import rips import dataroot -def test_loadProject(rips_instance, initializeTest): +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) \ No newline at end of file + 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') diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py index fba9d6c125..1c197bbe92 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py @@ -2,17 +2,18 @@ import os import grpc import pytest +import tempfile sys.path.insert(1, os.path.join(sys.path[0], '../../')) import rips import dataroot -def test_10kAsync(rips_instance, initializeTest): +def test_10kAsync(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - resultChunks = case.properties.activeCellPropertyAsync('DYNAMIC_NATIVE', 'SOIL', 1) + resultChunks = case.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', 1) mysum = 0.0 count = 0 for chunk in resultChunks: @@ -23,42 +24,42 @@ def test_10kAsync(rips_instance, initializeTest): assert(average != pytest.approx(0.0158893, abs=0.0000001)) assert(average == pytest.approx(0.0558893, abs=0.0000001)) -def test_10kSync(rips_instance, initializeTest): +def test_10kSync(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('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)) assert(average != pytest.approx(0.0158893, abs=0.0000001)) assert(average == pytest.approx(0.0558893, abs=0.0000001)) -def test_10k_set(rips_instance, initializeTest): +def test_10k_set(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', 1) - case.properties.setActiveCellProperty(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, initializeTest): +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.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('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.setActiveCellProperty(results, 'GENERATED', 'SOIL', 1) + assert case.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) -def test_10k_set_out_of_bounds_client(rips_instance, initializeTest): +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.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', 1) - case.properties.chunkSize = 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.setActiveCellProperty(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): @@ -72,20 +73,30 @@ def checkResults(poroValues, permxValues, poropermxValues): recalc = poro * permx assert(recalc == pytest.approx(poropermx, rel=1.0e-10)) -def test_10k_PoroPermX(rips_instance, initializeTest): +def test_10k_PoroPermX(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - poroChunks = case.properties.activeCellPropertyAsync('STATIC_NATIVE', 'PORO', 0) - permxChunks = case.properties.activeCellPropertyAsync('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.setActiveCellPropertyAsync(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0) + case.set_active_cell_property_async(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0) - poro = case.properties.activeCellProperty('STATIC_NATIVE', 'PORO', 0) - permx = case.properties.activeCellProperty('STATIC_NATIVE', 'PERMX', 0) - poroPermX = case.properties.activeCellProperty('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) - - \ No newline at end of file +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)) \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/view.py b/ApplicationCode/GrpcInterface/Python/rips/view.py new file mode 100644 index 0000000000..1c31cc7703 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/view.py @@ -0,0 +1,209 @@ +""" +ResInsight 3d view module +""" +import rips.generated.Commands_pb2 as Cmd + +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: + id(int): View Id corresponding to the View Id in ResInsight project. + + """ + def __init__(self, pdm_object): + PdmObject.__init__(self, pdm_object.pb2_object(), pdm_object.channel()) + self.view_id = pdm_object.get_value("ViewId") + + def show_grid_box(self): + """Check if the grid box is meant to be shown in the view""" + return self.get_value("ShowGridBox") + + def set_show_grid_box(self, value): + """Set if the grid box is meant to be shown in the view""" + self.set_value("ShowGridBox", value) + + def background_color(self): + """Get the current background color in the view""" + return self.get_value("ViewBackgroundColor") + + def set_background_color(self, bgcolor): + """Set the background color in the view""" + self.set_value("ViewBackgroundColor", bgcolor) + + def set_cell_result(self): + """Retrieve the current cell results""" + return self.children("GridCellResult")[0] + + def apply_cell_result(self, result_type, result_variable): + """Apply a regular cell result + + Arguments: + result_type (str): String representing the result category. The valid values are + - DYNAMIC_NATIVE + - STATIC_NATIVE + - SOURSIMRL + - GENERATED + - INPUT_PROPERTY + - FORMATION_NAMES + - FLOW_DIAGNOSTICS + - INJECTION_FLOODING + result_variable (str): String representing the result variable. + """ + cell_result = self.set_cell_result() + cell_result.set_value("ResultType", result_type) + 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=None, + producers=None): + """Apply a flow diagnostics cell result + + Parameter | Description | Type + ------------------- | ------------------------------------------------------ | ----- + result_variable | String representing the result value | String + selection_mode | String specifying which tracers to select | String + injectors | List of injector names, used by 'FLOW_TR_BY_SELECTION' | String List + producers | List of injector names, used by 'FLOW_TR_BY_SELECTION' | String List + + ##### Enum compdat_export + + Option | Description + ------------------------| ------------ + "TOF" | Time of flight + "Fraction" | Fraction + "MaxFractionTracer" | Max Fraction Tracer + "Communication" | Communication + + """ + 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) + cell_result.set_value("FlowTracerSelectionMode", selection_mode) + if selection_mode == 'FLOW_TR_BY_SELECTION': + cell_result.set_value("SelectedInjectorTracers", injectors) + cell_result.set_value("SelectedProducerTracers", producers) + cell_result.update() + + def case(self): + """Get the case the view belongs to""" + pdm_case = self.ancestor("EclipseCase") + if pdm_case is None: + pdm_case = self.ancestor("ResInsightGeoMechCase") + if pdm_case is None: + return None + return rips.case.Case(self._channel, pdm_case.get_value("CaseId")) + + def clone(self): + """Clone the current view""" + 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): + """Set the time step for current view""" + 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): + """Export fracture completions for simulation wells + + Parameter | Description | Type + ----------------------------| ------------------------------------------------ | ----- + time_step | Time step to export for | Integer + simulation_well_names | List of simulation well names | List + file_split | Controls how export data is split into files | String enum + compdat_export | Compdat export type | String enum + + ##### Enum file_split + + Option | Description + ----------------------------------- | ------------ + "UNIFIED_FILE" Default Option| A single file with all transmissibilities + "SPLIT_ON_WELL" | One file for each well transmissibilities + "SPLIT_ON_WELL_AND_COMPLETION_TYPE" | One file for each completion type for each well + + ##### Enum compdat_export + + Option | Description + -----------------------------------------| ------------ + "TRANSMISSIBILITIES"Default Option| Direct export of transmissibilities + "WPIMULT_AND_DEFAULT_CONNECTION_FACTORS" | Include export of WPIMULT + + """ + 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): + """Export special properties for all visible cells. + + Arguments: + export_keyword (string): The keyword to export. + Choices: 'FLUXNUM' or 'MULTNUM'. Default: 'FLUXNUM' + visible_active_cells_value (int): Value to export forvisible active cells. Default: 1 + hidden_active_cells_value (int): Value to export for hidden active cells. Default: 0 + inactive_cells_value (int): Value to export for inactive cells. Default: 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)) diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp index 89c6017eaf..61fc4862ac 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp @@ -250,19 +250,10 @@ void Rim3dWellLogCurve::initAfterRead() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Rim3dWellLogCurve::resetMinMaxValuesAndUpdateUI() -{ - this->resetMinMaxValues(); - this->updateConnectedEditors(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool Rim3dWellLogCurve::findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, - cvf::Vec3d* closestPoint, - double* measuredDepthAtPoint, - double* valueAtPoint) const +bool Rim3dWellLogCurve::findClosestPointOnCurve( const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint ) const { if (m_geometryGenerator.notNull()) { diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h index df9145bf94..0f457dd392 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h @@ -75,25 +75,28 @@ class Rim3dWellLogCurve : public caf::PdmObject, public RimNameConfigHolderInter void setColor(const cvf::Color3f& color); - float minCurveUIValue() const; - float maxCurveUIValue() const; - void resetMinMaxValuesAndUpdateUI(); - bool findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, - cvf::Vec3d* closestPoint, - double* measuredDepthAtPoint, - double* valueAtPoint) const; + float minCurveUIValue() const; + float maxCurveUIValue() const; + void resetMinMaxValues(); + bool findClosestPointOnCurve( const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint ) const; void setGeometryGenerator(Riv3dWellLogCurveGeometryGenerator* generator); cvf::ref geometryGenerator(); protected: - caf::PdmFieldHandle* objectToggleField() override; - void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - void configurationUiOrdering(caf::PdmUiOrdering& uiOrdering); - void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - void initAfterRead() override; -private: - void resetMinMaxValues(); + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) override; + void configurationUiOrdering( caf::PdmUiOrdering& uiOrdering ); + void defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) override; + void initAfterRead() override; + protected: caf::PdmField m_drawPlane; caf::PdmField m_color; diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp index f40afa0626..af326f699e 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp @@ -436,11 +436,13 @@ void Rim3dWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* ch m_geomResultDefinition->setGeoMechCase(geoMechCase); } - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } else if (changedField == &m_timeStep) { - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } Rim3dWellLogCurve::fieldChangedByUi(changedField, oldValue, newValue); } diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp index 47121f150c..da8564200a 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp @@ -187,7 +187,8 @@ void Rim3dWellLogFileCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedF { if (changedField == &m_wellLogFile || changedField == &m_wellLogChannelName) { - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } Rim3dWellLogCurve::fieldChangedByUi(changedField, oldValue, newValue); } diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp index 7665f3b1ff..78619b7a92 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp @@ -147,7 +147,8 @@ void Rim3dWellLogRftCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedFi { if (changedField == &m_wellLogChannelName || changedField == &m_timeStep) { - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } Rim3dWellLogCurve::fieldChangedByUi(changedField, oldValue, newValue); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp index 9ee5933e0a..4038045578 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp @@ -202,8 +202,11 @@ std::vector RimEclipseContourMapProjection::generateResults(int timeStep else if (!(cellColors->hasStaticResult() && timeStep > 0)) { m_currentResultName = cellColors->resultVariable(); - RigEclipseResultAddress resAddr(cellColors->resultType(), cellColors->resultVariable()); - if (resAddr.isValid() && resultData->hasResultEntry(resAddr)) + RigEclipseResultAddress resAddr( cellColors->resultType(), + cellColors->resultVariable(), + cellColors->timeLapseBaseTimeStep(), + cellColors->caseDiffIndex() ); + if ( resAddr.isValid() && resultData->hasResultEntry( resAddr ) ) { gridResultValues = resultData->cellScalarResults(resAddr, timeStep); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 94f50131a4..906836bc43 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -52,6 +52,8 @@ #include "RimReservoirCellResultsStorage.h" #include "RimViewLinker.h" #include "RimWellLogExtractionCurve.h" +#include "RimContourMapProjection.h" +#include "RimEclipseContourMapView.h" #include "cafPdmUiListEditor.h" #include "cafPdmUiToolButtonEditor.h" @@ -286,14 +288,28 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha loadDataAndUpdate(); } + RimEclipseContourMapView* contourMapView = nullptr; + this->firstAncestorOrThisOfType(contourMapView); + if (&m_differenceCase == changedField) { m_timeLapseBaseTimestep = RigEclipseResultAddress::noTimeLapseValue(); + + if (contourMapView) + { + contourMapView->contourMapProjection()->updatedWeightingResult(); + } + loadDataAndUpdate(); } if (&m_timeLapseBaseTimestep == changedField) { + if (contourMapView) + { + contourMapView->contourMapProjection()->updatedWeightingResult(); + } + loadDataAndUpdate(); } @@ -414,7 +430,7 @@ void RimEclipseResultDefinition::updateAnyFieldHasChanged() this->firstAncestorOrThisOfType(rim3dWellLogCurve); if (rim3dWellLogCurve) { - rim3dWellLogCurve->resetMinMaxValuesAndUpdateUI(); + rim3dWellLogCurve->resetMinMaxValues(); } RimEclipseContourMapProjection* contourMap = nullptr; @@ -968,6 +984,26 @@ QString RimEclipseResultDefinition::diffResultUiShortNameHTML() const return diffResult.join("
"); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimEclipseResultDefinition::timeLapseBaseTimeStep() const +{ + return m_timeLapseBaseTimestep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimEclipseResultDefinition::caseDiffIndex() const +{ + if ( m_differenceCase ) + { + return m_differenceCase->caseId(); + } + return -1; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1529,39 +1565,41 @@ QList optionList.push_back(caf::PdmOptionItemInfo(s, s)); } - // Ternary Result - if (ternaryEnabled) + if ( addPerCellFaceOptionItems ) { - bool hasAtLeastOneTernaryComponent = false; - if (cellCenterResultNames.contains("SOIL")) - hasAtLeastOneTernaryComponent = true; - else if (cellCenterResultNames.contains("SGAS")) - hasAtLeastOneTernaryComponent = true; - else if (cellCenterResultNames.contains("SWAT")) - hasAtLeastOneTernaryComponent = true; - - if (resultCatType == RiaDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent) + for ( const QString& s : cellFaceResultNames ) { - optionList.push_front( - caf::PdmOptionItemInfo(RiaDefines::ternarySaturationResultName(), RiaDefines::ternarySaturationResultName())); - } - } - if (addPerCellFaceOptionItems) - { - for (const QString& s : cellFaceResultNames) - { - if (showDerivedResultsFirst) + if ( showDerivedResultsFirst ) { - optionList.push_front(caf::PdmOptionItemInfo(s, s)); + optionList.push_front( caf::PdmOptionItemInfo( s, s ) ); } else { - optionList.push_back(caf::PdmOptionItemInfo(s, s)); + optionList.push_back( caf::PdmOptionItemInfo( s, s ) ); + } + } + + // Ternary Result + if ( ternaryEnabled ) + { + bool hasAtLeastOneTernaryComponent = false; + if ( cellCenterResultNames.contains( "SOIL" ) ) + hasAtLeastOneTernaryComponent = true; + else if ( cellCenterResultNames.contains( "SGAS" ) ) + hasAtLeastOneTernaryComponent = true; + else if ( cellCenterResultNames.contains( "SWAT" ) ) + hasAtLeastOneTernaryComponent = true; + + if ( resultCatType == RiaDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent ) + { + optionList.push_front( caf::PdmOptionItemInfo( RiaDefines::ternarySaturationResultName(), + RiaDefines::ternarySaturationResultName() ) ); } } } - optionList.push_front(caf::PdmOptionItemInfo(RiaDefines::undefinedResultName(), RiaDefines::undefinedResultName())); + optionList.push_front( + caf::PdmOptionItemInfo( RiaDefines::undefinedResultName(), RiaDefines::undefinedResultName() ) ); return optionList; } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index 2f7dc83962..0d062cce1d 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -98,16 +98,19 @@ class RimEclipseResultDefinition : public caf::PdmObject QString diffResultUiShortName() const; QString diffResultUiShortNameHTML() const; - void loadResult(); - RigEclipseResultAddress eclipseResultAddress() const; - void setFromEclipseResultAddress(const RigEclipseResultAddress& resultAddress); - bool hasStaticResult() const; - bool hasDynamicResult() const; - bool hasResult() const; - bool isTernarySaturationSelected() const; - bool isCompletionTypeSelected() const; - bool hasCategoryResult() const; - bool isFlowDiagOrInjectionFlooding() const; + int timeLapseBaseTimeStep() const; + int caseDiffIndex() const; + + void loadResult(); + RigEclipseResultAddress eclipseResultAddress() const; + void setFromEclipseResultAddress( const RigEclipseResultAddress& resultAddress ); + bool hasStaticResult() const; + bool hasDynamicResult() const; + bool hasResult() const; + bool isTernarySaturationSelected() const; + bool isCompletionTypeSelected() const; + bool hasCategoryResult() const; + bool isFlowDiagOrInjectionFlooding() const; RigCaseCellResultsData* currentGridCellResults() const; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp index 98f5c66a15..a3512369a0 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp @@ -353,20 +353,10 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha } } } - - if (propFilter) - { - propFilter->updateConnectedEditors(); - } - if (curve) + if ( rim3dWellLogCurve ) { - curve->updateConnectedEditors(); - } - - if (rim3dWellLogCurve) - { - rim3dWellLogCurve->resetMinMaxValuesAndUpdateUI(); + rim3dWellLogCurve->resetMinMaxValues(); } } diff --git a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp index 92d3de5e1d..276dc3202f 100644 --- a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp +++ b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp @@ -131,7 +131,7 @@ void RimSummaryCalculationVariable::fieldChangedByUi(const caf::PdmFieldHandle* QString RimSummaryCalculationVariable::summaryAddressDisplayString() const { QString caseName; - if (m_case() ) caseName = m_case()->caseName(); + if (m_case() ) caseName = m_case()->shortName(); return RiaSummaryCurveDefinition::curveDefinitionText(caseName, m_summaryAddress()->address()); } diff --git a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp index e8c8075ced..a04c556fe3 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp @@ -32,6 +32,7 @@ RimCalculatedSummaryCase::RimCalculatedSummaryCase() CAF_PDM_InitObject("Calculated",":/SummaryCase48x48.png","",""); m_calculatedCurveReader = nullptr; + m_shortName = "Calculated"; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp index 976427dc4a..1eaf372804 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp @@ -137,7 +137,7 @@ void RimSummaryCase::copyFrom(const RimSummaryCase& rhs) //-------------------------------------------------------------------------------------------------- bool RimSummaryCase::operator<(const RimSummaryCase& rhs) const { - return this->caseName() < rhs.caseName(); + return this->shortName() < rhs.shortName(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp index 95396885f6..280b34555f 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp @@ -276,7 +276,7 @@ std::set RimSummaryCaseCollection::ensembleSummaryAddr } } - if (maxAddrIndex >= 0) + if (maxAddrIndex >= 0 && m_cases[maxAddrIndex]->summaryReader()) { const std::set& addrs = m_cases[maxAddrIndex]->summaryReader()->allResultAddresses(); addresses.insert(addrs.begin(), addrs.end()); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index 9ae2c362b2..0ab6edd76d 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -382,7 +382,7 @@ QList RimSummaryCurve::calculateValueOptions(const caf:: for (RimSummaryCase* rimCase : cases) { - options.push_back(caf::PdmOptionItemInfo(rimCase->caseName(), rimCase)); + options.push_back(caf::PdmOptionItemInfo(rimCase->shortName(), rimCase)); } if (options.size() > 0) @@ -515,16 +515,19 @@ void RimSummaryCurve::onLoadDataAndUpdate(bool updateParentPlot) if (plot->timeAxisProperties()->timeMode() == RimSummaryTimeAxisProperties::DATE) { auto reader = summaryCaseY()->summaryReader(); - auto errAddress = reader->errorAddress(summaryAddressY()); - if (errAddress.isValid()) + if (reader) { - std::vector errValues; - reader->values(errAddress, &errValues); - m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, errValues, isLogCurve); - } - else - { - m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, isLogCurve); + auto errAddress = reader->errorAddress(summaryAddressY()); + if (errAddress.isValid()) + { + std::vector errValues; + reader->values(errAddress, &errValues); + m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, errValues, isLogCurve); + } + else + { + m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, isLogCurve); + } } } else diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp index 2cd03a7725..20c9624b5a 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp @@ -102,7 +102,7 @@ QString RimSummaryCurveAutoName::curveNameY(const RifEclipseSummaryAddress& summ if (caseName.isEmpty() && summaryCurve && summaryCurve->summaryCaseY()) { - caseName = summaryCurve->summaryCaseY()->caseName(); + caseName = summaryCurve->summaryCaseY()->shortName(); } if (!caseName.isEmpty()) @@ -152,7 +152,7 @@ QString RimSummaryCurveAutoName::curveNameX(const RifEclipseSummaryAddress& summ if (m_caseName && !skipSubString) { - QString caseName = summaryCurve->summaryCaseX()->caseName(); + QString caseName = summaryCurve->summaryCaseX()->shortName(); if (!text.empty()) text += ", "; text += caseName.toStdString(); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp index ef8f462c80..48c7e4a59f 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp @@ -292,7 +292,7 @@ void RimSummaryPlotNameHelper::extractPlotTitleSubStrings() if (summaryCase) { - m_titleCaseName = summaryCase->caseName(); + m_titleCaseName = summaryCase->shortName(); } } else if (ensembleCases.size() == 1 && summaryCases.empty()) diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp index 402f93bbf0..65c9b0e60f 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp @@ -195,7 +195,7 @@ QList RimSummaryPlotSourceStepping::calculateValueOption auto summaryCases = RimSummaryPlotSourceStepping::summaryCasesForSourceStepping(); for (auto sumCase : summaryCases) { - options.append(caf::PdmOptionItemInfo(sumCase->caseName(), sumCase)); + options.append(caf::PdmOptionItemInfo(sumCase->shortName(), sumCase)); } return options; @@ -581,12 +581,12 @@ std::vector RimSummaryPlotSourceStepping::summaryRea { for (auto curve : curveCollection->curves()) { - if (isYAxisStepping() && curve->summaryCaseY()) + if (isYAxisStepping() && curve->summaryCaseY() && curve->summaryCaseY()->summaryReader()) { readers.push_back(curve->summaryCaseY()->summaryReader()); } - if (isXAxisStepping() && curve->summaryCaseX()) + if (isXAxisStepping() && curve->summaryCaseX() && curve->summaryCaseX()->summaryReader()) { readers.push_back(curve->summaryCaseX()->summaryReader()); } @@ -602,7 +602,7 @@ std::vector RimSummaryPlotSourceStepping::summaryRea { for (auto curve : curveSet->curves()) { - if (isYAxisStepping() && curve->summaryCaseY()) + if (isYAxisStepping() && curve->summaryCaseY() && curve->summaryCaseY()->summaryReader()) { readers.push_back(curve->summaryCaseY()->summaryReader()); } diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index f581892150..88834d1437 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -1441,7 +1441,10 @@ void RiuMainWindow::selectedObjectsChanged() // Set focus in MDI area to this window if it exists if (selectedReservoirView->viewer()) { + setBlockSlotSubWindowActivated(true); setActiveViewer(selectedReservoirView->viewer()->layoutWidget()); + setBlockSlotSubWindowActivated(false); + isActiveViewChanged = true; } } @@ -1490,8 +1493,8 @@ void RiuMainWindow::slotSnapshotAllViewsToFile() RiaApplication* app = RiaApplication::instance(); // Save images in snapshot catalog relative to project directory - QString absolutePathToSnapshotDir = app->createAbsolutePathFromProjectRelativePath("snapshots"); - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(absolutePathToSnapshotDir); + QString absolutePathToSnapshotDir = app->createAbsolutePathFromProjectRelativePath( "snapshots" ); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp index 9e1d40998d..e7b8f9a1cd 100644 --- a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp @@ -757,7 +757,9 @@ void RiuPlotMainWindow::selectedObjectsChanged() { if (selectedWindow->viewWidget()) { + setBlockSlotSubWindowActivated(true); setActiveViewer(selectedWindow->viewWidget()); + setBlockSlotSubWindowActivated(false); } // The only way to get to this code is by selection change initiated from the project tree view // As we are activating an MDI-window, the focus is given to this MDI-window diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp index be1b2935ec..ca130efc49 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp @@ -423,7 +423,7 @@ void RiuSummaryCurveDefSelection::setDefaultSelection(const std::vector 0) { - RifEclipseSummaryAddress defaultAddress = RifEclipseSummaryAddress::fieldAddress("FOPT"); + RifEclipseSummaryAddress defaultAddress; std::vector selectTheseSources = defaultSources; if (selectTheseSources.empty()) selectTheseSources.push_back(allSumCases[0]); @@ -456,11 +456,6 @@ void RiuSummaryCurveDefSelection::setSelectedCurveDefinitions(const std::vector< RimSummaryCase* summaryCase = curveDef.summaryCase(); RifEclipseSummaryAddress summaryAddress = curveDef.summaryAddress(); - if (summaryAddress.category() == RifEclipseSummaryAddress::SUMMARY_INVALID) - { - // If we have an invalid address, set the default address to Field - summaryAddress = RifEclipseSummaryAddress::fieldAddress(summaryAddress.quantityName()); - } // Ignore ensemble statistics curves if (summaryAddress.category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) continue; @@ -471,7 +466,15 @@ void RiuSummaryCurveDefSelection::setSelectedCurveDefinitions(const std::vector< if (std::find(selectedCategories.begin(), selectedCategories.end(), summaryAddress.category()) == selectedCategories.end()) { - m_selectedSummaryCategories.v().push_back(summaryAddress.category()); + if ( summaryAddress.category() != RifEclipseSummaryAddress::SUMMARY_INVALID ) + { + m_selectedSummaryCategories.v().push_back( summaryAddress.category() ); + } + else + { + // Use field category as fall back category to avoid an empty list of vectors + summaryAddress = RifEclipseSummaryAddress::fieldAddress( "" ); + } } // Select case if not already selected @@ -591,7 +594,7 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions // Top level cases for (const auto& sumCase : sumCaseMainColl->topLevelSummaryCases()) { - options.push_back(caf::PdmOptionItemInfo(sumCase->caseName(), sumCase)); + options.push_back(caf::PdmOptionItemInfo(sumCase->shortName(), sumCase)); } } @@ -626,7 +629,7 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions for (const auto& sumCase : sumCaseColl->allSummaryCases()) { - auto optionItem = caf::PdmOptionItemInfo(sumCase->caseName(), sumCase); + auto optionItem = caf::PdmOptionItemInfo(sumCase->shortName(), sumCase); optionItem.setLevel(1); options.push_back(optionItem); } @@ -640,7 +643,7 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions for (const auto& obsData : observedDataColl->allObservedData()) { - auto optionItem = caf::PdmOptionItemInfo(obsData->caseName(), obsData); + auto optionItem = caf::PdmOptionItemInfo(obsData->shortName(), obsData); optionItem.setLevel(1); options.push_back(optionItem); } diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index edeb0f96fd..f3358452d4 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -83,7 +83,7 @@ class EnsembleCurveInfoTextProvider : public IPlotCurveInfoTextProvider sumCurve = dynamic_cast(riuCurve->ownerRimCurve()); } - return sumCurve && sumCurve->summaryCaseY() ? sumCurve->summaryCaseY()->caseName() : ""; + return sumCurve && sumCurve->summaryCaseY() ? sumCurve->summaryCaseY()->shortName() : ""; } }; static EnsembleCurveInfoTextProvider ensembleCurveInfoTextProvider; diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 86c856eba2..8af8784a2a 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,10 +1,10 @@ set(RESINSIGHT_MAJOR_VERSION 2019) set(RESINSIGHT_MINOR_VERSION 08) -set(RESINSIGHT_PATCH_VERSION 1) +set(RESINSIGHT_PATCH_VERSION 2) # Opional text with no restrictions -#set(RESINSIGHT_VERSION_TEXT "-rc1") +#set(RESINSIGHT_VERSION_TEXT "-rc3") # Optional text # Must be unique and increasing within one combination of major/minor/patch version diff --git a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp index 09cd1a0d6b..2396395372 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp @@ -290,17 +290,13 @@ const int * ecl_coarse_cell_get_box_ptr( const ecl_coarse_cell_type * coarse_cel void ecl_coarse_cell_update_index( ecl_coarse_cell_type * coarse_cell , int global_index , int * active_index , int * active_fracture_index , int active_value) { if (active_value & CELL_ACTIVE_MATRIX) { - if (coarse_cell->active_index == -1) { - coarse_cell->active_index = *active_index; - (*active_index) += 1; - } + coarse_cell->active_index = *active_index; + (*active_index) += 1; } if (active_value & CELL_ACTIVE_FRACTURE) { - if (coarse_cell->active_fracture_index == -1) { - coarse_cell->active_fracture_index = *active_fracture_index; - (*active_fracture_index) += 1; - } + coarse_cell->active_fracture_index = *active_fracture_index; + (*active_fracture_index) += 1; } int_vector_append( coarse_cell->active_cells , global_index );