diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp index 9e6b4a5daf..aa2655a733 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp @@ -117,9 +117,8 @@ void RicEclipsePropertyFilterFeatureImpl::setDefaults(RimEclipsePropertyFilter* CVF_ASSERT(reservoirView); propertyFilter->resultDefinition->setEclipseCase(reservoirView->eclipseCase()); - propertyFilter->resultDefinition->setResultVariable(reservoirView->cellResult->resultVariable()); - propertyFilter->resultDefinition->setPorosityModel(reservoirView->cellResult->porosityModel()); - propertyFilter->resultDefinition->setResultType(reservoirView->cellResult->resultType()); + propertyFilter->resultDefinition->simpleCopy(reservoirView->cellResult); + propertyFilter->resultDefinition->loadResult(); propertyFilter->setToDefaultValues(); propertyFilter->updateFilterName(); diff --git a/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.cpp b/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.cpp index ff3aac0a75..58ceba0d67 100644 --- a/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.cpp +++ b/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.cpp @@ -19,12 +19,30 @@ #include "RicExportMultipleSnapshotsFeature.h" #include "RiaApplication.h" + +#include "RicSnapshotViewToClipboardFeature.h" + +#include "RimCase.h" +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechView.h" +#include "RimMultiSnapshotDefinition.h" #include "RimProject.h" +#include "RimView.h" + #include "RiuExportMultipleSnapshotsWidget.h" +#include "RiuViewer.h" #include "cafCmdExecCommandManager.h" +#include "cafFrameAnimationControl.h" +#include "cafUtils.h" #include +#include +#include CAF_CMD_SOURCE_INIT(RicExportMultipleSnapshotsFeature, "RicExportMultipleSnapshotsFeature"); @@ -66,3 +84,167 @@ void RicExportMultipleSnapshotsFeature::setupActionLook(QAction* actionToSetup) //actionToSetup->setIcon(QIcon(":/Save.png")); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportMultipleSnapshotsFeature::exportMultipleSnapshots(const QString& folder, RimProject* project) +{ + if (!project) return; + + QDir snapshotPath(folder); + if (!snapshotPath.exists()) + { + if (!snapshotPath.mkpath(".")) return; + } + + for (RimMultiSnapshotDefinition* msd : project->multiSnapshotDefinitions()) + { + RimView* rimView = msd->viewObject(); + if (!rimView) continue; + if (!rimView->viewer()) continue; + + int initialFramIndex = rimView->viewer()->currentFrameIndex(); + + exportViewVariationsToFolder(rimView, msd, folder); + + for (RimCase* rimCase : msd->additionalCases()) + { + RimView* copyOfView = dynamic_cast(rimView->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); + + RimEclipseCase* eclCase = dynamic_cast(rimCase); + if (eclCase) + { + RimEclipseView* eclView = dynamic_cast(copyOfView); + CVF_ASSERT(eclView); + + eclCase->reservoirViews().push_back(eclView); + + eclView->setEclipseCase(eclCase); + + // Resolve references after reservoir view has been inserted into Rim structures + // Intersections referencing a well path/ simulation well requires this + // TODO: initAfterReadRecursively can probably be removed + eclView->initAfterReadRecursively(); + eclView->resolveReferencesRecursively(); + + eclView->loadDataAndUpdate(); + + exportViewVariationsToFolder(eclView, msd, folder); + + eclCase->reservoirViews().removeChildObject(eclView); + } + + RimGeoMechCase* geomCase = dynamic_cast(rimCase); + if (geomCase) + { + RimGeoMechView* geoMechView = dynamic_cast(copyOfView); + CVF_ASSERT(geoMechView); + + geomCase->geoMechViews().push_back(geoMechView); + + geoMechView->setGeoMechCase(geomCase); + + // Resolve references after reservoir view has been inserted into Rim structures + // Intersections referencing a well path/ simulation well requires this + // TODO: initAfterReadRecursively can probably be removed + geoMechView->initAfterReadRecursively(); + geoMechView->resolveReferencesRecursively(); + + geoMechView->loadDataAndUpdate(); + + exportViewVariationsToFolder(geoMechView, msd, folder); + + geomCase->geoMechViews().removeChildObject(geoMechView); + } + + delete copyOfView; + } + + // Set view back to initial state + rimView->viewer()->setCurrentFrame(initialFramIndex); + rimView->viewer()->animationControl()->setCurrentFrameOnly(initialFramIndex); + + rimView->scheduleCreateDisplayModelAndRedraw(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportMultipleSnapshotsFeature::exportViewVariationsToFolder(RimView* rimView, RimMultiSnapshotDefinition* msd, const QString& folder) +{ + RimCase* rimCase = rimView->ownerCase(); + CVF_ASSERT(rimCase); + + RiuViewer* viewer = rimView->viewer(); + QStringList timeSteps = rimCase->timeStepStrings(); + + for (int i = msd->timeStepStart(); i <= msd->timeStepEnd(); i++) + { + QString timeStepIndexString = QString("%1").arg(i, 2, 10, QLatin1Char('0')); + + QString timeStepString = timeStepIndexString + "_" + timeSteps[i].replace(".", "-"); + + if (viewer) + { + viewer->setCurrentFrame(i); + viewer->animationControl()->setCurrentFrameOnly(i); + } + + if (msd->sliceDirection == RimMultiSnapshotDefinition::NO_RANGEFILTER) + { + QString fileName = rimCase->caseUserDescription() + "_" + rimView->name() + "_" + timeStepString; + fileName.replace(" ", "-"); + QString absoluteFileName = caf::Utils::constructFullFileName(folder, fileName, ".png"); + + QCoreApplication::instance()->processEvents(); + + RicSnapshotViewToFileFeature::saveSnapshotAs(absoluteFileName, rimView); + } + else + { + RimCellRangeFilter* rangeFilter = new RimCellRangeFilter; + rimView->rangeFilterCollection()->rangeFilters.push_back(rangeFilter); + + bool rangeFilterInitState = rimView->rangeFilterCollection()->isActive(); + rimView->rangeFilterCollection()->isActive = true; + + for (int i = msd->startSliceIndex(); i <= msd->endSliceIndex(); i++) + { + QString rangeFilterString = msd->sliceDirection().text() + "-" + QString::number(i); + QString fileName = rimCase->caseUserDescription() + "_" + rimView->name() + "_" + timeStepString + "_" + rangeFilterString; + fileName.replace(" ", "-"); + + rangeFilter->setDefaultValues(); + if (msd->sliceDirection == RimMultiSnapshotDefinition::RANGEFILTER_I) + { + rangeFilter->cellCountI = 1; + rangeFilter->startIndexI = i; + } + else if (msd->sliceDirection == RimMultiSnapshotDefinition::RANGEFILTER_J) + { + rangeFilter->cellCountJ = 1; + rangeFilter->startIndexJ = i; + } + else if (msd->sliceDirection == RimMultiSnapshotDefinition::RANGEFILTER_K) + { + rangeFilter->cellCountK = 1; + rangeFilter->startIndexK = i; + } + + rimView->rangeFilterCollection()->updateDisplayModeNotifyManagedViews(rangeFilter); + // Make sure the redraw is processed + QCoreApplication::instance()->processEvents(); + + QString absoluteFileName = caf::Utils::constructFullFileName(folder, fileName, ".png"); + RicSnapshotViewToFileFeature::saveSnapshotAs(absoluteFileName, rimView); + } + + rimView->rangeFilterCollection()->rangeFilters.removeChildObject(rangeFilter); + delete rangeFilter; + + rimView->rangeFilterCollection()->isActive = rangeFilterInitState; + } + } +} + diff --git a/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.h b/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.h index e6c8a4b202..3a3dda23a0 100644 --- a/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.h +++ b/ApplicationCode/Commands/RicExportMultipleSnapshotsFeature.h @@ -20,6 +20,7 @@ #include "cafCmdFeature.h" +class RimProject; //================================================================================================== /// @@ -32,5 +33,11 @@ protected: virtual bool isCommandEnabled() override; virtual void onActionTriggered( bool isChecked ) override; virtual void setupActionLook(QAction* actionToSetup) override; + +public: + static void exportMultipleSnapshots(const QString& folder, RimProject* project); + + static void exportViewVariationsToFolder(RimView* rimView, RimMultiSnapshotDefinition* msd, const QString& folder); + }; diff --git a/ApplicationCode/Commands/RicExportToLasFileFeature.cpp b/ApplicationCode/Commands/RicExportToLasFileFeature.cpp index 4c9cb68ca7..5c75841442 100644 --- a/ApplicationCode/Commands/RicExportToLasFileFeature.cpp +++ b/ApplicationCode/Commands/RicExportToLasFileFeature.cpp @@ -24,6 +24,8 @@ #include "RigLasFileExporter.h" #include "RimWellLogCurve.h" +#include "WellLogCommands/RicWellLogPlotCurveFeatureImpl.h" + #include "cafPdmUiPropertyViewDialog.h" #include "cafSelectionManager.h" @@ -39,7 +41,7 @@ CAF_CMD_SOURCE_INIT(RicExportToLasFileFeature, "RicExportToLasFileFeature"); //-------------------------------------------------------------------------------------------------- bool RicExportToLasFileFeature::isCommandEnabled() { - return selectedWellLogCurves().size() > 0; + return RicWellLogPlotCurveFeatureImpl::selectedWellLogCurves().size() > 0; } //-------------------------------------------------------------------------------------------------- @@ -47,7 +49,7 @@ bool RicExportToLasFileFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicExportToLasFileFeature::onActionTriggered(bool isChecked) { - std::vector curves = selectedWellLogCurves(); + std::vector curves = RicWellLogPlotCurveFeatureImpl::selectedWellLogCurves(); if (curves.size() == 0) return; RiaApplication* app = RiaApplication::instance(); @@ -103,39 +105,3 @@ void RicExportToLasFileFeature::setupActionLook(QAction* actionToSetup) actionToSetup->setText("Export To LAS Files..."); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RicExportToLasFileFeature::selectedWellLogCurves() const -{ - std::set curveSet; - - { - std::vector selectedItems; - caf::SelectionManager::instance()->selectedItems(selectedItems); - - for (auto selectedItem : selectedItems) - { - caf::PdmObjectHandle* objHandle = dynamic_cast(selectedItem); - if (objHandle) - { - std::vector childCurves; - objHandle->descendantsIncludingThisOfType(childCurves); - - for (auto curve : childCurves) - { - curveSet.insert(curve); - } - } - } - } - - std::vector allCurves; - for (auto curve : curveSet) - { - allCurves.push_back(curve); - } - - return allCurves; -} - diff --git a/ApplicationCode/Commands/RicExportToLasFileFeature.h b/ApplicationCode/Commands/RicExportToLasFileFeature.h index a3d5526e53..ebb1362d00 100644 --- a/ApplicationCode/Commands/RicExportToLasFileFeature.h +++ b/ApplicationCode/Commands/RicExportToLasFileFeature.h @@ -37,8 +37,5 @@ protected: virtual bool isCommandEnabled(); virtual void onActionTriggered( bool isChecked ); virtual void setupActionLook( QAction* actionToSetup ); - -private: - std::vector selectedWellLogCurves() const; }; diff --git a/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake index 16c6d03451..3baf857dbe 100644 --- a/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake @@ -18,6 +18,8 @@ ${CEE_CURRENT_LIST_DIR}RicWellLogPlotTrackFeatureImpl.h ${CEE_CURRENT_LIST_DIR}RicPasteWellLogCurveFeature.h ${CEE_CURRENT_LIST_DIR}RicPasteWellLogTrackFeature.h ${CEE_CURRENT_LIST_DIR}RicPasteWellLogPlotFeature.h +${CEE_CURRENT_LIST_DIR}RicChangeDataSourceFeature.h +${CEE_CURRENT_LIST_DIR}RicChangeDataSourceFeatureUi.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -34,6 +36,8 @@ ${CEE_CURRENT_LIST_DIR}RicWellLogPlotTrackFeatureImpl.cpp ${CEE_CURRENT_LIST_DIR}RicPasteWellLogCurveFeature.cpp ${CEE_CURRENT_LIST_DIR}RicPasteWellLogTrackFeature.cpp ${CEE_CURRENT_LIST_DIR}RicPasteWellLogPlotFeature.cpp +${CEE_CURRENT_LIST_DIR}RicChangeDataSourceFeature.cpp +${CEE_CURRENT_LIST_DIR}RicChangeDataSourceFeatureUi.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.cpp new file mode 100644 index 0000000000..ad4e426315 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.cpp @@ -0,0 +1,98 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 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 "RicChangeDataSourceFeature.h" + +#include "RicChangeDataSourceFeatureUi.h" +#include "RicWellLogPlotCurveFeatureImpl.h" + +#include "RimCase.h" +#include "RimWellLogCurve.h" +#include "RimWellLogExtractionCurve.h" +#include "RimWellPath.h" + +#include "cafPdmUiPropertyViewDialog.h" + +#include + +CAF_CMD_SOURCE_INIT(RicChangeDataSourceFeature, "RicChangeDataSourceFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicChangeDataSourceFeature::isCommandEnabled() +{ + std::vector extrCurves = extractionCurves(); + + return extrCurves.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicChangeDataSourceFeature::onActionTriggered(bool isChecked) +{ + std::vector extrCurves = extractionCurves(); + if (extrCurves.size() == 0) return; + + RicChangeDataSourceFeatureUi featureUi; + featureUi.wellPathToApply = extrCurves[0]->wellPath(); + featureUi.caseToApply = extrCurves[0]->rimCase(); + + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &featureUi, "Change Data Source for Selected Curves", ""); + propertyDialog.resize(QSize(500, 200)); + if (propertyDialog.exec() == QDialog::Accepted) + { + for (RimWellLogExtractionCurve* extractionCurve : extrCurves) + { + extractionCurve->setWellPath(featureUi.wellPathToApply); + extractionCurve->setCase(featureUi.caseToApply); + + extractionCurve->loadDataAndUpdate(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicChangeDataSourceFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Change Data Source"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicChangeDataSourceFeature::extractionCurves() +{ + std::vector extrCurves; + + std::vector curves = RicWellLogPlotCurveFeatureImpl::selectedWellLogCurves(); + + for (RimWellLogCurve* c : curves) + { + if (dynamic_cast(c)) + { + extrCurves.push_back(dynamic_cast(c)); + } + } + + return extrCurves; +} + diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.h b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.h new file mode 100644 index 0000000000..83cff04e9a --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 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 RimWellLogExtractionCurve; + +//================================================================================================== +/// +//================================================================================================== +class RicChangeDataSourceFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + virtual bool isCommandEnabled() override; + virtual void onActionTriggered( bool isChecked ) override; + virtual void setupActionLook(QAction* actionToSetup) override; + +private: + static std::vector extractionCurves(); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.cpp b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.cpp new file mode 100644 index 0000000000..d6b29c2a8b --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.cpp @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 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 "RicChangeDataSourceFeatureUi.h" + +#include "RimCase.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "RiaApplication.h" + +CAF_PDM_SOURCE_INIT(RicChangeDataSourceFeatureUi, "ChangeDataSourceFeatureUi"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicChangeDataSourceFeatureUi::RicChangeDataSourceFeatureUi() +{ + CAF_PDM_InitObject("Change Data Source", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&wellPathToApply, "CurveWellPath", "Well Path", "", "", ""); + CAF_PDM_InitFieldNoDefault(&caseToApply, "CurveCase", "Case", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RicChangeDataSourceFeatureUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + QList optionList; + + if (fieldNeedingOptions == &caseToApply) + { + RimProject* proj = RiaApplication::instance()->project(); + + std::vector cases; + proj->allCases(cases); + + for (RimCase* c : cases) + { + optionList.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c)); + } + } + else if (fieldNeedingOptions == &wellPathToApply) + { + RimProject* proj = RiaApplication::instance()->project(); + + if (proj->activeOilField()->wellPathCollection()) + { + for (RimWellPath* wellPath : proj->activeOilField()->wellPathCollection()->wellPaths) + { + optionList.push_back(caf::PdmOptionItemInfo(wellPath->name(), wellPath)); + } + } + } + + return optionList; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicChangeDataSourceFeatureUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Apply the following for all selected curves"); + + group->add(&caseToApply); + group->add(&wellPathToApply); +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.h b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.h new file mode 100644 index 0000000000..f97ec5c768 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 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 "cafPdmObject.h" +#include "cafPdmPtrField.h" +#include "cafPdmUiOrdering.h" + +class RimCase; +class RimWellPath; + + +//================================================================================================== +/// +//================================================================================================== +class RicChangeDataSourceFeatureUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicChangeDataSourceFeatureUi(); + + caf::PdmPtrField caseToApply; + caf::PdmPtrField wellPathToApply; + +protected: + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp index ae5c4325c7..187c479156 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp @@ -19,6 +19,10 @@ #include "RicWellLogPlotCurveFeatureImpl.h" +#include "RimWellLogCurve.h" + +#include "cafSelectionManager.h" + #include static const int RI_LOGPLOT_CURVECOLORSCOUNT = 15; @@ -52,3 +56,39 @@ cvf::Color3f RicWellLogPlotCurveFeatureImpl::curveColorFromTable() cvf::Color3f cvfColor(color.redF(), color.greenF(), color.blueF()); return cvfColor; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicWellLogPlotCurveFeatureImpl::selectedWellLogCurves() +{ + std::set curveSet; + + { + std::vector selectedItems; + caf::SelectionManager::instance()->selectedItems(selectedItems); + + for (caf::PdmUiItem* selectedItem : selectedItems) + { + caf::PdmObjectHandle* objHandle = dynamic_cast(selectedItem); + if (objHandle) + { + std::vector childCurves; + objHandle->descendantsIncludingThisOfType(childCurves); + + for (RimWellLogCurve* curve : childCurves) + { + curveSet.insert(curve); + } + } + } + } + + std::vector allCurves; + for (RimWellLogCurve* curve : curveSet) + { + allCurves.push_back(curve); + } + + return allCurves; +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.h b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.h index 5e508d0208..c9889bbdd3 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.h +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.h @@ -21,12 +21,14 @@ #include "cafPdmFieldCvfColor.h" +class RimWellLogCurve; + //================================================================================================== /// //================================================================================================== class RicWellLogPlotCurveFeatureImpl { - public: static cvf::Color3f curveColorFromTable(); + static std::vector selectedWellLogCurves(); }; diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 223952d74d..55a4d894fa 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -282,7 +282,7 @@ bool RifEclipseInputFileTools::readDataFromKeyword(ecl_kw_type* eclipseKeywordDa bool mathingItemCount = false; { - int itemCount = ecl_kw_get_size(eclipseKeywordData); + size_t itemCount = static_cast(ecl_kw_get_size(eclipseKeywordData)); if (itemCount == caseData->mainGrid()->cellCount()) { mathingItemCount = true; @@ -488,7 +488,7 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa return false; } - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, eclipseCase->mainGrid()->gridIndex(), porosityModel, timeStep, resultName); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCase, eclipseCase->mainGrid()->gridIndex(), porosityModel, timeStep, resultName); if (resultAccessor.isNull()) { return false; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp index 2f86eb7f10..dc2c4bee97 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp @@ -287,16 +287,13 @@ float RigFemPart::characteristicElementSize() { if (m_characteristicElementSize != std::numeric_limits::infinity()) return m_characteristicElementSize; - // take 100 elements - float elmIdxJump = elementCount() / 100.0f; - int elmIdxIncrement = elmIdxJump < 1 ? 1: (int) elmIdxJump; int elmsToAverageCount = 0; float sumMaxEdgeLength = 0; - for (int elmIdx = 0; elmIdx < elementCount(); elmIdx += elmIdxIncrement) + for (int elmIdx = 0; elmIdx < elementCount(); elmIdx++) { RigElementType eType = this->elementType(elmIdx); - if (eType == HEX8 || eType == HEX8P) + if (eType == HEX8P) { const int* elmentConn = this->connectivities(elmIdx); cvf::Vec3f nodePos0 = this->nodes().coordinates[elmentConn[0]]; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h index 0010f2bada..02dd5372b0 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h @@ -51,9 +51,9 @@ public: } RigFemResultPosEnum resultPosType; - std::string fieldName; - std::string componentName; - int timeLapseBaseFrameIdx; + std::string fieldName; + std::string componentName; + int timeLapseBaseFrameIdx; static const int ALL_TIME_LAPSES = -2; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemScalarResultFrames.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemScalarResultFrames.h index 4c0d11bbcf..72c0db1930 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemScalarResultFrames.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemScalarResultFrames.h @@ -20,12 +20,10 @@ #pragma once #include "cvfObject.h" #include -#include //================================================================================================== /// //================================================================================================== -class RigStatisticsDataCache; class RigFemScalarResultFrames: public cvf::Object { @@ -33,11 +31,11 @@ public: RigFemScalarResultFrames(int frameCount); virtual ~RigFemScalarResultFrames(); - void enableAsSingleFrameResult(); + void enableAsSingleFrameResult(); - std::vector& frameData(size_t frameIndex); + std::vector& frameData(size_t frameIndex); const std::vector& frameData(size_t frameIndex) const; - int frameCount() const; + int frameCount() const; private: std::vector< std::vector > m_dataForEachFrame; diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp index d5d8ca1755..42e4af4976 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp @@ -126,10 +126,10 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) } else { - resultAccessor = RigResultAccessorFactory::createResultAccessor(cellResultColors->reservoirView()->eclipseCase()->reservoirData(), - 0, - timeStepIndex, - cellResultColors); + resultAccessor = RigResultAccessorFactory::createFromResultDefinition(cellResultColors->reservoirView()->eclipseCase()->reservoirData(), + 0, + timeStepIndex, + cellResultColors); } RivIntersectionPartMgr::calculateEclipseTextureCoordinates(m_intersectionBoxFacesTextureCoords.p(), diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp index 64bf8d9f53..25d984ca3b 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp @@ -130,10 +130,10 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex) } else { - resultAccessor = RigResultAccessorFactory::createResultAccessor(cellResultColors->reservoirView()->eclipseCase()->reservoirData(), - 0, - timeStepIndex, - cellResultColors); + resultAccessor = RigResultAccessorFactory::createFromResultDefinition(cellResultColors->reservoirView()->eclipseCase()->reservoirData(), + 0, + timeStepIndex, + cellResultColors); } RivIntersectionPartMgr::calculateEclipseTextureCoordinates(m_crossSectionFacesTextureCoords.p(), diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp index 9e063bfbe1..7ef9d0aa1b 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp +++ b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp @@ -315,7 +315,7 @@ cvf::ref RivCellEdgeGeometryUtils::createCellEdgeResultAccess adjustedTimeStep = 0; } - cvf::ref daObj = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, adjustedTimeStep, resultIndices[cubeFaceIdx]); + cvf::ref daObj = RigResultAccessorFactory::createFromResultIdx(eclipseCase, grid->gridIndex(), porosityModel, adjustedTimeStep, resultIndices[cubeFaceIdx]); cellEdgeResultAccessor->setDataAccessObjectForFace(static_cast(cubeFaceIdx), daObj.p()); } } @@ -332,14 +332,7 @@ cvf::ref RivCellEdgeGeometryUtils::createCellCenterResultAcce if (cellResultColors->hasResult()) { - if (!cellResultColors->hasDynamicResult()) - { - // Static result values are located at time step 0 - timeStepIndex = 0; - } - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); - resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, timeStepIndex, cellResultColors->resultVariable()); + resultAccessor = RigResultAccessorFactory::createFromResultDefinition(eclipseCase, grid->gridIndex(), timeStepIndex, cellResultColors); } if (resultAccessor.isNull()) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index f517f779d4..0b2d4d620a 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -234,21 +234,26 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC if (cellResultColors->isTernarySaturationSelected()) { RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), - timeStepIndex, - m_grid->gridIndex(), - m_surfaceGenerator.quadToCellFaceMapper()); + timeStepIndex, + m_grid->gridIndex(), + m_surfaceGenerator.quadToCellFaceMapper()); texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_surfaceFaces.p(), + m_surfaceFacesTextureCoords.p(), + mapper, + m_opacityLevel, + caf::FC_NONE, + cellResultColors->reservoirView()->isLightingDisabled()); } else { RivTextureCoordsCreator texturer(cellResultColors, - timeStepIndex, - m_grid->gridIndex(), - m_surfaceGenerator.quadToCellFaceMapper()); + timeStepIndex, + m_grid->gridIndex(), + m_surfaceGenerator.quadToCellFaceMapper()); if (!texturer.isValid()) { return; @@ -257,7 +262,12 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); + RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), + m_surfaceFacesTextureCoords.p(), + mapper, + m_opacityLevel, + caf::FC_NONE, + cellResultColors->reservoirView()->isLightingDisabled()); } } } diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp index e68546347e..c5d6d98803 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -789,16 +789,7 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis RigCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->reservoirData(); - size_t adjustedTimeStepIndex = timeStepIndex; - - // Set time step to zero for static results - if (propertyFilter->resultDefinition()->hasStaticResult()) - { - adjustedTimeStepIndex = 0; - } - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(propertyFilter->resultDefinition()->porosityModel()); - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, adjustedTimeStepIndex, propertyFilter->resultDefinition->resultVariable(), propertyFilter->resultDefinition->resultType()); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromResultDefinition(eclipseCase, grid->gridIndex(), timeStepIndex, propertyFilter->resultDefinition); CVF_ASSERT(resultAccessor.notNull()); diff --git a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp index c6819e2ae1..90773ab638 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp +++ b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp @@ -55,9 +55,9 @@ RivTernaryTextureCoordsCreator::RivTernaryTextureCoordsCreator( RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); - cvf::ref soil = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SOIL"); - cvf::ref sgas = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SGAS"); - cvf::ref swat = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SWAT"); + cvf::ref soil = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SOIL"); + cvf::ref sgas = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SGAS"); + cvf::ref swat = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SWAT"); m_resultAccessor = new RigTernaryResultAccessor(); m_resultAccessor->setTernaryResultAccessors(soil.p(), sgas.p(), swat.p()); @@ -90,9 +90,9 @@ RivTernaryTextureCoordsCreator::RivTernaryTextureCoordsCreator( RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); size_t gridIndex = 0; - cvf::ref soil = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SOIL"); - cvf::ref sgas = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SGAS"); - cvf::ref swat = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SWAT"); + cvf::ref soil = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SOIL"); + cvf::ref sgas = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SGAS"); + cvf::ref swat = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SWAT"); m_resultAccessor = new RigTernaryResultAccessor(); m_resultAccessor->setTernaryResultAccessors(soil.p(), sgas.p(), swat.p()); diff --git a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp index d0d8b77fe3..308e538f05 100644 --- a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp +++ b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp @@ -43,7 +43,7 @@ RivTextureCoordsCreator::RivTextureCoordsCreator(RimEclipseCellColors* cellResul m_quadMapper = quadMapper; CVF_ASSERT(quadMapper && eclipseCase ); - m_resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, timeStepIndex, cellResultColors); + m_resultAccessor = RigResultAccessorFactory::createFromResultDefinition(eclipseCase, gridIndex, timeStepIndex, cellResultColors); cvf::ref pipeInCellEval = new RigPipeInCellEvaluator(cellResultColors->reservoirView()->wellCollection()->resultWellGeometryVisibilities(timeStepIndex), @@ -79,11 +79,10 @@ void RivTextureCoordsCreator::createTextureCoords(cvf::Vec2fArray* quadTextureCo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivTextureCoordsCreator::createTextureCoords( - cvf::Vec2fArray* quadTextureCoords, - const cvf::StructGridQuadToCellFaceMapper* quadMapper, - const RigResultAccessor* resultAccessor, - const RivResultToTextureMapper* texMapper) +void RivTextureCoordsCreator::createTextureCoords(cvf::Vec2fArray* quadTextureCoords, + const cvf::StructGridQuadToCellFaceMapper* quadMapper, + const RigResultAccessor* resultAccessor, + const RivResultToTextureMapper* texMapper) { CVF_ASSERT(quadTextureCoords && quadMapper && resultAccessor && texMapper); diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index ffd069bd20..5685f9e142 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -208,6 +208,9 @@ void Rim3dOverlayInfoConfig::updateEclipse3DInfo(RimEclipseView * eclipseView) if (isResultsInfoRelevant) { size_t scalarIndex = eclipseView->cellResult()->scalarResultIndex(); + if (scalarIndex != cvf::UNDEFINED_SIZE_T) + { + if (m_statisticsCellRange == ALL_CELLS) { if (m_statisticsTimeRange == ALL_TIMESTEPS) @@ -256,6 +259,7 @@ void Rim3dOverlayInfoConfig::updateEclipse3DInfo(RimEclipseView * eclipseView) histogram = &(m_visibleCellStatistics->cellScalarValuesHistogram(currentTimeStep)); } } + } } } @@ -364,7 +368,7 @@ void Rim3dOverlayInfoConfig::updateEclipse3DInfo(RimEclipseView * eclipseView) if (showHistogram()) { - if (isResultsInfoRelevant) + if (isResultsInfoRelevant && histogram) { eclipseView->viewer()->showHistogram(true); eclipseView->viewer()->setHistogram(min, max, *histogram); diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index 1accf7d1b2..fb0041ff5e 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -409,6 +409,7 @@ QStringList RimContextCommandBuilder::commandsFromSelection() { commandIds << "RicCopyReferencesToClipboardFeature"; commandIds << "RicExportToLasFileFeature"; + commandIds << "RicChangeDataSourceFeature"; } else if (dynamic_cast(uiItem)) { diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp index 46db4325e5..cf92907663 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp @@ -37,6 +37,8 @@ #include "cvfAssert.h" #include "cvfMath.h" +#include "RigFlowDiagResults.h" +#include "RimFlowDiagSolution.h" namespace caf @@ -292,32 +294,53 @@ void RimEclipsePropertyFilter::computeResultValueRange() clearCategories(); - size_t scalarIndex = resultDefinition->scalarResultIndex(); - if (scalarIndex != cvf::UNDEFINED_SIZE_T) + if (resultDefinition->resultType() == RimDefines::FLOW_DIAGNOSTICS) { - RimReservoirCellResultsStorage* results = resultDefinition->currentGridCellResults(); - if (results) + RimView* view; + this->firstAncestorOrThisOfType(view); + + int timeStep = 0; + if (view) timeStep = view->currentTimeStep(); + RigFlowDiagResultAddress resAddr = resultDefinition->flowDiagResAddress(); + if ( resultDefinition->flowDiagSolution() ) { - results->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); + RigFlowDiagResults* results = resultDefinition->flowDiagSolution()->flowDiagResults(); + results->minMaxScalarValues(resAddr, timeStep, &max, &max); - if (resultDefinition->hasCategoryResult()) + if ( resultDefinition->hasCategoryResult() ) { - if (resultDefinition->resultType() != RimDefines::FORMATION_NAMES) - { - setCategoryValues(results->cellResults()->uniqueCellScalarValues(scalarIndex)); - } - else - { - CVF_ASSERT(parentContainer()->reservoirView()->eclipseCase()->reservoirData()); - CVF_ASSERT(parentContainer()->reservoirView()->eclipseCase()->reservoirData()->activeFormationNames()); + setCategoryValues(results->uniqueCellScalarValues(resAddr, timeStep)); + } + } + } + else + { + size_t scalarIndex = resultDefinition->scalarResultIndex(); + if ( scalarIndex != cvf::UNDEFINED_SIZE_T ) + { + RimReservoirCellResultsStorage* results = resultDefinition->currentGridCellResults(); + if ( results ) + { + results->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); - const std::vector& fnVector = parentContainer()->reservoirView()->eclipseCase()->reservoirData()->activeFormationNames()->formationNames(); - setCategoryNames(fnVector); + if ( resultDefinition->hasCategoryResult() ) + { + if ( resultDefinition->resultType() != RimDefines::FORMATION_NAMES ) + { + setCategoryValues(results->cellResults()->uniqueCellScalarValues(scalarIndex)); + } + else + { + CVF_ASSERT(parentContainer()->reservoirView()->eclipseCase()->reservoirData()); + CVF_ASSERT(parentContainer()->reservoirView()->eclipseCase()->reservoirData()->activeFormationNames()); + + const std::vector& fnVector = parentContainer()->reservoirView()->eclipseCase()->reservoirData()->activeFormationNames()->formationNames(); + setCategoryNames(fnVector); + } } } } } - m_maximumResultValue = max; m_minimumResultValue = min; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp index 2ab655b4ec..c32875a5f5 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -35,6 +35,7 @@ #include "RimReservoirCellResultsStorage.h" #include "RimTools.h" #include "RimFlowDiagSolution.h" +#include "RigFlowDiagSolverInterface.h" #include "cafPdmSettings.h" #include "cafPdmUiPropertyViewDialog.h" @@ -71,6 +72,8 @@ RimEclipseResultCase::RimEclipseResultCase() flipYAxis.xmlCapability()->setIOWritable(true); //flipYAxis.uiCapability()->setUiHidden(true); + m_flowDagSolverInterface = new RigFlowDiagSolverInterface(this); + m_activeCellInfoIsReadFromFile = false; m_gridAndWellDataIsReadFromFile = false; } @@ -357,6 +360,14 @@ std::vector RimEclipseResultCase::flowDiagSolutions() return flowSols; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagSolverInterface* RimEclipseResultCase::flowDiagSolverInterface() +{ + return m_flowDagSolverInterface.p(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h index bb67fa856a..4543cec58e 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h @@ -25,6 +25,7 @@ class RifReaderInterface; class RigMainGrid; class RimFlowDiagSolution; +class RigFlowDiagSolverInterface; //================================================================================================== // @@ -52,6 +53,8 @@ public: virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); std::vector flowDiagSolutions(); + RigFlowDiagSolverInterface* flowDiagSolverInterface(); + private: cvf::ref createMockModel(QString modelName); @@ -59,6 +62,8 @@ private: virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + cvf::ref m_flowDagSolverInterface; + // Fields: caf::PdmField caseFileName; caf::PdmChildArrayField m_flowDiagSolutions; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 8da5368c7a..b867cfe623 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -38,6 +38,8 @@ #include "cafPdmUiListEditor.h" #include "RimEclipseResultCase.h" +#include "RigFlowDiagResultAddress.h" + CAF_PDM_SOURCE_INIT(RimEclipseResultDefinition, "ResultDefinition"); //-------------------------------------------------------------------------------------------------- @@ -96,6 +98,18 @@ RimEclipseResultDefinition::~RimEclipseResultDefinition() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::simpleCopy(const RimEclipseResultDefinition* other) +{ + this->setResultVariable(other->resultVariable()); + this->setPorosityModel(other->porosityModel()); + this->setResultType(other->resultType()); + this->setFlowSolution(other->m_flowSolution()); + this->setSelectedTracers(other->m_selectedTracers()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -122,23 +136,35 @@ RimReservoirCellResultsStorage* RimEclipseResultDefinition::currentGridCellResul //-------------------------------------------------------------------------------------------------- void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - if ( &m_resultTypeUiField == changedField + if ( &m_flowSolutionUiField == changedField + || &m_resultTypeUiField == changedField || &m_porosityModelUiField == changedField ) { + // If the user are seeing the list with the actually selected result, + // select that result in the list. Otherwise select nothing. + QStringList varList = getResultNamesForCurrentUiResultType(); - // If the user are seeing the list with the actually selected result, select that result in the list. Otherwise select nothing. - if ( m_resultTypeUiField() == m_resultType() - && m_porosityModelUiField() == m_porosityModel() - && varList.contains(resultVariable())) + bool isFlowDiagFieldsRelevant = (m_resultType() == RimDefines::FLOW_DIAGNOSTICS); + + + if ( ( m_flowSolutionUiField() == m_flowSolution() || !isFlowDiagFieldsRelevant) + && m_resultTypeUiField() == m_resultType() + && m_porosityModelUiField() == m_porosityModel() ) { - m_resultVariableUiField = resultVariable(); + if (varList.contains(resultVariable())) + { + m_resultVariableUiField = resultVariable(); + } + + if (isFlowDiagFieldsRelevant) m_selectedTracersUiField = m_selectedTracers(); + else m_selectedTracersUiField = std::vector(); } else { m_resultVariableUiField = ""; + m_selectedTracersUiField = std::vector(); } - } if (&m_resultVariableUiField == changedField) @@ -285,10 +311,10 @@ QList RimEclipseResultDefinition::calculateValueOptions( { if ( fieldNeedingOptions == &m_resultVariableUiField ) { - optionItems.push_back(caf::PdmOptionItemInfo("Time Of Flight (Weighted Sum)", "TOF")); - optionItems.push_back(caf::PdmOptionItemInfo("Tracer Concentration (Sum)", "Concentrations")); - optionItems.push_back(caf::PdmOptionItemInfo("Tracer with Max Concentration", "MaxTracer")); - optionItems.push_back(caf::PdmOptionItemInfo("Injector Producer Communication", "Communication")); + optionItems.push_back(caf::PdmOptionItemInfo("Time Of Flight (Weighted Sum)", RIG_FLD_TOF_RESNAME)); + optionItems.push_back(caf::PdmOptionItemInfo("Tracer Cell Fraction (Sum)", RIG_FLD_CELL_FRACTION_RESNAME)); + optionItems.push_back(caf::PdmOptionItemInfo("Max Fraction Tracer", RIG_FLD_MAX_FRACTION_TRACER_RESNAME)); + optionItems.push_back(caf::PdmOptionItemInfo("Injector Producer Communication", RIG_FLD_COMMUNICATION_RESNAME)); } else if (fieldNeedingOptions == &m_flowSolutionUiField) { @@ -446,13 +472,11 @@ QStringList RimEclipseResultDefinition::getResultNamesForCurrentUiResultType() } else { - // TODO: Get this form some sensible place - QStringList flowVars; - flowVars.push_back("TOF"); - flowVars.push_back("Concentrations"); - flowVars.push_back("MaxTracer"); - flowVars.push_back("Communication"); + flowVars.push_back(RIG_FLD_TOF_RESNAME); + flowVars.push_back(RIG_FLD_CELL_FRACTION_RESNAME); + flowVars.push_back(RIG_FLD_MAX_FRACTION_TRACER_RESNAME); + flowVars.push_back(RIG_FLD_COMMUNICATION_RESNAME); return flowVars; } } @@ -464,6 +488,8 @@ size_t RimEclipseResultDefinition::scalarResultIndex() const { size_t gridScalarResultIndex = cvf::UNDEFINED_SIZE_T; + if (m_resultType() == RimDefines::FLOW_DIAGNOSTICS) return cvf::UNDEFINED_SIZE_T; + const RimReservoirCellResultsStorage* gridCellResults = this->currentGridCellResults(); if (gridCellResults && gridCellResults->cellResults()) { @@ -473,11 +499,29 @@ size_t RimEclipseResultDefinition::scalarResultIndex() const return gridScalarResultIndex; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResultAddress RimEclipseResultDefinition::flowDiagResAddress() const +{ + CVF_ASSERT(m_resultType() == RimDefines::FLOW_DIAGNOSTICS); + + std::set selTracerNames; + for (const QString& tName : m_selectedTracers()) + { + selTracerNames.insert(tName.toStdString()); + } + + return RigFlowDiagResultAddress(m_resultVariable().toStdString(), selTracerNames); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimEclipseResultDefinition::loadResult() { + if (m_resultType() == RimDefines::FLOW_DIAGNOSTICS) return; // Will load automatically on access + RimReservoirCellResultsStorage* gridCellResults = this->currentGridCellResults(); if (gridCellResults) { @@ -492,6 +536,8 @@ void RimEclipseResultDefinition::loadResult() //-------------------------------------------------------------------------------------------------- bool RimEclipseResultDefinition::hasStaticResult() const { + if (this->resultType() == RimDefines::FLOW_DIAGNOSTICS) return false; + const RimReservoirCellResultsStorage* gridCellResults = this->currentGridCellResults(); size_t gridScalarResultIndex = this->scalarResultIndex(); @@ -510,7 +556,11 @@ bool RimEclipseResultDefinition::hasStaticResult() const //-------------------------------------------------------------------------------------------------- bool RimEclipseResultDefinition::hasResult() const { - if (this->currentGridCellResults() && this->currentGridCellResults()->cellResults()) + if (this->resultType() == RimDefines::FLOW_DIAGNOSTICS) + { + if (m_flowSolution() && !m_resultVariable().isEmpty()) return true; + } + else if (this->currentGridCellResults() && this->currentGridCellResults()->cellResults()) { const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults()->cellResults(); size_t gridScalarResultIndex = gridCellResults->findScalarResultIndex(m_resultType(), m_resultVariable()); @@ -532,6 +582,10 @@ bool RimEclipseResultDefinition::hasDynamicResult() const { return true; } + else if (m_resultType() == RimDefines::FLOW_DIAGNOSTICS) + { + return true; + } if (this->currentGridCellResults() && this->currentGridCellResults()->cellResults()) { @@ -590,6 +644,32 @@ void RimEclipseResultDefinition::setResultVariable(const QString& val) m_resultVariableUiField = val; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFlowDiagSolution* RimEclipseResultDefinition::flowDiagSolution() +{ + return m_flowSolution(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setFlowSolution(RimFlowDiagSolution* flowSol) +{ + this->m_flowSolution = flowSol; + this->m_flowSolutionUiField = flowSol; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedTracers(const std::vector& selectedTracers) +{ + this->m_selectedTracers = selectedTracers; + this->m_selectedTracersUiField = selectedTracers; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -611,6 +691,9 @@ bool RimEclipseResultDefinition::hasCategoryResult() const && m_eclipseCase->reservoirData() && m_eclipseCase->reservoirData()->activeFormationNames() ) return true; + if (this->m_resultType() == RimDefines::FLOW_DIAGNOSTICS + && m_resultVariable() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME) return true; + if (!this->hasStaticResult()) return false; return this->resultVariable().contains("NUM", Qt::CaseInsensitive); @@ -648,6 +731,17 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm { uiOrdering.add(&m_flowSolutionUiField); uiOrdering.add(&m_selectedTracersUiField); + + if ( m_flowSolution() == nullptr ) + { + RimEclipseResultCase* eclCase; + this->firstAncestorOrThisOfType(eclCase); + if ( eclCase ) + { + std::vector flowSols = eclCase->flowDiagSolutions(); + if (flowSols.size()){ this->setFlowSolution(flowSols[0]); } + } + } } uiOrdering.add(&m_resultVariableUiField); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index 75f53342de..ca4c638294 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -27,6 +27,7 @@ #include "cafPdmObject.h" #include "cafPdmPointer.h" #include "cafPdmPtrField.h" +#include "RigFlowDiagResultAddress.h" class RigCaseCellResultsData; class RimEclipseCase; @@ -45,6 +46,8 @@ public: RimEclipseResultDefinition(); virtual ~RimEclipseResultDefinition(); + void simpleCopy(const RimEclipseResultDefinition* other); + void setEclipseCase(RimEclipseCase* eclipseCase); RimDefines::ResultCatType resultType() const { return m_resultType(); } @@ -53,6 +56,8 @@ public: void setPorosityModel(RimDefines::PorosityModelType val); QString resultVariable() const { return m_resultVariable(); } virtual void setResultVariable(const QString& val); + RimFlowDiagSolution* flowDiagSolution(); + RigFlowDiagResultAddress flowDiagResAddress() const; void loadResult(); size_t scalarResultIndex() const; @@ -100,7 +105,10 @@ protected: caf::PdmPointer m_eclipseCase; private: - bool hasDualPorFractureResult(); + void setFlowSolution(RimFlowDiagSolution* flowSol); + void setSelectedTracers(const std::vector& selectedTracers); + + bool hasDualPorFractureResult(); QList calcOptionsForVariableUiFieldStandard(); QStringList getResultNamesForCurrentUiResultType(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp index f43aa7a128..74eec71515 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp @@ -161,7 +161,7 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults(const QList& // Trigger loading of dataset sourceCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex); - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(sourceCase->reservoirData(), gridIdx, poroModel, dataAccessTimeStepIndex, resultName, resultType); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromNameAndType(sourceCase->reservoirData(), gridIdx, poroModel, dataAccessTimeStepIndex, resultName, resultType); if (resultAccessor.notNull()) { sourceDataAccessList.push_back(resultAccessor.p()); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index c90e0a6709..c210251aa1 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -76,6 +76,9 @@ #include #include +#include "RimEclipseResultDefinition.h" +#include "RimFlowDiagSolution.h" +#include "RigFlowDiagResults.h" @@ -947,6 +950,7 @@ void RimEclipseView::updateLegends() CVF_ASSERT(results); updateMinMaxValuesAndAddLegendToView(QString("Cell Results: \n"), this->cellResult(), results); + if (this->faultResultSettings()->showCustomFaultResult() && this->faultResultSettings()->hasValidCustomResult()) { updateMinMaxValuesAndAddLegendToView(QString("Fault Results: \n"), this->currentFaultResultColors(), results); @@ -992,47 +996,90 @@ void RimEclipseView::updateMinMaxValuesAndAddLegendToView(QString legendLabel, R { if (resultColors->hasResult()) { - double globalMin, globalMax; - double globalPosClosestToZero, globalNegClosestToZero; - cellResultsData->minMaxCellScalarValues(resultColors->scalarResultIndex(), globalMin, globalMax); - cellResultsData->posNegClosestToZero(resultColors->scalarResultIndex(), globalPosClosestToZero, globalNegClosestToZero); - - double localMin, localMax; - double localPosClosestToZero, localNegClosestToZero; - if (resultColors->hasDynamicResult()) + if (resultColors->resultType() == RimDefines::FLOW_DIAGNOSTICS) { - cellResultsData->minMaxCellScalarValues(resultColors->scalarResultIndex(), m_currentTimeStep, localMin, localMax); - cellResultsData->posNegClosestToZero(resultColors->scalarResultIndex(), m_currentTimeStep, localPosClosestToZero, localNegClosestToZero); - } - else - { - localMin = globalMin; - localMax = globalMax; + double globalMin, globalMax; + double globalPosClosestToZero, globalNegClosestToZero; + RigFlowDiagResults* cellResultsData = resultColors->flowDiagSolution()->flowDiagResults(); + RigFlowDiagResultAddress resAddr = resultColors->flowDiagResAddress(); - localPosClosestToZero = globalPosClosestToZero; - localNegClosestToZero = globalNegClosestToZero; - } + cellResultsData->minMaxScalarValues(resAddr, m_currentTimeStep, &globalMin, &globalMax); + cellResultsData->posNegClosestToZero(resAddr, m_currentTimeStep, &globalPosClosestToZero, &globalNegClosestToZero); - CVF_ASSERT(resultColors->legendConfig()); - - resultColors->legendConfig()->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero); - resultColors->legendConfig()->setAutomaticRanges(globalMin, globalMax, localMin, localMax); - - if (resultColors->hasCategoryResult()) - { - if(resultColors->resultType() != RimDefines::FORMATION_NAMES) + double localMin, localMax; + double localPosClosestToZero, localNegClosestToZero; + if ( resultColors->hasDynamicResult() ) { - resultColors->legendConfig()->setIntegerCategories(cellResultsData->uniqueCellScalarValues(resultColors->scalarResultIndex())); + cellResultsData->minMaxScalarValues(resAddr, m_currentTimeStep, &localMin, &localMax); + cellResultsData->posNegClosestToZero(resAddr, m_currentTimeStep, &localPosClosestToZero, &localNegClosestToZero); } else { - const std::vector& fnVector = eclipseCase()->reservoirData()->activeFormationNames()->formationNames(); - resultColors->legendConfig()->setNamedCategoriesInverse(fnVector); - } - } + localMin = globalMin; + localMax = globalMax; - m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig()->legend()); - resultColors->legendConfig()->setTitle(cvfqt::Utils::toString(legendLabel + resultColors->resultVariable())); + localPosClosestToZero = globalPosClosestToZero; + localNegClosestToZero = globalNegClosestToZero; + } + + CVF_ASSERT(resultColors->legendConfig()); + + resultColors->legendConfig()->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero); + resultColors->legendConfig()->setAutomaticRanges(globalMin, globalMax, localMin, localMax); + + if ( resultColors->hasCategoryResult() ) + { + resultColors->legendConfig()->setIntegerCategories(cellResultsData->uniqueCellScalarValues(resAddr, m_currentTimeStep)); + } + + m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig()->legend()); + resultColors->legendConfig()->setTitle(cvfqt::Utils::toString(legendLabel + resultColors->resultVariable())); + + } + else + { + double globalMin, globalMax; + double globalPosClosestToZero, globalNegClosestToZero; + cellResultsData->minMaxCellScalarValues(resultColors->scalarResultIndex(), globalMin, globalMax); + cellResultsData->posNegClosestToZero(resultColors->scalarResultIndex(), globalPosClosestToZero, globalNegClosestToZero); + + double localMin, localMax; + double localPosClosestToZero, localNegClosestToZero; + if ( resultColors->hasDynamicResult() ) + { + cellResultsData->minMaxCellScalarValues(resultColors->scalarResultIndex(), m_currentTimeStep, localMin, localMax); + cellResultsData->posNegClosestToZero(resultColors->scalarResultIndex(), m_currentTimeStep, localPosClosestToZero, localNegClosestToZero); + } + else + { + localMin = globalMin; + localMax = globalMax; + + localPosClosestToZero = globalPosClosestToZero; + localNegClosestToZero = globalNegClosestToZero; + } + + CVF_ASSERT(resultColors->legendConfig()); + + resultColors->legendConfig()->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero); + resultColors->legendConfig()->setAutomaticRanges(globalMin, globalMax, localMin, localMax); + + if ( resultColors->hasCategoryResult() ) + { + if ( resultColors->resultType() != RimDefines::FORMATION_NAMES ) + { + resultColors->legendConfig()->setIntegerCategories(cellResultsData->uniqueCellScalarValues(resultColors->scalarResultIndex())); + } + else + { + const std::vector& fnVector = eclipseCase()->reservoirData()->activeFormationNames()->formationNames(); + resultColors->legendConfig()->setNamedCategoriesInverse(fnVector); + } + } + + m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig()->legend()); + resultColors->legendConfig()->setTitle(cvfqt::Utils::toString(legendLabel + resultColors->resultVariable())); + } } diff --git a/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.cpp b/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.cpp index b69975630e..f32298c065 100644 --- a/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.cpp +++ b/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.cpp @@ -20,6 +20,9 @@ #include "RimEclipseResultCase.h" #include "RigCaseData.h" +#include "RigFlowDiagResults.h" +#include "RigCaseCellResultsData.h" + CAF_PDM_SOURCE_INIT(RimFlowDiagSolution, "FlowDiagSolution"); //-------------------------------------------------------------------------------------------------- @@ -32,6 +35,9 @@ RimFlowDiagSolution::RimFlowDiagSolution(void) //CAF_PDM_InitFieldNoDefault(&m_selectedWells, "SelectedWells", "Selected Wells","",""); CAF_PDM_InitField(&m_userDescription, "UserDescription", QString("All Wells") ,"Description", "", "",""); + + + } //-------------------------------------------------------------------------------------------------- @@ -42,6 +48,30 @@ RimFlowDiagSolution::~RimFlowDiagSolution(void) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResults* RimFlowDiagSolution::flowDiagResults() +{ + if ( m_flowDiagResults.isNull() ) + { + size_t timeStepCount; + { + RimEclipseResultCase* eclCase; + this->firstAncestorOrThisOfType(eclCase); + + CVF_ASSERT(eclCase && eclCase->reservoirData() && eclCase->reservoirData() ); + + timeStepCount = eclCase->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount(); + + } + + m_flowDiagResults = new RigFlowDiagResults(this, timeStepCount); + } + + return m_flowDiagResults.p(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -65,6 +95,82 @@ std::set RimFlowDiagSolution::tracerNames() return tracerNameSet; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map > RimFlowDiagSolution::allInjectorTracerActiveCellIndices(size_t timeStepIndex) +{ + return allTracerActiveCellIndices(timeStepIndex, true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map > RimFlowDiagSolution::allProducerTracerActiveCellIndices(size_t timeStepIndex) +{ + return allTracerActiveCellIndices(timeStepIndex, false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map > RimFlowDiagSolution::allTracerActiveCellIndices(size_t timeStepIndex, bool useInjectors) +{ + RimEclipseResultCase* eclCase; + this->firstAncestorOrThisOfType(eclCase); + TracerStatusType tracerStatus = UNDEFINED; + + std::map > tracersWithCells; + + if ( eclCase ) + { + const cvf::Collection& wellResults = eclCase->reservoirData()->wellResults(); + RigMainGrid* mainGrid = eclCase->reservoirData()->mainGrid(); + RigActiveCellInfo* activeCellInfo = eclCase->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); //Todo: Must come from the results definition + + for ( size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx ) + { + if (!wellResults[wIdx]->hasWellResult(timeStepIndex) ) continue; + + size_t wellTimeStep = wellResults[wIdx]->m_resultTimeStepIndexToWellTimeStepIndex[timeStepIndex]; + const RigWellResultFrame& wellResFrame = wellResults[wIdx]->m_wellCellsTimeSteps[wellTimeStep]; + + if ( !wellResFrame.m_isOpen ) continue; + + bool useWell = ( useInjectors && ( wellResFrame.m_productionType == RigWellResultFrame::GAS_INJECTOR + || wellResFrame.m_productionType == RigWellResultFrame::OIL_INJECTOR + || wellResFrame.m_productionType == RigWellResultFrame::WATER_INJECTOR) ) + || (!useInjectors && wellResFrame.m_productionType == RigWellResultFrame::PRODUCER); + + + if (useWell) + { + std::string wellname = wellResults[wIdx]->m_wellName.toStdString(); + std::vector& tracerCells = tracersWithCells[wellname]; + + for (const RigWellResultBranch& wBr: wellResFrame.m_wellResultBranches) + { + for (const RigWellResultPoint& wrp: wBr.m_branchResultPoints) + { + if (wrp.isValid() && wrp.m_isOpen) + { + RigGridBase * grid = mainGrid->gridByIndex(wrp.m_gridIndex); + size_t reservoirCellIndex = grid->reservoirCellIndex(wrp.m_gridCellIndex); + + int cellActiveIndex = static_cast(activeCellInfo->cellResultIndex(reservoirCellIndex)); + tracerCells.push_back(cellActiveIndex); + } + } + } + } + } + } + + return tracersWithCells; +} + + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.h b/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.h index 3bf940e184..f55d76a645 100644 --- a/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.h +++ b/ApplicationCode/ProjectDataModel/RimFlowDiagSolution.h @@ -23,8 +23,11 @@ #include "cafPdmPointer.h" #include "cafAppEnum.h" -class RimEclipseWell; +#include "cvfBase.h" +#include "cvfObject.h" +class RimEclipseWell; +class RigFlowDiagResults; //================================================================================================== /// /// @@ -33,12 +36,15 @@ class RimFlowDiagSolution : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: - RimFlowDiagSolution(void); - virtual ~RimFlowDiagSolution(void); + RimFlowDiagSolution(); + virtual ~RimFlowDiagSolution(); - QString userDescription() { return m_userDescription();} + QString userDescription() { return m_userDescription();} + RigFlowDiagResults* flowDiagResults(); + std::set tracerNames(); - std::set tracerNames(); + std::map > allInjectorTracerActiveCellIndices(size_t timeStepIndex); + std::map > allProducerTracerActiveCellIndices(size_t timeStepIndex); enum TracerStatusType { @@ -50,12 +56,17 @@ public: TracerStatusType tracerStatus(QString tracerName); + protected: //virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; private: + std::map > allTracerActiveCellIndices(size_t timeStepIndex, bool useInjectors); + virtual caf::PdmFieldHandle* userDescriptionField() override; caf::PdmField m_userDescription; + cvf::ref m_flowDiagResults; + //caf::PdmPtrArrayField m_selectedWells; }; diff --git a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp index 6e69b7b66b..9a3db92292 100644 --- a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp @@ -19,7 +19,11 @@ #include "RimMultiSnapshotDefinition.h" #include "RiaApplication.h" + +#include "RigActiveCellInfo.h" + #include "RimCase.h" +#include "RimCellRangeFilterCollection.h" #include "RimProject.h" #include "RimView.h" @@ -33,6 +37,7 @@ namespace caf addItem(RimMultiSnapshotDefinition::RANGEFILTER_I, "I", "i-direction"); addItem(RimMultiSnapshotDefinition::RANGEFILTER_J, "J", "j-direction"); addItem(RimMultiSnapshotDefinition::RANGEFILTER_K, "K", "k-direction"); + addItem(RimMultiSnapshotDefinition::NO_RANGEFILTER, "None", "None"); setDefault(RimMultiSnapshotDefinition::RANGEFILTER_K); } @@ -48,16 +53,15 @@ RimMultiSnapshotDefinition::RimMultiSnapshotDefinition() //CAF_PDM_InitObject("MultiSnapshotDefinition", ":/Well.png", "", ""); CAF_PDM_InitObject("MultiSnapshotDefinition", "", "", ""); - CAF_PDM_InitFieldNoDefault(&caseObject, "Case", "Case", "", "", ""); CAF_PDM_InitFieldNoDefault(&viewObject, "View", "View", "", "", ""); CAF_PDM_InitField(&timeStepStart, "TimeStepStart", 0, "Timestep Start", "", "", ""); CAF_PDM_InitField(&timeStepEnd, "TimeStepEnd", 0, "Timestep End", "", "", ""); - CAF_PDM_InitField(&sliceDirection, "SnapShotDirection", caf::AppEnum(RANGEFILTER_K), "Range Filter direction", "", "", ""); - CAF_PDM_InitField(&startSliceIndex, "RangeFilterStart", 0, "RangeFilter Start", "", "", ""); - CAF_PDM_InitField(&endSliceIndex, "RangeFilterEnd", 0, "RangeFilter End", "", "", ""); - + CAF_PDM_InitField(&sliceDirection, "SnapShotDirection", caf::AppEnum(NO_RANGEFILTER), "Range Filter direction", "", "", ""); + CAF_PDM_InitField(&startSliceIndex, "RangeFilterStart", 1, "RangeFilter Start", "", "", ""); + CAF_PDM_InitField(&endSliceIndex, "RangeFilterEnd", 1, "RangeFilter End", "", "", ""); + CAF_PDM_InitFieldNoDefault(&additionalCases, "AdditionalCases", "Additional Cases", "", "", ""); } @@ -77,41 +81,50 @@ QList RimMultiSnapshotDefinition::calculateValueOptions( RimProject* proj = RiaApplication::instance()->project(); - if (fieldNeedingOptions == &caseObject && proj) + if (fieldNeedingOptions == &viewObject) { + std::vector views; + + RimProject* proj = RiaApplication::instance()->project(); std::vector cases; proj->allCases(cases); - for (RimCase* c : cases) + for (RimCase* rimCase : cases) { - options.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), QVariant::fromValue(caf::PdmPointer(c)))); - } - - //options.push_back(caf::PdmOptionItemInfo("All", QVariant::fromValue(caf::PdmPointer(nullptr)))); - } - else if (fieldNeedingOptions == &viewObject) - { - if (caseObject()) - { - std::vector views = caseObject()->views(); - for (RimView* view : views) + for (RimView* rimView : rimCase->views()) { - options.push_back(caf::PdmOptionItemInfo(view->name(), QVariant::fromValue(caf::PdmPointer(view)))); + views.push_back(rimView); } } - //options.push_back(caf::PdmOptionItemInfo("All", QVariant::fromValue(caf::PdmPointer(nullptr)))); + for (RimView* view : views) + { + QString caseAndView = view->ownerCase()->caseUserDescription() + " - " + view->name(); + options.push_back(caf::PdmOptionItemInfo(caseAndView, view)); + } + options.push_back(caf::PdmOptionItemInfo("-- All views --", nullptr)); } else if (fieldNeedingOptions == &timeStepEnd) { getTimeStepStrings(options); - } else if (fieldNeedingOptions == &timeStepStart) { getTimeStepStrings(options); } + else if (fieldNeedingOptions == &additionalCases) + { + RimProject* proj = RiaApplication::instance()->project(); + std::vector cases; + proj->allCases(cases); + for (RimCase* rimCase : cases) + { + options.push_back(caf::PdmOptionItemInfo(rimCase->caseUserDescription(), rimCase)); + } + + if (useOptionsOnly) *useOptionsOnly = true; + } return options; } @@ -121,13 +134,72 @@ QList RimMultiSnapshotDefinition::calculateValueOptions( //-------------------------------------------------------------------------------------------------- void RimMultiSnapshotDefinition::getTimeStepStrings(QList &options) { - if (!caseObject()) return; - - QStringList timeSteps = caseObject()->timeStepStrings(); + QStringList timeSteps; + + timeSteps = viewObject->ownerCase()->timeStepStrings(); + for (int i = 0; i < timeSteps.size(); i++) { options.push_back(caf::PdmOptionItemInfo(timeSteps[i], i)); } - +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMultiSnapshotDefinition::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + + if (changedField == &sliceDirection) + { + const cvf::StructGridInterface* mainGrid = nullptr; + RigActiveCellInfo* actCellInfo = nullptr; + + if (viewObject()) + { + mainGrid = viewObject()->rangeFilterCollection()->gridByIndex(0); + actCellInfo = viewObject()->rangeFilterCollection()->activeCellInfo(); + } + + if (mainGrid && actCellInfo) + { + cvf::Vec3st min, max; + actCellInfo->IJKBoundingBox(min, max); + + // Adjust to Eclipse indexing + min.x() = min.x() + 1; + min.y() = min.y() + 1; + min.z() = min.z() + 1; + + max.x() = max.x() + 1; + max.y() = max.y() + 1; + max.z() = max.z() + 1; + + int maxInt = 0; + int minInt = 0; + + if (newValue == RimMultiSnapshotDefinition::RANGEFILTER_I) + { + maxInt = static_cast(max.x()); + minInt = static_cast(min.x()); + } + else if (newValue == RimMultiSnapshotDefinition::RANGEFILTER_J) + { + maxInt = static_cast(max.y()); + minInt = static_cast(min.y()); + } + else if (newValue == RimMultiSnapshotDefinition::RANGEFILTER_K) + { + maxInt = static_cast(max.z()); + minInt = static_cast(min.z()); + } + + startSliceIndex = minInt; + endSliceIndex = maxInt; + + } + + startSliceIndex.uiCapability()->updateConnectedEditors(); + } } diff --git a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h index 11a328d7f7..f73e1bc995 100644 --- a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h @@ -18,10 +18,11 @@ #pragma once +#include "cafAppEnum.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPtrField.h" -#include "cafAppEnum.h" +#include "cafPdmPtrArrayField.h" class RimCase; class RimView; @@ -37,7 +38,6 @@ public: RimMultiSnapshotDefinition(); virtual ~RimMultiSnapshotDefinition(); - caf::PdmPtrField caseObject; caf::PdmPtrField viewObject; caf::PdmField timeStepStart; @@ -47,16 +47,20 @@ public: { RANGEFILTER_I, RANGEFILTER_J, - RANGEFILTER_K + RANGEFILTER_K, + NO_RANGEFILTER }; caf::PdmField< caf::AppEnum< SnapShotDirectionEnum > > sliceDirection; caf::PdmField startSliceIndex; caf::PdmField endSliceIndex; + caf::PdmPtrArrayField additionalCases; + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; void getTimeStepStrings(QList &options); - + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; }; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index bd52b976a8..8fe8d1a4af 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -180,6 +180,8 @@ void RimProject::close() commandObjects.deleteAllChildObjects(); + multiSnapshotDefinitions.deleteAllChildObjects(); + delete viewLinkerCollection->viewLinker(); viewLinkerCollection->viewLinker = NULL; diff --git a/ApplicationCode/ProjectDataModel/RimViewController.cpp b/ApplicationCode/ProjectDataModel/RimViewController.cpp index da28fa0a79..3081fc57f0 100644 --- a/ApplicationCode/ProjectDataModel/RimViewController.cpp +++ b/ApplicationCode/ProjectDataModel/RimViewController.cpp @@ -67,6 +67,7 @@ RimViewController::RimViewController(void) m_managedView.uiCapability()->setUiTreeChildrenHidden(true); CAF_PDM_InitField(&m_syncCamera, "SyncCamera", true, "Camera", "", "", ""); + CAF_PDM_InitField(&m_showCursor, "ShowCursor", true, " Show Cursor", "", "", ""); CAF_PDM_InitField(&m_syncTimeStep, "SyncTimeStep", true, "Time Step", "", "", ""); CAF_PDM_InitField(&m_syncCellResult, "SyncCellResult", false, "Cell Result", "", "", ""); CAF_PDM_InitField(&m_syncLegendDefinitions, "SyncLegendDefinitions", true, " Legend Definition", "", "", ""); @@ -174,6 +175,13 @@ void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField { updateTimeStepLink(); } + else if (changedField == &m_showCursor) + { + if (!m_showCursor && m_managedView && m_managedView->viewer()) + { + m_managedView->viewer()->setCursorPosition(cvf::Vec3d::UNDEFINED); + } + } else if (changedField == &m_syncCellResult) { updateResultColorsControl(); @@ -223,7 +231,7 @@ void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimEclipseView* RimViewController::managedEclipseView() +RimEclipseView* RimViewController::managedEclipseView() const { RimView* rimView = m_managedView; @@ -233,7 +241,7 @@ RimEclipseView* RimViewController::managedEclipseView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimGeoMechView* RimViewController::managedGeoView() +RimGeoMechView* RimViewController::managedGeoView() const { RimView* rimView = m_managedView; @@ -418,13 +426,23 @@ void RimViewController::updateOptionSensitivity() this->m_syncRangeFilters = false; } + if (m_syncCamera) + { + this->m_showCursor.uiCapability()->setUiReadOnly(false); + } + else + { + this->m_showCursor.uiCapability()->setUiReadOnly(true); + this->m_showCursor = false; + } + m_syncVisibleCells.uiCapability()->setUiReadOnly(!this->isMasterAndDepViewDifferentType()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimView* RimViewController::managedView() +RimView* RimViewController::managedView() const { return m_managedView; } @@ -455,6 +473,7 @@ void RimViewController::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderin caf::PdmUiGroup* scriptGroup = uiOrdering.addNewGroup("Link Options"); scriptGroup->add(&m_syncCamera); + scriptGroup->add(&m_showCursor); scriptGroup->add(&m_syncTimeStep); scriptGroup->add(&m_syncCellResult); scriptGroup->add(&m_syncLegendDefinitions); @@ -530,7 +549,7 @@ void RimViewController::updateLegendDefinitions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimViewLinker* RimViewController::ownerViewLinker() +RimViewLinker* RimViewController::ownerViewLinker() const { RimViewLinker* viewLinker = NULL; this->firstAncestorOrThisOfType(viewLinker); @@ -609,7 +628,7 @@ const RigCaseToCaseCellMapper* RimViewController::cellMapper() } else if (masterFemPart && dependEclGrid) { - m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterFemPart, dependEclGrid); + m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterFemPart, dependEclGrid); } } @@ -619,7 +638,7 @@ const RigCaseToCaseCellMapper* RimViewController::cellMapper() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimView* RimViewController::masterView() +RimView* RimViewController::masterView() const { return ownerViewLinker()->masterView(); } @@ -627,7 +646,7 @@ RimView* RimViewController::masterView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isMasterAndDepViewDifferentType() +bool RimViewController::isMasterAndDepViewDifferentType() const { RimEclipseView* eclipseMasterView = dynamic_cast(masterView()); RimGeoMechView* geoMasterView = dynamic_cast(masterView()); @@ -648,7 +667,7 @@ bool RimViewController::isMasterAndDepViewDifferentType() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimViewController::scheduleCreateDisplayModelAndRedrawForDependentView() +void RimViewController::scheduleCreateDisplayModelAndRedrawForDependentView() const { if (!this->isActive()) return; @@ -668,7 +687,7 @@ void RimViewController::scheduleCreateDisplayModelAndRedrawForDependentView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimViewController::scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType) +void RimViewController::scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType) const { if (!this->isActive()) return; @@ -693,7 +712,7 @@ void RimViewController::scheduleGeometryRegenForDepViews(RivCellSetEnum geometry //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isActive() +bool RimViewController::isActive() const { return ownerViewLinker()->isActive() && this->m_isActive(); } @@ -701,7 +720,7 @@ bool RimViewController::isActive() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isCameraLinked() +bool RimViewController::isCameraLinked() const { if (ownerViewLinker()->isActive() && this->m_isActive()) { @@ -716,7 +735,15 @@ bool RimViewController::isCameraLinked() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isTimeStepLinked() +bool RimViewController::showCursor() const +{ + return m_showCursor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isTimeStepLinked() const { if (ownerViewLinker()->isActive() && this->m_isActive()) { @@ -731,7 +758,7 @@ bool RimViewController::isTimeStepLinked() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isResultColorControlled() +bool RimViewController::isResultColorControlled() const { if (ownerViewLinker()->isActive() && this->m_isActive()) { @@ -746,7 +773,7 @@ bool RimViewController::isResultColorControlled() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isLegendDefinitionsControlled() +bool RimViewController::isLegendDefinitionsControlled() const { if (ownerViewLinker()->isActive() && this->m_isActive()) { @@ -761,7 +788,7 @@ bool RimViewController::isLegendDefinitionsControlled() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isVisibleCellsOveridden() +bool RimViewController::isVisibleCellsOveridden() const { if (isMasterAndDepViewDifferentType()) { @@ -783,7 +810,7 @@ bool RimViewController::isVisibleCellsOveridden() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isRangeFilterControlPossible() +bool RimViewController::isRangeFilterControlPossible() const { return true; #if 0 @@ -817,7 +844,7 @@ bool RimViewController::isRangeFilterControlPossible() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isRangeFilterMappingApliccable() +bool RimViewController::isRangeFilterMappingApliccable() const { if (!isMasterAndDepViewDifferentType()) return false; @@ -850,7 +877,7 @@ bool RimViewController::isRangeFilterMappingApliccable() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isRangeFiltersControlled() +bool RimViewController::isRangeFiltersControlled() const { if (!isRangeFilterControlPossible()) return false; @@ -866,7 +893,7 @@ bool RimViewController::isRangeFiltersControlled() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isPropertyFilterControlPossible() +bool RimViewController::isPropertyFilterControlPossible() const { // The cases need to be the same RimGeoMechView* geomView = dynamic_cast(masterView()); @@ -898,7 +925,7 @@ bool RimViewController::isPropertyFilterControlPossible() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isPropertyFilterOveridden() +bool RimViewController::isPropertyFilterOveridden() const { if (!isPropertyFilterControlPossible()) return false; diff --git a/ApplicationCode/ProjectDataModel/RimViewController.h b/ApplicationCode/ProjectDataModel/RimViewController.h index b3eb903dae..e8eda82175 100644 --- a/ApplicationCode/ProjectDataModel/RimViewController.h +++ b/ApplicationCode/ProjectDataModel/RimViewController.h @@ -47,28 +47,29 @@ public: RimViewController(void); virtual ~RimViewController(void); - bool isActive(); + bool isActive() const; - RimView* managedView(); + RimView* managedView() const; void setManagedView(RimView* view); - RimView* masterView(); - RimViewLinker* ownerViewLinker(); + RimView* masterView() const; + RimViewLinker* ownerViewLinker() const; const RigCaseToCaseCellMapper* cellMapper(); - bool isCameraLinked(); - bool isTimeStepLinked(); + bool isCameraLinked() const; + bool showCursor() const; + bool isTimeStepLinked() const; - bool isResultColorControlled(); - bool isLegendDefinitionsControlled(); - bool isRangeFiltersControlled(); + bool isResultColorControlled() const; + bool isLegendDefinitionsControlled() const; + bool isRangeFiltersControlled() const; - bool isVisibleCellsOveridden(); - bool isPropertyFilterOveridden(); + bool isVisibleCellsOveridden() const; + bool isPropertyFilterOveridden() const; - void scheduleCreateDisplayModelAndRedrawForDependentView(); - void scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType); + void scheduleCreateDisplayModelAndRedrawForDependentView() const; + void scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType) const; void updateOverrides(); void updateOptionSensitivity(); void removeOverrides(); @@ -93,24 +94,27 @@ private: void updateResultColorsControl(); void updateLegendDefinitions(); - bool isMasterAndDepViewDifferentType(); - bool isRangeFilterControlPossible(); - bool isPropertyFilterControlPossible(); - bool isRangeFilterMappingApliccable(); + bool isMasterAndDepViewDifferentType() const; + bool isRangeFilterControlPossible() const; + bool isPropertyFilterControlPossible() const; + bool isRangeFilterMappingApliccable() const; - RimEclipseView* managedEclipseView(); - RimGeoMechView* managedGeoView(); + RimEclipseView* managedEclipseView() const; + RimGeoMechView* managedGeoView() const; + static void removeOverrides(RimView* view); - static bool askUserToRestoreOriginalRangeFilterCollection(const QString& viewName); + private: caf::PdmField m_name; caf::PdmPtrField m_managedView; caf::PdmField m_isActive; caf::PdmField m_syncCamera; + caf::PdmField m_showCursor; caf::PdmField m_syncTimeStep; + // Overridden properties caf::PdmField m_syncCellResult; caf::PdmField m_syncLegendDefinitions; diff --git a/ApplicationCode/ProjectDataModel/RimViewLinker.cpp b/ApplicationCode/ProjectDataModel/RimViewLinker.cpp index bde63a1260..3fa9b6111a 100644 --- a/ApplicationCode/ProjectDataModel/RimViewLinker.cpp +++ b/ApplicationCode/ProjectDataModel/RimViewLinker.cpp @@ -142,9 +142,7 @@ void RimViewLinker::updateCellResult() { if (viewLink->isResultColorControlled()) { - eclipeView->cellResult()->setPorosityModel(eclipseCellResultDefinition->porosityModel()); - eclipeView->cellResult()->setResultType(eclipseCellResultDefinition->resultType()); - eclipeView->cellResult()->setResultVariable(eclipseCellResultDefinition->resultVariable()); + eclipeView->cellResult()->simpleCopy(eclipseCellResultDefinition); if (viewLink->isLegendDefinitionsControlled()) { @@ -247,7 +245,7 @@ void RimViewLinker::removeOverrides() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimViewLinker::allViewsForCameraSync(RimView* source, std::vector& views) +void RimViewLinker::allViewsForCameraSync(const RimView* source, std::vector& views) const { if (!isActive()) return; @@ -322,7 +320,7 @@ void RimViewLinker::setMasterView(RimView* view) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimView* RimViewLinker::masterView() +RimView* RimViewLinker::masterView() const { return m_masterView; } @@ -330,7 +328,7 @@ RimView* RimViewLinker::masterView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimViewLinker::allViews(std::vector& views) +void RimViewLinker::allViews(std::vector& views) const { views.push_back(m_masterView()); @@ -382,7 +380,7 @@ void RimViewLinker::updateScaleZ(RimView* sourceView, double scaleZ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimViewLinker::isActive() +bool RimViewLinker::isActive() const { RimViewLinkerCollection* viewLinkerCollection = NULL; this->firstAncestorOrThisOfType(viewLinkerCollection); @@ -482,6 +480,40 @@ void RimViewLinker::findNameAndIconFromView(QString* name, QIcon* icon, RimView* } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateCursorPosition(const RimView* sourceView, const cvf::Vec3d& domainCoord) +{ + RimViewController* sourceViewLink = sourceView->viewController(); + if (sourceViewLink && !sourceViewLink->showCursor()) + { + return; + } + + std::vector viewsToUpdate; + allViewsForCameraSync(sourceView, viewsToUpdate); + + for (RimView* destinationView : viewsToUpdate) + { + if (destinationView == sourceView) continue; + + if (destinationView != m_masterView) + { + RimViewController* viewLink = destinationView->viewController(); + if (!viewLink) continue; + + if (!viewLink->showCursor()) continue; + } + + RiuViewer* destinationViewer = destinationView->viewer(); + if (destinationViewer) + { + destinationViewer->setCursorPosition(domainCoord); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -626,18 +658,16 @@ void RimViewLinker::addDependentView(RimView* view) this->m_viewControllers.push_back(viewContr); viewContr->setManagedView(view); - - } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimViewLinker::addViewControllers(caf::PdmUiTreeOrdering& uiTreeOrdering) +void RimViewLinker::addViewControllers(caf::PdmUiTreeOrdering& uiTreeOrdering) const { for (size_t j = 0; j < m_viewControllers.size(); j++) { - uiTreeOrdering.add(m_viewControllers()[j]); + uiTreeOrdering.add(m_viewControllers[j]); } } diff --git a/ApplicationCode/ProjectDataModel/RimViewLinker.h b/ApplicationCode/ProjectDataModel/RimViewLinker.h index b453b2a74d..61c39d8f54 100644 --- a/ApplicationCode/ProjectDataModel/RimViewLinker.h +++ b/ApplicationCode/ProjectDataModel/RimViewLinker.h @@ -28,6 +28,9 @@ #include "cafPdmObject.h" #include "cafPdmPtrField.h" +#include "cvfBase.h" +#include "cvfVector3.h" + namespace cvf { class BoundingBox; @@ -50,10 +53,10 @@ public: RimViewLinker(void); virtual ~RimViewLinker(void); - bool isActive(); + bool isActive() const; void setMasterView(RimView* view); - RimView* masterView(); + RimView* masterView() const; void addDependentView(RimView* view); void updateDependentViews(); @@ -73,15 +76,17 @@ public: void scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType); void scheduleCreateDisplayModelAndRedrawForDependentViews(); - void allViews(std::vector& views); + void allViews(std::vector& views) const; void updateUiNameAndIcon(); - void addViewControllers(caf::PdmUiTreeOrdering& uiTreeOrdering); + void addViewControllers(caf::PdmUiTreeOrdering& uiTreeOrdering) const; static void applyIconEnabledState(caf::PdmObject* obj, const QIcon& icon, bool disable); static void findNameAndIconFromView(QString* name, QIcon* icon, RimView* view); + void updateCursorPosition(const RimView* sourceView, const cvf::Vec3d& domainCoord); + public: static QString displayNameForView(RimView* view); @@ -90,7 +95,7 @@ protected: virtual void initAfterRead(); private: - void allViewsForCameraSync(RimView* source, std::vector& views); + void allViewsForCameraSync(const RimView* source, std::vector& views) const; void removeOverrides(); diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp index b00a0c7b14..fb76e70358 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp @@ -113,6 +113,30 @@ void RimWellLogExtractionCurve::setWellPath(RimWellPath* wellPath) m_wellPath = wellPath; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RimWellLogExtractionCurve::wellPath() const +{ + return m_wellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setCase(RimCase* rimCase) +{ + m_case = rimCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCase* RimWellLogExtractionCurve::rimCase() const +{ + return m_case; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -128,8 +152,8 @@ void RimWellLogExtractionCurve::setPropertiesFromView(RimView* view) RimEclipseView* eclipseView = dynamic_cast(view); if (eclipseView) { - m_eclipseResultDefinition->setResultType(eclipseView->cellResult()->resultType()); - m_eclipseResultDefinition->setResultVariable(eclipseView->cellResult()->resultVariable()); + m_eclipseResultDefinition->simpleCopy(eclipseView->cellResult()); + m_timeStep = eclipseView->currentTimeStep(); } @@ -224,11 +248,10 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate() m_eclipseResultDefinition->loadResult(); - cvf::ref resAcc = RigResultAccessorFactory::createResultAccessor( - eclipseCase->reservoirData(), - 0, - m_timeStep, - m_eclipseResultDefinition); + cvf::ref resAcc = RigResultAccessorFactory::createFromResultDefinition(eclipseCase->reservoirData(), + 0, + m_timeStep, + m_eclipseResultDefinition); if (resAcc.notNull()) { diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h index 0df85b9df2..2ebf168c03 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h @@ -41,8 +41,12 @@ public: RimWellLogExtractionCurve(); virtual ~RimWellLogExtractionCurve(); - void setWellPath(RimWellPath* wellPath); + RimWellPath* wellPath() const; + + void setCase(RimCase* rimCase); + RimCase* rimCase() const; + void setPropertiesFromView(RimView* view); virtual QString wellName() const; diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index 6f63e66697..37b2250550 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -20,6 +20,13 @@ ${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.h ${CEE_CURRENT_LIST_DIR}RigResultModifier.h ${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.h ${CEE_CURRENT_LIST_DIR}RigFormationNames.h +${CEE_CURRENT_LIST_DIR}RigFlowDiagResultAddress.h +${CEE_CURRENT_LIST_DIR}RigFlowDiagResults.h +${CEE_CURRENT_LIST_DIR}RigFlowDiagResultFrames.h +${CEE_CURRENT_LIST_DIR}RigFlowDiagSolverInterface.h +${CEE_CURRENT_LIST_DIR}RigFlowDiagInterfaceTools.h +${CEE_CURRENT_LIST_DIR}RigFlowDiagStatCalc.h +${CEE_CURRENT_LIST_DIR}RigFlowDiagVisibleCellsStatCalc.h ${CEE_CURRENT_LIST_DIR}RigWellLogExtractor.h ${CEE_CURRENT_LIST_DIR}RigEclipseWellLogExtractor.h ${CEE_CURRENT_LIST_DIR}RigLocalGrid.h @@ -59,6 +66,11 @@ ${CEE_CURRENT_LIST_DIR}RigCombTransResultAccessor.cpp ${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.cpp ${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.cpp ${CEE_CURRENT_LIST_DIR}RigFormationNames.cpp +${CEE_CURRENT_LIST_DIR}RigFlowDiagResults.cpp +${CEE_CURRENT_LIST_DIR}RigFlowDiagResultFrames.cpp +${CEE_CURRENT_LIST_DIR}RigFlowDiagSolverInterface.cpp +${CEE_CURRENT_LIST_DIR}RigFlowDiagStatCalc.cpp +${CEE_CURRENT_LIST_DIR}RigFlowDiagVisibleCellsStatCalc.cpp ${CEE_CURRENT_LIST_DIR}RigWellLogExtractor.cpp ${CEE_CURRENT_LIST_DIR}RigEclipseWellLogExtractor.cpp ${CEE_CURRENT_LIST_DIR}RigLocalGrid.cpp diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp index 2db41e94b7..f09a8d8fc8 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp @@ -25,7 +25,7 @@ #include -RigActiveCellsResultAccessor::RigActiveCellsResultAccessor(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) +RigActiveCellsResultAccessor::RigActiveCellsResultAccessor(const RigGridBase* grid, const std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) : m_grid(grid), m_reservoirResultValues(reservoirResultValues), m_activeCellInfo(activeCellInfo) diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h index 2f48e6e682..41a27903a3 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h @@ -31,7 +31,7 @@ class RigActiveCellInfo; class RigActiveCellsResultAccessor : public RigResultAccessor { public: - RigActiveCellsResultAccessor(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo); + RigActiveCellsResultAccessor(const RigGridBase* grid, const std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo); virtual double cellScalar(size_t gridLocalCellIndex) const; virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; @@ -42,6 +42,6 @@ public: private: const RigActiveCellInfo* m_activeCellInfo; const RigGridBase* m_grid; - std::vector* m_reservoirResultValues; + const std::vector* m_reservoirResultValues; }; diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h b/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h index 0012bb6741..a6274adb2b 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h @@ -21,33 +21,26 @@ #include "RigStatisticsCalculator.h" -#include "cvfBase.h" -#include "cvfObject.h" -#include "cvfCollection.h" - class RigHistogramCalculator; class RigCaseCellResultsData; //================================================================================================== /// //================================================================================================== + class RigEclipseNativeStatCalc : public RigStatisticsCalculator { public: RigEclipseNativeStatCalc(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndex); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); - - virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); - - virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); - + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); + virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); virtual void uniqueValues(size_t timeStepIndex, std::set& values); - virtual size_t timeStepCount(); private: RigCaseCellResultsData* m_resultsData; - size_t m_scalarResultIndex; + size_t m_scalarResultIndex; }; diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagInterfaceTools.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagInterfaceTools.h new file mode 100644 index 0000000000..7861663ef4 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagInterfaceTools.h @@ -0,0 +1,131 @@ + +#pragma once + + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace RigFlowDiagInterfaceTools { + + + inline Opm::FlowDiagnostics::ConnectionValues + extractFluxField(const Opm::ECLGraph& G) + { + using ConnVals = Opm::FlowDiagnostics::ConnectionValues; + + using NConn = ConnVals::NumConnections; + using NPhas = ConnVals::NumPhases; + + const auto nconn = NConn{G.numConnections()}; + const auto nphas = NPhas{3}; + + auto flux = ConnVals(nconn, nphas); + + auto phas = ConnVals::PhaseID{0}; + + for (const auto& p : { Opm::ECLGraph::PhaseIndex::Aqua , + Opm::ECLGraph::PhaseIndex::Liquid , + Opm::ECLGraph::PhaseIndex::Vapour }) + { + const std::vector pflux = G.flux(p); + + if (! pflux.empty()) { + assert (pflux.size() == nconn.total); + + auto conn = ConnVals::ConnID{0}; + + for (const auto& v : pflux) { + flux(conn, phas) = v; + + conn.id += 1; + } + } + + phas.id += 1; + } + + return flux; + } + + template + Opm::FlowDiagnostics::CellSetValues + extractWellFlows(const Opm::ECLGraph& G, + const WellFluxes& well_fluxes) + { + Opm::FlowDiagnostics::CellSetValues inflow; + for (const auto& well : well_fluxes) { + for (const auto& completion : well.completions) { + const int grid_index = completion.grid_index; + const auto& ijk = completion.ijk; + const int cell_index = G.activeCell(ijk, grid_index); + if (cell_index >= 0) { + inflow.emplace(cell_index, completion.reservoir_inflow_rate); + } + } + } + + return inflow; + } + + namespace Hack { + inline Opm::FlowDiagnostics::ConnectionValues + convert_flux_to_SI(Opm::FlowDiagnostics::ConnectionValues&& fl) + { + using Co = Opm::FlowDiagnostics::ConnectionValues::ConnID; + using Ph = Opm::FlowDiagnostics::ConnectionValues::PhaseID; + + const auto nconn = fl.numConnections(); + const auto nphas = fl.numPhases(); + + for (auto phas = Ph{0}; phas.id < nphas; ++phas.id) { + for (auto conn = Co{0}; conn.id < nconn; ++conn.id) { + fl(conn, phas) /= 86400; + } + } + + return fl; + } + } + + inline Opm::FlowDiagnostics::Toolbox + initialiseFlowDiagnostics(const Opm::ECLGraph& G) + { + const Opm::FlowDiagnostics::ConnectivityGraph connGraph = + Opm::FlowDiagnostics::ConnectivityGraph{ static_cast(G.numCells()), + G.neighbours() }; + + // Create the Toolbox. + + Opm::FlowDiagnostics::Toolbox tool = Opm::FlowDiagnostics::Toolbox{ connGraph }; + + tool.assignPoreVolume(G.poreVolume()); + + Opm::FlowDiagnostics::ConnectionValues connectionsVals = Hack::convert_flux_to_SI(extractFluxField(G)); + tool.assignConnectionFlux(connectionsVals); + + Opm::ECLWellSolution wsol = Opm::ECLWellSolution{}; + + const std::vector well_fluxes = + wsol.solution(G.rawResultData(), G.numGrids()); + + tool.assignInflowFlux(extractWellFlows(G, well_fluxes)); + + return tool; + } + + + +} + + + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResultAddress.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultAddress.h new file mode 100644 index 0000000000..ee34af7ffb --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultAddress.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- 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 +#include + +#define RIG_FLD_TOF_RESNAME "TOF" +#define RIG_FLD_CELL_FRACTION_RESNAME "Fraction" +#define RIG_FLD_MAX_FRACTION_TRACER_RESNAME "MaxFractionTracer" +#define RIG_FLD_COMMUNICATION_RESNAME "Communication" + +class RigFlowDiagResultAddress +{ + +public: + RigFlowDiagResultAddress(const std::string& aVariableName, const std::set& someSelectedTracerNames) + : variableName(aVariableName), selectedTracerNames(someSelectedTracerNames) {} + + RigFlowDiagResultAddress(const std::string& aVariableName, const std::string& tracerName) + : variableName(aVariableName) + { + selectedTracerNames.insert(tracerName); + } + + bool isNativeResult() { return ( ( (variableName == RIG_FLD_TOF_RESNAME) || (variableName == RIG_FLD_CELL_FRACTION_RESNAME) ) && selectedTracerNames.size() <= 1); } + + std::string variableName; + std::set selectedTracerNames; + + bool operator< (const RigFlowDiagResultAddress& other) const + { + if ( selectedTracerNames != other.selectedTracerNames ) + { + return selectedTracerNames < other.selectedTracerNames; + } + + return variableName < other.variableName; + } +}; + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.cpp new file mode 100644 index 0000000000..17802af085 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.cpp @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 + +#include "RigFlowDiagResultFrames.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResultFrames::RigFlowDiagResultFrames(size_t frameCount) +{ + m_dataForEachFrame.resize(frameCount); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResultFrames::~RigFlowDiagResultFrames() +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigFlowDiagResultFrames::frameCount() const +{ + return m_dataForEachFrame.size(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RigFlowDiagResultFrames::frameData(size_t frameIndex) +{ + return m_dataForEachFrame[frameIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigFlowDiagResultFrames::frameData(size_t frameIndex) const +{ + return m_dataForEachFrame[frameIndex]; +} diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.h new file mode 100644 index 0000000000..ea4ae8ec22 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- 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 "cvfBase.h" +#include "cvfObject.h" + +#include + +class RigFlowDiagResultFrames: public cvf::Object +{ +public: + RigFlowDiagResultFrames(size_t frameCount); + virtual ~RigFlowDiagResultFrames(); + + const + std::vector& frameData(size_t frameIndex) const; + std::vector& frameData(size_t frameIndex); + size_t frameCount() const; + +private: + std::vector< std::vector > m_dataForEachFrame; +}; + + + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp new file mode 100644 index 0000000000..7513f78d0f --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.cpp @@ -0,0 +1,298 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- 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 "RigFlowDiagResults.h" +#include "RigFlowDiagSolverInterface.h" +#include "RimFlowDiagSolution.h" +#include "RimEclipseResultCase.h" +#include "RimEclipseCase.h" +#include "RigCaseData.h" +#include "RigFlowDiagStatCalc.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResults::RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount) + : m_flowDiagSolution(flowSolution) +{ + + m_timeStepCount = timeStepCount; + m_hasAtemptedNativeResults.resize(timeStepCount, false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResults::~RigFlowDiagResults() +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector* RigFlowDiagResults::resultValues(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex) +{ + CVF_ASSERT(m_timeStepCount != cvf::UNDEFINED_SIZE_T); // Forgotten to call init + + return findOrCalculateResult(resVarAddr, frameIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigActiveCellInfo * RigFlowDiagResults::activeCellInfo(const RigFlowDiagResultAddress& resVarAddr) +{ + RimEclipseResultCase* eclCase; + m_flowDiagSolution->firstAncestorOrThisOfType(eclCase); + + return eclCase->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); // Todo: base on resVarAddr member +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector* RigFlowDiagResults::findOrCalculateResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex) +{ + + std::vector* frameData = findScalarResultFrame(resVarAddr, frameIndex); + + if ( frameData ) return frameData; + + frameData = calculateDerivedResult(resVarAddr, frameIndex); + + if ( frameData ) return frameData; + + // We need to access the native data from the opm solver + + if (!m_hasAtemptedNativeResults[frameIndex]) + { + + RigFlowDiagTimeStepResult nativeTimestepResults = solverInterface()->calculate(frameIndex, + m_flowDiagSolution->allInjectorTracerActiveCellIndices(frameIndex), + m_flowDiagSolution->allProducerTracerActiveCellIndices(frameIndex)); + + std::map >& nativeResults = nativeTimestepResults.nativeResults(); + + for ( auto& resIt: nativeResults ) + { + RigFlowDiagResultFrames* nativeResFrames = findScalarResult(resIt.first); + if ( !nativeResFrames ) nativeResFrames = createScalarResult(resIt.first); + + nativeResFrames->frameData(frameIndex).swap(resIt.second); + } + + m_hasAtemptedNativeResults[frameIndex] = true; + } + + return findScalarResultFrame(resVarAddr, frameIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector* RigFlowDiagResults::findScalarResultFrame(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex) +{ + RigFlowDiagResultFrames* resFrames = findScalarResult (resVarAddr); + + if ( resFrames ) + { + std::vector& frame = resFrames->frameData(frameIndex); + if ( frame.size() ) return(&frame); + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagSolverInterface* RigFlowDiagResults::solverInterface() +{ + RimEclipseResultCase* eclCase; + m_flowDiagSolution->firstAncestorOrThisOfType(eclCase); + + return eclCase->flowDiagSolverInterface(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResultFrames* RigFlowDiagResults::createScalarResult(const RigFlowDiagResultAddress& resVarAddr) +{ + cvf::ref newFrameSet = new RigFlowDiagResultFrames(m_timeStepCount); + m_resultSets[resVarAddr] = newFrameSet; + + return newFrameSet.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResultFrames* RigFlowDiagResults::findScalarResult(const RigFlowDiagResultAddress& resVarAddr) +{ + decltype(m_resultSets)::iterator it = m_resultSets.find(resVarAddr); + + if ( it == m_resultSets.end() ) return nullptr; + + return it->second.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector* RigFlowDiagResults::calculateDerivedResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex) +{ + return nullptr; // Todo +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigStatisticsDataCache* RigFlowDiagResults::statistics(const RigFlowDiagResultAddress& resVarAddr) +{ + RigStatisticsDataCache* statCache = m_resultStatistics[resVarAddr].p(); + if ( !statCache ) + { + RigFlowDiagStatCalc* calculator = new RigFlowDiagStatCalc(this, resVarAddr); + statCache = new RigStatisticsDataCache(calculator); + m_resultStatistics[resVarAddr] = statCache; + } + + return statCache; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::minMaxScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, + double* localMin, double* localMax) +{ + this->statistics(resVarAddr)->minMaxCellScalarValues(frameIndex, *localMin, *localMax); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::minMaxScalarValues(const RigFlowDiagResultAddress& resVarAddr, + double* globalMin, double* globalMax) +{ + this->statistics(resVarAddr)->minMaxCellScalarValues(*globalMin, *globalMax); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* localPosClosestToZero, double* localNegClosestToZero) +{ + this->statistics(resVarAddr)->posNegClosestToZero(frameIndex, *localPosClosestToZero, *localNegClosestToZero); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, double* globalPosClosestToZero, double* globalNegClosestToZero) +{ + this->statistics(resVarAddr)->posNegClosestToZero(*globalPosClosestToZero, *globalNegClosestToZero); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* meanValue) +{ + CVF_ASSERT(meanValue); + + this->statistics(resVarAddr)->meanCellScalarValues(*meanValue); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* meanValue) +{ + this->statistics(resVarAddr)->meanCellScalarValues(frameIndex, *meanValue); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, double* p10, double* p90) +{ + this->statistics(resVarAddr)->p10p90CellScalarValues(*p10, *p90); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* p10, double* p90) +{ + this->statistics(resVarAddr)->p10p90CellScalarValues(frameIndex, *p10, *p90); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* sum) +{ + CVF_ASSERT(sum); + + this->statistics(resVarAddr)->sumCellScalarValues(*sum); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagResults::sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* sum) +{ + CVF_ASSERT(sum); + + this->statistics(resVarAddr)->sumCellScalarValues(frameIndex, *sum); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigFlowDiagResults::scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr) +{ + return this->statistics(resVarAddr)->cellScalarValuesHistogram(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigFlowDiagResults::scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr, int frameIndex) +{ + return this->statistics(resVarAddr)->cellScalarValuesHistogram(frameIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigFlowDiagResults::uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr) +{ + return this->statistics(resVarAddr)->uniqueCellScalarValues(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigFlowDiagResults::uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex) +{ + return this->statistics(resVarAddr)->uniqueCellScalarValues(frameIndex); +} diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h new file mode 100644 index 0000000000..935702e16a --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- 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 "RigFlowDiagResultAddress.h" + +#include "cvfBase.h" +#include "cvfObject.h" + +#include +#include +#include + +#include "RigFlowDiagResultFrames.h" +#include "RigStatisticsDataCache.h" +#include "cafPdmPointer.h" + +class RigFlowDiagSolverInterface; +class RimFlowDiagSolution; +class RigActiveCellInfo; + +class RigFlowDiagResults: public cvf::Object +{ +public: + RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount); + virtual ~RigFlowDiagResults(); + + const std::vector* resultValues(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex); + size_t timeStepCount() { return m_timeStepCount; } + const RigActiveCellInfo * activeCellInfo(const RigFlowDiagResultAddress& resVarAddr); + + + void minMaxScalarValues (const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* localMin, double* localMax); + void minMaxScalarValues (const RigFlowDiagResultAddress& resVarAddr, double* globalMin, double* globalMax); + void posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* localPosClosestToZero, double* localNegClosestToZero); + void posNegClosestToZero(const RigFlowDiagResultAddress& resVarAddr, double* globalPosClosestToZero, double* globalNegClosestToZero); + void meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* meanValue); + void meanScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* meanValue); + void p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, double* p10, double* p90); + void p10p90ScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* p10, double* p90); + void sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, double* sum); + void sumScalarValue(const RigFlowDiagResultAddress& resVarAddr, int frameIndex, double* sum); + const std::vector& scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr); + const std::vector& scalarValuesHistogram(const RigFlowDiagResultAddress& resVarAddr, int frameIndex); + const std::vector& uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr); + const std::vector& uniqueCellScalarValues(const RigFlowDiagResultAddress& resVarAddr, int frameIndex); + +private: + const std::vector* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex); + std::vector* calculateDerivedResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex); + RigStatisticsDataCache* statistics(const RigFlowDiagResultAddress& resVarAddr); + + void calculateFractionWeightedTOF (size_t timeStepIdx, std::set selectedTracerNames); + void calculateSumOfFractions ( size_t timeStepIdx, std::set selectedTracerNames); + void calculateTracerWithMaxFraction( size_t timeStepIdx, std::set selectedTracerNames); // Needs a tracer index + void calculateCommunication ( size_t timeStepIdx, std::set selectedTracerNames); + + RigFlowDiagResultFrames* createScalarResult(const RigFlowDiagResultAddress& resVarAddr); + RigFlowDiagResultFrames* findScalarResult (const RigFlowDiagResultAddress& resVarAddr) ; + std::vector* findScalarResultFrame (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex); + + //void deleteScalarResult(const RigFlowDiagResultAddress& resVarAddr); + + size_t m_timeStepCount; + + std::map< RigFlowDiagResultAddress, cvf::ref > m_resultSets; + std::map< RigFlowDiagResultAddress, cvf::ref > m_resultStatistics; + + RigFlowDiagSolverInterface* solverInterface(); + + caf::PdmPointer m_flowDiagSolution; + + std::vector m_hasAtemptedNativeResults; +}; + + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp new file mode 100644 index 0000000000..f6e6863efd --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp @@ -0,0 +1,212 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- 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 "RigFlowDiagSolverInterface.h" +#include "RimFlowDiagSolution.h" +#include "RimEclipseResultCase.h" +#include "RigCaseCellResultsData.h" + +#include "RigFlowDiagInterfaceTools.h" +#include "RifEclipseOutputFileTools.h" +#include "RigCaseData.h" +#include "RimEclipseCase.h" +#include "RifReaderInterface.h" +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount) + : m_activeCellCount(activeCellCount) +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagTimeStepResult::setInjectorTracerTOF(const std::string& tracerName, const std::map& cellValues) +{ + std::set tracers; + tracers.insert(tracerName); + + this->addResult(RigFlowDiagResultAddress(RIG_FLD_TOF_RESNAME, tracers), cellValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagTimeStepResult::setInjectorTracerFraction(const std::string& tracerName, const std::map& cellValues) +{ + std::set tracers; + tracers.insert(tracerName); + + this->addResult(RigFlowDiagResultAddress(RIG_FLD_CELL_FRACTION_RESNAME, tracers), cellValues); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagTimeStepResult::setProducerTracerTOF(const std::string& tracerName, const std::map& cellValues) +{ + std::set tracers; + tracers.insert(tracerName); + + this->addResult(RigFlowDiagResultAddress(RIG_FLD_TOF_RESNAME, tracers), cellValues); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagTimeStepResult::setProducerTracerFraction(const std::string& tracerName, const std::map& cellValues) +{ + std::set tracers; + tracers.insert(tracerName); + + this->addResult(RigFlowDiagResultAddress(RIG_FLD_CELL_FRACTION_RESNAME, tracers), cellValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagTimeStepResult::addResult(const RigFlowDiagResultAddress& resAddr, const std::map& cellValues) +{ + std::vector& activeCellValues = m_nativeResults[resAddr]; + activeCellValues.resize(m_activeCellCount, HUGE_VAL); + + for (const auto& pairIt : cellValues) + { + activeCellValues[pairIt.first] = pairIt.second; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagSolverInterface::RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase) +: m_eclipseCase(eclipseCase) +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagSolverInterface::~RigFlowDiagSolverInterface() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepIndex, + std::map > injectorTracers, + std::map > producerTracers) +{ + using namespace Opm::FlowDiagnostics; + + RigFlowDiagTimeStepResult result(m_eclipseCase->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->reservoirActiveCellCount()); + + // Get set of files + QString gridFileName = m_eclipseCase->gridFileName(); + + QStringList m_filesWithSameBaseName; + + if ( !RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(gridFileName, &m_filesWithSameBaseName) ) return result; + + QString initFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_INIT_FILE); + + Opm::ECLGraph graph = Opm::ECLGraph::load(gridFileName.toStdString(), + initFileName.toStdString()); + + // Look for unified restart file + QString restartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE); + + if ( restartFileName.isEmpty() ) + { + // Look for set of restart files (one file per time step) + + QStringList restartFileNames; + restartFileNames = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE); + + size_t restartFileCount = static_cast(restartFileNames.size()); + size_t maxTimeStepCount = m_eclipseCase->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount(); + + if (restartFileCount <= timeStepIndex && restartFileCount != maxTimeStepCount ) + { + QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: Could not find all the restart files. Results will not be loaded."); + return result; + } + + restartFileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file. + restartFileName = restartFileNames[static_cast(timeStepIndex)]; + } + + graph.assignFluxDataSource(restartFileName.toStdString()); + + if ( ! graph.selectReportStep(static_cast(timeStepIndex)) ) + { + QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: Could not find the requested timestep in the result file. Results will not be loaded."); + return result; + } + + { + Toolbox fdTool = RigFlowDiagInterfaceTools::initialiseFlowDiagnostics(graph); + { + std::vector injectorCellSet; + for ( const auto& tIt: injectorTracers ) + { + injectorCellSet.push_back(CellSet(CellSetID(tIt.first), tIt.second)); + } + + Solution injSol = fdTool.computeInjectionDiagnostics(injectorCellSet).fd; + + for ( const CellSetID& tracerId: injSol.startPoints() ) + { + CellSetValues tofVals = injSol.timeOfFlight(tracerId); + result.setInjectorTracerTOF(tracerId.to_string(), tofVals); + CellSetValues fracVals = injSol.concentration(tracerId); + result.setInjectorTracerFraction(tracerId.to_string(), fracVals); + } + } + + { + std::vector prodjCellSet; + for ( const auto& tIt: producerTracers ) + { + prodjCellSet.push_back(CellSet(CellSetID(tIt.first), tIt.second)); + } + Solution prodSol = fdTool.computeProductionDiagnostics(prodjCellSet).fd; + for ( const CellSetID& tracerId: prodSol.startPoints() ) + { + CellSetValues tofVals = prodSol.timeOfFlight(tracerId); + result.setProducerTracerTOF(tracerId.to_string(), tofVals); + CellSetValues fracVals = prodSol.concentration(tracerId); + result.setInjectorTracerFraction(tracerId.to_string(), fracVals); + } + } + } + + + return result; // Relying on implicit move constructor +} + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h new file mode 100644 index 0000000000..7149a969fc --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- 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 "RigFlowDiagResultAddress.h" +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmPointer.h" + +#include +#include +#include + +class RimEclipseResultCase; +class RimFlowDiagSolution; + + +class RigFlowDiagTimeStepResult +{ +public: + RigFlowDiagTimeStepResult(size_t activeCellCount); + + void setInjectorTracerTOF (const std::string& tracerName, const std::map& cellValues); + void setInjectorTracerFraction(const std::string& tracerName, const std::map& cellValues); + void setProducerTracerTOF (const std::string& tracerName, const std::map& cellValues); + void setProducerTracerFraction(const std::string& tracerName, const std::map& cellValues); + + // Use to "steal" the data from this one using swap + std::map >& nativeResults() { return m_nativeResults; } +private: + + void addResult(const RigFlowDiagResultAddress& resAddr, const std::map& cellValues); + + std::map > m_nativeResults; + size_t m_activeCellCount; +}; + + +class RigCaseData; + +class RigFlowDiagSolverInterface : public cvf::Object +{ +public: + RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase); + virtual ~RigFlowDiagSolverInterface(); + + RigFlowDiagTimeStepResult calculate(size_t timestep, + std::map > injectorTracers, + std::map > producerTracers); + +private: + RimEclipseResultCase * m_eclipseCase; + +}; + + + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.cpp new file mode 100644 index 0000000000..724d026ebd --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.cpp @@ -0,0 +1,107 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigFlowDiagStatCalc.h" +#include "RigFlowDiagResults.h" + +#include +#include "RigStatisticsMath.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagStatCalc::RigFlowDiagStatCalc(RigFlowDiagResults* flowDiagResults, const RigFlowDiagResultAddress& resVarAddr) +: m_resVarAddr(resVarAddr) +{ + m_resultsData = flowDiagResults; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagStatCalc::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) +{ + MinMaxAccumulator minMaxCalc(min, max); + const std::vector* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex); + + if (vals) minMaxCalc.addData(*vals); + + min = minMaxCalc.min; + max = minMaxCalc.max; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) +{ + PosNegAccumulator posNegCalc(pos, neg); + const std::vector* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex); + + if ( vals ) posNegCalc.addData(*vals); + + pos = posNegCalc.pos; + neg = posNegCalc.neg; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagStatCalc::valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount) +{ + SumCountAccumulator sumCountCalc(valueSum, sampleCount); + const std::vector* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex); + + if ( vals ) sumCountCalc.addData(*vals); + + valueSum = sumCountCalc.valueSum; + sampleCount = sumCountCalc.sampleCount; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagStatCalc::addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator) +{ + const std::vector* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex); + + if ( vals ) histogramCalculator.addData(*vals); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagStatCalc::uniqueValues(size_t timeStepIndex, std::set& uniqueValues) +{ + const std::vector* vals = m_resultsData->resultValues(m_resVarAddr, timeStepIndex); + + if ( vals ) for ( double val : (*vals) ) uniqueValues.insert(static_cast(val)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigFlowDiagStatCalc::timeStepCount() +{ + return m_resultsData->timeStepCount(); +} + + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h new file mode 100644 index 0000000000..bd145c43d2 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigStatisticsCalculator.h" +#include "RigFlowDiagResultAddress.h" + +class RigHistogramCalculator; +class RigFlowDiagResults; + +//================================================================================================== +/// +//================================================================================================== + +class RigFlowDiagStatCalc : public RigStatisticsCalculator +{ +public: + RigFlowDiagStatCalc(RigFlowDiagResults* femResultCollection, const RigFlowDiagResultAddress& resVarAddr); + + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); + virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); + virtual void uniqueValues(size_t timeStepIndex, std::set& values); + virtual size_t timeStepCount(); + +private: + RigFlowDiagResults* m_resultsData; + RigFlowDiagResultAddress m_resVarAddr; +}; + + + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.cpp new file mode 100644 index 0000000000..2fc30a2de9 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.cpp @@ -0,0 +1,99 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 "RigFlowDiagVisibleCellsStatCalc.h" +#include "RigActiveCellInfo.h" + +#include +#include "RigStatisticsMath.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagVisibleCellsStatCalc::RigFlowDiagVisibleCellsStatCalc(RigFlowDiagResults* resultsData, + const RigFlowDiagResultAddress& resVarAddr, + const cvf::UByteArray* cellVisibilities) +: m_resultsData(resultsData), m_resVarAddr(resVarAddr), m_cellVisibilities(cellVisibilities) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagVisibleCellsStatCalc::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) +{ + MinMaxAccumulator acc(min, max); + traverseElementNodes(acc, timeStepIndex); + min = acc.min; + max = acc.max; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagVisibleCellsStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) +{ + PosNegAccumulator acc(pos, neg); + traverseElementNodes(acc, timeStepIndex); + pos = acc.pos; + neg = acc.neg; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagVisibleCellsStatCalc::valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount) +{ + SumCountAccumulator acc(valueSum, sampleCount); + traverseElementNodes(acc, timeStepIndex); + valueSum = acc.valueSum; + sampleCount = acc.sampleCount; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagVisibleCellsStatCalc::addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator) +{ + traverseElementNodes(histogramCalculator, timeStepIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFlowDiagVisibleCellsStatCalc::uniqueValues(size_t timeStepIndex, std::set& values) +{ + UniqueValueAccumulator acc; + traverseElementNodes(acc, timeStepIndex); + values = acc.uniqueValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigFlowDiagVisibleCellsStatCalc::timeStepCount() +{ + return m_resultsData->timeStepCount(); +} + + diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.h new file mode 100644 index 0000000000..7a0bf1261e --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 "RigStatisticsCalculator.h" +#include "RigFlowDiagResultAddress.h" +#include "RigFlowDiagResults.h" +#include "RigActiveCellInfo.h" + +#include "cvfArray.h" + +class RigFlowDiagResults; +class RigActiveCellInfo; + +class RigFlowDiagVisibleCellsStatCalc : public RigStatisticsCalculator +{ +public: + RigFlowDiagVisibleCellsStatCalc(RigFlowDiagResults* resultsData, + const RigFlowDiagResultAddress& resVarAddr, + const cvf::UByteArray* cellVisibilities); + + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); + virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); + virtual void uniqueValues(size_t timeStepIndex, std::set& values); + virtual size_t timeStepCount(); + +private: + RigFlowDiagResults* m_resultsData; + RigFlowDiagResultAddress m_resVarAddr; + cvf::cref m_cellVisibilities; + + template + void traverseElementNodes(StatisticsAccumulator& accumulator, size_t timeStepIndex) + { + const std::vector* values = m_resultsData->resultValues(m_resVarAddr, timeStepIndex); + if (!values) return; + + const RigActiveCellInfo* actCellInfo = m_resultsData->activeCellInfo(m_resVarAddr); + + size_t cellCount = actCellInfo->reservoirCellCount(); + + CVF_TIGHT_ASSERT(cellCount == m_cellVisibilities->size()); + + for ( size_t cIdx = 0; cIdx < cellCount; ++cIdx ) + { + if ( !(*m_cellVisibilities)[cIdx] ) continue; + + size_t cellResultIndex = actCellInfo->cellResultIndex(cIdx); + + if ( cellResultIndex != cvf::UNDEFINED_SIZE_T ) accumulator.addValue((*values)[cellResultIndex]); + } + } + +}; + + + diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp index c9d3514bad..b96971d0fc 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp @@ -38,15 +38,17 @@ #include "cvfObject.h" #include +#include "RimFlowDiagSolution.h" +#include "RigFlowDiagResults.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName) +cvf::ref RigResultAccessorFactory::createFromUiResultName(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName) { CVF_ASSERT(gridIndex < eclipseCase->gridCount()); CVF_ASSERT(eclipseCase); @@ -61,9 +63,9 @@ cvf::ref RigResultAccessorFactory::createResultAccessor(RigCa cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); - cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANX"); - cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANY"); - cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANZ"); + cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANX"); + cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANY"); + cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANZ"); cellFaceAccessObject->setTransResultAccessors(xTransAccessor.p(), yTransAccessor.p(), zTransAccessor.p()); @@ -75,12 +77,12 @@ cvf::ref RigResultAccessorFactory::createResultAccessor(RigCa cvf::ref cellFaceAccessObject = new RigCombMultResultAccessor(grid); - cvf::ref multXPos = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTX"); - cvf::ref multXNeg = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTX-"); - cvf::ref multYPos = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTY"); - cvf::ref multYNeg = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTY-"); - cvf::ref multZPos = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTZ"); - cvf::ref multZNeg = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTZ-"); + cvf::ref multXPos = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTX"); + cvf::ref multXNeg = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTX-"); + cvf::ref multYPos = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTY"); + cvf::ref multYNeg = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTY-"); + cvf::ref multZPos = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTZ"); + cvf::ref multZNeg = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTZ-"); cellFaceAccessObject->setMultResultAccessors(multXPos.p(), multXNeg.p(), multYPos.p(), multYNeg.p(), multZPos.p(), multZNeg.p()); @@ -92,9 +94,9 @@ cvf::ref RigResultAccessorFactory::createResultAccessor(RigCa cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); - cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranXResultName()); - cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranYResultName()); - cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranZResultName()); + cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranXResultName()); + cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranYResultName()); + cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranZResultName()); cellFaceAccessObject->setTransResultAccessors(xTransAccessor.p(), yTransAccessor.p(), zTransAccessor.p()); @@ -106,9 +108,9 @@ cvf::ref RigResultAccessorFactory::createResultAccessor(RigCa cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); - cvf::ref xRiMultAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultXResultName()); - cvf::ref yRiMultAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultYResultName()); - cvf::ref zRiMultAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultZResultName()); + cvf::ref xRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultXResultName()); + cvf::ref yRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultYResultName()); + cvf::ref zRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultZResultName()); cellFaceAccessObject->setTransResultAccessors(xRiMultAccessor.p(), yRiMultAccessor.p(), zRiMultAccessor.p()); @@ -120,27 +122,27 @@ cvf::ref RigResultAccessorFactory::createResultAccessor(RigCa cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); - cvf::ref xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranXResultName()); - cvf::ref yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranYResultName()); - cvf::ref zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranZResultName()); + cvf::ref xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranXResultName()); + cvf::ref yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranYResultName()); + cvf::ref zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranZResultName()); cellFaceAccessObject->setTransResultAccessors(xRiAreaNormTransAccessor.p(), yRiAreaNormTransAccessor.p(), zRiAreaNormTransAccessor.p()); return cellFaceAccessObject; } - return RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, uiResultName); + return RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, uiResultName); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName, - RimDefines::ResultCatType resultType) +cvf::ref RigResultAccessorFactory::createFromNameAndType(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName, + RimDefines::ResultCatType resultType) { CVF_ASSERT(gridIndex < eclipseCase->gridCount()); CVF_ASSERT(eclipseCase); @@ -164,38 +166,59 @@ cvf::ref RigResultAccessorFactory::createResultAccessor(RigCa adjustedTimeStepIndex = 0; } - return createResultAccessor(eclipseCase, gridIndex, porosityModel, adjustedTimeStepIndex, scalarSetIndex); + return createFromResultIdx(eclipseCase, gridIndex, porosityModel, adjustedTimeStepIndex, scalarSetIndex); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, size_t gridIndex, size_t timeStepIndex, RimEclipseResultDefinition* resultDefinition) +cvf::ref RigResultAccessorFactory::createFromResultDefinition(RigCaseData* eclipseCase, + size_t gridIndex, + size_t timeStepIndex, + RimEclipseResultDefinition* resultDefinition) { RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultDefinition->porosityModel()); - size_t adjustedTimeStepIndex = timeStepIndex; - if (resultDefinition->hasStaticResult()) + if (resultDefinition->resultType() != RimDefines::FLOW_DIAGNOSTICS) { - adjustedTimeStepIndex = 0; - } - return RigResultAccessorFactory::createResultAccessor( - eclipseCase, - gridIndex, - porosityModel, - adjustedTimeStepIndex, - resultDefinition->resultVariable()); + size_t adjustedTimeStepIndex = timeStepIndex; + if ( resultDefinition->hasStaticResult() ) + { + adjustedTimeStepIndex = 0; + } + + return RigResultAccessorFactory::createFromUiResultName(eclipseCase, + gridIndex, + porosityModel, + adjustedTimeStepIndex, + resultDefinition->resultVariable()); + } + else + { + RimFlowDiagSolution* flowSol = resultDefinition->flowDiagSolution(); + if (!flowSol) return new RigHugeValResultAccessor;; + + const std::vector* resultValues = flowSol->flowDiagResults()->resultValues( resultDefinition->flowDiagResAddress(), timeStepIndex); + if (!resultValues) return new RigHugeValResultAccessor; + + RigGridBase* grid = eclipseCase->grid(gridIndex); + if ( !grid ) return new RigHugeValResultAccessor; + + cvf::ref object = new RigActiveCellsResultAccessor(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); + + return object; + } } //-------------------------------------------------------------------------------------------------- /// This function must be harmonized with RigResultModifierFactory::createResultModifier() //-------------------------------------------------------------------------------------------------- -cvf::ref RigResultAccessorFactory::createNativeResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName) +cvf::ref RigResultAccessorFactory::createNativeFromUiResultName(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName) { CVF_ASSERT(gridIndex < eclipseCase->gridCount()); CVF_ASSERT(eclipseCase); @@ -213,19 +236,19 @@ cvf::ref RigResultAccessorFactory::createNativeResultAccessor return NULL; } - return createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); + return createFromResultIdx(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t resultIndex) +cvf::ref RigResultAccessorFactory::createFromResultIdx(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t resultIndex) { - if (resultIndex == cvf::UNDEFINED_SIZE_T) + if ( resultIndex == cvf::UNDEFINED_SIZE_T ) { return new RigHugeValResultAccessor; } diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h index b85440b573..f3e995e0d6 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h @@ -33,40 +33,40 @@ class RigResultAccessorFactory { public: static cvf::ref - createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - size_t timeStepIndex, - RimEclipseResultDefinition* resultDefinition); - - static cvf::ref - createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName); + createFromResultDefinition(RigCaseData* eclipseCase, + size_t gridIndex, + size_t timeStepIndex, + RimEclipseResultDefinition* resultDefinition); static cvf::ref - createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName, - RimDefines::ResultCatType resultType); + createFromUiResultName(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName); static cvf::ref - createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t resultIndex); + createFromNameAndType(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName, + RimDefines::ResultCatType resultType); + + static cvf::ref + createFromResultIdx(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t resultIndex); private: - static cvf::ref - createNativeResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& resultName); + static cvf::ref + createNativeFromUiResultName(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& resultName); }; diff --git a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp index bb7746d9d2..3b9064324f 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp +++ b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp @@ -30,10 +30,10 @@ /// This function must be harmonized with RigResultAccessorFactory::createNativeResultAccessor() //-------------------------------------------------------------------------------------------------- cvf::ref RigResultModifierFactory::createResultModifier(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - QString& uiResultName) + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + QString& uiResultName) { if (!eclipseCase) return NULL; @@ -52,11 +52,11 @@ cvf::ref RigResultModifierFactory::createResultModifier(RigCa /// //-------------------------------------------------------------------------------------------------- cvf::ref RigResultModifierFactory::createResultModifier(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, size_t scalarResultIndex) + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, size_t scalarResultIndex) { - if (!eclipseCase) return NULL; + if ( !eclipseCase ) return NULL; if (!eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) { diff --git a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.h b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.h index 7c320fa4ad..0ca58f7800 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.h +++ b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.h @@ -27,19 +27,19 @@ class RigResultModifier; class RigResultModifierFactory { public: - static cvf::ref + static cvf::ref createResultModifier(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - QString& uiResultName); + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + QString& uiResultName); - static cvf::ref + static cvf::ref createResultModifier(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t scalarResultIndex); + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarResultIndex); }; diff --git a/ApplicationCode/ReservoirDataModel/RigTimeHistoryResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigTimeHistoryResultAccessor.cpp index 2a1bb6aaa4..05f98083a8 100644 --- a/ApplicationCode/ReservoirDataModel/RigTimeHistoryResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigTimeHistoryResultAccessor.cpp @@ -104,7 +104,7 @@ void RigTimeHistoryResultAccessor::computeTimeHistoryData() for (size_t i = 0; i < timeStepCount; i++) { - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(m_eclipseCaseData, m_gridIndex, m_porosityModel, i, m_scalarResultIndex); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromResultIdx(m_eclipseCaseData, m_gridIndex, m_porosityModel, i, m_scalarResultIndex); m_timeHistoryValues.push_back(resultAccessor->cellScalar(m_cellIndex)); } diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp index 73cf73a540..1becf85281 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp @@ -262,7 +262,17 @@ const std::vector& RigStatisticsDataCache::uniqueCellScalarValues() { computeUniqueValuesIfNeeded(); - return m_uniqueValues; + return m_statsAllTimesteps.m_uniqueValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigStatisticsDataCache::uniqueCellScalarValues(size_t timeStepIndex) +{ + computeUniqueValuesIfNeeded(timeStepIndex); + + return m_statsPrTs[timeStepIndex].m_uniqueValues; } //-------------------------------------------------------------------------------------------------- @@ -334,15 +344,31 @@ void RigStatisticsDataCache::computeHistogramStatisticsIfNeeded(size_t timeStepI //-------------------------------------------------------------------------------------------------- void RigStatisticsDataCache::computeUniqueValuesIfNeeded() { - if (m_uniqueValues.size() == 0) + if (m_statsAllTimesteps.m_uniqueValues.size() == 0) { std::set setValues; - m_statisticsCalculator->uniqueValues(0, setValues); + m_statisticsCalculator->uniqueValues(0, setValues); // This is a Hack ! Only using first timestep. Ok for Static eclipse results but beware ! for (auto val : setValues) { - m_uniqueValues.push_back(val); + m_statsAllTimesteps.m_uniqueValues.push_back(val); } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::computeUniqueValuesIfNeeded(size_t timeStepIndex) +{ + if ( m_statsPrTs[timeStepIndex].m_uniqueValues.size() == 0 ) + { + std::set setValues; + m_statisticsCalculator->uniqueValues(timeStepIndex, setValues); + + for ( auto val : setValues ) + { + m_statsPrTs[timeStepIndex].m_uniqueValues.push_back(val); + } + } +} diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h index e35a60f578..251b058af5 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h @@ -56,12 +56,14 @@ public: const std::vector& cellScalarValuesHistogram(size_t timeStepIndex); const std::vector& uniqueCellScalarValues(); + const std::vector& uniqueCellScalarValues(size_t timeStepIndex); private: void computeHistogramStatisticsIfNeeded(); void computeHistogramStatisticsIfNeeded(size_t timeStepIndex); void computeUniqueValuesIfNeeded(); + void computeUniqueValuesIfNeeded(size_t timeStepIndex); private: struct StatisticsValues @@ -100,11 +102,12 @@ private: bool m_isValueSumCalculated; std::vector m_histogram; + std::vector m_uniqueValues; }; StatisticsValues m_statsAllTimesteps; std::vector m_statsPrTs; - std::vector m_uniqueValues; + cvf::ref m_statisticsCalculator; }; diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h b/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h index 7c299b380a..34079596a0 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h @@ -62,7 +62,24 @@ private: class MinMaxAccumulator { public: - MinMaxAccumulator(double initMin, double initMax): max(initMax), min(initMin) {} + MinMaxAccumulator(double initMin = -HUGE_VAL, double initMax = HUGE_VAL): max(initMax), min(initMin) {} + + void addData(const std::vector& values) + { + for ( double val : values ) + { + addValue(val); + } + } + + void addData(const std::vector& values) + { + for ( float val : values ) + { + addValue(val); + } + } + void addValue(double value) { if (value == HUGE_VAL) // TODO @@ -89,7 +106,24 @@ public: class PosNegAccumulator { public: - PosNegAccumulator(double initPos, double initNeg): pos(initPos), neg(initNeg) {} + PosNegAccumulator(double initPos = HUGE_VAL, double initNeg = -HUGE_VAL): pos(initPos), neg(initNeg) {} + + void addData(const std::vector& values) + { + for (double val : values) + { + addValue(val); + } + } + + void addData(const std::vector& values) + { + for ( float val : values ) + { + addValue(val); + } + } + void addValue(double value) { if (value == HUGE_VAL) @@ -116,7 +150,23 @@ public: class SumCountAccumulator { public: - SumCountAccumulator(double initSum, size_t initCount): valueSum(initSum), sampleCount(initCount) {} + SumCountAccumulator(double initSum = 0.0, size_t initCount = 0): valueSum(initSum), sampleCount(initCount) {} + + void addData(const std::vector& values) + { + for ( double val : values ) + { + addValue(val); + } + } + + void addData(const std::vector& values) + { + for ( float val : values ) + { + addValue(val); + } + } void addValue(double value) { @@ -140,6 +190,22 @@ public: UniqueValueAccumulator() {} + void addData(const std::vector& values) + { + for ( double val : values ) + { + addValue(val); + } + } + + void addData(const std::vector& values) + { + for ( float val : values ) + { + addValue(val); + } + } + void addValue(double value) { uniqueValues.insert(static_cast(value)); diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index d40db3aa32..1bbb800216 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -320,7 +320,7 @@ public: for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(rimCase->reservoirData(), gridIdx, porosityModelEnum, requestedTimesteps[tsIdx], propertyName); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromUiResultName(rimCase->reservoirData(), gridIdx, porosityModelEnum, requestedTimesteps[tsIdx], propertyName); if (resultAccessor.isNull()) { diff --git a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp index 31c20b0a82..e9b4740c3e 100644 --- a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp +++ b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp @@ -20,6 +20,8 @@ #include "RiaApplication.h" +#include "RicExportMultipleSnapshotsFeature.h" + #include "RimCase.h" #include "RimMultiSnapshotDefinition.h" #include "RimProject.h" @@ -40,6 +42,7 @@ #include #include #include +#include //-------------------------------------------------------------------------------------------------- @@ -65,8 +68,9 @@ RiuExportMultipleSnapshotsWidget::RiuExportMultipleSnapshotsWidget(QWidget* pare connect(m_pdmTableView->tableView(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); m_pdmTableView->setListField(&(project->multiSnapshotDefinitions())); - m_pdmTableView->tableView()->resizeRowsToContents(); - m_pdmTableView->tableView()->resizeColumnsToContents(); + + QHeaderView* verticalHeader = m_pdmTableView->tableView()->verticalHeader(); + verticalHeader->setResizeMode(QHeaderView::Interactive); // Set active child array to be able to use generic delete caf::SelectionManager::instance()->setActiveChildArrayFieldHandle(&(project->multiSnapshotDefinitions())); @@ -82,13 +86,13 @@ RiuExportMultipleSnapshotsWidget::RiuExportMultipleSnapshotsWidget(QWidget* pare // Save images in snapshot catalog relative to project directory QString snapshotFolderName = RiaApplication::instance()->createAbsolutePathFromProjectRelativePath("snapshots"); - m_lineEdit = new QLineEdit(snapshotFolderName); + m_exportFolderLineEdit = new QLineEdit(snapshotFolderName); QToolButton* button = new QToolButton; button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred)); button->setText(QLatin1String("...")); - layout->addWidget(m_lineEdit); + layout->addWidget(m_exportFolderLineEdit); layout->addWidget(button); connect(button, SIGNAL(clicked()), this, SLOT(folderSelectionClicked())); @@ -145,7 +149,6 @@ void RiuExportMultipleSnapshotsWidget::customMenuRequested(QPoint pos) menu.exec(globalPos); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -158,32 +161,29 @@ void RiuExportMultipleSnapshotsWidget::deleteAllSnapshotItems() m_rimProject->multiSnapshotDefinitions.uiCapability()->updateConnectedEditors(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuExportMultipleSnapshotsWidget::exportSnapshots() { - // TODO: wire up call of static method - // RicExportMultipleSnapshotsFeature::staticMethod() + RicExportMultipleSnapshotsFeature::exportMultipleSnapshots(m_exportFolderLineEdit->text(), m_rimProject); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuExportMultipleSnapshotsWidget::folderSelectionClicked() { - QString defaultPath = m_lineEdit->text(); + QString defaultPath = m_exportFolderLineEdit->text(); - QString directoryPath = QFileDialog::getExistingDirectory(m_lineEdit, + QString directoryPath = QFileDialog::getExistingDirectory(m_exportFolderLineEdit, tr("Get existing directory"), defaultPath, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (!directoryPath.isEmpty()) { - m_lineEdit->setText(directoryPath); + m_exportFolderLineEdit->setText(directoryPath); } } @@ -196,60 +196,38 @@ void RiuExportMultipleSnapshotsWidget::addSnapshotItem() RimMultiSnapshotDefinition* multiSnapshot = new RimMultiSnapshotDefinition(); - - //Getting default value from last entered line: if (m_rimProject->multiSnapshotDefinitions.size() > 0) { + //Getting default value from last entered line: RimMultiSnapshotDefinition* other = m_rimProject->multiSnapshotDefinitions[m_rimProject->multiSnapshotDefinitions.size() - 1]; - multiSnapshot->caseObject = other->caseObject(); multiSnapshot->viewObject = other->viewObject(); multiSnapshot->timeStepStart = other->timeStepStart(); multiSnapshot->timeStepEnd = other->timeStepEnd(); - - - // Variant using copy based on xml string -// QString copyOfOriginalObject = other->writeObjectToXmlString(); -// multiSnapshot->readObjectFromXmlString(copyOfOriginalObject, caf::PdmDefaultObjectFactory::instance()); - - } - else { RimProject* proj = RiaApplication::instance()->project(); std::vector cases; proj->allCases(cases); - RimCase* CaseExample = nullptr; - RimView* ViewExample = nullptr; if (cases.size() > 0) { - CaseExample = cases.at(0); - multiSnapshot->caseObject = CaseExample; + RimCase* caseExample = cases.at(0); std::vector viewExamples; - viewExamples = CaseExample->views(); + viewExamples = caseExample->views(); if (viewExamples.size() > 0) { - ViewExample = viewExamples.at(0); - multiSnapshot->viewObject = ViewExample; + RimView* viewExample = viewExamples.at(0); + multiSnapshot->viewObject = viewExample; + multiSnapshot->timeStepStart = viewExample->currentTimeStep(); + multiSnapshot->timeStepEnd = viewExample->currentTimeStep(); } } - - } - - - m_rimProject->multiSnapshotDefinitions.push_back(multiSnapshot); m_rimProject->multiSnapshotDefinitions.uiCapability()->updateConnectedEditors(); - - if (m_rimProject->multiSnapshotDefinitions.size() == 1) - { - m_pdmTableView->tableView()->resizeRowsToContents(); - m_pdmTableView->tableView()->resizeColumnsToContents(); - } } diff --git a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h index d5bd442f7f..570cd4423c 100644 --- a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h +++ b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h @@ -47,5 +47,5 @@ private slots: private: RimProject* m_rimProject; caf::PdmUiTableView* m_pdmTableView; - QLineEdit* m_lineEdit; + QLineEdit* m_exportFolderLineEdit; }; diff --git a/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp index f7604389bd..cece373605 100644 --- a/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp +++ b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp @@ -378,9 +378,9 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - cvf::ref dataAccessObjectX = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, soilScalarSetIndex); - cvf::ref dataAccessObjectY = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, sgasScalarSetIndex); - cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, swatScalarSetIndex); + cvf::ref dataAccessObjectX = RigResultAccessorFactory::createFromResultIdx(eclipseCase, gridIndex, porosityModel, timeStepIndex, soilScalarSetIndex); + cvf::ref dataAccessObjectY = RigResultAccessorFactory::createFromResultIdx(eclipseCase, gridIndex, porosityModel, timeStepIndex, sgasScalarSetIndex); + cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createFromResultIdx(eclipseCase, gridIndex, porosityModel, timeStepIndex, swatScalarSetIndex); double scalarValue = 0.0; @@ -406,7 +406,7 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, { if (resultColors->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) { - cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedTransmissibilityResultName()); + cvf::ref transResultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedTransmissibilityResultName()); { double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); resultInfoText->append(QString("Tran X : %1\n").arg(scalarValue)); @@ -420,7 +420,7 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, } else if (resultColors->resultVariable().compare(RimDefines::combinedMultResultName(), Qt::CaseInsensitive) == 0) { - cvf::ref multResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedMultResultName()); + cvf::ref multResultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedMultResultName()); { double scalarValue = 0.0; @@ -442,7 +442,7 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, } else if (resultColors->resultVariable().compare(RimDefines::combinedRiTranResultName(), Qt::CaseInsensitive) == 0) { - cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiTranResultName()); + cvf::ref transResultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiTranResultName()); { double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); resultInfoText->append(QString("riTran X : %1\n").arg(scalarValue)); @@ -456,7 +456,7 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, } else if (resultColors->resultVariable().compare(RimDefines::combinedRiMultResultName(), Qt::CaseInsensitive) == 0) { - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiMultResultName()); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiMultResultName()); { double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); resultInfoText->append(QString("riMult X : %1\n").arg(scalarValue)); @@ -470,7 +470,7 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, } else if (resultColors->resultVariable().compare(RimDefines::combinedRiAreaNormTranResultName(), Qt::CaseInsensitive) == 0) { - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiAreaNormTranResultName()); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiAreaNormTranResultName()); { double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); resultInfoText->append(QString("riTransByArea X : %1\n").arg(scalarValue)); @@ -484,12 +484,12 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, } else { - resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, resultColors->scalarResultIndex()); + resultAccessor = RigResultAccessorFactory::createFromResultIdx(eclipseCase, gridIndex, porosityModel, 0, resultColors->scalarResultIndex()); } } else { - resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, resultColors->scalarResultIndex()); + resultAccessor = RigResultAccessorFactory::createFromResultIdx(eclipseCase, gridIndex, porosityModel, timeStepIndex, resultColors->scalarResultIndex()); } if (resultAccessor.notNull()) @@ -531,7 +531,7 @@ QString RiuResultTextBuilder::cellEdgeResultDetails() } RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_reservoirView->cellResult()->porosityModel()); - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(m_reservoirView->eclipseCase()->reservoirData(), m_gridIndex, porosityModel, adjustedTimeStep, resultIndex); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromResultIdx(m_reservoirView->eclipseCase()->reservoirData(), m_gridIndex, porosityModel, adjustedTimeStep, resultIndex); if (resultAccessor.notNull()) { double scalarValue = resultAccessor->cellScalar(m_cellIndex); @@ -660,9 +660,9 @@ QString RiuResultTextBuilder::cellResultText(RimEclipseCellColors* resultColors) size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - cvf::ref dataAccessObjectX = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, soilScalarSetIndex); - cvf::ref dataAccessObjectY = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, sgasScalarSetIndex); - cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, swatScalarSetIndex); + cvf::ref dataAccessObjectX = RigResultAccessorFactory::createFromResultIdx(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, soilScalarSetIndex); + cvf::ref dataAccessObjectY = RigResultAccessorFactory::createFromResultIdx(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, sgasScalarSetIndex); + cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createFromResultIdx(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, swatScalarSetIndex); double scalarValue = 0.0; @@ -687,7 +687,7 @@ QString RiuResultTextBuilder::cellResultText(RimEclipseCellColors* resultColors) adjustedTimeStep = 0; } - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, adjustedTimeStep, resultVar); + cvf::ref resultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, m_gridIndex, porosityModel, adjustedTimeStep, resultVar); if (resultAccessor.notNull()) { double scalarValue = resultAccessor->cellFaceScalar(m_cellIndex, m_face); diff --git a/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp b/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp index 61446f0b28..e24c06dcaf 100644 --- a/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp +++ b/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp @@ -103,7 +103,11 @@ void RiuSelectionChangedHandler::addCurveFromSelectionItem(const RiuEclipseSelec { RimEclipseView* eclipseView = eclipseSelectionItem->m_view.p(); - if (eclipseView->cellResult()->hasDynamicResult() && + if (eclipseView->cellResult()->resultType() == RimDefines::FLOW_DIAGNOSTICS) + { + // Todo + } + else if (eclipseView->cellResult()->hasDynamicResult() && eclipseView->eclipseCase() && eclipseView->eclipseCase()->reservoirData()) { diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index 28d57bc88f..6ab27d888b 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -39,6 +39,7 @@ #include "cafCategoryLegend.h" #include "cafCeetronPlusNavigation.h" +#include "cafDisplayCoordTransform.h" #include "cafEffectGenerator.h" #include "cafFrameAnimationControl.h" @@ -170,8 +171,9 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent) setContextMenuPolicy(Qt::PreventContextMenu); m_gridBoxGenerator = new RivGridBoxGenerator; -} + m_cursorPositionDomainCoords = cvf::Vec3d::UNDEFINED; +} //-------------------------------------------------------------------------------------------------- /// @@ -408,6 +410,29 @@ void RiuViewer::paintOverlayItems(QPainter* painter) m_versionInfoLabel->render(painter, pos); yPos += size.height() + margin; } + + if (!m_cursorPositionDomainCoords.isUndefined()) + { + if (mainCamera()) + { + cvf::ref trans = m_rimView->displayCoordTransform(); + + cvf::Vec3d displayCoord = trans->transformToDisplayCoord(m_cursorPositionDomainCoords); + + cvf::Vec3d screenCoords; + if (mainCamera()->project(displayCoord, &screenCoords)) + { + int translatedMousePosY = height() - screenCoords.y(); + QPoint centerPos(screenCoords.x(), translatedMousePosY); + + // Draw a cross hair marker + int markerHalfLength = 6; + + painter->drawLine(centerPos.x(), centerPos.y() - markerHalfLength, centerPos.x(), centerPos.y() + markerHalfLength); + painter->drawLine(centerPos.x() - markerHalfLength, centerPos.y(), centerPos.x() + markerHalfLength, centerPos.y()); + } + } + } } //-------------------------------------------------------------------------------------------------- @@ -658,6 +683,54 @@ void RiuViewer::resizeGL(int width, int height) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::mouseMoveEvent(QMouseEvent* mouseEvent) +{ + if (m_rimView) + { + RimViewLinker* viewLinker = m_rimView->assosiatedViewLinker(); + if (viewLinker) + { + int translatedMousePosX = mouseEvent->pos().x(); + int translatedMousePosY = height() - mouseEvent->pos().y(); + + cvf::Vec3d displayCoord(0, 0, 0); + if (mainCamera()->unproject(cvf::Vec3d(static_cast(translatedMousePosX), static_cast(translatedMousePosY), 0), &displayCoord)) + { + if (m_cursorPositionDomainCoords != cvf::Vec3d::UNDEFINED) + { + // Reset the extra cursor if the view currently is receiving mouse cursor events + // Set undefined and redraw to remove the previously displayed cursor + m_cursorPositionDomainCoords = cvf::Vec3d::UNDEFINED; + + update(); + } + + cvf::ref trans = m_rimView->displayCoordTransform(); + cvf::Vec3d domainCoord = trans->transformToDomainCoord(displayCoord); + + viewLinker->updateCursorPosition(m_rimView, domainCoord); + } + } + } + + caf::Viewer::mouseMoveEvent(mouseEvent); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::leaveEvent(QEvent *) +{ + if (m_rimView && m_rimView->assosiatedViewLinker()) + { + RimViewLinker* viewLinker = m_rimView->assosiatedViewLinker(); + viewLinker->updateCursorPosition(m_rimView, cvf::Vec3d::UNDEFINED); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -755,6 +828,19 @@ void RiuViewer::updateParallelProjectionSettings(RiuViewer* sourceViewer) this->updateParallelProjectionCameraPosFromPointOfInterestMove(poi); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::setCursorPosition(const cvf::Vec3d& domainCoord) +{ + if (m_cursorPositionDomainCoords != domainCoord) + { + m_cursorPositionDomainCoords = domainCoord; + + update(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuViewer.h b/ApplicationCode/UserInterface/RiuViewer.h index 525ea5342c..d13961462e 100644 --- a/ApplicationCode/UserInterface/RiuViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -96,6 +96,8 @@ public: void updateParallelProjectionSettings(RiuViewer* sourceViewer); + void setCursorPosition(const cvf::Vec3d& domainCoord); + public slots: virtual void slotSetCurrentFrame(int frameIndex); virtual void slotEndAnimation(); @@ -103,6 +105,8 @@ public slots: protected: virtual void optimizeClippingPlanes(); virtual void resizeGL(int width, int height); + virtual void mouseMoveEvent(QMouseEvent* e) override; + virtual void leaveEvent(QEvent *) override; private: void updateTextAndTickMarkColorForOverlayItems(); @@ -140,5 +144,7 @@ private: RiuViewerCommands* m_viewerCommands; RivGridBoxGenerator* m_gridBoxGenerator; + + cvf::Vec3d m_cursorPositionDomainCoords; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp index a67100b185..c1575db075 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp @@ -425,6 +425,10 @@ caf::PdmUiFieldEditorHandle* PdmUiFieldEditorHelper::fieldEditorForField(PdmUiFi { fieldTypeName = caf::PdmUiComboBoxEditor::uiEditorTypeName(); } + else if (fieldTypeName.indexOf("PdmPtrArrayField") != -1) + { + fieldTypeName = caf::PdmUiListEditor::uiEditorTypeName(); + } else if (field->toUiBasedQVariant().type() != QVariant::List) { // Handle a single value field with valueOptions: Make a combobox diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp index c47655e838..501fb1c547 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp @@ -119,6 +119,10 @@ QVariant PdmUiTableViewModel::headerData(int section, Qt::Orientation orientatio return uiFieldHandle->uiName(m_currentConfigName); } } + else if (orientation == Qt::Vertical) + { + return section; + } } return QVariant(); @@ -188,6 +192,30 @@ QVariant PdmUiTableViewModel::data(const QModelIndex &index, int role /*= Qt::Di if (role == Qt::DisplayRole || role == Qt::EditRole) { PdmFieldHandle* fieldHandle = getField(index); + if (dynamic_cast(fieldHandle)) + { + PdmPtrArrayFieldHandle* ptrArrayFieldHandle = dynamic_cast(fieldHandle); + + QString displayText; + + for (size_t i = 0; i < ptrArrayFieldHandle->size(); i++) + { + PdmObjectHandle* objHandle = ptrArrayFieldHandle->at(i); + if (objHandle && objHandle->uiCapability()) + { + PdmUiObjectHandle* uiObjHandle = objHandle->uiCapability(); + if (!displayText.isEmpty()) displayText += ", "; + + caf::PdmUiFieldHandle* uiFieldHandle = uiObjHandle->userDescriptionField()->uiCapability(); + if (uiFieldHandle) + { + displayText += uiFieldHandle->uiValue().toString(); + } + } + } + + return displayText; + } PdmUiFieldHandle* uiFieldHandle = fieldHandle->uiCapability(); if (uiFieldHandle) { diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h index ff130d65f2..f438cc55f6 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h @@ -82,8 +82,6 @@ public: void selectedUiItems(std::vector& objects); - PdmUiFieldEditorHandle* getEditor(const QModelIndex &index); - QWidget* getEditorWidgetAndTransferOwnership(QWidget* parent, const QModelIndex &index); void notifyDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); bool isRepresentingBoolean(const QModelIndex &index) const; @@ -92,6 +90,10 @@ private: int getFieldIndex(PdmFieldHandle* field) const; void recreateTableItemEditors(); + friend class PdmUiTableViewDelegate; + QWidget* getEditorWidgetAndTransferOwnership(QWidget* parent, const QModelIndex &index); + PdmUiFieldEditorHandle* getEditor(const QModelIndex &index); + private: PdmChildArrayFieldHandle* m_pdmList; QString m_currentConfigName;