Merge pull request #4758 from OPM/patch-2018.08.2

Patch release 2019.08.2
This commit is contained in:
Magne Sjaastad 2019-10-01 13:14:51 +02:00 committed by GitHub
commit fa27234e6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
97 changed files with 2551 additions and 1970 deletions

View File

@ -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 );
}
}

View File

@ -115,7 +115,7 @@ QString RiaSummaryCurveDefinition::curveDefinitionText() const
{
QString caseName;
if (summaryCase())
caseName = summaryCase()->caseName();
caseName = summaryCase()->shortName();
else if (ensemble())
caseName = ensemble()->name();

View File

@ -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);

View File

@ -282,6 +282,9 @@ void RiaSummaryCurveAnalyzer::clear()
m_wellCompletions.clear();
m_wellSegmentNumbers.clear();
m_blocks.clear();
m_quantitiesNoMatchingHistory.clear();
m_quantitiesWithMatchingHistory.clear();
}
//--------------------------------------------------------------------------------------------------

View File

@ -54,6 +54,11 @@ RiaTimeHistoryCurveResampler::RiaTimeHistoryCurveResampler()
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::setCurveData(const std::vector<double>& values, const std::vector<time_t>& timeSteps)
{
if (values.empty() || timeSteps.empty())
{
return;
}
CVF_ASSERT(values.size() == timeSteps.size());
clearData();

View File

@ -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<RimEclipseView*>( v );
if ( eclipseView && eclipseView->id() == viewId )
{
return eclipseView;
}
}
}
}
return nullptr;
}

View File

@ -34,9 +34,10 @@ class QStringList;
class RicfApplicationTools
{
public:
static std::vector<RimWellPath*> wellPathsFromNames(const QStringList& wellPathNames, QStringList* wellsNotFound);
static RimEclipseCase* caseFromId(int caseId);
static RimEclipseView* viewFromCaseIdAndViewName(int caseId, const QString& viewName);
static std::vector<RimWellPath*> wellPathsFromNames( const QStringList& wellPathNames, QStringList* wellsNotFound );
static RimEclipseCase* caseFromId( int caseId );
static RimEclipseView* viewFromCaseIdAndViewName( int caseId, const QString& viewName );
static RimEclipseView* viewFromCaseIdAndViewId( int caseId, int viewId );
static std::vector<QString> toStringVector(const QStringList& stringList);
static QStringList toQStringList(const std::vector<QString>& v);

View File

@ -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<QString>(), "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<int>(), "View IDs", "", "", "" );
RICF_InitField( &m_viewNames, "viewNames", std::vector<QString>(), "View Names", "", "", "" );
RICF_InitField( &m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", "" );
}
//--------------------------------------------------------------------------------------------------
@ -74,22 +75,35 @@ RicfCommandResponse RicfExportPropertyInViews::execute()
RimEclipseView* view = dynamic_cast<RimEclipseView*>(v);
if (!view) continue;
if (m_viewNames().empty())
if ( m_viewNames().empty() && m_viewIds().empty() )
{
viewsForExport.push_back(view);
}
else
{
bool matchingName = false;
for (const auto& viewName : m_viewNames())
bool matchingIdOrName = false;
for ( auto viewId : m_viewIds() )
{
if (view->name().compare(viewName, Qt::CaseInsensitive) == 0)
if ( view->id() == viewId )
{
matchingName = true;
matchingIdOrName = true;
break;
}
}
if (matchingName)
if ( !matchingIdOrName )
{
for ( const auto& viewName : m_viewNames() )
{
if ( view->name().compare( viewName, Qt::CaseInsensitive ) == 0 )
{
matchingIdOrName = true;
}
}
}
if ( matchingIdOrName )
{
viewsForExport.push_back(view);
}

View File

@ -44,6 +44,7 @@ public:
private:
caf::PdmField<int> m_caseId;
caf::PdmField<std::vector<int>> m_viewIds;
caf::PdmField<std::vector<QString>> m_viewNames;
caf::PdmField<double> m_undefinedValue;
};

View File

@ -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<QString>(), "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<QString>(), "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<RimEclipseView*> views;
for (Rim3dView* v : exportSettings->caseToApply->views())
{
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>(v);
if (eclipseView && eclipseView->name() == m_viewName())
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>( 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;

View File

@ -40,10 +40,11 @@ public:
RicfCommandResponse execute() override;
private:
caf::PdmField<int> m_caseId;
caf::PdmField<QString> m_viewName;
caf::PdmField<int> m_timeStep;
caf::PdmField< std::vector<QString> > m_simWellNames;
caf::PdmField<int> m_caseId;
caf::PdmField<int> m_viewId;
caf::PdmField<QString> m_viewName;
caf::PdmField<int> m_timeStep;
caf::PdmField<std::vector<QString>> m_simWellNames;
caf::PdmField<RicExportCompletionDataSettingsUi::ExportSplitType> m_fileSplit;
caf::PdmField<RicExportCompletionDataSettingsUi::CompdatExportType> m_compdatExport;

View File

@ -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)
{

View File

@ -51,4 +51,5 @@ private:
caf::PdmField<SnapshotsTypeEnum> m_type;
caf::PdmField<QString> m_prefix;
caf::PdmField<int> m_caseId;
caf::PdmField<int> m_viewId;
};

View File

@ -63,13 +63,19 @@ void AppEnum<RicfExportVisibleCells::ExportKeyword>::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<RicfExportVisibleCells::ExportKeyword>(), "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<RicfExportVisibleCells::ExportKeyword>(),
"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 )
{
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);
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 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);

View File

@ -51,6 +51,7 @@ private:
void buildExportSettings(const QString& exportFolder, RicSaveEclipseInputVisibleCellsUi* exportSettings);
caf::PdmField<int> m_caseId;
caf::PdmField<int> m_viewId;
caf::PdmField<QString> m_viewName;
caf::PdmField<caf::AppEnum<ExportKeyword>> m_exportKeyword;
caf::PdmField<int> m_visibleActiveCellsValue;

View File

@ -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();

View File

@ -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<int> m_caseId;
caf::PdmField<int> m_viewId;
caf::PdmField<int> m_timeStepIndex;
};

