From 280656ca2617adfaa82bcfb70a74ab129885fd07 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Mon, 11 Jun 2018 13:47:21 +0200 Subject: [PATCH] #3043 Implement Time step filtering on import for Geomech --- .../Application/RiaApplication.cpp | 14 +- ApplicationCode/Application/RiaApplication.h | 2 +- .../Commands/CMakeLists_files.cmake | 2 + ...ImportGeoMechCaseTimeStepFilterFeature.cpp | 72 +++++ ...icImportGeoMechCaseTimeStepFilterFeature.h | 38 +++ .../RigFemPartResultsCollection.cpp | 10 +- .../RigFemPartResultsCollection.h | 2 +- .../GeoMechDataModel/RigGeoMechCaseData.cpp | 41 ++- .../GeoMechDataModel/RigGeoMechCaseData.h | 5 +- .../OdbReader/RifGeoMechReaderInterface.cpp | 52 ++++ .../OdbReader/RifGeoMechReaderInterface.h | 9 +- .../GeoMech/OdbReader/RifOdbReader.cpp | 49 +++- .../GeoMech/OdbReader/RifOdbReader.h | 7 +- ApplicationCode/ProjectDataModel/RimCase.cpp | 2 +- .../ProjectDataModel/RimEclipseCase.cpp | 17 +- .../ProjectDataModel/RimEclipseResultCase.cpp | 10 +- .../ProjectDataModel/RimGeoMechCase.cpp | 137 +++++++-- .../ProjectDataModel/RimGeoMechCase.h | 11 +- .../RimGeoMechResultDefinition.cpp | 13 +- .../ProjectDataModel/RimTimeStepFilter.cpp | 274 +++++++++++------- .../ProjectDataModel/RimTimeStepFilter.h | 40 +-- .../UserInterface/RiuMainWindow.cpp | 12 +- ApplicationCode/UserInterface/RiuMainWindow.h | 6 +- 23 files changed, 616 insertions(+), 209 deletions(-) create mode 100644 ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.cpp create mode 100644 ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.h diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index fe99f64cce..bbf4946c09 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -1077,7 +1077,7 @@ QString RiaApplication::createAbsolutePathFromProjectRelativePath(QString projec //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RiaApplication::openOdbCaseFromFile(const QString& fileName) +bool RiaApplication::openOdbCaseFromFile(const QString& fileName, bool applyTimeStepFilter) { if (!caf::Utils::fileExists(fileName)) return false; @@ -1087,7 +1087,8 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName) RimGeoMechCase* geoMechCase = new RimGeoMechCase(); geoMechCase->setFileName(fileName); geoMechCase->caseUserDescription = caseName; - + geoMechCase->setApplyTimeFilter(applyTimeStepFilter); + RimGeoMechModels* geoMechModelCollection = m_project->activeOilField() ? m_project->activeOilField()->geoMechModels() : nullptr; // Create the geoMech model container if it is not there already @@ -1097,14 +1098,19 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName) m_project->activeOilField()->geoMechModels = geoMechModelCollection; } - geoMechModelCollection->cases.push_back(geoMechCase); - RimGeoMechView* riv = geoMechCase->createAndAddReservoirView(); caf::ProgressInfo progress(11, "Loading Case"); progress.setNextProgressIncrement(10); riv->loadDataAndUpdate(); + if (!riv->geoMechCase()) + { + delete geoMechCase; + return false; + } + geoMechModelCollection->cases.push_back(geoMechCase); + //if (!riv->cellResult()->hasResult()) //{ // riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName()); diff --git a/ApplicationCode/Application/RiaApplication.h b/ApplicationCode/Application/RiaApplication.h index 0d538520c8..c1b5299e74 100644 --- a/ApplicationCode/Application/RiaApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -120,7 +120,7 @@ public: bool openFile(const QString& fileName); - bool openOdbCaseFromFile(const QString& fileName); + bool openOdbCaseFromFile(const QString& fileName, bool applyTimeStepFilter = false); QString currentProjectPath() const; QString createAbsolutePathFromProjectRelativePath(QString projectRelativePath); diff --git a/ApplicationCode/Commands/CMakeLists_files.cmake b/ApplicationCode/Commands/CMakeLists_files.cmake index ea1f4736cd..e29002127c 100644 --- a/ApplicationCode/Commands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/CMakeLists_files.cmake @@ -36,6 +36,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicWellLogsImportFileFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicTogglePerspectiveViewFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCaseFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCasesFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataFeature.h @@ -106,6 +107,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSelectColorResult.cpp ${CMAKE_CURRENT_LIST_DIR}/RicTogglePerspectiveViewFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCaseFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCasesFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataFeature.cpp diff --git a/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.cpp b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.cpp new file mode 100644 index 0000000000..a29077cc76 --- /dev/null +++ b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.cpp @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicImportGeoMechCaseTimeStepFilterFeature.h" + +#include "RiaApplication.h" +#include "RiaImportEclipseCaseTools.h" + +#include "Riu3DMainWindowTools.h" + +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicImportGeoMechCaseTimeStepFilterFeature, "RicImportGeoMechCaseTimeStepFilterFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportGeoMechCaseTimeStepFilterFeature::onActionTriggered(bool isChecked) +{ + RiaApplication* app = RiaApplication::instance(); + + QString defaultDir = app->lastUsedDialogDirectory("GEOMECH_MODEL"); + QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, "Import Geo-Mechanical Model", defaultDir, "Abaqus results (*.odb)"); + if (fileNames.size()) defaultDir = QFileInfo(fileNames.last()).absolutePath(); + for (QString fileName : fileNames) + { + if (!fileName.isEmpty()) + { + defaultDir = QFileInfo(fileName).absolutePath(); + app->setLastUsedDialogDirectory("GEOMECH_MODEL", defaultDir); + if (app->openOdbCaseFromFile(fileName, true)) + { + app->addToRecentFiles(fileName); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportGeoMechCaseTimeStepFilterFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/GeoMechCase48x48.png")); + actionToSetup->setText("Import Geo Mechanical Model (Time Step Filtered)"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicImportGeoMechCaseTimeStepFilterFeature::isCommandEnabled() +{ + return true; +} diff --git a/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.h b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.h new file mode 100644 index 0000000000..1a3c771feb --- /dev/null +++ b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicImportGeoMechCaseTimeStepFilterFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + virtual void onActionTriggered(bool isChecked) override; + virtual void setupActionLook(QAction* actionToSetup) override; + virtual bool isCommandEnabled() override; +}; + + diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp index e677459d31..82c052d080 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp @@ -90,11 +90,11 @@ RigFemPartResultsCollection::RigFemPartResultsCollection(RifGeoMechReaderInterfa m_femParts = femPartCollection; m_femPartResults.resize(m_femParts->partCount()); - std::vector stepNames = m_readerInterface->stepNames(); + std::vector filteredStepNames = m_readerInterface->filteredStepNames(); for (auto & femPartResult : m_femPartResults) { femPartResult = new RigFemPartResults; - femPartResult->initResultSteps(stepNames); + femPartResult->initResultSteps(filteredStepNames); } m_cohesion = 10.0; @@ -2150,10 +2150,10 @@ std::vector< RigFemResultAddress> RigFemPartResultsCollection::getResAddrToCompo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigFemPartResultsCollection::stepNames() const +std::vector RigFemPartResultsCollection::filteredStepNames() const { CVF_ASSERT(m_readerInterface.notNull()); - return m_readerInterface->stepNames(); + return m_readerInterface->filteredStepNames(); } //-------------------------------------------------------------------------------------------------- @@ -2161,7 +2161,7 @@ std::vector RigFemPartResultsCollection::stepNames() const //-------------------------------------------------------------------------------------------------- int RigFemPartResultsCollection::frameCount() { - return static_cast(stepNames().size()); + return static_cast(filteredStepNames().size()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h index 63c601c009..5a4ee4acd0 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h @@ -64,7 +64,7 @@ public: double parameterFrictionAngleRad() const { return m_frictionAngleRad; } std::map > scalarFieldAndComponentNames(RigFemResultPosEnum resPos); - std::vector stepNames() const; + std::vector filteredStepNames() const; bool assertResultsLoaded(const RigFemResultAddress& resVarAddr); void deleteResult(const RigFemResultAddress& resVarAddr); diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp index a354b73ad0..003ee30269 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp @@ -88,17 +88,48 @@ RigFemPartResultsCollection* RigGeoMechCaseData::femPartResults() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool RigGeoMechCaseData::openAndReadFemParts(std::string* errorMessage) +bool RigGeoMechCaseData::open(std::string* errorMessage) { - #ifdef USE_ODB_API m_readerInterface = new RifOdbReader; #endif if (m_readerInterface.notNull() && m_readerInterface->openFile(m_geoMechCaseFileName, errorMessage)) { + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGeoMechCaseData::readTimeSteps(std::string* errorMessage, std::vector* stepNames) +{ + CVF_ASSERT(stepNames); +#ifdef USE_ODB_API + if (m_readerInterface.notNull() && m_readerInterface->isOpen()) + { + *stepNames = m_readerInterface->allStepNames(); + return true; + } +#endif + *errorMessage = std::string("Could not read time steps"); + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGeoMechCaseData::readFemParts(std::string* errorMessage, const std::vector& timeStepFilter) +{ + CVF_ASSERT(errorMessage); +#ifdef USE_ODB_API + if (m_readerInterface.notNull() && m_readerInterface->isOpen()) + { + m_readerInterface->setTimeStepFilter(timeStepFilter); m_femParts = new RigFemPartCollection(); caf::ProgressInfo progress(10, ""); // Here because the next call uses progress @@ -117,9 +148,11 @@ bool RigGeoMechCaseData::openAndReadFemParts(std::string* errorMessage) { m_femParts->part(pIdx)->assertNodeToElmIndicesIsCalculated(); m_femParts->part(pIdx)->assertElmNeighborsIsCalculated(); - } + } return true; } } +#endif + *errorMessage = std::string("Could not read FEM parts"); return false; } diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h index c76749e029..27a7ce14c9 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h @@ -39,8 +39,9 @@ public: explicit RigGeoMechCaseData(const std::string& fileName); ~RigGeoMechCaseData(); - bool openAndReadFemParts(std::string* errorMessage); - + bool open(std::string* errorMessage); + bool readTimeSteps(std::string* errorMessage, std::vector* stepNames); + bool readFemParts(std::string* errorMessage, const std::vector& timeStepFilter = std::vector()); RigFemPartCollection* femParts(); const RigFemPartCollection* femParts() const; diff --git a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp index 84c784f9fd..e330453867 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp +++ b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp @@ -36,3 +36,55 @@ RifGeoMechReaderInterface::~RifGeoMechReaderInterface() { } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifGeoMechReaderInterface::setTimeStepFilter(const std::vector& fileTimeStepIndices) +{ + m_fileTimeStepIndices.reserve(fileTimeStepIndices.size()); + for (size_t stepIndex : fileTimeStepIndices) + { + m_fileTimeStepIndices.push_back(static_cast(stepIndex)); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifGeoMechReaderInterface::isTimeStepIncludedByFilter(int timeStepIndex) const +{ + CVF_ASSERT(timeStepIndex >= 0); + if (m_fileTimeStepIndices.empty()) return true; + + for (auto i : m_fileTimeStepIndices) + { + if (i == static_cast(timeStepIndex)) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifGeoMechReaderInterface::timeStepIndexOnFile(int timeStepIndex) const +{ + if (m_fileTimeStepIndices.empty()) + { + return timeStepIndex; + } + CVF_ASSERT(timeStepIndex >= 0); + CVF_ASSERT(static_cast(timeStepIndex) < m_fileTimeStepIndices.size()); + + if (static_cast(timeStepIndex) < m_fileTimeStepIndices.size()) + { + return static_cast(m_fileTimeStepIndices[timeStepIndex]); + } + + return timeStepIndex; +} \ No newline at end of file diff --git a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h index 6ec6370e65..10ade9ac64 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h +++ b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h @@ -42,9 +42,10 @@ public: virtual ~RifGeoMechReaderInterface(); virtual bool openFile(const std::string& fileName, std::string* errorMessage) = 0; - + virtual bool isOpen() const = 0; virtual bool readFemParts(RigFemPartCollection* geoMechCase) = 0; - virtual std::vector stepNames() const = 0; + virtual std::vector allStepNames() const = 0; + virtual std::vector filteredStepNames() const = 0; virtual std::vector frameTimes(int stepIndex) const = 0; virtual std::vector elementSetNames(int partIndex) = 0; @@ -60,5 +61,9 @@ public: virtual void readElementNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) = 0; virtual void readIntegrationPointField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) = 0; + void setTimeStepFilter(const std::vector& fileTimeStepIndices); + bool isTimeStepIncludedByFilter(int timeStepIndex) const; + int timeStepIndexOnFile(int timeStepIndex) const; private: + std::vector m_fileTimeStepIndices; }; diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp index f2844f7c2f..c31676cd99 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp @@ -234,6 +234,14 @@ bool RifOdbReader::openFile(const std::string& fileName, std::string* errorMessa } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifOdbReader::isOpen() const +{ + return m_odb != NULL; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -422,7 +430,7 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RifOdbReader::stepNames() const +std::vector RifOdbReader::allStepNames() const { CVF_ASSERT(m_odb != NULL); @@ -430,9 +438,34 @@ std::vector RifOdbReader::stepNames() const odb_StepRepository stepRepository = m_odb->steps(); odb_StepRepositoryIT sIter(stepRepository); - for (sIter.first(); !sIter.isDone(); sIter.next()) + for (sIter.first(); !sIter.isDone(); sIter.next()) { - stepNames.push_back(stepRepository[sIter.currentKey()].name().CStr()); + std::string stepName(sIter.currentValue().name().CStr()); + stepNames.push_back(stepName); + } + + return stepNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifOdbReader::filteredStepNames() const +{ + CVF_ASSERT(m_odb != NULL); + + std::vector stepNames; + + odb_StepRepository stepRepository = m_odb->steps(); + odb_StepRepositoryIT sIter(stepRepository); + int stepIndex = 0; + for (sIter.first(); !sIter.isDone(); sIter.next()) + { + std::string stepName(sIter.currentValue().name().CStr()); + if (this->isTimeStepIncludedByFilter(stepIndex++)) + { + stepNames.push_back(stepName); + } } return stepNames; @@ -449,7 +482,10 @@ std::vector RifOdbReader::frameTimes(int stepIndex) const odb_StepRepository& stepRepository = m_odb->steps(); odb_StepList stepList = stepRepository.stepList(); - odb_Step& step = stepList.Get(stepIndex); + + int stepFileIndex = this->timeStepIndexOnFile(stepIndex); + + odb_Step& step = stepList.Get(stepFileIndex); odb_SequenceFrame& stepFrames = step.frames(); @@ -573,7 +609,10 @@ const odb_Frame& RifOdbReader::stepFrame(int stepIndex, int frameIndex) const const odb_StepRepository& stepRepository = m_odb->steps(); const odb_StepList& stepList = stepRepository.stepList(); - const odb_Step& step = stepList.ConstGet(stepIndex); + + int stepFileIndex = this->timeStepIndexOnFile(stepIndex); + + const odb_Step& step = stepList.ConstGet(stepFileIndex); const odb_SequenceFrame& stepFrames = step.frames(); return stepFrames.constGet(frameIndex); diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h index 6e2df2008d..bd8675c5e6 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h @@ -42,9 +42,10 @@ public: virtual ~RifOdbReader(); virtual bool openFile(const std::string& fileName, std::string* errorMessage); - + virtual bool isOpen() const; virtual bool readFemParts(RigFemPartCollection* geoMechCase); - virtual std::vector stepNames() const override; + virtual std::vector allStepNames() const override; + virtual std::vector filteredStepNames() const override; virtual std::vector frameTimes(int stepIndex) const override; virtual std::vector elementSetNames(int partIndex); @@ -93,7 +94,7 @@ private: size_t resultItemCount(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex); size_t componentsCount(const std::string& fieldName, ResultPosition position); const odb_Frame& stepFrame(int stepIndex, int frameIndex) const; - odb_Instance* instance(int instanceIndex); + odb_Instance* instance(int instanceIndex); int componentIndex(const RifOdbResultKey& result, const std::string& componentName); std::vector componentNames(const RifOdbResultKey& result); diff --git a/ApplicationCode/ProjectDataModel/RimCase.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp index ee0ce66da0..c0f221c39b 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -121,7 +121,7 @@ void RimCase::setFormationNames(RimFormationNames* formationNames) //-------------------------------------------------------------------------------------------------- size_t RimCase::uiToNativeTimeStepIndex(size_t uiTimeStepIndex) { - std::vector nativeTimeIndices = m_timeStepFilter->filteredNativeTimeStepIndices(); + std::vector nativeTimeIndices = m_timeStepFilter->filteredTimeSteps(); if (nativeTimeIndices.size() > 0) { diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index 04e6ea9c39..a6b1ba3c7f 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -823,11 +823,12 @@ QStringList RimEclipseCase::timeStepStrings() const QString RimEclipseCase::timeStepName(int frameIdx) const { std::vector timeStepDates = this->timeStepDates(); - CVF_ASSERT(frameIdx < static_cast(timeStepDates.size())); - - QDateTime date = timeStepDates.at(frameIdx); - - return date.toString(m_timeStepFormatString); + if (frameIdx < static_cast(timeStepDates.size())) + { + QDateTime date = timeStepDates.at(frameIdx); + return date.toString(m_timeStepFormatString); + } + return QString(""); } //-------------------------------------------------------------------------------------------------- @@ -929,5 +930,9 @@ void RimEclipseCase::setFormationNames(RimFormationNames* formationNames) //-------------------------------------------------------------------------------------------------- std::vector RimEclipseCase::timeStepDates() const { - return results(RiaDefines::MATRIX_MODEL)->timeStepDates(); + if (results(RiaDefines::MATRIX_MODEL)) + { + return results(RiaDefines::MATRIX_MODEL)->timeStepDates(); + } + return std::vector(); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp index 28c0c2d5a0..9bdf7a5702 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -159,19 +159,15 @@ bool RimEclipseResultCase::importGridAndResultMetaData(bool showTimeStepFilter) { return false; } - - m_timeStepFilter->clearTimeStepsFromFile(); - + m_timeStepFilter->updateFilteredTimeStepsFromUi(); // Set cursor in wait state to continue display of progress dialog including // wait cursor QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); } - readerEclipseOutput->setFileDataAccess(restartDataAccess.p()); } - - readerEclipseOutput->setTimeStepFilter(m_timeStepFilter->filteredNativeTimeStepIndices()); - + readerEclipseOutput->setTimeStepFilter(m_timeStepFilter->filteredTimeSteps()); + cvf::ref eclipseCase = new RigEclipseCaseData(this); if (!readerEclipseOutput->open(caseFileName(), eclipseCase.p())) { diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp index 2e4dd648f1..806430d612 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp @@ -20,6 +20,7 @@ #include "RimGeoMechCase.h" #include "RiaApplication.h" +#include "RiaLogging.h" #include "RiaPreferences.h" #include "RifOdbReader.h" @@ -39,9 +40,11 @@ #include "RimIntersectionCollection.h" #include "RimMainPlotCollection.h" #include "RimProject.h" +#include "RimTimeStepFilter.h" #include "RimTools.h" #include "RimWellLogPlotCollection.h" +#include "cafPdmUiPropertyViewDialog.h" #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiTreeOrdering.h" #include "cafUtils.h" @@ -54,6 +57,7 @@ CAF_PDM_SOURCE_INIT(RimGeoMechCase, "ResInsightGeoMechCase"); /// //-------------------------------------------------------------------------------------------------- RimGeoMechCase::RimGeoMechCase(void) + : m_applyTimeFilter(false) { CAF_PDM_InitObject("Geomechanical Case", ":/GeoMechCase48x48.png", "", ""); @@ -136,6 +140,27 @@ const RigGeoMechCaseData* RimGeoMechCase::geoMechData() const return m_geoMechCaseData.p(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechCase::reloadDataAndUpdate() +{ + if (this->geoMechData()) + { + m_geoMechCaseData = nullptr; + std::string errMsg; + if (!this->openGeoMechCase(&errMsg)) + { + RiaLogging::error(QString::fromStdString(errMsg)); + } + for (auto v : geoMechViews()) + { + v->loadDataAndUpdate(); + v->setCurrentTimeStep(v->currentTimeStep()); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -164,35 +189,69 @@ bool RimGeoMechCase::openGeoMechCase(std::string* errorMessage) return false; } - m_geoMechCaseData = new RigGeoMechCaseData(m_caseFileName().path().toStdString()); - - bool fileOpenSuccess = m_geoMechCaseData->openAndReadFemParts(errorMessage); + cvf::ref geoMechCaseData = new RigGeoMechCaseData(m_caseFileName().path().toStdString()); + bool fileOpenSuccess = geoMechCaseData->open(errorMessage); + if (!fileOpenSuccess) + { + return false; + } + + std::vector stepNames; + if (!geoMechCaseData->readTimeSteps(errorMessage, &stepNames)) + { + return false; + } + + std::vector> timeSteps; + for (const std::string& timeStepStringStdString : stepNames) + { + QString timeStepString = QString::fromStdString(timeStepStringStdString); + timeSteps.push_back(std::make_pair(timeStepString, dateTimeFromTimeStepString(timeStepString))); + } + + m_timeStepFilter->setTimeStepsFromFile(timeSteps); + + if (m_applyTimeFilter) + { + m_applyTimeFilter = false; // Clear when we've done this once. + + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, m_timeStepFilter, "Time Step Filter", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + propertyDialog.resize(QSize(400, 400)); + + QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); + if (propertyDialog.exec() != QDialog::Accepted) + { + return false; + } + m_timeStepFilter->updateFilteredTimeStepsFromUi(); + QApplication::restoreOverrideCursor(); + } + + // Continue reading the open file + fileOpenSuccess = geoMechCaseData->readFemParts(errorMessage, m_timeStepFilter->filteredTimeSteps()); + if (!fileOpenSuccess) { - // If opening failed, release all data - // Also, several places is checked for this data to validate availability of data - m_geoMechCaseData = nullptr; return false; } if (activeFormationNames()) { - m_geoMechCaseData->femPartResults()->setActiveFormationNames(activeFormationNames()->formationNamesData()); + geoMechCaseData->femPartResults()->setActiveFormationNames(activeFormationNames()->formationNamesData()); } else { - m_geoMechCaseData->femPartResults()->setActiveFormationNames(nullptr); + geoMechCaseData->femPartResults()->setActiveFormationNames(nullptr); } - if (m_geoMechCaseData.notNull()) + std::vector fileNames; + for (const caf::FilePath& fileName : m_elementPropertyFileNames.v()) { - std::vector fileNames; - for (const caf::FilePath& fileName : m_elementPropertyFileNames.v()) - { - fileNames.push_back(fileName.path()); - } - geoMechData()->femPartResults()->addElementPropertyFiles(fileNames); + fileNames.push_back(fileName.path()); } + geoMechCaseData->femPartResults()->addElementPropertyFiles(fileNames); + + m_geoMechCaseData = geoMechCaseData; return fileOpenSuccess; } @@ -244,7 +303,7 @@ std::vector RimGeoMechCase::timeStepDates() const { QStringList timeStrings = timeStepStrings(); - return RimGeoMechCase::dateTimeVectorFromTimeStepStrings(timeStrings); + return RimGeoMechCase::vectorOfValidDateTimesFromTimeStepStrings(timeStrings); } //-------------------------------------------------------------------------------------------------- @@ -273,7 +332,7 @@ QStringList RimGeoMechCase::timeStepStrings() const const RigGeoMechCaseData* rigCaseData = geoMechData(); if (rigCaseData && rigCaseData->femPartResults()) { - std::vector stepNames = rigCaseData->femPartResults()->stepNames(); + std::vector stepNames = rigCaseData->femPartResults()->filteredStepNames(); for (size_t i = 0; i < stepNames.size(); i++) { stringList += QString::fromStdString(stepNames[i]); @@ -291,9 +350,11 @@ QString RimGeoMechCase::timeStepName(int frameIdx) const const RigGeoMechCaseData* rigCaseData = geoMechData(); if (rigCaseData && rigCaseData->femPartResults()) { - std::vector stepNames = rigCaseData->femPartResults()->stepNames(); - - return QString::fromStdString(stepNames[frameIdx]); + std::vector stepNames = rigCaseData->femPartResults()->filteredStepNames(); + if (frameIdx < static_cast(stepNames.size())) + { + return QString::fromStdString(stepNames[frameIdx]); + } } return ""; @@ -399,6 +460,14 @@ double RimGeoMechCase::frictionAngleDeg() const return m_frictionAngleDeg; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechCase::setApplyTimeFilter(bool applyTimeFilter) +{ + m_applyTimeFilter = applyTimeFilter; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -410,19 +479,15 @@ cvf::Vec3d RimGeoMechCase::displayModelOffset() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimGeoMechCase::dateTimeVectorFromTimeStepStrings(const QStringList& timeStepStrings) +std::vector RimGeoMechCase::vectorOfValidDateTimesFromTimeStepStrings(const QStringList& timeStepStrings) { std::vector dates; - QString dateFormat = "ddMMyyyy"; + QString dateFormat = "yyyyMMdd"; - for (int i = 0; i < timeStepStrings.size(); i++) + for (const QString& timeStepString : timeStepStrings) { - QString timeStepString = timeStepStrings[i]; - - QString dateStr = subStringOfDigits(timeStepString, dateFormat.size()); - - QDateTime dateTime = QDateTime::fromString(dateStr, dateFormat); + QDateTime dateTime = dateTimeFromTimeStepString(timeStepString); if (dateTime.isValid()) { dates.push_back(dateTime); @@ -432,6 +497,16 @@ std::vector RimGeoMechCase::dateTimeVectorFromTimeStepStrings(const Q return dates; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QDateTime RimGeoMechCase::dateTimeFromTimeStepString(const QString& timeStepString) +{ + QString dateFormat = "yyyyMMdd"; + QString dateStr = subStringOfDigits(timeStepString, dateFormat.size()); + return QDateTime::fromString(dateStr, dateFormat); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -661,6 +736,12 @@ void RimGeoMechCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& elmPropGroup->add(&m_elementPropertyFileNameIndexUiSelection); elmPropGroup->add(&m_reloadElementPropertyFileCommand); elmPropGroup->add(&m_closeElementPropertyFileCommand); + + + caf::PdmUiGroup* timeStepFilterGroup = uiOrdering.addNewGroup("Time Step Filter"); + timeStepFilterGroup->setCollapsedByDefault(true); + m_timeStepFilter->uiOrdering(uiConfigName, *timeStepFilterGroup); + } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h index 3caae63564..021a26649c 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h @@ -54,6 +54,8 @@ public: RigGeoMechCaseData* geoMechData(); const RigGeoMechCaseData* geoMechData() const; + void reloadDataAndUpdate(); + RimGeoMechView* createAndAddReservoirView(); virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath); @@ -74,16 +76,14 @@ public: double cohesion() const; double frictionAngleDeg() const; + void setApplyTimeFilter(bool applyTimeFilter); // Fields: caf::PdmChildArrayField geoMechViews; - - - - private: virtual cvf::Vec3d displayModelOffset() const override; - static std::vector dateTimeVectorFromTimeStepStrings(const QStringList& timeStepStrings); + static std::vector vectorOfValidDateTimesFromTimeStepStrings(const QStringList& timeStepStrings); + static QDateTime dateTimeFromTimeStepString(const QString& timeStepString); virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; @@ -109,4 +109,5 @@ private: caf::PdmField > m_elementPropertyFileNameIndexUiSelection; caf::PdmField m_closeElementPropertyFileCommand; caf::PdmField m_reloadElementPropertyFileCommand; + bool m_applyTimeFilter; }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp index 1c2352daf3..50080f9183 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp @@ -208,7 +208,7 @@ QList RimGeoMechResultDefinition::calculateValueOptions( std::vector stepNames; if(m_geomCase->geoMechData()) { - stepNames = m_geomCase->geoMechData()->femPartResults()->stepNames(); + stepNames = m_geomCase->geoMechData()->femPartResults()->filteredStepNames(); } for (size_t stepIdx = 0; stepIdx < stepNames.size(); ++stepIdx) @@ -531,7 +531,16 @@ RigGeoMechCaseData* RimGeoMechResultDefinition::ownerCaseData() //-------------------------------------------------------------------------------------------------- bool RimGeoMechResultDefinition::hasResult() { - return ownerCaseData()->femPartResults()->assertResultsLoaded(this->resultAddress()); + RigGeoMechCaseData* caseData = ownerCaseData(); + if (caseData) + { + RigFemPartResultsCollection* results = caseData->femPartResults(); + if (results) + { + return results->assertResultsLoaded(this->resultAddress()); + } + } + return false; } diff --git a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp index d11262f34e..689175ae20 100644 --- a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp @@ -19,16 +19,19 @@ #include "RimTimeStepFilter.h" #include "RifReaderEclipseOutput.h" +#include "RigCaseCellResultsData.h" #include "RimEclipseResultCase.h" +#include "RimGeoMechCase.h" #include "RimReservoirCellResultsStorage.h" #include "RimTools.h" +#include "cafPdmUiListEditor.h" #include "cafPdmUiPushButtonEditor.h" -#include "cafPdmUiTextEditor.h" #include -#include "RigCaseCellResultsData.h" + +#include namespace caf { @@ -57,22 +60,24 @@ RimTimeStepFilter::RimTimeStepFilter() { CAF_PDM_InitObject("Time Step Filter", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_selectedTimeStepIndices, "TimeStepIndicesToImport", "Values", "", "", ""); + caf::AppEnum< RimTimeStepFilter::TimeStepFilterTypeEnum > filterType = TS_ALL; + CAF_PDM_InitField(&m_filterType, "FilterType", filterType, "Filter Type", "", "", ""); CAF_PDM_InitField(&m_firstTimeStep, "FirstTimeStep", 0, "First Time Step", "", "", ""); CAF_PDM_InitField(&m_lastTimeStep, "LastTimeStep", 0, "Last Time Step", "", "", ""); - caf::AppEnum< RimTimeStepFilter::TimeStepFilterTypeEnum > filterType = TS_ALL; - CAF_PDM_InitField(&m_filterType, "FilterType", filterType, "Filter Type", "", "", ""); - CAF_PDM_InitField(&m_interval, "Interval", 1, "Interval", "", "", ""); - CAF_PDM_InitField(&m_filteredTimeStepsText, "FilteredTimeSteps", QString(), "Filtered TimeSteps", "", "", ""); - m_filteredTimeStepsText.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); - m_filteredTimeStepsText.uiCapability()->setUiReadOnly(true); - m_filteredTimeStepsText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + CAF_PDM_InitField(&m_timeStepNamesFromFile, "TimeStepsFromFile", std::vector(), "TimeSteps From File", "", "", ""); + CAF_PDM_InitField(&m_dateFormat, "DateFormat", QString("yyyy-MM-dd"), "Date Format", "", "", ""); - m_filteredTimeStepsText.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&m_filteredTimeSteps, "TimeStepIndicesToImport", "Select From Time Steps", "", "", ""); + m_filteredTimeSteps.uiCapability()->setUiReadOnly(true); + + CAF_PDM_InitFieldNoDefault(&m_filteredTimeStepsUi, "TimeStepIndicesUi", "Select From TimeSteps", "", "", ""); + m_filteredTimeStepsUi.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_filteredTimeStepsUi.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + m_filteredTimeStepsUi.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault(&m_applyReloadOfCase, "ApplyReloadOfCase", "", "", "", ""); caf::PdmUiPushButtonEditor::configureEditorForField(&m_applyReloadOfCase); @@ -83,62 +88,131 @@ RimTimeStepFilter::RimTimeStepFilter() //-------------------------------------------------------------------------------------------------- void RimTimeStepFilter::setTimeStepsFromFile(const std::vector& timeSteps) { - m_timeStepsFromFile = timeSteps; + m_dateFormat = RimTools::createTimeFormatStringFromDates(timeSteps); + std::vector timeStepStrings; + for (const QDateTime& date : timeSteps) + { + timeStepStrings.push_back(date.toString(m_dateFormat)); + } + m_timeStepNamesFromFile = timeStepStrings; m_lastTimeStep = static_cast(timeSteps.size()) - 1; - updateSelectedTimeStepIndices(); - updateDerivedData(); + if (m_filteredTimeSteps().empty()) + { + m_filteredTimeSteps = filteredTimeStepIndicesFromUi(); + } + m_filteredTimeStepsUi = m_filteredTimeSteps; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimTimeStepFilter::clearTimeStepsFromFile() +void RimTimeStepFilter::setTimeStepsFromFile(const std::vector>& timeSteps) { - m_timeStepsFromFile.clear(); + std::vector validDates; + for (auto stringDatePair : timeSteps) + { + if (stringDatePair.second.isValid()) + { + validDates.push_back(stringDatePair.second); + } + } + m_dateFormat = RimTools::createTimeFormatStringFromDates(validDates); + + std::vector timeStepStrings; + for (auto stringDatePair : timeSteps) + { + QString stepString = stringDatePair.first; + if (stringDatePair.second.isValid()) + { + stepString = stringDatePair.second.toString(m_dateFormat); + } + timeStepStrings.push_back(stepString); + } + + m_timeStepNamesFromFile = timeStepStrings; + m_lastTimeStep = static_cast(timeSteps.size()) - 1; + + if (m_filteredTimeSteps().empty()) + { + m_filteredTimeSteps = filteredTimeStepIndicesFromUi(); + } + m_filteredTimeStepsUi = m_filteredTimeSteps; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimTimeStepFilter::filteredNativeTimeStepIndices() const +std::vector RimTimeStepFilter::filteredTimeSteps() const { std::vector indices; // Convert vector from int to size_t - for (auto intValue : m_selectedTimeStepIndices.v()) + for (int index : m_filteredTimeSteps()) { - indices.push_back(intValue); + indices.push_back(static_cast(index)); } return indices; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimTimeStepFilter::updateFilteredTimeStepsFromUi() +{ + std::vector timeSteps = m_filteredTimeStepsUi; + std::sort(timeSteps.begin(), timeSteps.end()); + if (m_filteredTimeSteps() == timeSteps) + { + return false; + } + m_filteredTimeSteps = timeSteps; + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTimeStepFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { RimEclipseResultCase* rimEclipseResultCase = parentEclipseResultCase(); - + RimGeoMechCase* rimGeoMechCase = parentGeoMechCase(); if (changedField == &m_applyReloadOfCase) { - if (rimEclipseResultCase) + if (updateFilteredTimeStepsFromUi()) { - rimEclipseResultCase->reloadDataAndUpdate(); - } - return; + if (rimEclipseResultCase) + { + rimEclipseResultCase->reloadDataAndUpdate(); + } + else if (rimGeoMechCase) + { + rimGeoMechCase->reloadDataAndUpdate(); + } + + return; + } } - updateSelectedTimeStepIndices(); - updateDerivedData(); + if (changedField == &m_filterType || + changedField == &m_firstTimeStep || + changedField == &m_lastTimeStep || + changedField == &m_interval) + { + m_filteredTimeStepsUi = filteredTimeStepIndicesFromUi(); + } if (rimEclipseResultCase) { rimEclipseResultCase->updateConnectedEditors(); } + else if (rimGeoMechCase) + { + rimGeoMechCase->updateConnectedEditors(); + } } //-------------------------------------------------------------------------------------------------- @@ -151,13 +225,18 @@ QList RimTimeStepFilter::calculateValueOptions(const caf if (fieldNeedingOptions == &m_firstTimeStep || fieldNeedingOptions == &m_lastTimeStep) { - std::vector timeSteps = allTimeSteps(); - - QString formatString = RimTools::createTimeFormatStringFromDates(timeSteps); - - for (size_t i = 0; i < timeSteps.size(); i++) + for (size_t i = 0; i < m_timeStepNamesFromFile().size(); i++) { - optionItems.push_back(caf::PdmOptionItemInfo(timeSteps[i].toString(formatString), static_cast(i))); + optionItems.push_back(caf::PdmOptionItemInfo(m_timeStepNamesFromFile()[i], static_cast(i))); + } + } + + if (fieldNeedingOptions == &m_filteredTimeStepsUi) + { + std::vector filteredTimeSteps = filteredTimeStepIndicesFromUi(); + for (auto filteredIndex : filteredTimeSteps) + { + optionItems.push_back(caf::PdmOptionItemInfo(m_timeStepNamesFromFile()[filteredIndex], static_cast(filteredIndex))); } } @@ -182,62 +261,20 @@ void RimTimeStepFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimTimeStepFilter::filteredTimeStepsAsText() const +std::vector> RimTimeStepFilter::allTimeSteps() const { - QString text; - - std::vector timeSteps = allTimeSteps(); - - QString formatString = RimTools::createTimeFormatStringFromDates(timeSteps); - - for (auto selectedIndex : m_selectedTimeStepIndices.v()) + std::vector> timeSteps; + for (const QString& dateString : m_timeStepNamesFromFile()) { - size_t timeStepIndex = static_cast(selectedIndex); - - if (timeStepIndex < timeSteps.size()) - { - text += timeSteps[timeStepIndex].toString(formatString); - text += "\n"; - } + timeSteps.push_back(std::make_pair(dateString, QDateTime::fromString(dateString, m_dateFormat))); } - - return text; + return timeSteps; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimTimeStepFilter::updateDerivedData() -{ - m_filteredTimeStepsText = filteredTimeStepsAsText(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimTimeStepFilter::updateSelectedTimeStepIndices() -{ - m_selectedTimeStepIndices = selectedTimeStepIndicesFromUi(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimTimeStepFilter::allTimeSteps() const -{ - RimEclipseResultCase* rimEclipseResultCase = parentEclipseResultCase(); - if (rimEclipseResultCase && rimEclipseResultCase->results(RiaDefines::MATRIX_MODEL)) - { - return rimEclipseResultCase->results(RiaDefines::MATRIX_MODEL)->allTimeStepDatesFromEclipseReader(); - } - - return m_timeStepsFromFile; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimTimeStepFilter::selectedTimeStepIndicesFromUi() const +std::vector RimTimeStepFilter::filteredTimeStepIndicesFromUi() const { std::vector indices; @@ -271,20 +308,32 @@ std::vector RimTimeStepFilter::selectedTimeStepIndicesFromUi() const int daysToSkip = m_interval * intervalFactor; + std::vector> timeSteps = allTimeSteps(); - std::vector timeSteps = allTimeSteps(); - - indices.push_back(m_firstTimeStep); - QDateTime d = timeSteps[m_firstTimeStep].addDays(daysToSkip); - - for (int i = m_firstTimeStep + 1; i <= m_lastTimeStep; i++) + QDateTime d; + for (int i = m_firstTimeStep; i <= m_lastTimeStep; i++) { - if (timeSteps[i] > d) + if (!timeSteps[i].second.isValid()) { - d = d.addDays(daysToSkip); indices.push_back(i); } - } + else + { + if (d.isValid()) + { + if (timeSteps[i].second > d) + { + d = d.addDays(daysToSkip); + indices.push_back(i); + } + } + else + { + d = timeSteps[i].second.addDays(daysToSkip); + indices.push_back(i); + } + } + } } return indices; @@ -316,36 +365,49 @@ RimEclipseResultCase* RimTimeStepFilter::parentEclipseResultCase() const return rimEclipseResultCase; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechCase* RimTimeStepFilter::parentGeoMechCase() const +{ + RimGeoMechCase* rimGeoMechCase = nullptr; + this->firstAncestorOrThisOfType(rimGeoMechCase); + return rimGeoMechCase; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTimeStepFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { + uiOrdering.add(&m_filterType); uiOrdering.add(&m_firstTimeStep); uiOrdering.add(&m_lastTimeStep); - uiOrdering.add(&m_filterType); uiOrdering.add(&m_interval); + uiOrdering.add(&m_filteredTimeStepsUi); + size_t numberOfFilterOptions = filteredTimeStepIndicesFromUi().size(); + QString displayUiName = QString("Select From %1 Time Steps:").arg(numberOfFilterOptions); + m_filteredTimeStepsUi.uiCapability()->setUiName(displayUiName); - if (m_timeStepsFromFile.size() == 0) + bool caseLoaded = false; + + RimEclipseResultCase* eclipseCase = parentEclipseResultCase(); + RimGeoMechCase* geoMechCase = parentGeoMechCase(); + + if (eclipseCase) + { + caseLoaded = eclipseCase->eclipseCaseData() != nullptr; + } + else if (geoMechCase) + { + caseLoaded = geoMechCase->geoMechData() != nullptr; + } + + if (caseLoaded) { uiOrdering.add(&m_applyReloadOfCase); } - QString displayUiName = QString("Filtered Time Steps (%1)").arg(m_selectedTimeStepIndices().size()); - - caf::PdmUiGroup* group = uiOrdering.addNewGroupWithKeyword(displayUiName, "FilteredTimeStepKeyword"); - group->add(&m_filteredTimeStepsText); - - if (m_timeStepsFromFile.size() == 0) - { - group->setCollapsedByDefault(true); - } - else - { - group->setCollapsedByDefault(false); - } - - updateDerivedData(); updateFieldVisibility(); uiOrdering.skipRemainingFields(); diff --git a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h index 55d282ae51..b39116486a 100644 --- a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h +++ b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h @@ -25,6 +25,7 @@ class QDateTime; class RimEclipseResultCase; +class RimGeoMechCase; //-------------------------------------------------------------------------------------------------- /// @@ -48,22 +49,16 @@ public: RimTimeStepFilter(); void setTimeStepsFromFile(const std::vector& timeSteps); - void clearTimeStepsFromFile(); - - std::vector filteredNativeTimeStepIndices() const; - + void setTimeStepsFromFile(const std::vector>& timeSteps); + std::vector filteredTimeSteps() const; + bool updateFilteredTimeStepsFromUi(); private: - QString filteredTimeStepsAsText() const; - - void updateDerivedData(); - void updateSelectedTimeStepIndices(); - - std::vector allTimeSteps() const; - std::vector selectedTimeStepIndicesFromUi() const; + std::vector> allTimeSteps() const; + std::vector filteredTimeStepIndicesFromUi() const; void updateFieldVisibility(); - RimEclipseResultCase* parentEclipseResultCase() const; + RimGeoMechCase* parentGeoMechCase() const; // PDM overrides virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; @@ -72,17 +67,14 @@ private: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: - caf::PdmField< std::vector > m_selectedTimeStepIndices; - caf::PdmField< caf::AppEnum< TimeStepFilterTypeEnum > > m_filterType; - - caf::PdmField m_firstTimeStep; - caf::PdmField m_lastTimeStep; - caf::PdmField m_interval; - - caf::PdmField m_filteredTimeStepsText; - - caf::PdmField m_applyReloadOfCase; - - std::vector m_timeStepsFromFile; /// Temporarily set to provide correct options before the case data structures are operative + + caf::PdmField< std::vector > m_filteredTimeSteps; + caf::PdmField< std::vector > m_filteredTimeStepsUi; + caf::PdmField m_firstTimeStep; + caf::PdmField m_lastTimeStep; + caf::PdmField m_interval; + caf::PdmField m_applyReloadOfCase; + caf::PdmField m_dateFormat; + caf::PdmField> m_timeStepNamesFromFile; }; diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 5a9eb6ef90..68a2ef1b55 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -139,6 +139,15 @@ RiuMainWindow::RiuMainWindow() // Enabling the line below will activate the undo stack // When enableUndoCommandSystem is set false, all commands are executed and deleted immediately //caf::CmdExecCommandManager::instance()->enableUndoCommandSystem(true); + + QLabel* memoryDescriptionLabel = new QLabel("Memory usage:"); + m_memoryUsedStatus = new QLabel("Used: 128 MiB"); + m_memoryUsedStatus->setStyleSheet("QLabel {color: green; }"); + m_memoryAvailableStatus = new QLabel("Physical Memory: 32 GiB"); + + statusBar()->addPermanentWidget(memoryDescriptionLabel); + statusBar()->addPermanentWidget(m_memoryUsedStatus); + statusBar()->addPermanentWidget(m_memoryAvailableStatus); } @@ -180,7 +189,7 @@ void RiuMainWindow::initializeGuiNewProjectLoaded() if (statusBar() && !RiaRegressionTestRunner::instance()->isRunningRegressionTests()) { - statusBar()->showMessage("Ready ..."); + statusBar()->showMessage("Ready ..."); } } @@ -391,6 +400,7 @@ void RiuMainWindow::createMenus() importMenu->addSeparator(); QMenu* importGeoMechMenu = importMenu->addMenu(QIcon(":/GeoMechCase48x48.png"), "Geo Mechanical Cases"); importGeoMechMenu->addAction(cmdFeatureMgr->action("RicImportGeoMechCaseFeature")); + importGeoMechMenu->addAction(cmdFeatureMgr->action("RicImportGeoMechCaseTimeStepFilterFeature")); importGeoMechMenu->addAction(cmdFeatureMgr->action("RicImportElementPropertyFeature")); #endif diff --git a/ApplicationCode/UserInterface/RiuMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h index f53ea53321..3566fc241b 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -26,8 +26,9 @@ #include "cafPdmObjectHandle.h" #include -#include +#include #include +#include #include #include @@ -180,7 +181,8 @@ private: RiuPvtPlotPanel* m_pvtPlotPanel; QMenu* m_windowMenu; - + QLabel* m_memoryUsedStatus; + QLabel* m_memoryAvailableStatus; // Menu and action slots private slots: