From 1d97f376fb75e5f120d55d4f344e144c44fca312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 20 Dec 2019 13:39:02 +0100 Subject: [PATCH] #5200 New allen result type, and working full and binary allen diagrams for formations --- .../RimEclipseResultDefinition.cpp | 57 +++++++++ .../ReservoirDataModel/CMakeLists_files.cmake | 2 + .../RigAllenDiagramData.cpp | 33 ++++++ .../ReservoirDataModel/RigAllenDiagramData.h | 44 +++++++ .../RigCaseCellResultsData.cpp | 112 ++++++++++-------- .../RigCaseCellResultsData.h | 7 +- .../RigEclipseAllenFaultsStatCalc.h | 1 + .../ReservoirDataModel/RigEclipseCaseData.cpp | 8 ++ .../ReservoirDataModel/RigEclipseCaseData.h | 8 +- 9 files changed, 218 insertions(+), 54 deletions(-) create mode 100644 ApplicationCode/ReservoirDataModel/RigAllenDiagramData.cpp create mode 100644 ApplicationCode/ReservoirDataModel/RigAllenDiagramData.h diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index dddae859dd..ac857b196d 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -28,6 +28,7 @@ #include "RicfCommandObject.h" #include "RigActiveCellInfo.h" +#include "RigAllenDiagramData.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigEclipseResultInfo.h" @@ -62,6 +63,7 @@ #include "RimViewLinker.h" #include "RimWellLogExtractionCurve.h" +#include "cafCategoryMapper.h" #include "cafPdmUiListEditor.h" #include "cafPdmUiToolButtonEditor.h" #include "cafPdmUiTreeSelectionEditor.h" @@ -1883,6 +1885,61 @@ void RimEclipseResultDefinition::updateRangesForExplicitLegends( RimRegularLegen const std::vector& fnVector = eclipseCaseData->activeFormationNames()->formationNames(); legendConfigToUpdate->setNamedCategoriesInverse( fnVector ); } + else if ( this->resultType() == RiaDefines::ALLEN_DIAGRAMS ) + { + if ( this->resultVariable() == RiaDefines::allCombinationsAllenResultName() ) + { + const std::vector& fnVector = eclipseCaseData->activeFormationNames()->formationNames(); + std::vector fnameIdxes; + for ( int i = static_cast( fnVector.size() ); i > 0; --i ) + fnameIdxes.push_back( i - 1 ); + + cvf::Color3ubArray legendBaseColors = RiaColorTables::categoryPaletteColors().color3ubArray(); + + cvf::ref formationColorMapper = new caf::CategoryMapper; + formationColorMapper->setCategories( fnameIdxes ); + formationColorMapper->setInterpolateColors( legendBaseColors ); + + const std::map, int>& formationCombToCathegory = + eclipseCaseData->allenDiagramData()->formationCombinationToCategory(); + + std::vector> categories; + for ( int frmNameIdx : fnameIdxes ) + { + cvf::Color3ub formationColor = formationColorMapper->mapToColor( frmNameIdx ); + categories.emplace_back( std::make_tuple( fnVector[frmNameIdx], frmNameIdx, formationColor ) ); + } + + for ( auto it = formationCombToCathegory.rbegin(); it != formationCombToCathegory.rend(); ++it ) + { + int frmIdx1 = it->first.first; + int frmIdx2 = it->first.second; + int combIndex = it->second; + + QString frmName1 = fnVector[frmIdx1]; + QString frmName2 = fnVector[frmIdx2]; + + cvf::Color3f formationColor1 = cvf::Color3f( formationColorMapper->mapToColor( frmIdx1 ) ); + cvf::Color3f formationColor2 = cvf::Color3f( formationColorMapper->mapToColor( frmIdx2 ) ); + + cvf::Color3ub blendColor = cvf::Color3ub( + cvf::Color3f( 0.5f * ( formationColor1.r() + formationColor2.r() ), + 0.5f * ( formationColor1.g() + formationColor2.g() ), + 0.5f * ( formationColor1.b() + formationColor2.b() ) ) ); + categories.emplace_back( std::make_tuple( frmName1 + "-" + frmName2, combIndex, blendColor ) ); + } + + legendConfigToUpdate->setCategoryItems( categories ); + } + else if ( this->resultVariable() == RiaDefines::binaryAllenResultName() ) + { + std::vector> categories; + categories.emplace_back( std::make_tuple( "Same formation", 0, cvf::Color3ub::BROWN ) ); + categories.emplace_back( std::make_tuple( "Different formation", 1, cvf::Color3ub::ORANGE ) ); + + legendConfigToUpdate->setCategoryItems( categories ); + } + } else if ( this->resultType() == RiaDefines::DYNAMIC_NATIVE && this->resultVariable() == RiaDefines::completionTypeResultName() ) { diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index 424a018f1d..97889429b1 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -16,6 +16,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigCombMultResultAccessor.h ${CMAKE_CURRENT_LIST_DIR}/RigResultModifier.h ${CMAKE_CURRENT_LIST_DIR}/RigResultModifierFactory.h ${CMAKE_CURRENT_LIST_DIR}/RigFormationNames.h +${CMAKE_CURRENT_LIST_DIR}/RigAllenDiagramData.h ${CMAKE_CURRENT_LIST_DIR}/RigFlowDiagResultAddress.h ${CMAKE_CURRENT_LIST_DIR}/RigFlowDiagResults.h ${CMAKE_CURRENT_LIST_DIR}/RigFlowDiagResultFrames.h @@ -91,6 +92,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigCombTransResultAccessor.cpp ${CMAKE_CURRENT_LIST_DIR}/RigCombMultResultAccessor.cpp ${CMAKE_CURRENT_LIST_DIR}/RigResultModifierFactory.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFormationNames.cpp +${CMAKE_CURRENT_LIST_DIR}/RigAllenDiagramData.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFlowDiagResultAddress.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFlowDiagResults.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFlowDiagResultFrames.cpp diff --git a/ApplicationCode/ReservoirDataModel/RigAllenDiagramData.cpp b/ApplicationCode/ReservoirDataModel/RigAllenDiagramData.cpp new file mode 100644 index 0000000000..a4dfcf886d --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigAllenDiagramData.cpp @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 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 "RigAllenDiagramData.h" + +#include "RigCaseCellResultsData.h" +#include "RigFormationNames.h" +#include "RigMainGrid.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigAllenDiagramData::RigAllenDiagramData() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigAllenDiagramData::~RigAllenDiagramData() {} diff --git a/ApplicationCode/ReservoirDataModel/RigAllenDiagramData.h b/ApplicationCode/ReservoirDataModel/RigAllenDiagramData.h new file mode 100644 index 0000000000..ec11a6e811 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigAllenDiagramData.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 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 "cvfObject.h" +#include + +#include + +class RigAllenDiagramData : public cvf::Object +{ +public: + RigAllenDiagramData(); + ~RigAllenDiagramData() override; + + const std::map, int>& formationCombinationToCategory() + { + return m_formationCombinationToCategory; + } + + void setFormationCombinationToCategorymap( const std::map, int>& mapping ) + { + m_formationCombinationToCategory = mapping; + } + +private: + std::map, int> m_formationCombinationToCategory; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 2fc4b9336f..6fc5631154 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -23,6 +23,7 @@ #include "RiaApplication.h" #include "RiaLogging.h" +#include "RigAllenDiagramData.h" #include "RigCaseCellResultCalculator.h" #include "RigEclipseCaseData.h" #include "RigEclipseMultiPropertyStatCalc.h" @@ -61,6 +62,8 @@ RigCaseCellResultsData::RigCaseCellResultsData( RigEclipseCaseData* ow m_ownerCaseData = ownerCaseData; m_ownerMainGrid = ownerCaseData->mainGrid(); + + m_allenDiagramData = new RigAllenDiagramData; } //-------------------------------------------------------------------------------------------------- @@ -2892,6 +2895,14 @@ RigFormationNames* RigCaseCellResultsData::activeFormationNames() return m_activeFormationNamesData.p(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigAllenDiagramData* RigCaseCellResultsData::allenDiagramData() +{ + return m_allenDiagramData.p(); +} + //-------------------------------------------------------------------------------------------------- /// If we have any results on any time step, assume we have loaded results //-------------------------------------------------------------------------------------------------- @@ -2990,64 +3001,65 @@ void RigCaseCellResultsData::computeAllenResults( RigCaseCellResultsData* cellRe CVF_ASSERT( mainGrid ); CVF_ASSERT( cellResultsData ); - auto allAllenEclResAddr = RigEclipseResultAddress( RiaDefines::ALLEN_DIAGRAMS, - RiaDefines::allCombinationsAllenResultName() ); - - auto binaryAllenEclResAddr = RigEclipseResultAddress( RiaDefines::ALLEN_DIAGRAMS, - RiaDefines::binaryAllenResultName() ); - - if ( mainGrid->nncData()->staticConnectionScalarResult( allAllenEclResAddr ) ) return; - - std::vector& allAllenResults = mainGrid->nncData()->makeStaticConnectionScalarResult( - RiaDefines::allCombinationsAllenResultName() ); - - std::vector& allAllenFormationResults = mainGrid->nncData()->makeStaticConnectionScalarResult( - RiaDefines::activeFormationNamesResultName() ); - - std::vector& binaryAllenResults = mainGrid->nncData()->makeStaticConnectionScalarResult( - RiaDefines::binaryAllenResultName() ); - - mainGrid->nncData()->setEclResultAddress( RiaDefines::allCombinationsAllenResultName(), allAllenEclResAddr ); - mainGrid->nncData()->setEclResultAddress( RiaDefines::binaryAllenResultName(), binaryAllenEclResAddr ); - mainGrid->nncData()->setEclResultAddress( RiaDefines::activeFormationNamesResultName(), - RigEclipseResultAddress( RiaDefines::FORMATION_NAMES, - RiaDefines::activeFormationNamesResultName() ) ); - - bool hasFormationData = cellResultsData->hasResultEntry( - RigEclipseResultAddress( RiaDefines::FORMATION_NAMES, RiaDefines::activeFormationNamesResultName() ) ); + auto fnNamesResAddr = RigEclipseResultAddress( RiaDefines::FORMATION_NAMES, + RiaDefines::activeFormationNamesResultName() ); + bool hasFormationData = cellResultsData->hasResultEntry( fnNamesResAddr ); if ( hasFormationData ) { - const std::vector& fnData = - cellResultsData->cellScalarResults( RigEclipseResultAddress( RiaDefines::FORMATION_NAMES, - RiaDefines::activeFormationNamesResultName() ), - 0 ); + auto fnAllenResultResAddr = RigEclipseResultAddress( RiaDefines::ALLEN_DIAGRAMS, + RiaDefines::allCombinationsAllenResultName() ); + auto fnBinAllenResAddr = RigEclipseResultAddress( RiaDefines::ALLEN_DIAGRAMS, + RiaDefines::binaryAllenResultName() ); + + // Create and retreive nnc result arrays + + std::vector& fnAllenNncResults = mainGrid->nncData()->makeStaticConnectionScalarResult( + RiaDefines::allCombinationsAllenResultName() ); + std::vector& fnBinAllenNncResults = mainGrid->nncData()->makeStaticConnectionScalarResult( + RiaDefines::binaryAllenResultName() ); + + // Associate them with eclipse result address + + mainGrid->nncData()->setEclResultAddress( RiaDefines::allCombinationsAllenResultName(), fnAllenResultResAddr ); + mainGrid->nncData()->setEclResultAddress( RiaDefines::binaryAllenResultName(), fnBinAllenResAddr ); + + const std::vector& fnData = cellResultsData->cellScalarResults( fnNamesResAddr, 0 ); + + // Add a result entry for the special allen grid data (used only for the grid cells without nnc coverage) cellResultsData->addStaticScalarResult( RiaDefines::ALLEN_DIAGRAMS, RiaDefines::allCombinationsAllenResultName(), false, fnData.size() ); + cellResultsData->addStaticScalarResult( RiaDefines::ALLEN_DIAGRAMS, + RiaDefines::binaryAllenResultName(), + false, + fnData.size() ); - std::vector* alData = cellResultsData->modifiableCellScalarResult( allAllenEclResAddr, 0 ); + std::vector* alData = cellResultsData->modifiableCellScalarResult( fnAllenResultResAddr, 0 ); + std::vector* binAlData = cellResultsData->modifiableCellScalarResult( fnBinAllenResAddr, 0 ); ( *alData ) = fnData; - std::map, int> formationCombinationToCategory; - - for ( size_t i = 0; i < mainGrid->nncData()->connections().size(); i++ ) + for ( double& val : ( *binAlData ) ) { - const auto& c = mainGrid->nncData()->connections()[i]; + val = 0.0; + } + + size_t formationCount = cellResultsData->activeFormationNames()->formationNames().size(); + + const std::vector& nncConnections = mainGrid->nncData()->connections(); + + std::map, int> formationCombinationToCategory; + for ( size_t i = 0; i < nncConnections.size(); i++ ) + { + const auto& c = nncConnections[i]; size_t globCellIdx1 = c.m_c1GlobIdx; size_t globCellIdx2 = c.m_c2GlobIdx; - size_t i1, j1, k1; - mainGrid->ijkFromCellIndex( globCellIdx1, &i1, &j1, &k1 ); - int formation1 = (int)( fnData[globCellIdx1] ); - - size_t i2, j2, k2; - mainGrid->ijkFromCellIndex( globCellIdx2, &i2, &j2, &k2 ); int formation2 = (int)( fnData[globCellIdx2] ); int category = -1; @@ -3067,7 +3079,7 @@ void RigCaseCellResultsData::computeAllenResults( RigCaseCellResultsData* cellRe } else { - category = static_cast( formationCombinationToCategory.size() ); + category = static_cast( formationCombinationToCategory.size() + formationCount ); formationCombinationToCategory[formationCombination] = category; } @@ -3075,20 +3087,21 @@ void RigCaseCellResultsData::computeAllenResults( RigCaseCellResultsData* cellRe if ( category < 0 ) { - binaryAllenResults[i] = 0.0; - allAllenResults[i] = std::numeric_limits::max(); - allAllenFormationResults[i] = std::numeric_limits::max(); + fnBinAllenNncResults[i] = 0.0; + fnAllenNncResults[i] = std::numeric_limits::max(); } else { - binaryAllenResults[i] = 1.0; - allAllenResults[i] = category; - allAllenFormationResults[i] = formation1; + fnBinAllenNncResults[i] = 1.0; + fnAllenNncResults[i] = category; } } + + cellResultsData->allenDiagramData()->setFormationCombinationToCategorymap( formationCombinationToCategory ); } else { +#if 0 for ( size_t i = 0; i < mainGrid->nncData()->connections().size(); i++ ) { const auto& c = mainGrid->nncData()->connections()[i]; @@ -3108,10 +3121,11 @@ void RigCaseCellResultsData::computeAllenResults( RigCaseCellResultsData* cellRe binaryValue = 1.0; } - allAllenResults[i] = k1; + fnAllenNncResults[i] = k1; allAllenFormationResults[i] = k1; - binaryAllenResults[i] = binaryValue; + fnBinAllenNncResults[i] = binaryValue; } +#endif } } diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h index aa29fe5a67..e5d1b7c656 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h @@ -40,6 +40,7 @@ class RigStatisticsDataCache; class RigEclipseTimeStepInfo; class RigEclipseCaseData; class RigFormationNames; +class RigAllenDiagramData; class RimEclipseCase; @@ -58,6 +59,7 @@ public: void setHdf5Filename( const QString& hdf5SourSimFilename ); void setActiveFormationNames( RigFormationNames* activeFormationNames ); RigFormationNames* activeFormationNames(); + RigAllenDiagramData* allenDiagramData(); void setMainGrid( RigMainGrid* ownerGrid ); void setActiveCellInfo( RigActiveCellInfo* activeCellInfo ); @@ -194,8 +196,9 @@ private: static void computeAllenResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid ); private: - cvf::ref m_readerInterface; - cvf::ref m_activeFormationNamesData; + cvf::ref m_readerInterface; + cvf::ref m_activeFormationNamesData; + cvf::ref m_allenDiagramData; std::vector>> m_cellScalarResults; ///< Scalar results on the complete reservoir for each Result index (ResultVariable) and timestep diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h b/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h index 2541f50edc..26d962cf87 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h @@ -60,5 +60,6 @@ private: accumulator.addValue( v ); } } + } }; diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp index c7a16519c3..d2ba7c58b0 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp @@ -732,6 +732,14 @@ RigFormationNames* RigEclipseCaseData::activeFormationNames() return m_matrixModelResults->activeFormationNames(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigAllenDiagramData* RigEclipseCaseData::allenDiagramData() +{ + return m_matrixModelResults->allenDiagramData(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h index 96493e6ddd..6c448a0607 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h @@ -47,6 +47,7 @@ class RigWellPath; class RimEclipseCase; class RigVirtualPerforationTransmissibilities; class RigEquil; +class RigAllenDiagramData; struct RigWellResultPoint; @@ -88,9 +89,10 @@ public: bool hasFractureResults() const; - void setActiveFormationNames( RigFormationNames* activeFormationNames ); - void setActiveFormationNamesAndUpdatePlots( RigFormationNames* activeFormationNames ); - RigFormationNames* activeFormationNames(); + void setActiveFormationNames( RigFormationNames* activeFormationNames ); + void setActiveFormationNamesAndUpdatePlots( RigFormationNames* activeFormationNames ); + RigFormationNames* activeFormationNames(); + RigAllenDiagramData* allenDiagramData(); void setSimWellData( const cvf::Collection& data ); const cvf::Collection& wellResults() const