View File

@ -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))
{

View File

@ -427,7 +427,7 @@ void RicExportFractureCompletionsImpl::getWellPressuresAndInitialProductionTimeS
{
RimSummaryCase* summaryCase = mainCollection->findSummaryCaseFromEclipseResultCase(resultCase);
if (summaryCase)
if (summaryCase && summaryCase->summaryReader())
{
std::vector<double> values;
if (summaryCase->summaryReader()->values(wbhpPressureAddress, &values))

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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<int>() << 1 << 2);
m_firstColumnSplitter->insertWidget( 0, firstRowFrame );
m_firstColumnSplitter->insertWidget( 1, secondRowFrame );
const int firstRowPixelHeight = 500;
const int secondRowPixelHeight = 300;
m_firstColumnSplitter->setSizes( QList<int>() << firstRowPixelHeight << secondRowPixelHeight );
m_layout->addWidget(m_firstColumnSplitter);

View File

@ -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<RimSummaryCurve*> RicSummaryPlotFeatureImpl::addDefaultCurvesToPlot(
{
std::vector<RimSummaryCurve*> defaultCurves;
if (!plot) return defaultCurves;
if (!summaryCase || !summaryCase->summaryReader()) return defaultCurves;
QString curvesTextFilter = RiaApplication::instance()->preferences()->defaultSummaryCurvesTextFilter;
QStringList curveFilters = curvesTextFilter.split(";", QString::SkipEmptyParts);

View File

@ -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<int> days;
std::set<int> months;
std::set<int> 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<QDateTime> 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);

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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')

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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))

View File

@ -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())

View File

@ -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()

View File

@ -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])

