From 8a937116e5ea214d1a6eb280e9bc7789c7c25577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Wed, 31 May 2017 13:23:25 +0200 Subject: [PATCH 1/5] Correct return type of lateral count for fishbones --- .../ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp | 2 +- .../ProjectDataModel/Completions/RimFishbonesMultipleSubs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp index adc207a6ef..f4cdda444a 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp @@ -179,7 +179,7 @@ double RimFishbonesMultipleSubs::tubingDiameter() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::lateralCountPerSub() const +size_t RimFishbonesMultipleSubs::lateralCountPerSub() const { return m_lateralCountPerSub; } diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h index f8809abcac..854bd158f5 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h @@ -73,7 +73,7 @@ public: double tubingDiameter() const; double holeDiameter() const { return m_pipeProperties()->holeDiameter(); } double openHoleRoughnessFactor() const { return m_lateralOpenHoleRoghnessFactor(); } - double lateralCountPerSub() const; + size_t lateralCountPerSub() const; std::vector lateralLengths() const; std::vector coordsForLateral(size_t subIndex, size_t lateralIndex) const; From b20a563517f249a4941db30e22d4dc2ddd45b3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Wed, 31 May 2017 16:16:28 +0200 Subject: [PATCH 2/5] #1520 Establish new result type 'Completion Type' --- ...NewFishbonesSubsAtMeasuredDepthFeature.cpp | 3 +- .../RicNewFishbonesSubsFeature.cpp | 5 + .../Completions/CMakeLists_files.cmake | 2 + .../RimCompletionCellIntersectionCalc.cpp | 106 ++++++++++++++++++ .../RimCompletionCellIntersectionCalc.h | 44 ++++++++ .../RimFishboneWellPathCollection.cpp | 14 +-- .../Completions/RimFishbonesMultipleSubs.cpp | 2 +- .../Completions/RimPerforationCollection.cpp | 9 +- .../Completions/RimPerforationInterval.cpp | 8 +- .../ProjectDataModel/RimDefines.cpp | 9 ++ ApplicationCode/ProjectDataModel/RimDefines.h | 26 +++-- .../ProjectDataModel/RimEclipseCase.cpp | 47 +------- .../ProjectDataModel/RimEclipseCase.h | 3 +- .../ProjectDataModel/RimEclipseCellColors.cpp | 19 +++- .../RimEclipsePropertyFilter.cpp | 19 +++- .../RimEclipseResultDefinition.cpp | 3 + .../ProjectDataModel/RimProject.cpp | 22 ++++ ApplicationCode/ProjectDataModel/RimProject.h | 7 +- .../RimReservoirCellResultsStorage.cpp | 58 +++++++++- .../RimReservoirCellResultsStorage.h | 4 + .../RimWellPathCollection.cpp | 4 + .../RigCaseCellResultsData.cpp | 9 ++ 22 files changed, 341 insertions(+), 82 deletions(-) create mode 100644 ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp create mode 100644 ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.h diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp index 3d3e5685f4..016bebc50e 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp +++ b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp @@ -53,6 +53,7 @@ void RicNewFishbonesSubsAtMeasuredDepthFeature::onActionTriggered(bool isChecked int integerValue = wellPathSelItem->m_measuredDepth; obj->setMeasuredDepthAndCount(integerValue, 24, 1); + RicNewFishbonesSubsFeature::askUserToSetUsefulScaling(wellPath->fishbonesCollection()); wellPath->updateConnectedEditors(); @@ -60,7 +61,7 @@ void RicNewFishbonesSubsAtMeasuredDepthFeature::onActionTriggered(bool isChecked RimProject* proj; wellPath->firstAncestorOrThisOfTypeAsserted(proj); - proj->createDisplayModelAndRedrawAllViews(); + proj->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp index 7d071ecd63..5c8519f173 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp +++ b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp @@ -20,6 +20,7 @@ #include "RiaApplication.h" +#include "RimProject.h" #include "RimFishboneWellPathCollection.h" #include "RimFishbonesCollection.h" #include "RimFishbonesMultipleSubs.h" @@ -52,6 +53,10 @@ void RicNewFishbonesSubsFeature::onActionTriggered(bool isChecked) fishbonesCollection->updateConnectedEditors(); RiuMainWindow::instance()->selectAsCurrentItem(obj); + + RimProject* proj; + fishbonesCollection->firstAncestorOrThisOfTypeAsserted(proj); + proj->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake index fa73750ed0..501d61583d 100644 --- a/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake @@ -5,6 +5,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") endif() set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RimCompletionCellIntersectionCalc.h ${CEE_CURRENT_LIST_DIR}RimFishbonesCollection.h ${CEE_CURRENT_LIST_DIR}RimFishbonesMultipleSubs.h ${CEE_CURRENT_LIST_DIR}RimFishbonesPipeProperties.h @@ -16,6 +17,7 @@ ${CEE_CURRENT_LIST_DIR}RimWellPathCompletions.h ) set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RimCompletionCellIntersectionCalc.cpp ${CEE_CURRENT_LIST_DIR}RimFishbonesCollection.cpp ${CEE_CURRENT_LIST_DIR}RimFishbonesMultipleSubs.cpp ${CEE_CURRENT_LIST_DIR}RimFishbonesPipeProperties.cpp diff --git a/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp b/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp new file mode 100644 index 0000000000..891df1045e --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp @@ -0,0 +1,106 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimCompletionCellIntersectionCalc.h" + +#include "RimDefines.h" +#include "RimProject.h" +#include "RimOilField.h" +#include "RimWellPathCollection.h" +#include "RimWellPath.h" +#include "RimWellPathCompletions.h" +#include "RimFishbonesCollection.h" +#include "RimFishbonesMultipleSubs.h" +#include "RimPerforationCollection.h" +#include "RimPerforationInterval.h" + +#include "RigMainGrid.h" +#include "RigWellPath.h" +#include "RigWellPathIntersectionTools.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCompletionCellIntersectionCalc::calculateIntersections(const RimProject* project, const RigMainGrid* grid, std::vector& values, const QDateTime& fromDate) +{ + for (const RimWellPath* wellPath : project->activeOilField()->wellPathCollection->wellPaths) + { + if (wellPath->showWellPath()) + { + calculateWellPathIntersections(wellPath, grid, values, fromDate); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCompletionCellIntersectionCalc::calculateWellPathIntersections(const RimWellPath* wellPath, const RigMainGrid* grid, std::vector& values, const QDateTime& fromDate) +{ + std::vector intersections = RigWellPathIntersectionTools::getIntersectedCells(grid, wellPath->wellPathGeometry()->m_wellPathPoints); + + for (auto& intersection : intersections) + { + values[intersection.m_hexIndex] = RimDefines::WELL_PATH; + } + + for (const RimFishbonesMultipleSubs* fishbones : wellPath->fishbonesCollection()->fishbonesSubs) + { + calculateFishbonesIntersections(fishbones, grid, values); + } + + for (const RimPerforationInterval* perforationInterval : wellPath->perforationIntervalCollection()->perforations()) + { + if (perforationInterval->isActiveOnDate(fromDate)) + { + calculatePerforationIntersections(wellPath, perforationInterval, grid, values); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCompletionCellIntersectionCalc::calculateFishbonesIntersections(const RimFishbonesMultipleSubs* fishbonesSubs, const RigMainGrid* grid, std::vector& values) +{ + for (size_t subIndex = 0; subIndex < fishbonesSubs->locationOfSubs().size(); ++subIndex) + { + for (size_t lateralIndex = 0; lateralIndex < fishbonesSubs->lateralCountPerSub(); ++lateralIndex) + { + std::vector intersections = RigWellPathIntersectionTools::getIntersectedCells(grid, fishbonesSubs->coordsForLateral(subIndex, lateralIndex)); + for (auto& intersection : intersections) + { + values[intersection.m_hexIndex] = RimDefines::FISHBONE; + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCompletionCellIntersectionCalc::calculatePerforationIntersections(const RimWellPath* wellPath, const RimPerforationInterval* perforationInterval, const RigMainGrid* grid, std::vector& values) +{ + std::vector intersections = RigWellPathIntersectionTools::getIntersectedCells(grid, wellPath->wellPathGeometry()->clippedPointSubset(perforationInterval->startMD(), perforationInterval->endMD())); + for (auto& intersection : intersections) + { + values[intersection.m_hexIndex] = RimDefines::PERFORATION_INTERVAL; + } +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.h b/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.h new file mode 100644 index 0000000000..24491eeac7 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +class RimProject; +class RimWellPath; +class RimFishbonesMultipleSubs; +class RimPerforationInterval; + +class RigMainGrid; +class QDateTime; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimCompletionCellIntersectionCalc +{ +public: + static void calculateIntersections(const RimProject* project, const RigMainGrid* grid, std::vector& values, const QDateTime& fromDate); + +private: + static void calculateWellPathIntersections(const RimWellPath* wellPath, const RigMainGrid* grid, std::vector& values, const QDateTime& fromDate); + static void calculateFishbonesIntersections(const RimFishbonesMultipleSubs* fishbonesSubs, const RigMainGrid* grid, std::vector& values); + static void calculatePerforationIntersections(const RimWellPath* wellPath, const RimPerforationInterval* perforationInterval, const RigMainGrid* grid, std::vector& values); +}; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp index 739df5e921..8e98995953 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp @@ -97,14 +97,14 @@ void RimFishboneWellPathCollection::appendCompletion(RimFishboneWellPath* comple updateConnectedEditors(); RiuMainWindow::instance()->selectAsCurrentItem(completion); - RimView* rimView = NULL; - firstAncestorOrThisOfType(rimView); - if (rimView) - { - rimView->scheduleCreateDisplayModelAndRedraw(); - } - uiCapability()->setUiHidden(!m_wellPaths.empty()); + + RimProject* project = NULL; + firstAncestorOrThisOfTypeAsserted(project); + if (project) + { + project->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp index f4cdda444a..3f5a37a4ad 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp @@ -279,7 +279,7 @@ void RimFishbonesMultipleSubs::fieldChangedByUi(const caf::PdmFieldHandle* chang RimProject* proj; this->firstAncestorOrThisOfTypeAsserted(proj); - proj->createDisplayModelAndRedrawAllViews(); + proj->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp index d8972940e0..bd30ec346a 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp @@ -75,12 +75,9 @@ void RimPerforationCollection::appendPerforation(RimPerforationInterval* perfora updateConnectedEditors(); RiuMainWindow::instance()->selectAsCurrentItem(perforation); - RimView* rimView = NULL; - firstAncestorOrThisOfType(rimView); - if (rimView) - { - rimView->scheduleCreateDisplayModelAndRedraw(); - } + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp b/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp index f62e69d620..c7eefb36d7 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp @@ -20,6 +20,7 @@ #include "RimPerforationInterval.h" #include "RigWellPath.h" +#include "RigCaseCellResultsData.h" #include "RimProject.h" #include "RimWellPath.h" @@ -136,14 +137,15 @@ cvf::BoundingBox RimPerforationInterval::boundingBoxInDomainCoords() //-------------------------------------------------------------------------------------------------- void RimPerforationInterval::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - RimProject* proj; - this->firstAncestorOrThisOfTypeAsserted(proj); - proj->createDisplayModelAndRedrawAllViews(); if (changedField == &m_startOfHistory) { m_date.uiCapability()->setUiReadOnly(m_startOfHistory()); } + + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimDefines.cpp b/ApplicationCode/ProjectDataModel/RimDefines.cpp index ec64948c4a..e73ba06a63 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.cpp +++ b/ApplicationCode/ProjectDataModel/RimDefines.cpp @@ -65,6 +65,15 @@ namespace caf setDefault(RimDefines::PLOT_AXIS_LEFT); } + template<> + void caf::AppEnum< RimDefines::CompletionType >::setUp() + { + addItem(RimDefines::WELL_PATH, "WELL_PATH", "Well Path"); + addItem(RimDefines::PERFORATION_INTERVAL, "PERFORATION_INTERVAL", "Perforation Interval"); + addItem(RimDefines::FISHBONE, "FISHBONE", "Fishbone"); + + setDefault(RimDefines::WELL_PATH); + } } diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index 779f763d27..507121ade1 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -43,6 +43,12 @@ public: FRACTURE_MODEL }; + enum CompletionType { + WELL_PATH, + PERFORATION_INTERVAL, + FISHBONE + }; + static bool isPerCellFaceResult(const QString& resultName); static QString undefinedResultName() { return "None"; } @@ -52,10 +58,10 @@ public: static QString ternarySaturationResultName() { return "TERNARY"; } static QString combinedMultResultName() { return "MULTXYZ"; } - static QString riTranXResultName() { return "riTRANX"; } - static QString riTranYResultName() { return "riTRANY"; } - static QString riTranZResultName() { return "riTRANZ"; } - static QString combinedRiTranResultName() { return "riTRANXYZ"; } + static QString riTranXResultName() { return "riTRANX"; } + static QString riTranYResultName() { return "riTRANY"; } + static QString riTranZResultName() { return "riTRANZ"; } + static QString combinedRiTranResultName() { return "riTRANXYZ"; } static QString riMultXResultName() { return "riMULTX"; } static QString riMultYResultName() { return "riMULTY"; } @@ -67,12 +73,14 @@ public: static QString riAreaNormTranZResultName() { return "riTRANZbyArea"; } static QString combinedRiAreaNormTranResultName() { return "riTRANXYZbyArea"; } + static QString completionTypeResultName() { return "Completion Type"; } + // Mock model text identifiers - static QString mockModelBasic() { return "Result Mock Debug Model Simple"; } - static QString mockModelBasicWithResults() { return "Result Mock Debug Model With Results"; } - static QString mockModelLargeWithResults() { return "Result Mock Debug Model Large With Results"; } - static QString mockModelCustomized() { return "Result Mock Debug Model Customized"; } - static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; } + static QString mockModelBasic() { return "Result Mock Debug Model Simple"; } + static QString mockModelBasicWithResults() { return "Result Mock Debug Model With Results"; } + static QString mockModelLargeWithResults() { return "Result Mock Debug Model Large With Results"; } + static QString mockModelCustomized() { return "Result Mock Debug Model Customized"; } + static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; } enum DepthUnitType { diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index b800d32ea3..10fe3567be 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -249,50 +249,13 @@ RimEclipseView* RimEclipseCase::createCopyAndAddView(const RimEclipseView* sourc //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseCase::removeResult(const QString& resultName) +void RimEclipseCase::removeResult(RimDefines::ResultCatType type, const QString& resultName) { - size_t i; - for (i = 0; i < reservoirViews().size(); i++) + m_matrixModelResults->clearScalarResult(type, resultName); + + for (RimView* view : views()) { - RimEclipseView* reservoirView = reservoirViews()[i]; - CVF_ASSERT(reservoirView); - - RimEclipseCellColors* result = reservoirView->cellResult; - CVF_ASSERT(result); - - bool rebuildDisplayModel = false; - - // Set cell result variable to none if displaying - if (result->resultVariable() == resultName) - { - result->setResultVariable(RimDefines::undefinedResultName()); - result->loadResult(); - - rebuildDisplayModel = true; - } - - RimEclipsePropertyFilterCollection* propFilterCollection = reservoirView->eclipsePropertyFilterCollection(); - for (size_t filter = 0; filter < propFilterCollection->propertyFilters().size(); filter++) - { - RimEclipsePropertyFilter* propertyFilter = propFilterCollection->propertyFilters()[filter]; - if (propertyFilter->resultDefinition->resultVariable() == resultName) - { - propertyFilter->resultDefinition->setResultVariable(RimDefines::undefinedResultName()); - propertyFilter->resultDefinition->loadResult(); - propertyFilter->setToDefaultValues(); - - rebuildDisplayModel = true; - } - } - - if (rebuildDisplayModel) - { - reservoirViews()[i]->createDisplayModelAndRedraw(); - } - - - // TODO - // CellEdgeResults are not considered, as they do not support display of input properties yet + view->loadDataAndUpdate(); } } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.h b/ApplicationCode/ProjectDataModel/RimEclipseCase.h index 81cf3f1b46..83348be3ed 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.h @@ -23,6 +23,7 @@ #include "RifReaderInterface.h" #include "RimCase.h" +#include "RimDefines.h" #include "cafPdmChildArrayField.h" #include "cafPdmChildField.h" @@ -77,7 +78,7 @@ public: RimEclipseView* createAndAddReservoirView(); RimEclipseView* createCopyAndAddView(const RimEclipseView* sourceView); - void removeResult(const QString& resultName); + void removeResult(RimDefines::ResultCatType type, const QString& resultName); virtual QString locationOnDisc() const { return QString(); } virtual QString gridFileName() const { return QString(); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp index e68d97f876..6f60c6c4e6 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp @@ -377,15 +377,24 @@ void RimEclipseCellColors::updateLegendData(size_t currentTimeStep) if (this->hasCategoryResult()) { - if (this->resultType() != RimDefines::FORMATION_NAMES) - { - this->legendConfig()->setIntegerCategories(cellResultsData->uniqueCellScalarValues(this->scalarResultIndex())); - } - else + if (this->resultType() == RimDefines::FORMATION_NAMES) { const std::vector& fnVector = eclipseCase->activeFormationNames()->formationNames(); this->legendConfig()->setNamedCategoriesInverse(fnVector); } + else if (this->resultType() == RimDefines::DYNAMIC_NATIVE && this->resultVariable() == RimDefines::completionTypeResultName()) + { + std::vector ctNames; + for (QString ctName : caf::AppEnum::uiTexts()) + { + ctNames.push_back(ctName); + } + this->legendConfig()->setNamedCategoriesInverse(ctNames); + } + else + { + this->legendConfig()->setIntegerCategories(cellResultsData->uniqueCellScalarValues(this->scalarResultIndex())); + } } } } diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp index 12c707e1b6..a5248e909b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp @@ -379,11 +379,7 @@ void RimEclipsePropertyFilter::computeResultValueRange() if ( resultDefinition->hasCategoryResult() ) { - if ( resultDefinition->resultType() != RimDefines::FORMATION_NAMES ) - { - setCategoryValues(results->cellResults()->uniqueCellScalarValues(scalarIndex)); - } - else + if ( resultDefinition->resultType() == RimDefines::FORMATION_NAMES ) { CVF_ASSERT(parentContainer()->reservoirView()->eclipseCase()->eclipseCaseData()); CVF_ASSERT(parentContainer()->reservoirView()->eclipseCase()->eclipseCaseData()->activeFormationNames()); @@ -391,6 +387,19 @@ void RimEclipsePropertyFilter::computeResultValueRange() const std::vector& fnVector = parentContainer()->reservoirView()->eclipseCase()->eclipseCaseData()->activeFormationNames()->formationNames(); setCategoryNames(fnVector); } + else if (resultDefinition->resultVariable() == RimDefines::completionTypeResultName()) + { + std::vector ctNames; + for (QString ctName : caf::AppEnum::uiTexts()) + { + ctNames.push_back(ctName); + } + setCategoryNames(ctNames); + } + else + { + setCategoryValues(results->cellResults()->uniqueCellScalarValues(scalarIndex)); + } } } } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 8b6497ec70..dd0e99ac37 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -966,6 +966,9 @@ bool RimEclipseResultDefinition::hasCategoryResult() const && m_eclipseCase->eclipseCaseData() && m_eclipseCase->eclipseCaseData()->activeFormationNames() ) return true; + if (this->m_resultType() == RimDefines::DYNAMIC_NATIVE + && this->resultVariable() == RimDefines::completionTypeResultName()) return true; + if (this->m_resultType() == RimDefines::FLOW_DIAGNOSTICS && m_resultVariable() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME) return true; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index f784c71e42..a01bf20c0f 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -626,6 +626,17 @@ RimOilField* RimProject::activeOilField() return oilFields[0]; } +//-------------------------------------------------------------------------------------------------- +/// Currently there will be only one oil field in Resinsight, so return hardcoded first oil field +/// from the RimOilField collection. +//-------------------------------------------------------------------------------------------------- +const RimOilField * RimProject::activeOilField() const +{ + CVF_ASSERT(oilFields.size() == 1); + + return oilFields[0]; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -752,6 +763,17 @@ bool RimProject::showPlotWindow() const return m_showPlotWindow; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::removeResult(RimDefines::ResultCatType type, const QString & resultName) +{ + for (RimEclipseCase* eclipseCase : activeOilField()->analysisModels->cases) + { + eclipseCase->removeResult(type, resultName); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimProject.h b/ApplicationCode/ProjectDataModel/RimProject.h index 63d8c151a5..2c08d9e2ea 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.h +++ b/ApplicationCode/ProjectDataModel/RimProject.h @@ -20,6 +20,8 @@ #pragma once +#include "RimDefines.h" + #include "cafPdmChildArrayField.h" #include "cafPdmChildField.h" #include "cafPdmDocument.h" @@ -98,13 +100,16 @@ public: void computeUtmAreaOfInterest(); - RimOilField* activeOilField(); + RimOilField* activeOilField(); + const RimOilField* activeOilField() const; void actionsBasedOnSelection(QMenu& contextMenu); bool show3DWindow() const; bool showPlotWindow() const; + void removeResult(RimDefines::ResultCatType type, const QString& resultName); + protected: // Overridden methods void initScriptDirectories(); diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp index 0beded7277..27577fbecf 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp @@ -27,6 +27,8 @@ #include "RimEclipseCase.h" #include "RimTools.h" +#include "RimProject.h" +#include "RimCompletionCellIntersectionCalc.h" #include "cafProgressInfo.h" #include "cafUtils.h" @@ -253,6 +255,14 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& res return scalarResultIndex; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::clearScalarResult(RimDefines::ResultCatType type, const QString & resultName) +{ + size_t scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); + m_cellResults->cellScalarResults(scalarResultIndex).clear(); +} //-------------------------------------------------------------------------------------------------- /// @@ -325,7 +335,6 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RimDefines::Result } } - if (isDataPresent(scalarResultIndex)) { return scalarResultIndex; @@ -352,6 +361,14 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RimDefines::Result return scalarResultIndex; } } + else if (resultName == RimDefines::completionTypeResultName()) + { + m_cellResults->cellScalarResults(scalarResultIndex).resize(m_cellResults->maxTimeStepCount()); + for (size_t timeStepIdx = 0; timeStepIdx < m_cellResults->maxTimeStepCount(); ++timeStepIdx) + { + computeCompletionTypeForTimeStep(timeStepIdx); + } + } if (type == RimDefines::GENERATED) { @@ -426,6 +443,12 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefi return soilScalarResultIndex; } } + else if (type == RimDefines::DYNAMIC_NATIVE && resultName == RimDefines::completionTypeResultName()) + { + size_t completionTypeScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); + computeCompletionTypeForTimeStep(timeStepIndex); + return completionTypeScalarResultIndex; + } size_t scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; @@ -1376,6 +1399,39 @@ void RimReservoirCellResultsStorage::computeNncCombRiTRANSbyArea() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeCompletionTypeForTimeStep(size_t timeStep) +{ + size_t completionTypeResultIndex = m_cellResults->findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); + + if (m_cellResults->cellScalarResults(completionTypeResultIndex).size() != timeStep) + { + m_cellResults->cellScalarResults(completionTypeResultIndex).resize(timeStep); + } + + std::vector& completionTypeResult = m_cellResults->cellScalarResults(completionTypeResultIndex, 0); + + size_t resultValues = m_ownerMainGrid->globalCellArray().size(); + + if (completionTypeResult.size() == resultValues) + { + return; + } + + completionTypeResult.resize(resultValues); + std::fill(completionTypeResult.begin(), completionTypeResult.end(), HUGE_VAL); + + RimProject* project; + firstAncestorOrThisOfTypeAsserted(project); + RimEclipseCase* eclipseCase; + firstAncestorOrThisOfTypeAsserted(eclipseCase); + QDateTime timeStepDate = eclipseCase->timeStepDates()[timeStep]; + + RimCompletionCellIntersectionCalc::calculateIntersections(project, m_ownerMainGrid, completionTypeResult, timeStepDate); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h index 9793d7d67f..9da06c28cd 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h @@ -63,6 +63,8 @@ public: size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName); size_t findOrLoadScalarResult(const QString& resultName); ///< Simplified search. Assumes unique names across types. + void clearScalarResult(RimDefines::ResultCatType type, const QString& resultName); + protected: // Overridden methods from PdmObject virtual void setupBeforeSave(); @@ -77,6 +79,8 @@ private: void computeRiTRANSbyAreaComponent(const QString& riTransByAreaCompResultName); void computeNncCombRiTRANSbyArea(); + void computeCompletionTypeForTimeStep(size_t timeStep); + double darchysValue(); QString getValidCacheFileName(); diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index abc22c9d85..8591556e6b 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -214,6 +214,10 @@ void RimWellPathCollection::addWellPaths( QStringList filePaths ) } readAndAddWellPaths(wellPathArray); + + RimProject* proj; + firstAncestorOrThisOfTypeAsserted(proj); + proj->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); } diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 60ece82835..123975174c 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -667,6 +667,15 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() } } + // Completion type + { + size_t completionTypeIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); + if (completionTypeIndex == cvf::UNDEFINED_SIZE_T) + { + addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName(), false); + } + } + // TRANSXYZ { size_t tranX, tranY, tranZ; From 52088156221cdc9e009acc129ac351c58f25ac19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Thu, 1 Jun 2017 12:54:37 +0200 Subject: [PATCH 3/5] #1520 Ensure cell results are updated when well path visibility is toggled --- ApplicationCode/ProjectDataModel/RimWellPath.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.cpp b/ApplicationCode/ProjectDataModel/RimWellPath.cpp index 57c0db8f0f..2beb1f8093 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPath.cpp @@ -240,8 +240,15 @@ void RimWellPath::fieldChangedByUi(const caf::PdmFieldHandle* changedField, cons partMgr()->scheduleGeometryRegen(); RimProject* proj; - this->firstAncestorOrThisOfType(proj); - if (proj) proj->createDisplayModelAndRedrawAllViews(); + this->firstAncestorOrThisOfTypeAsserted(proj); + if (changedField == &showWellPath) + { + proj->removeResult(RimDefines::DYNAMIC_NATIVE, RimDefines::completionTypeResultName()); + } + else + { + proj->createDisplayModelAndRedrawAllViews(); + } } //-------------------------------------------------------------------------------------------------- From 8e6322b5004d0ef0a16b4323cf5ce56bbe70c630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Thu, 1 Jun 2017 12:55:13 +0200 Subject: [PATCH 4/5] #1520 Use green and red colors for cells with and without perforations, respectively --- .../ProjectDataModel/RimEclipseCellColors.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp index 6f60c6c4e6..6a932e2f06 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp @@ -384,12 +384,17 @@ void RimEclipseCellColors::updateLegendData(size_t currentTimeStep) } else if (this->resultType() == RimDefines::DYNAMIC_NATIVE && this->resultVariable() == RimDefines::completionTypeResultName()) { - std::vector ctNames; - for (QString ctName : caf::AppEnum::uiTexts()) - { - ctNames.push_back(ctName); - } - this->legendConfig()->setNamedCategoriesInverse(ctNames); + std::vector< std::tuple > categories; + + caf::AppEnum wellPath(RimDefines::WELL_PATH); + caf::AppEnum fishbone(RimDefines::FISHBONE); + caf::AppEnum perforationInterval(RimDefines::PERFORATION_INTERVAL); + + categories.push_back(std::make_tuple(wellPath.uiText(), wellPath.index(), cvf::Color3::RED)); + categories.push_back(std::make_tuple(fishbone.uiText(), fishbone.index(), cvf::Color3::DARK_GREEN)); + categories.push_back(std::make_tuple(perforationInterval.uiText(), perforationInterval.index(), cvf::Color3::GREEN)); + + legendConfig()->setCategoryItems(categories); } else { From e5b71965371c3843a03e99dd7083548a529a140b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Grip=20Fj=C3=A6r?= Date: Thu, 1 Jun 2017 13:46:22 +0200 Subject: [PATCH 5/5] #1520 Show completion type cells as transparent --- .../ModelVisualization/RivGridPartMgr.cpp | 12 ++++++++++++ .../ProjectDataModel/RimEclipseResultDefinition.cpp | 8 ++++++++ .../ProjectDataModel/RimEclipseResultDefinition.h | 1 + 3 files changed, 21 insertions(+) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 075636e32d..1cf4859aa2 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -262,6 +262,18 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); + if (cellResultColors->isCompletionTypeSelected()) + { + cvf::Vec2fArray& surfaceCoords = *m_surfaceFacesTextureCoords.p(); + for (cvf::Vec2f& vec : surfaceCoords) + { + { + vec[1] = 0.5; + } + } + m_opacityLevel = 0.5; + } + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index dd0e99ac37..2775c9386b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -956,6 +956,14 @@ bool RimEclipseResultDefinition::isTernarySaturationSelected() const return isTernary; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isCompletionTypeSelected() const +{ + return (m_resultType() == RimDefines::DYNAMIC_NATIVE && m_resultVariable() == RimDefines::completionTypeResultName()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index e0a12d143d..5249a975ab 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -84,6 +84,7 @@ public: bool hasDynamicResult() const; bool hasResult() const; bool isTernarySaturationSelected() const; + bool isCompletionTypeSelected() const; bool hasCategoryResult() const; RimReservoirCellResultsStorage* currentGridCellResults() const;