#1769 Add time step filtering when importing model

Move import code from RiaApplication to command feature
Show time step selection UI when importing Eclipse data
Support time step reading of HDF data
This commit is contained in:
Magne Sjaastad 2017-08-25 06:51:56 +02:00
parent d344cf11a2
commit cb506cf86d
24 changed files with 843 additions and 449 deletions

View File

@ -23,6 +23,7 @@
#include "RiaBaseDefs.h"
#include "RiaImageCompareReporter.h"
#include "RiaImageFileCompare.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
#include "RiaProjectModifier.h"
@ -38,20 +39,13 @@
#include "RimCellRangeFilterCollection.h"
#include "RimCommandObject.h"
#include "RimEclipseCaseCollection.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseFaultColors.h"
#include "RimEclipseInputCase.h"
#include "RimEclipseInputPropertyCollection.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseResultCase.h"
#include "RimEclipseStatisticsCase.h"
#include "RimEclipseView.h"
#include "RimEclipseWellCollection.h"
#include "RimFaultCollection.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimFlowPlotCollection.h"
#include "RimFormationNamesCollection.h"
#include "RimEclipseCase.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechCellColors.h"
#include "RimGeoMechModels.h"
@ -94,6 +88,7 @@
#endif // USE_PROTOTYPE_FEATURE_FRACTURES
#include "RicImportInputEclipseCaseFeature.h"
#include "RicImportSummaryCaseFeature.h"
#include "ExportCommands/RicSnapshotViewToFileFeature.h"
#include "ExportCommands/RicSnapshotAllPlotsToFileFeature.h"
@ -963,192 +958,6 @@ QString RiaApplication::createAbsolutePathFromProjectRelativePath(QString projec
return projectDir.absoluteFilePath(projectRelativePath);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication::openEclipseCaseFromFile(const QString& fileName)
{
if (!caf::Utils::fileExists(fileName)) return false;
QFileInfo gridFileName(fileName);
QString caseName = gridFileName.completeBaseName();
return openEclipseCase(caseName, fileName);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication::openEclipseCase(const QString& caseName, const QString& caseFileName)
{
RimEclipseResultCase* rimResultReservoir = new RimEclipseResultCase();
rimResultReservoir->setCaseInfo(caseName, caseFileName);
RimEclipseCaseCollection* analysisModels = m_project->activeOilField() ? m_project->activeOilField()->analysisModels() : NULL;
if (analysisModels == NULL) return false;
RiuMainWindow::instance()->show();
analysisModels->cases.push_back(rimResultReservoir);
RimEclipseView* riv = rimResultReservoir->createAndAddReservoirView();
// Select SOIL as default result variable
riv->cellResult()->setResultType(RiaDefines::DYNAMIC_NATIVE);
if (m_preferences->loadAndShowSoil)
{
riv->cellResult()->setResultVariable("SOIL");
}
riv->hasUserRequestedAnimation = true;
riv->loadDataAndUpdate();
if (analysisModels->cases.size() > 0)
{
if (rimResultReservoir->eclipseCaseData())
{
#ifdef USE_PROTOTYPE_FEATURE_FRACTURES
project()->activeOilField()->fractureDefinitionCollection->defaultUnitsForFracTemplates = rimResultReservoir->eclipseCaseData()->unitsType();
#endif // USE_PROTOTYPE_FEATURE_FRACTURES
}
}
// Add a corresponding summary case if it exists
{
RimSummaryCaseCollection* sumCaseColl = m_project->activeOilField() ? m_project->activeOilField()->summaryCaseCollection() : NULL;
if(sumCaseColl)
{
if (sumCaseColl->summaryCaseCount() == 0 && m_mainPlotWindow)
{
m_mainPlotWindow->hide();
}
if (!sumCaseColl->findSummaryCaseFromEclipseResultCase(rimResultReservoir))
{
RimSummaryCase* newSumCase = sumCaseColl->createAndAddSummaryCaseFromEclipseResultCase(rimResultReservoir);
if (newSumCase)
{
newSumCase->loadCase();
RimSummaryCase* existingFileSummaryCase = sumCaseColl->findSummaryCaseFromFileName(newSumCase->summaryHeaderFilename());
if (existingFileSummaryCase)
{
// Replace all occurrences of file sum with ecl sum
std::vector<caf::PdmObjectHandle*> referringObjects;
existingFileSummaryCase->objectsWithReferringPtrFields(referringObjects);
std::set<RimSummaryCurveFilter*> curveFilters;
for (caf::PdmObjectHandle* objHandle : referringObjects)
{
RimSummaryCurve* summaryCurve = dynamic_cast<RimSummaryCurve*>(objHandle);
if (summaryCurve)
{
summaryCurve->setSummaryCase(newSumCase);
summaryCurve->updateConnectedEditors();
RimSummaryCurveFilter* parentFilter = nullptr;
summaryCurve->firstAncestorOrThisOfType(parentFilter);
if (parentFilter)
{
curveFilters.insert(parentFilter);
}
}
}
// UI settings of a curve filter is updated based
// on the new case association for the curves in the curve filter
// UI is updated by loadDataAndUpdate()
for (RimSummaryCurveFilter* curveFilter : curveFilters)
{
curveFilter->loadDataAndUpdate();
curveFilter->updateConnectedEditors();
}
sumCaseColl->deleteCase(existingFileSummaryCase);
delete existingFileSummaryCase;
}
else
{
if (m_preferences->autoCreatePlotsOnImport())
{
RimMainPlotCollection* mainPlotColl = m_project->mainPlotCollection();
RimSummaryPlotCollection* summaryPlotColl = mainPlotColl->summaryPlotCollection();
RicNewSummaryPlotFeature::createNewSummaryPlot(summaryPlotColl, newSumCase);
}
}
sumCaseColl->updateConnectedEditors();
}
}
}
}
if (!riv->cellResult()->hasResult())
{
riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
}
analysisModels->updateConnectedEditors();
RiuMainWindow::instance()->selectAsCurrentItem(riv->cellResult());
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication::openInputEclipseCaseFromFileNames(const QStringList& fileNames)
{
RimEclipseInputCase* rimInputReservoir = new RimEclipseInputCase();
m_project->assignCaseIdToCase(rimInputReservoir);
rimInputReservoir->openDataFileSet(fileNames);
RimEclipseCaseCollection* analysisModels = m_project->activeOilField() ? m_project->activeOilField()->analysisModels() : NULL;
if (analysisModels == NULL) return false;
analysisModels->cases.push_back(rimInputReservoir);
RimEclipseView* riv = rimInputReservoir->createAndAddReservoirView();
riv->cellResult()->setResultType(RiaDefines::INPUT_PROPERTY);
riv->hasUserRequestedAnimation = true;
riv->loadDataAndUpdate();
if (!riv->cellResult()->hasResult())
{
riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
}
analysisModels->updateConnectedEditors();
RiuMainWindow::instance()->selectAsCurrentItem(riv->cellResult());
if (fileNames.size() == 1)
{
addToRecentFiles(fileNames[0]);
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1201,7 +1010,7 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName)
//--------------------------------------------------------------------------------------------------
void RiaApplication::createMockModel()
{
openEclipseCase(RiaDefines::mockModelBasic(), RiaDefines::mockModelBasic());
RiaImportEclipseCaseTools::openMockModel(RiaDefines::mockModelBasic());
}
//--------------------------------------------------------------------------------------------------
@ -1209,7 +1018,7 @@ void RiaApplication::createMockModel()
//--------------------------------------------------------------------------------------------------
void RiaApplication::createResultsMockModel()
{
openEclipseCase(RiaDefines::mockModelBasicWithResults(), RiaDefines::mockModelBasicWithResults());
RiaImportEclipseCaseTools::openMockModel(RiaDefines::mockModelBasicWithResults());
}
@ -1218,7 +1027,7 @@ void RiaApplication::createResultsMockModel()
//--------------------------------------------------------------------------------------------------
void RiaApplication::createLargeResultsMockModel()
{
openEclipseCase(RiaDefines::mockModelLargeWithResults(), RiaDefines::mockModelLargeWithResults());
RiaImportEclipseCaseTools::openMockModel(RiaDefines::mockModelLargeWithResults());
}
@ -1227,7 +1036,7 @@ void RiaApplication::createLargeResultsMockModel()
//--------------------------------------------------------------------------------------------------
void RiaApplication::createMockModelCustomized()
{
openEclipseCase(RiaDefines::mockModelCustomized(), RiaDefines::mockModelCustomized());
RiaImportEclipseCaseTools::openMockModel(RiaDefines::mockModelCustomized());
}
//--------------------------------------------------------------------------------------------------
@ -1235,7 +1044,7 @@ void RiaApplication::createMockModelCustomized()
//--------------------------------------------------------------------------------------------------
void RiaApplication::createInputMockModel()
{
openInputEclipseCaseFromFileNames(QStringList(RiaDefines::mockModelBasicInputCase()));
RicImportInputEclipseCaseFeature::openInputEclipseCaseFromFileNames(QStringList(RiaDefines::mockModelBasicInputCase()));
}
//--------------------------------------------------------------------------------------------------
@ -1549,21 +1358,21 @@ bool RiaApplication::parseArguments()
if (caf::Utils::fileExists(caseName) &&
(fileExtension == "EGRID" || fileExtension == "GRID"))
{
openEclipseCaseFromFile(caseName);
RiaImportEclipseCaseTools::openEclipseCaseFromFile(caseName);
}
else
{
QString caseFileNameWithExt = caseName + ".EGRID";
if (caf::Utils::fileExists(caseFileNameWithExt))
{
openEclipseCaseFromFile(caseFileNameWithExt);
RiaImportEclipseCaseTools::openEclipseCaseFromFile(caseFileNameWithExt);
}
else
{
caseFileNameWithExt = caseName + ".GRID";
if (caf::Utils::fileExists(caseFileNameWithExt))
{
openEclipseCaseFromFile(caseFileNameWithExt);
RiaImportEclipseCaseTools::openEclipseCaseFromFile(caseFileNameWithExt);
}
}
}
@ -2270,11 +2079,11 @@ bool RiaApplication::openFile(const QString& fileName)
}
else if (fileName.contains(".egrid", Qt::CaseInsensitive) || fileName.contains(".grid", Qt::CaseInsensitive))
{
loadingSucceded = openEclipseCaseFromFile(fileName);
loadingSucceded = RiaImportEclipseCaseTools::openEclipseCaseFromFile(fileName);
}
else if (fileName.contains(".grdecl", Qt::CaseInsensitive))
{
loadingSucceded = openInputEclipseCaseFromFileNames(QStringList(fileName));
loadingSucceded = RicImportInputEclipseCaseFeature::openInputEclipseCaseFromFileNames(QStringList(fileName));
}
else if (fileName.contains(".odb", Qt::CaseInsensitive))
{
@ -2574,100 +2383,6 @@ void RiaApplication::updateRegressionTest(const QString& testRootPath)
}
}
//--------------------------------------------------------------------------------------------------
/// Make sure changes in this functions is validated to RimIdenticalGridCaseGroup::initAfterRead()
//--------------------------------------------------------------------------------------------------
bool RiaApplication::addEclipseCases(const QStringList& fileNames)
{
if (fileNames.size() == 0) return true;
// First file is read completely including grid.
// The main grid from the first case is reused directly in for the other cases.
// When reading active cell info, only the total cell count is tested for consistency
RimEclipseResultCase* mainResultCase = NULL;
std::vector< std::vector<int> > mainCaseGridDimensions;
RimIdenticalGridCaseGroup* gridCaseGroup = NULL;
{
QString firstFileName = fileNames[0];
QFileInfo gridFileName(firstFileName);
QString caseName = gridFileName.completeBaseName();
RimEclipseResultCase* rimResultReservoir = new RimEclipseResultCase();
rimResultReservoir->setCaseInfo(caseName, firstFileName);
if (!rimResultReservoir->openEclipseGridFile())
{
delete rimResultReservoir;
return false;
}
rimResultReservoir->readGridDimensions(mainCaseGridDimensions);
mainResultCase = rimResultReservoir;
RimOilField* oilField = m_project->activeOilField();
if (oilField && oilField->analysisModels())
{
gridCaseGroup = oilField->analysisModels->createIdenticalCaseGroupFromMainCase(mainResultCase);
}
}
caf::ProgressInfo info(fileNames.size(), "Reading Active Cell data");
for (int i = 1; i < fileNames.size(); i++)
{
QString caseFileName = fileNames[i];
QFileInfo gridFileName(caseFileName);
QString caseName = gridFileName.completeBaseName();
RimEclipseResultCase* rimResultReservoir = new RimEclipseResultCase();
rimResultReservoir->setCaseInfo(caseName, caseFileName);
std::vector< std::vector<int> > caseGridDimensions;
rimResultReservoir->readGridDimensions(caseGridDimensions);
bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions);
if (identicalGrid)
{
if (rimResultReservoir->openAndReadActiveCellData(mainResultCase->eclipseCaseData()))
{
RimOilField* oilField = m_project->activeOilField();
if (oilField && oilField->analysisModels())
{
oilField->analysisModels()->insertCaseInCaseGroup(gridCaseGroup, rimResultReservoir);
}
}
else
{
delete rimResultReservoir;
}
}
else
{
delete rimResultReservoir;
}
info.setProgress(i);
}
if (gridCaseGroup)
{
// Create placeholder results and propagate results info from main case to all other cases
gridCaseGroup->loadMainCaseAndActiveCellInfo();
}
m_project->activeOilField()->analysisModels()->updateConnectedEditors();
if (gridCaseGroup->statisticsCaseCollection()->reservoirs.size() > 0)
{
RiuMainWindow::instance()->selectAsCurrentItem(gridCaseGroup->statisticsCaseCollection()->reservoirs[0]);
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -121,10 +121,6 @@ public:
void setLastUsedDialogDirectory(const QString& dialogName, const QString& directory);
bool openFile(const QString& fileName);
bool openEclipseCaseFromFile(const QString& fileName);
bool openEclipseCase(const QString& caseName, const QString& caseFileName);
bool addEclipseCases(const QStringList& fileNames);
bool openInputEclipseCaseFromFileNames(const QStringList& fileNames);
bool openOdbCaseFromFile(const QString& fileName);

View File

@ -13,6 +13,7 @@ ${CEE_CURRENT_LIST_DIR}RiaImageFileCompare.h
${CEE_CURRENT_LIST_DIR}RiaLogging.h
${CEE_CURRENT_LIST_DIR}RiaProjectModifier.h
${CEE_CURRENT_LIST_DIR}RiaRegressionTest.h
${CEE_CURRENT_LIST_DIR}RiaImportEclipseCaseTools.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -23,6 +24,7 @@ ${CEE_CURRENT_LIST_DIR}RiaImageFileCompare.cpp
${CEE_CURRENT_LIST_DIR}RiaLogging.cpp
${CEE_CURRENT_LIST_DIR}RiaProjectModifier.cpp
${CEE_CURRENT_LIST_DIR}RiaRegressionTest.cpp
${CEE_CURRENT_LIST_DIR}RiaImportEclipseCaseTools.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,311 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaImportEclipseCaseTools.h"
#include "../SummaryPlotCommands/RicNewSummaryPlotFeature.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RigGridManager.h"
#include "RimCaseCollection.h"
#include "RimEclipseCaseCollection.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseResultCase.h"
#include "RimEclipseView.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimMainPlotCollection.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryCurve.h"
#include "RimSummaryCurveFilter.h"
#include "RimSummaryPlotCollection.h"
#include "RiuMainPlotWindow.h"
#include "RiuMainWindow.h"
#include "cafUtils.h"
#include "cafProgressInfo.h"
#include <QFileInfo>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaImportEclipseCaseTools::openEclipseCaseFromFile(const QString& fileName)
{
if (!caf::Utils::fileExists(fileName)) return false;
return RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilterImpl(fileName, false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilter(const QString& fileName)
{
if (!caf::Utils::fileExists(fileName)) return false;
return RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilterImpl(fileName, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaImportEclipseCaseTools::openMockModel(const QString& name)
{
return RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilterImpl(name, false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilterImpl(const QString& fileName, bool showTimeStepFilter)
{
QFileInfo gridFileName(fileName);
QString caseName = gridFileName.completeBaseName();
RimEclipseResultCase* rimResultReservoir = new RimEclipseResultCase();
rimResultReservoir->setCaseInfo(caseName, fileName);
RiaApplication* app = RiaApplication::instance();
RimProject* project = app->project();
RimEclipseCaseCollection* analysisModels = project->activeOilField() ? project->activeOilField()->analysisModels() : NULL;
if (analysisModels == NULL) return false;
RiuMainWindow::instance()->show();
analysisModels->cases.push_back(rimResultReservoir);
if (!rimResultReservoir->importGridAndResultMetaData(showTimeStepFilter))
{
analysisModels->removeCaseFromAllGroups(rimResultReservoir);
delete rimResultReservoir;
return false;
}
RimEclipseView* riv = rimResultReservoir->createAndAddReservoirView();
// Select SOIL as default result variable
riv->cellResult()->setResultType(RiaDefines::DYNAMIC_NATIVE);
if (app->preferences()->loadAndShowSoil)
{
riv->cellResult()->setResultVariable("SOIL");
}
riv->hasUserRequestedAnimation = true;
riv->loadDataAndUpdate();
// Add a corresponding summary case if it exists
{
RimSummaryCaseCollection* sumCaseColl = project->activeOilField() ? project->activeOilField()->summaryCaseCollection() : NULL;
if (sumCaseColl)
{
{
RiuMainPlotWindow* mainPlotWindow = app->mainPlotWindow();
if (sumCaseColl->summaryCaseCount() == 0 && mainPlotWindow)
{
mainPlotWindow->hide();
}
}
if (!sumCaseColl->findSummaryCaseFromEclipseResultCase(rimResultReservoir))
{
RimSummaryCase* newSumCase = sumCaseColl->createAndAddSummaryCaseFromEclipseResultCase(rimResultReservoir);
if (newSumCase)
{
newSumCase->loadCase();
RimSummaryCase* existingFileSummaryCase = sumCaseColl->findSummaryCaseFromFileName(newSumCase->summaryHeaderFilename());
if (existingFileSummaryCase)
{
// Replace all occurrences of file sum with ecl sum
std::vector<caf::PdmObjectHandle*> referringObjects;
existingFileSummaryCase->objectsWithReferringPtrFields(referringObjects);
std::set<RimSummaryCurveFilter*> curveFilters;
for (caf::PdmObjectHandle* objHandle : referringObjects)
{
RimSummaryCurve* summaryCurve = dynamic_cast<RimSummaryCurve*>(objHandle);
if (summaryCurve)
{
summaryCurve->setSummaryCase(newSumCase);
summaryCurve->updateConnectedEditors();
RimSummaryCurveFilter* parentFilter = nullptr;
summaryCurve->firstAncestorOrThisOfType(parentFilter);
if (parentFilter)
{
curveFilters.insert(parentFilter);
}
}
}
// UI settings of a curve filter is updated based
// on the new case association for the curves in the curve filter
// UI is updated by loadDataAndUpdate()
for (RimSummaryCurveFilter* curveFilter : curveFilters)
{
curveFilter->loadDataAndUpdate();
curveFilter->updateConnectedEditors();
}
sumCaseColl->deleteCase(existingFileSummaryCase);
delete existingFileSummaryCase;
}
else
{
if (app->preferences()->autoCreatePlotsOnImport())
{
RimMainPlotCollection* mainPlotColl = project->mainPlotCollection();
RimSummaryPlotCollection* summaryPlotColl = mainPlotColl->summaryPlotCollection();
RicNewSummaryPlotFeature::createNewSummaryPlot(summaryPlotColl, newSumCase);
}
}
sumCaseColl->updateConnectedEditors();
}
}
}
}
if (!riv->cellResult()->hasResult())
{
riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
}
analysisModels->updateConnectedEditors();
RiuMainWindow::instance()->selectAsCurrentItem(riv->cellResult());
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaImportEclipseCaseTools::addEclipseCases(const QStringList& fileNames)
{
if (fileNames.size() == 0) return true;
// First file is read completely including grid.
// The main grid from the first case is reused directly in for the other cases.
// When reading active cell info, only the total cell count is tested for consistency
RimEclipseResultCase* mainResultCase = NULL;
std::vector< std::vector<int> > mainCaseGridDimensions;
RimIdenticalGridCaseGroup* gridCaseGroup = NULL;
RiaApplication* app = RiaApplication::instance();
RimProject* project = app->project();
{
QString firstFileName = fileNames[0];
QFileInfo gridFileName(firstFileName);
QString caseName = gridFileName.completeBaseName();
RimEclipseResultCase* rimResultReservoir = new RimEclipseResultCase();
rimResultReservoir->setCaseInfo(caseName, firstFileName);
if (!rimResultReservoir->openEclipseGridFile())
{
delete rimResultReservoir;
return false;
}
rimResultReservoir->readGridDimensions(mainCaseGridDimensions);
mainResultCase = rimResultReservoir;
RimOilField* oilField = project->activeOilField();
if (oilField && oilField->analysisModels())
{
gridCaseGroup = oilField->analysisModels->createIdenticalCaseGroupFromMainCase(mainResultCase);
}
}
caf::ProgressInfo info(fileNames.size(), "Reading Active Cell data");
for (int i = 1; i < fileNames.size(); i++)
{
QString caseFileName = fileNames[i];
QFileInfo gridFileName(caseFileName);
QString caseName = gridFileName.completeBaseName();
RimEclipseResultCase* rimResultReservoir = new RimEclipseResultCase();
rimResultReservoir->setCaseInfo(caseName, caseFileName);
std::vector< std::vector<int> > caseGridDimensions;
rimResultReservoir->readGridDimensions(caseGridDimensions);
bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions);
if (identicalGrid)
{
if (rimResultReservoir->openAndReadActiveCellData(mainResultCase->eclipseCaseData()))
{
RimOilField* oilField = project->activeOilField();
if (oilField && oilField->analysisModels())
{
oilField->analysisModels()->insertCaseInCaseGroup(gridCaseGroup, rimResultReservoir);
}
}
else
{
delete rimResultReservoir;
}
}
else
{
delete rimResultReservoir;
}
info.setProgress(i);
}
if (gridCaseGroup)
{
// Create placeholder results and propagate results info from main case to all other cases
gridCaseGroup->loadMainCaseAndActiveCellInfo();
}
project->activeOilField()->analysisModels()->updateConnectedEditors();
if (gridCaseGroup->statisticsCaseCollection()->reservoirs.size() > 0)
{
RiuMainWindow::instance()->selectAsCurrentItem(gridCaseGroup->statisticsCaseCollection()->reservoirs[0]);
}
return true;
}

View File

@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
class QString;
class QStringList;
//==================================================================================================
///
//==================================================================================================
class RiaImportEclipseCaseTools
{
public:
static bool openEclipseCaseFromFile(const QString& fileName);
static bool openEclipseCaseShowTimeStepFilter(const QString& fileName);
static bool openMockModel(const QString& name);
static bool addEclipseCases(const QStringList& fileNames);
private:
static bool openEclipseCaseShowTimeStepFilterImpl(const QString& fileName, bool showTimeStepFilter);
};

View File

@ -18,7 +18,8 @@
#include "RicfLoadCase.h"
#include "RiaApplication.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaLogging.h"
CAF_PDM_SOURCE_INIT(RicfLoadCase, "loadCase");
@ -36,7 +37,7 @@ RicfLoadCase::RicfLoadCase()
//--------------------------------------------------------------------------------------------------
void RicfLoadCase::execute()
{
bool ok = RiaApplication::instance()->openEclipseCaseFromFile(m_path);
bool ok = RiaImportEclipseCaseTools::openEclipseCaseFromFile(m_path);
if (!ok)
{
RiaLogging::error(QString("loadCase: Unable to load case from %1").arg(m_path()));

View File

@ -19,6 +19,7 @@ ${CEE_CURRENT_LIST_DIR}RicImportEclipseCaseFeature.h
${CEE_CURRENT_LIST_DIR}RicImportInputEclipseCaseFeature.h
${CEE_CURRENT_LIST_DIR}RicNewStatisticsCaseFeature.h
${CEE_CURRENT_LIST_DIR}RicApplyPropertyFilterAsCellResultFeature.h
${CEE_CURRENT_LIST_DIR}RicImportEclipseCaseTimeStepFilterFeature.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -36,6 +37,7 @@ ${CEE_CURRENT_LIST_DIR}RicImportEclipseCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicImportInputEclipseCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewStatisticsCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicApplyPropertyFilterAsCellResultFeature.cpp
${CEE_CURRENT_LIST_DIR}RicImportEclipseCaseTimeStepFilterFeature.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -19,8 +19,9 @@
#include "RicCreateGridCaseGroupFeature.h"
#include "RiaImportEclipseCaseTools.h"
#include "RimEclipseCaseCollection.h"
#include "RiaApplication.h"
#include "RiuMultiCaseImportDialog.h"
#include "cafSelectionManager.h"
@ -42,13 +43,12 @@ bool RicCreateGridCaseGroupFeature::isCommandEnabled()
//--------------------------------------------------------------------------------------------------
void RicCreateGridCaseGroupFeature::onActionTriggered(bool isChecked)
{
RiaApplication* app = RiaApplication::instance();
RiuMultiCaseImportDialog dialog;
int action = dialog.exec();
if (action == QDialog::Accepted)
{
QStringList gridFileNames = dialog.eclipseCaseFileNames();
app->addEclipseCases(gridFileNames);
RiaImportEclipseCaseTools::addEclipseCases(gridFileNames);
}
}

View File

@ -19,8 +19,12 @@
#include "RicImportEclipseCaseFeature.h"
#include "RimEclipseCaseCollection.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaApplication.h"
#include "RimEclipseCaseCollection.h"
#include "RiuMainWindow.h"
#include "cafSelectionManager.h"
@ -57,7 +61,7 @@ void RicImportEclipseCaseFeature::onActionTriggered(bool isChecked)
if (!fileNames.isEmpty())
{
if (app->openEclipseCaseFromFile(fileName))
if (RiaImportEclipseCaseTools::openEclipseCaseFromFile(fileName))
{
app->addToRecentFiles(fileName);
}

View File

@ -0,0 +1,69 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicImportEclipseCaseTimeStepFilterFeature.h"
#include "RiaApplication.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiuMainWindow.h"
#include <QAction>
#include <QFileDialog>
#include <QFileInfo>
CAF_CMD_SOURCE_INIT(RicImportEclipseCaseTimeStepFilterFeature, "RicImportEclipseCaseTimeStepFilterFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportEclipseCaseTimeStepFilterFeature::onActionTriggered(bool isChecked)
{
RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory("BINARY_GRID");
QString fileName = QFileDialog::getOpenFileName(RiuMainWindow::instance(), "Import Eclipse File", defaultDir, "Eclipse Grid Files (*.GRID *.EGRID)");
if (!fileName.isEmpty())
{
defaultDir = QFileInfo(fileName).absolutePath();
app->setLastUsedDialogDirectory("BINARY_GRID", defaultDir);
if (RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilter(fileName))
{
app->addToRecentFiles(fileName);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportEclipseCaseTimeStepFilterFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setIcon(QIcon(":/Case48x48.png"));
actionToSetup->setText("Import Eclipse Case (Time Step Filtered)");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicImportEclipseCaseTimeStepFilterFeature::isCommandEnabled()
{
return true;
}

View File

@ -0,0 +1,38 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
#include <vector>
//==================================================================================================
///
//==================================================================================================
class RicImportEclipseCaseTimeStepFilterFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
virtual void onActionTriggered(bool isChecked) override;
virtual void setupActionLook(QAction* actionToSetup) override;
virtual bool isCommandEnabled() override;
};

View File

@ -19,17 +19,68 @@
#include "RicImportInputEclipseCaseFeature.h"
#include "RimEclipseCaseCollection.h"
#include "RiaApplication.h"
#include "RiaPorosityModel.h"
#include "RimEclipseCaseCollection.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseInputCase.h"
#include "RimEclipseView.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RiuMainWindow.h"
#include "cafSelectionManager.h"
#include <QAction>
#include <QFileDialog>
CAF_CMD_SOURCE_INIT(RicImportInputEclipseCaseFeature, "RicImportInputEclipseCaseFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicImportInputEclipseCaseFeature::openInputEclipseCaseFromFileNames(const QStringList& fileNames)
{
RimEclipseInputCase* rimInputReservoir = new RimEclipseInputCase();
RiaApplication* app = RiaApplication::instance();
RimProject* project = app->project();
project->assignCaseIdToCase(rimInputReservoir);
rimInputReservoir->openDataFileSet(fileNames);
RimEclipseCaseCollection* analysisModels = project->activeOilField() ? project->activeOilField()->analysisModels() : NULL;
if (analysisModels == NULL) return false;
analysisModels->cases.push_back(rimInputReservoir);
RimEclipseView* riv = rimInputReservoir->createAndAddReservoirView();
riv->cellResult()->setResultType(RiaDefines::INPUT_PROPERTY);
riv->hasUserRequestedAnimation = true;
riv->loadDataAndUpdate();
if (!riv->cellResult()->hasResult())
{
riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
}
analysisModels->updateConnectedEditors();
RiuMainWindow::instance()->selectAsCurrentItem(riv->cellResult());
if (fileNames.size() == 1)
{
app->addToRecentFiles(fileNames[0]);
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -52,8 +103,7 @@ void RicImportInputEclipseCaseFeature::onActionTriggered(bool isChecked)
// Remember the path to next time
app->setLastUsedDialogDirectory("INPUT_FILES", QFileInfo(fileNames.last()).absolutePath());
app->openInputEclipseCaseFromFileNames(fileNames);
RicImportInputEclipseCaseFeature::openInputEclipseCaseFromFileNames(fileNames);
}
//--------------------------------------------------------------------------------------------------

View File

@ -23,6 +23,8 @@
#include <vector>
class QStringList;
//==================================================================================================
///
//==================================================================================================
@ -30,6 +32,10 @@ class RicImportInputEclipseCaseFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
static bool openInputEclipseCaseFromFileNames(const QStringList& fileNames);
protected:
// Overrides
virtual bool isCommandEnabled();

View File

@ -20,6 +20,9 @@
#include "RifEclipseOutputFileTools.h"
#include "RifEclipseRestartFilesetAccess.h"
#include "RifEclipseUnifiedRestartFileAccess.h"
#include "ert/ecl/ecl_file.h"
#include "ert/ecl/ecl_grid.h"
#include "ert/ecl/ecl_kw_magic.h"
@ -337,6 +340,37 @@ int RifEclipseOutputFileTools::readUnitsType(ecl_file_type* ecl_file)
return unitsType;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<RifEclipseRestartDataAccess> RifEclipseOutputFileTools::createDynamicResultAccess(const QString& fileName)
{
QStringList filesWithSameBaseName;
RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(fileName, &filesWithSameBaseName);
cvf::ref<RifEclipseRestartDataAccess> resultsAccess;
// Look for unified restart file
QString unrstFileName = RifEclipseOutputFileTools::firstFileNameOfType(filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE);
if (unrstFileName.size() > 0)
{
resultsAccess = new RifEclipseUnifiedRestartFileAccess();
resultsAccess->setRestartFiles(QStringList(unrstFileName));
}
else
{
// Look for set of restart files (one file per time step)
QStringList restartFiles = RifEclipseOutputFileTools::filterFileNamesOfType(filesWithSameBaseName, ECL_RESTART_FILE);
if (restartFiles.size() > 0)
{
resultsAccess = new RifEclipseRestartFilesetAccess();
resultsAccess->setRestartFiles(restartFiles);
}
}
return resultsAccess;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -20,20 +20,23 @@
#pragma once
#include "RifEclipseRestartDataAccess.h"
#include "ert/ecl/ecl_util.h"
#include "cvfBase.h"
#include "cvfObject.h"
#include "RifReaderInterface.h"
#include "RifEclipseRestartDataAccess.h"
#include <QString>
#include <QStringList>
#include <QDateTime>
#include "ert/ecl/ecl_util.h"
#include <vector>
typedef struct ecl_file_struct ecl_file_type;
class RifEclipseRestartDataAccess;
//==================================================================================================
//
@ -62,6 +65,9 @@ public:
static int readUnitsType(ecl_file_type* ecl_file);
static cvf::ref<RifEclipseRestartDataAccess> createDynamicResultAccess(const QString& fileName);
private:
static void createReportStepsMetaData(std::vector<ecl_file_type*> ecl_files, std::vector<RifRestartReportStep>* reportSteps);
};

View File

@ -24,9 +24,6 @@
#include "RifEclipseInputFileTools.h"
#include "RifEclipseOutputFileTools.h"
#include "RifEclipseRestartFilesetAccess.h"
#include "RifEclipseUnifiedRestartFileAccess.h"
#include "RifHdf5ReaderInterface.h"
#ifdef USE_HDF5
#include "RifHdf5Reader.h"
@ -372,6 +369,8 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e
// Get set of files
QStringList fileSet;
if (!RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(fileName, &fileSet)) return false;
m_fileName = fileName;
progInfo.incrementProgress();
@ -470,12 +469,7 @@ void RifReaderEclipseOutput::setHdf5FileName(const QString& fileName)
RiaLogging::info("HDF: Removing all existing Sour Sim data ...");
matrixModelResults->eraseAllSourSimData();
std::vector<QDateTime> dateTimes;
std::vector<double> daysSinceSimulationStart;
if (m_dynamicResultsAccess.notNull())
{
m_dynamicResultsAccess->timeSteps(&dateTimes, &daysSinceSimulationStart);
}
std::vector<RigEclipseTimeStepInfo> timeStepInfos = createFilteredTimeStepInfos();
std::unique_ptr<RifHdf5ReaderInterface> myReader;
#ifdef USE_HDF5
@ -490,27 +484,21 @@ void RifReaderEclipseOutput::setHdf5FileName(const QString& fileName)
}
std::vector<QDateTime> hdfTimeSteps = myReader->timeSteps();
if (dateTimes.size() > 0)
{
if (hdfTimeSteps.size() != dateTimes.size())
{
RiaLogging::error("HDF: Time step count does not match");
RiaLogging::error(QString("HDF: Eclipse count %1").arg(dateTimes.size()));
RiaLogging::error(QString("HDF: HDF count %1").arg(hdfTimeSteps.size()));
return;
}
if (timeStepInfos.size() > 0)
{
bool isTimeStampsEqual = true;
for (size_t i = 0; i < dateTimes.size(); i++)
for (size_t i = 0; i < timeStepInfos.size(); i++)
{
if (hdfTimeSteps[i].date() != dateTimes[i].date())
size_t indexOnFile = timeStepIndexOnFile(i);
QString dateStr("yyyy.MMM.ddd hh:mm");
if (!isEclipseAndSoursimTimeStepsEqual(hdfTimeSteps[indexOnFile], timeStepInfos[i].m_date))
{
RiaLogging::error("HDF: Time steps does not match");
QString dateStr("yyyy.MMM.ddd hh:mm");
RiaLogging::error(QString("HDF: Eclipse date %1").arg(dateTimes[i].toString(dateStr)));
RiaLogging::error(QString("HDF: Eclipse date %1").arg(timeStepInfos[i].m_date.toString(dateStr)));
RiaLogging::error(QString("HDF: HDF date %1").arg(hdfTimeSteps[i].toString(dateStr)));
isTimeStampsEqual = false;
@ -522,19 +510,15 @@ void RifReaderEclipseOutput::setHdf5FileName(const QString& fileName)
else
{
// Use time steps from HDF to define the time steps
dateTimes = hdfTimeSteps;
QDateTime firstDate = hdfTimeSteps[0];
std::vector<double> daysSinceSimulationStart;
for (auto d : hdfTimeSteps)
{
daysSinceSimulationStart.push_back(firstDate.daysTo(d));
}
}
std::vector<RigEclipseTimeStepInfo> timeStepInfos;
{
std::vector<int> reportNumbers;
if (m_dynamicResultsAccess.notNull())
{
@ -542,13 +526,13 @@ void RifReaderEclipseOutput::setHdf5FileName(const QString& fileName)
}
else
{
for (size_t i = 0; i < dateTimes.size(); i++)
for (size_t i = 0; i < hdfTimeSteps.size(); i++)
{
reportNumbers.push_back(static_cast<int>(i));
}
}
timeStepInfos = RigEclipseTimeStepInfo::createTimeStepInfos(dateTimes, reportNumbers, daysSinceSimulationStart);
timeStepInfos = RigEclipseTimeStepInfo::createTimeStepInfos(hdfTimeSteps, reportNumbers, daysSinceSimulationStart);
}
QStringList resultNames = myReader->propertyNames();
@ -561,6 +545,14 @@ void RifReaderEclipseOutput::setHdf5FileName(const QString& fileName)
m_hdfReaderInterface = std::move(myReader);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput::setFileDataAccess(RifEclipseRestartDataAccess* restartDataAccess)
{
m_dynamicResultsAccess = restartDataAccess;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -686,7 +678,7 @@ bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName,
return false;
}
m_dynamicResultsAccess = createDynamicResultsAccess();
ensureDynamicResultAccessIsPresent();
if (m_dynamicResultsAccess.notNull())
{
m_dynamicResultsAccess->setTimeSteps(mainCaseTimeSteps);
@ -801,7 +793,7 @@ void RifReaderEclipseOutput::buildMetaData()
std::vector<RigEclipseTimeStepInfo> timeStepInfos;
// Create access object for dynamic results
m_dynamicResultsAccess = createDynamicResultsAccess();
ensureDynamicResultAccessIsPresent();
if (m_dynamicResultsAccess.notNull())
{
m_dynamicResultsAccess->open();
@ -914,29 +906,12 @@ void RifReaderEclipseOutput::buildMetaData()
//--------------------------------------------------------------------------------------------------
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
//--------------------------------------------------------------------------------------------------
RifEclipseRestartDataAccess* RifReaderEclipseOutput::createDynamicResultsAccess()
void RifReaderEclipseOutput::ensureDynamicResultAccessIsPresent()
{
RifEclipseRestartDataAccess* resultsAccess = NULL;
// Look for unified restart file
QString unrstFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE);
if (unrstFileName.size() > 0)
if (m_dynamicResultsAccess.isNull())
{
resultsAccess = new RifEclipseUnifiedRestartFileAccess();
resultsAccess->setRestartFiles(QStringList(unrstFileName));
m_dynamicResultsAccess = RifEclipseOutputFileTools::createDynamicResultAccess(m_fileName);
}
else
{
// Look for set of restart files (one file per time step)
QStringList restartFiles = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE);
if (restartFiles.size() > 0)
{
resultsAccess = new RifEclipseRestartFilesetAccess();
resultsAccess->setRestartFiles(restartFiles);
}
}
return resultsAccess;
}
//--------------------------------------------------------------------------------------------------
@ -997,7 +972,9 @@ void RifReaderEclipseOutput::sourSimRlResult(const QString& result, size_t stepI
fracActCellInfo->gridActiveCellCounts(0, activeCellCount);
}
bool readCellResultOk = m_hdfReaderInterface->dynamicResult(result, stepIndex, values);
size_t fileIndex = timeStepIndexOnFile(stepIndex);
bool readCellResultOk = m_hdfReaderInterface->dynamicResult(result, fileIndex, values);
if (activeCellCount != values->size())
{
@ -1013,12 +990,7 @@ void RifReaderEclipseOutput::sourSimRlResult(const QString& result, size_t stepI
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseOutput::dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values)
{
if (m_dynamicResultsAccess.isNull())
{
m_dynamicResultsAccess = createDynamicResultsAccess();
}
ensureDynamicResultAccessIsPresent();
if (m_dynamicResultsAccess.notNull())
{
@ -1976,6 +1948,17 @@ std::vector<RigEclipseTimeStepInfo> RifReaderEclipseOutput::createFilteredTimeSt
return timeStepInfos;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseOutput::isEclipseAndSoursimTimeStepsEqual(const QDateTime& dt1, const QDateTime& dt2)
{
// Currently, HDF files do not contain hours and minutes
// Only compare date, and skip hour/minutes
return dt1.date() == dt2.date();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -54,6 +54,7 @@ public:
bool open(const QString& fileName, RigEclipseCaseData* eclipseCase);
void setHdf5FileName(const QString& fileName);
void setFileDataAccess(RifEclipseRestartDataAccess* restartDataAccess);
virtual bool openAndReadActiveCellData(const QString& fileName, const std::vector<QDateTime>& mainCaseTimeSteps, RigEclipseCaseData* eclipseCase);
void close();
@ -82,12 +83,14 @@ private:
void transferStaticNNCData(const ecl_grid_type* mainEclGrid , ecl_file_type* init_file, RigMainGrid* mainGrid);
void transferDynamicNNCData(const ecl_grid_type* mainEclGrid, RigMainGrid* mainGrid);
RifEclipseRestartDataAccess* createDynamicResultsAccess();
void ensureDynamicResultAccessIsPresent();
QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector<size_t>& keywordDataItemCounts, const RigActiveCellInfo* activeCellInfo, const RigActiveCellInfo* fractureActiveCellInfo, RiaDefines::PorosityModelType matrixOrFracture, size_t timeStepCount) const;
std::vector<RigEclipseTimeStepInfo> createFilteredTimeStepInfos();
static bool isEclipseAndSoursimTimeStepsEqual(const QDateTime& dt1, const QDateTime& dt2);
private:
QString m_fileName; // Name of file used to start accessing Eclipse output files
QStringList m_filesWithSameBaseName; // Set of files in filename's path with same base name as filename

View File

@ -37,17 +37,18 @@
#include "RimEclipsePropertyFilter.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseView.h"
#include "RimFormationNames.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimProject.h"
#include "RimMainPlotCollection.h"
#include "RimWellLogPlotCollection.h"
#include "RimSummaryPlotCollection.h"
#include "RimFlowPlotCollection.h"
#include "RimWellLogPlot.h"
#include "RimSummaryPlot.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimFlowPlotCollection.h"
#include "RimFormationNames.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimTools.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogPlotCollection.h"
#include "cafPdmDocument.h"
#include "cafProgressInfo.h"
@ -435,42 +436,7 @@ void RimEclipseCase::createTimeStepFormatString()
{
std::vector<QDateTime> timeStepDates = this->timeStepDates();
bool hasHoursAndMinutesInTimesteps = false;
bool hasSecondsInTimesteps = false;
bool hasMillisecondsInTimesteps = false;
for (size_t i = 0; i < timeStepDates.size(); i++)
{
if (timeStepDates[i].time().msec() != 0.0)
{
hasMillisecondsInTimesteps = true;
hasSecondsInTimesteps = true;
hasHoursAndMinutesInTimesteps = true;
break;
}
else if (timeStepDates[i].time().second() != 0.0)
{
hasHoursAndMinutesInTimesteps = true;
hasSecondsInTimesteps = true;
}
else if (timeStepDates[i].time().hour() != 0.0 || timeStepDates[i].time().minute() != 0.0)
{
hasHoursAndMinutesInTimesteps = true;
}
}
m_timeStepFormatString = "dd.MMM yyyy";
if (hasHoursAndMinutesInTimesteps)
{
m_timeStepFormatString += " - hh:mm";
if (hasSecondsInTimesteps)
{
m_timeStepFormatString += ":ss";
if (hasMillisecondsInTimesteps)
{
m_timeStepFormatString += ".zzz";
}
}
}
m_timeStepFormatString = RimTools::createTimeFormatStringFromDates(timeStepDates);
}
//--------------------------------------------------------------------------------------------------
@ -582,10 +548,6 @@ void RimEclipseCase::setFilesContainingFaults(const std::vector<QString>& val)
//--------------------------------------------------------------------------------------------------
bool RimEclipseCase::openReserviorCase()
{
// If read already, return
if (this->eclipseCaseData() != NULL) return true;
if (!openEclipseGridFile())
{
return false;
@ -593,7 +555,7 @@ bool RimEclipseCase::openReserviorCase()
{
RimReservoirCellResultsStorage* results = this->results(RiaDefines::MATRIX_MODEL);
if (results->cellResults())
if (results && results->cellResults())
{
results->cellResults()->createPlaceholderResultEntries();
// After the placeholder result for combined transmissibility is created,
@ -621,9 +583,13 @@ bool RimEclipseCase::openReserviorCase()
}
}
{
RimReservoirCellResultsStorage* results = this->results(RiaDefines::FRACTURE_MODEL);
if (results->cellResults()) results->cellResults()->createPlaceholderResultEntries();
if (results && results->cellResults())
{
results->cellResults()->createPlaceholderResultEntries();
}
}
createTimeStepFormatString();

View File

@ -93,11 +93,19 @@ RimEclipseResultCase::RimEclipseResultCase()
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultCase::openEclipseGridFile()
{
caf::ProgressInfo progInfo(50, "Reading Eclipse Grid File");
return importGridAndResultMetaData(false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultCase::importGridAndResultMetaData(bool showTimeStepFilter)
{
caf::ProgressInfo progInfo(50, "Reading Eclipse Grid File");
progInfo.setProgressDescription("Open Grid File");
progInfo.setNextProgressIncrement(48);
progInfo.setProgressDescription("Open Grid File");
progInfo.setNextProgressIncrement(48);
// Early exit if data is already read
if (m_gridAndWellDataIsReadFromFile) return true;
@ -115,24 +123,59 @@ bool RimEclipseResultCase::openEclipseGridFile()
}
RiaPreferences* prefs = RiaApplication::instance()->preferences();
readerInterface = new RifReaderEclipseOutput;
readerInterface->setReaderSetting(prefs->readerSettings());
readerInterface->setFilenamesWithFaults(this->filesContainingFaults());
cvf::ref<RifReaderEclipseOutput> readerEclipseOutput = new RifReaderEclipseOutput;
readerEclipseOutput->setReaderSetting(prefs->readerSettings());
readerEclipseOutput->setFilenamesWithFaults(this->filesContainingFaults());
if (!m_timeStepFilter->timeStepIndicesToImport().empty())
if (showTimeStepFilter)
{
readerInterface->setTimeStepFilter(m_timeStepFilter->timeStepIndicesToImport());
cvf::ref<RifEclipseRestartDataAccess> restartDataAccess = RifEclipseOutputFileTools::createDynamicResultAccess(caseFileName());
if (restartDataAccess.isNull())
{
return false;
}
{
std::vector<QDateTime> timeSteps;
std::vector<double> daysSinceSimulationStart;
restartDataAccess->timeSteps(&timeSteps, &daysSinceSimulationStart);
// Show GUI to select time steps
RimTimeStepFilter myTimeStepFilter;
myTimeStepFilter.setCustomTimeSteps(timeSteps);
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &myTimeStepFilter, "Time Step Filter", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
propertyDialog.resize(QSize(400, 200));
if (propertyDialog.exec() != QDialog::Accepted)
{
return false;
}
m_timeStepFilter->setSelectedTimeStepIndices(myTimeStepFilter.selectedTimeStepIndices());
}
readerEclipseOutput->setFileDataAccess(restartDataAccess.p());
}
if (!m_timeStepFilter->selectedTimeStepIndices().empty())
{
readerEclipseOutput->setTimeStepFilter(m_timeStepFilter->selectedTimeStepIndices());
}
cvf::ref<RigEclipseCaseData> eclipseCase = new RigEclipseCaseData;
if (!readerInterface->open(caseFileName(), eclipseCase.p()))
if (!readerEclipseOutput->open(caseFileName(), eclipseCase.p()))
{
return false;
}
this->setFilesContainingFaults(readerInterface->filenamesWithFaults());
this->setFilesContainingFaults(readerEclipseOutput->filenamesWithFaults());
this->setReservoirData( eclipseCase.p() );
this->setReservoirData(eclipseCase.p());
readerInterface = readerEclipseOutput;
}
results(RiaDefines::MATRIX_MODEL)->setReaderInterface(readerInterface.p());
@ -163,7 +206,7 @@ bool RimEclipseResultCase::openEclipseGridFile()
}
return true;
}
}
//--------------------------------------------------------------------------------------------------
///

View File

@ -46,6 +46,9 @@ public:
bool hasSourSimFile();
virtual bool openEclipseGridFile();
bool importGridAndResultMetaData(bool showTimeStepFilter);
virtual void reloadEclipseGridFile();
bool openAndReadActiveCellData(RigEclipseCaseData* mainEclipseCase);
void readGridDimensions(std::vector< std::vector<int> >& gridDimensions);

View File

@ -18,6 +18,11 @@
#include "RimTimeStepFilter.h"
#include "RimCase.h"
#include "RimTools.h"
#include <QDateTime>
CAF_PDM_SOURCE_INIT(RimTimeStepFilter, "TimeStepFilter");
//--------------------------------------------------------------------------------------------------
@ -27,21 +32,76 @@ RimTimeStepFilter::RimTimeStepFilter()
{
CAF_PDM_InitObject("Time Step Filter", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_timeStepIndicesToImport, "TimeStepIndicesToImport", "Values", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_selectedTimeStepIndices, "TimeStepIndicesToImport", "Values", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RimTimeStepFilter::timeStepIndicesToImport() const
void RimTimeStepFilter::setCustomTimeSteps(const std::vector<QDateTime>& timeSteps)
{
m_customTimeSteps = timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RimTimeStepFilter::selectedTimeStepIndices() const
{
std::vector<size_t> indices;
// Convert vector from int to size_t
for (auto intValue : m_timeStepIndicesToImport.v())
for (auto intValue : m_selectedTimeStepIndices.v())
{
indices.push_back(intValue);
}
return indices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTimeStepFilter::setSelectedTimeStepIndices(const std::vector<size_t>& indices)
{
m_selectedTimeStepIndices.v().clear();
for (auto sizetValue : indices)
{
m_selectedTimeStepIndices.v().push_back(static_cast<int>(sizetValue));
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimTimeStepFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> optionItems;
if (fieldNeedingOptions == &m_selectedTimeStepIndices)
{
RimCase* rimCase = nullptr;
this->firstAncestorOrThisOfType(rimCase);
if (rimCase)
{
QStringList timeSteps = rimCase->timeStepStrings();
for (int i = 0; i < timeSteps.size(); i++)
{
optionItems.push_back(caf::PdmOptionItemInfo(timeSteps[i], static_cast<int>(i)));
}
}
else
{
QString formatString = RimTools::createTimeFormatStringFromDates(m_customTimeSteps);
for (size_t i = 0; i < m_customTimeSteps.size(); i++)
{
optionItems.push_back(caf::PdmOptionItemInfo(m_customTimeSteps[i].toString(formatString), static_cast<int>(i)));
}
}
}
return optionItems;
}

View File

@ -23,6 +23,8 @@
#include <vector>
class QDateTime;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -32,9 +34,15 @@ class RimTimeStepFilter : public caf::PdmObject
public:
RimTimeStepFilter();
std::vector<size_t> timeStepIndicesToImport() const;
void setCustomTimeSteps(const std::vector<QDateTime>& timeSteps);
std::vector<size_t> selectedTimeStepIndices() const;
void setSelectedTimeStepIndices(const std::vector<size_t>& indices);
private:
caf::PdmField< std::vector<int> > m_timeStepIndicesToImport;
};
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
private:
caf::PdmField< std::vector<int> > m_selectedTimeStepIndices;
std::vector<QDateTime> m_customTimeSteps;
};

View File

@ -34,6 +34,7 @@
#include <QFileInfo>
#include <QDir>
#include <QDateTime>
//--------------------------------------------------------------------------------------------------
///
@ -259,3 +260,49 @@ void RimTools::caseOptionItems(QList<caf::PdmOptionItemInfo>* options)
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimTools::createTimeFormatStringFromDates(const std::vector<QDateTime>& dates)
{
bool hasHoursAndMinutesInTimesteps = false;
bool hasSecondsInTimesteps = false;
bool hasMillisecondsInTimesteps = false;
for (size_t i = 0; i < dates.size(); i++)
{
if (dates[i].time().msec() != 0.0)
{
hasMillisecondsInTimesteps = true;
hasSecondsInTimesteps = true;
hasHoursAndMinutesInTimesteps = true;
break;
}
else if (dates[i].time().second() != 0.0)
{
hasHoursAndMinutesInTimesteps = true;
hasSecondsInTimesteps = true;
}
else if (dates[i].time().hour() != 0.0 || dates[i].time().minute() != 0.0)
{
hasHoursAndMinutesInTimesteps = true;
}
}
QString formatString = "dd.MMM yyyy";
if (hasHoursAndMinutesInTimesteps)
{
formatString += " - hh:mm";
if (hasSecondsInTimesteps)
{
formatString += ":ss";
if (hasMillisecondsInTimesteps)
{
formatString += ".zzz";
}
}
}
return formatString;
}

View File

@ -25,10 +25,15 @@
#include <vector>
class QDateTime;
namespace caf {
class PdmOptionItemInfo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RimTools
{
public:
@ -38,4 +43,6 @@ public:
static void wellPathOptionItems(QList<caf::PdmOptionItemInfo>* options);
static void caseOptionItems(QList<caf::PdmOptionItemInfo>* options);
static QString createTimeFormatStringFromDates(const std::vector<QDateTime>& dates);
};