View File

@ -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 @@ with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
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)
resinsight.set_export_folder(export_type='SNAPSHOTS', path=tmpdirname)
resinsight.set_export_folder(export_type='PROPERTIES', path=tmpdirname)
# Export snapshots
resInsight.commands.exportSnapshots()
# Export all snapshots
resinsight.project.export_snapshots()
assert(len(os.listdir(tmpdirname)) > 0)
# Export properties in the view
view1.export_property()
# Check that the exported file exists
expected_file_name = case.name + "-" + str("3D_View") + "-" + "T2" + "-SOIL"
full_path = tmpdirname + "/" + expected_file_name
# Print contents of temporary folder
print(os.listdir(tmpdirname))
assert(len(os.listdir(tmpdirname)) > 0)
case = resInsight.project.case(id=0)
# Export properties in the view
resInsight.commands.exportPropertyInViews(0, "3D View", 0)
# Check that the exported file exists
expectedFileName = case.name + "-" + str("3D_View") + "-" + "T3" + "-SOIL"
fullPath = tmpdirname + "/" + expectedFileName
assert(os.path.exists(fullPath))
assert(os.path.exists(full_path))

View File

@ -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 @@ if case is not None:
# 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 @@ if case is not None:
# With a chunk size exactly matching the active cell count the server will not
# be able to see any error as it will successfully close the stream after receiving
# the correct number of values, even if the python client has more chunks to send
case.properties.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")

View File

@ -6,38 +6,38 @@ import os
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()

View File

@ -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)

View File

@ -7,9 +7,9 @@ import time
# 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')
view = case.views()[0].apply_cell_result('GENERATED', 'POROPERMXAS')

View File

@ -7,23 +7,23 @@ import rips
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 @@ end = time.time()
print("Time elapsed: ", end - start)
print("Transferred all results back")
view = case.views()[0].applyCellResult('GENERATED', 'POROPERMXSY')
view = case.views()[0].apply_cell_result('GENERATED', 'POROPERMXSY')

View File

@ -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')

View File

@ -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())

View File

@ -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)

View File

@ -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')

View File

@ -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'])

View File

@ -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)

View File

@ -6,27 +6,27 @@ import rips
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)

View File

@ -5,21 +5,20 @@ import rips
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))

View File

@ -7,41 +7,41 @@ import time
# 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')
view = case.views()[0].apply_cell_result('GENERATED', 'SOILPORVAsync')

View File

@ -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')
view = case.views()[0].apply_cell_result('GENERATED', 'SOILPORVSync')

View File

@ -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()
new_view = views[0].clone()
view.set_show_grid_box(False)
new_view.set_background_color("#FFAA33")
new_view.update()

View File

@ -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)

View File

@ -1,9 +1,12 @@
name = "rips"
from rips.Case import Case
from rips.Grid import Grid
from rips.Properties import Properties
from rips.Instance import Instance
from rips.Commands import Commands
from rips.PdmObject import PdmObject
from rips.View import View
from rips.Project import Project
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
from rips.case import Case
from rips.grid import Grid
from rips.instance import Instance
from rips.pdmobject import PdmObject
from rips.view import View
from rips.project import Project

View File

@ -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,
))

View File

@ -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

View File

@ -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))

View File

@ -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')

View File

@ -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)

View File

@ -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))

View File

@ -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):

View File

@ -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)

View File

@ -9,50 +9,3 @@ import rips
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)

View File

@ -6,10 +6,10 @@ import rips
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)

View File

@ -1,17 +1,42 @@
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_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)
@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')

View File

@ -2,17 +2,18 @@ import sys
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)
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))

View File

@ -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" <b>Default Option</b>| 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"<b>Default Option</b>| 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))

View File

@ -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())
{

View File

@ -75,25 +75,28 @@ public:
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<Riv3dWellLogCurveGeometryGenerator> 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<DrawPlaneEnum> m_drawPlane;
caf::PdmField<cvf::Color3f> m_color;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -202,8 +202,11 @@ std::vector<double> 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);
}

View File

@ -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("<br>");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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<caf::PdmOptionItemInfo>
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;
}

View File

@ -98,16 +98,19 @@ public:
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;

View File

@ -354,19 +354,9 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha
}
}
if (propFilter)
if ( rim3dWellLogCurve )
{
propFilter->updateConnectedEditors();
}
if (curve)
{
curve->updateConnectedEditors();
}
if (rim3dWellLogCurve)
{
rim3dWellLogCurve->resetMinMaxValuesAndUpdateUI();
rim3dWellLogCurve->resetMinMaxValues();
}
}

View File

@ -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());
}

View File

@ -32,6 +32,7 @@ RimCalculatedSummaryCase::RimCalculatedSummaryCase()
CAF_PDM_InitObject("Calculated",":/SummaryCase48x48.png","","");
m_calculatedCurveReader = nullptr;
m_shortName = "Calculated";
}
//--------------------------------------------------------------------------------------------------

View File

@ -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();
}
//--------------------------------------------------------------------------------------------------

View File

@ -276,7 +276,7 @@ std::set<RifEclipseSummaryAddress> RimSummaryCaseCollection::ensembleSummaryAddr
}
}
if (maxAddrIndex >= 0)
if (maxAddrIndex >= 0 && m_cases[maxAddrIndex]->summaryReader())
{
const std::set<RifEclipseSummaryAddress>& addrs = m_cases[maxAddrIndex]->summaryReader()->allResultAddresses();
addresses.insert(addrs.begin(), addrs.end());

View File

@ -382,7 +382,7 @@ QList<caf::PdmOptionItemInfo> 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<double> 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<double> errValues;
reader->values(errAddress, &errValues);
m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, errValues, isLogCurve);
}
else
{
m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, isLogCurve);
}
}
}
else

View File

@ -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();

View File

@ -292,7 +292,7 @@ void RimSummaryPlotNameHelper::extractPlotTitleSubStrings()
if (summaryCase)
{
m_titleCaseName = summaryCase->caseName();
m_titleCaseName = summaryCase->shortName();
}
}
else if (ensembleCases.size() == 1 && summaryCases.empty())

View File

@ -195,7 +195,7 @@ QList<caf::PdmOptionItemInfo> 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<RifSummaryReaderInterface*> 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<RifSummaryReaderInterface*> RimSummaryPlotSourceStepping::summaryRea
{
for (auto curve : curveSet->curves())
{
if (isYAxisStepping() && curve->summaryCaseY())
if (isYAxisStepping() && curve->summaryCaseY() && curve->summaryCaseY()->summaryReader())
{
readers.push_back(curve->summaryCaseY()->summaryReader());
}

View File

@ -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 );
}
//--------------------------------------------------------------------------------------------------

View File

@ -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

View File

@ -423,7 +423,7 @@ void RiuSummaryCurveDefSelection::setDefaultSelection(const std::vector<SummaryS
if (allSumCases.size() > 0)
{
RifEclipseSummaryAddress defaultAddress = RifEclipseSummaryAddress::fieldAddress("FOPT");
RifEclipseSummaryAddress defaultAddress;
std::vector<SummarySource*> 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<caf::PdmOptionItemInfo> 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<caf::PdmOptionItemInfo> 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<caf::PdmOptionItemInfo> 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);
}

View File

@ -83,7 +83,7 @@ public:
sumCurve = dynamic_cast<RimSummaryCurve*>(riuCurve->ownerRimCurve());
}
return sumCurve && sumCurve->summaryCaseY() ? sumCurve->summaryCaseY()->caseName() : "";
return sumCurve && sumCurve->summaryCaseY() ? sumCurve->summaryCaseY()->shortName() : "";
}
};
static EnsembleCurveInfoTextProvider ensembleCurveInfoTextProvider;

View File

@ -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

View File

@ -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 );