diff --git a/ApplicationCode/Application/RiaDefines.cpp b/ApplicationCode/Application/RiaDefines.cpp index 7c7dd04732..d768f152e2 100644 --- a/ApplicationCode/Application/RiaDefines.cpp +++ b/ApplicationCode/Application/RiaDefines.cpp @@ -33,6 +33,7 @@ void caf::AppEnum::setUp() addItem( RiaDefines::GENERATED, "GENERATED", "Generated" ); addItem( RiaDefines::INPUT_PROPERTY, "INPUT_PROPERTY", "Input Property" ); addItem( RiaDefines::FORMATION_NAMES, "FORMATION_NAMES", "Formation Names" ); + addItem( RiaDefines::ALLEN_DIAGRAMS, "ALLEN_DIAGRAMS", "Allen Diagrams" ); addItem( RiaDefines::FLOW_DIAGNOSTICS, "FLOW_DIAGNOSTICS", "Flow Diagnostics" ); addItem( RiaDefines::INJECTION_FLOODING, "INJECTION_FLOODING", "Injection Flooding" ); setDefault( RiaDefines::DYNAMIC_NATIVE ); @@ -368,6 +369,22 @@ QString RiaDefines::completionTypeResultName() return "Completion Type"; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::binaryAllenResultName() +{ + return "Binary Allen"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::allCombinationsAllenResultName() +{ + return "All Allen Categories"; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaDefines.h b/ApplicationCode/Application/RiaDefines.h index 2a51b9b92d..5d1208647e 100644 --- a/ApplicationCode/Application/RiaDefines.h +++ b/ApplicationCode/Application/RiaDefines.h @@ -33,6 +33,7 @@ enum ResultCatType GENERATED, INPUT_PROPERTY, FORMATION_NAMES, + ALLEN_DIAGRAMS, FLOW_DIAGNOSTICS, INJECTION_FLOODING, REMOVED, @@ -104,6 +105,10 @@ QString mobilePoreVolumeName(); QString completionTypeResultName(); +// Fault results +QString binaryAllenResultName(); +QString allCombinationsAllenResultName(); + // Mock model text identifiers QString mockModelBasic(); QString mockModelBasicWithResults(); diff --git a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp index facabd0ba9..2423dada44 100644 --- a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp @@ -154,7 +154,8 @@ void RivNNCGeometryGenerator::textureCoordinates( cvf::Vec2fArray* textureCoords->resize( numVertices ); cvf::Vec2f* rawPtr = textureCoords->ptr(); const std::vector* nncResultVals = nullptr; - if ( resultType == RiaDefines::STATIC_NATIVE ) + if ( resultType == RiaDefines::STATIC_NATIVE || resultType == RiaDefines::FORMATION_NAMES || + resultType == RiaDefines::ALLEN_DIAGRAMS ) { nncResultVals = m_nncData->staticConnectionScalarResult( resVarAddr ); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 6921ff9c57..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" @@ -644,32 +646,44 @@ QList RimGridTimeHistoryCurve* timeHistoryCurve; this->firstAncestorOrThisOfType( timeHistoryCurve ); - // Do not include flow diagnostics results if it is a time history curve - // Do not include SourSimRL if no SourSim file is loaded - if ( timeHistoryCurve != nullptr || !hasSourSimRLFile || !enableSouring ) + bool isSeparateFaultResult = false; { - using ResCatEnum = caf::AppEnum; - for ( size_t i = 0; i < ResCatEnum::size(); ++i ) + RimEclipseFaultColors* sepFaultResult; + this->firstAncestorOrThisOfType( sepFaultResult ); + if ( sepFaultResult ) isSeparateFaultResult = true; + } + + using ResCatEnum = caf::AppEnum; + for ( size_t i = 0; i < ResCatEnum::size(); ++i ) + { + RiaDefines::ResultCatType resType = ResCatEnum::fromIndex( i ); + + // Do not include flow diagnostics results if it is a time history curve + + if ( resType == RiaDefines::FLOW_DIAGNOSTICS && ( timeHistoryCurve ) ) { - RiaDefines::ResultCatType resType = ResCatEnum::fromIndex( i ); - if ( resType == RiaDefines::FLOW_DIAGNOSTICS && ( timeHistoryCurve ) ) - { - continue; - } - - if ( resType == RiaDefines::SOURSIMRL && ( !hasSourSimRLFile ) ) - { - continue; - } - - if ( resType == RiaDefines::INJECTION_FLOODING && !enableSouring ) - { - continue; - } - - QString uiString = ResCatEnum::uiTextFromIndex( i ); - options.push_back( caf::PdmOptionItemInfo( uiString, resType ) ); + continue; } + + // Do not include SourSimRL if no SourSim file is loaded + + if ( resType == RiaDefines::SOURSIMRL && ( !hasSourSimRLFile ) ) + { + continue; + } + + if ( resType == RiaDefines::INJECTION_FLOODING && !enableSouring ) + { + continue; + } + + if ( resType == RiaDefines::ALLEN_DIAGRAMS && !isSeparateFaultResult ) + { + continue; + } + + QString uiString = ResCatEnum::uiTextFromIndex( i ); + options.push_back( caf::PdmOptionItemInfo( uiString, resType ) ); } } @@ -1377,6 +1391,12 @@ bool RimEclipseResultDefinition::hasCategoryResult() const if ( this->m_resultType() == RiaDefines::FLOW_DIAGNOSTICS && m_resultVariable() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) return true; + if ( this->resultVariable() == RiaDefines::allCombinationsAllenResultName() || + this->resultVariable() == RiaDefines::binaryAllenResultName() ) + { + return true; + } + if ( !this->hasStaticResult() ) return false; return RiaDefines::isNativeCategoryResult( this->resultVariable() ); @@ -1865,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/ProjectDataModel/RimRegularLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.cpp index 4677d4e741..059a0c61a2 100644 --- a/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.cpp @@ -958,6 +958,7 @@ QList if ( rftCurveSet ) hasRftPlotParent = true; bool isCategoryResult = false; + bool isAllenDiagram = false; { RimEclipseCellColors* eclCellColors = nullptr; this->firstAncestorOrThisOfType( eclCellColors ); @@ -978,6 +979,11 @@ QList { isCategoryResult = true; } + + if ( eclCellColors && eclCellColors->resultType() == RiaDefines::ALLEN_DIAGRAMS ) + { + isAllenDiagram = true; + } } QList options; @@ -986,14 +992,17 @@ QList { // This is an app enum field, see cafInternalPdmFieldTypeSpecializations.h for the default specialization of this type std::vector mappingTypes; - mappingTypes.push_back( LINEAR_DISCRETE ); - - if ( !crossPlotCurveSet ) + if ( !isAllenDiagram ) { - mappingTypes.push_back( LINEAR_CONTINUOUS ); - mappingTypes.push_back( LOG10_CONTINUOUS ); + mappingTypes.push_back( LINEAR_DISCRETE ); + + if ( !crossPlotCurveSet ) + { + mappingTypes.push_back( LINEAR_CONTINUOUS ); + mappingTypes.push_back( LOG10_CONTINUOUS ); + } + mappingTypes.push_back( LOG10_DISCRETE ); } - mappingTypes.push_back( LOG10_DISCRETE ); if ( isCategoryResult ) { @@ -1009,27 +1018,30 @@ QList { // This is an app enum field, see cafInternalPdmFieldTypeSpecializations.h for the default specialization of this type std::vector rangeTypes; - if ( !hasEnsembleCurveSetParent && !hasRftPlotParent ) + if ( !isAllenDiagram ) { - rangeTypes.push_back( NORMAL ); - rangeTypes.push_back( OPPOSITE_NORMAL ); - rangeTypes.push_back( WHITE_PINK ); - rangeTypes.push_back( PINK_WHITE ); - rangeTypes.push_back( BLUE_WHITE_RED ); - rangeTypes.push_back( RED_WHITE_BLUE ); - rangeTypes.push_back( WHITE_BLACK ); - rangeTypes.push_back( BLACK_WHITE ); - rangeTypes.push_back( ANGULAR ); - } - else - { - for ( const auto& col : ColorManager::EnsembleColorRanges() ) + if ( !hasEnsembleCurveSetParent && !hasRftPlotParent ) { - rangeTypes.push_back( col.first ); + rangeTypes.push_back( NORMAL ); + rangeTypes.push_back( OPPOSITE_NORMAL ); + rangeTypes.push_back( WHITE_PINK ); + rangeTypes.push_back( PINK_WHITE ); + rangeTypes.push_back( BLUE_WHITE_RED ); + rangeTypes.push_back( RED_WHITE_BLUE ); + rangeTypes.push_back( WHITE_BLACK ); + rangeTypes.push_back( BLACK_WHITE ); + rangeTypes.push_back( ANGULAR ); + } + else + { + for ( const auto& col : ColorManager::EnsembleColorRanges() ) + { + rangeTypes.push_back( col.first ); + } } - } - if ( hasStimPlanParent ) rangeTypes.push_back( STIMPLAN ); + if ( hasStimPlanParent ) rangeTypes.push_back( STIMPLAN ); + } if ( isCategoryResult ) { diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index 010f177fdf..fe24fea64f 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 @@ -72,6 +73,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigGridCrossPlotCurveGrouping.h ${CMAKE_CURRENT_LIST_DIR}/RigEclipseCrossPlotDataExtractor.h ${CMAKE_CURRENT_LIST_DIR}/RigEquil.h ${CMAKE_CURRENT_LIST_DIR}/RigWbsParameter.h +${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllenFaultsStatCalc.h ) @@ -91,6 +93,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 @@ -141,6 +144,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RigEclipseCrossPlotDataExtractor.cpp ${CMAKE_CURRENT_LIST_DIR}/RigEquil.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWbsParameter.cpp +${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllenFaultsStatCalc.cpp ) list(APPEND CODE_HEADER_FILES 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 9f72fb8651..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" @@ -44,6 +45,7 @@ #include +#include "RigEclipseAllenFaultsStatCalc.h" #include #include @@ -60,6 +62,8 @@ RigCaseCellResultsData::RigCaseCellResultsData( RigEclipseCaseData* ow m_ownerCaseData = ownerCaseData; m_ownerMainGrid = ownerCaseData->mainGrid(); + + m_allenDiagramData = new RigAllenDiagramData; } //-------------------------------------------------------------------------------------------------- @@ -422,6 +426,13 @@ size_t RigCaseCellResultsData::findOrCreateScalarResultIndex( const RigEclipseRe QString( "%1K" ).arg( baseName ) ) ); statisticsCalculator = calc; } + else if ( resultName == RiaDefines::allCombinationsAllenResultName() || + resultName == RiaDefines::binaryAllenResultName() ) + { + cvf::ref calc = new RigEclipseAllenFaultsStatCalc( m_ownerMainGrid->nncData(), + resVarAddr ); + statisticsCalculator = calc; + } else { statisticsCalculator = new RigEclipseNativeStatCalc( this, resVarAddr ); @@ -438,7 +449,8 @@ size_t RigCaseCellResultsData::findOrCreateScalarResultIndex( const RigEclipseRe //-------------------------------------------------------------------------------------------------- QStringList RigCaseCellResultsData::resultNames( RiaDefines::ResultCatType resType ) const { - QStringList varList; + QStringList varList; + std::vector::const_iterator it; for ( it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it ) { @@ -448,6 +460,7 @@ QStringList RigCaseCellResultsData::resultNames( RiaDefines::ResultCatType resTy varList.push_back( it->resultName() ); } } + return varList; } @@ -897,6 +910,17 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() false ); } + // Fault results + { + findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ALLEN_DIAGRAMS, + RiaDefines::binaryAllenResultName() ), + false ); + + findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ALLEN_DIAGRAMS, + RiaDefines::allCombinationsAllenResultName() ), + false ); + } + // FLUX { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::DYNAMIC_NATIVE, "FLRWATI+" ) ) && @@ -1203,6 +1227,11 @@ size_t RigCaseCellResultsData::findOrLoadKnownScalarResult( const RigEclipseResu { computeRiTRANSbyAreaComponent( resultName ); } + else if ( resultName == RiaDefines::allCombinationsAllenResultName() || + resultName == RiaDefines::binaryAllenResultName() ) + { + computeAllenResults( this, m_ownerMainGrid ); + } } else if ( type == RiaDefines::DYNAMIC_NATIVE ) { @@ -2854,6 +2883,8 @@ void RigCaseCellResultsData::setActiveFormationNames( RigFormationNames* activeF fnData->at( cIdx ) = HUGE_VAL; } } + + computeAllenResults( this, m_ownerMainGrid ); } //-------------------------------------------------------------------------------------------------- @@ -2864,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 //-------------------------------------------------------------------------------------------------- @@ -2954,6 +2993,142 @@ RigStatisticsDataCache* RigCaseCellResultsData::statistics( const RigEclipseResu return m_statisticsDataCache[scalarResultIndex].p(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::computeAllenResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid ) +{ + CVF_ASSERT( mainGrid ); + CVF_ASSERT( cellResultsData ); + + auto fnNamesResAddr = RigEclipseResultAddress( RiaDefines::FORMATION_NAMES, + RiaDefines::activeFormationNamesResultName() ); + bool hasFormationData = cellResultsData->hasResultEntry( fnNamesResAddr ); + + if ( hasFormationData ) + { + 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( fnAllenResultResAddr, 0 ); + std::vector* binAlData = cellResultsData->modifiableCellScalarResult( fnBinAllenResAddr, 0 ); + + ( *alData ) = fnData; + + for ( double& val : ( *binAlData ) ) + { + 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; + + int formation1 = (int)( fnData[globCellIdx1] ); + int formation2 = (int)( fnData[globCellIdx2] ); + + int category = -1; + if ( formation1 != formation2 ) + { + if ( formation1 < formation2 ) + { + std::swap( formation1, formation2 ); + } + + auto formationCombination = std::make_pair( formation1, formation2 ); + + auto existingCategory = formationCombinationToCategory.find( formationCombination ); + if ( existingCategory != formationCombinationToCategory.end() ) + { + category = existingCategory->second; + } + else + { + category = static_cast( formationCombinationToCategory.size() + formationCount ); + + formationCombinationToCategory[formationCombination] = category; + } + } + + if ( category < 0 ) + { + fnBinAllenNncResults[i] = 0.0; + fnAllenNncResults[i] = std::numeric_limits::max(); + } + else + { + 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]; + + size_t globCellIdx1 = c.m_c1GlobIdx; + size_t globCellIdx2 = c.m_c2GlobIdx; + + size_t i1, j1, k1; + mainGrid->ijkFromCellIndex( globCellIdx1, &i1, &j1, &k1 ); + + size_t i2, j2, k2; + mainGrid->ijkFromCellIndex( globCellIdx2, &i2, &j2, &k2 ); + + double binaryValue = 0.0; + if ( k1 != k2 ) + { + binaryValue = 1.0; + } + + fnAllenNncResults[i] = k1; + allAllenFormationResults[i] = k1; + fnBinAllenNncResults[i] = binaryValue; + } +#endif + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h index 6ed4806747..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 ); @@ -191,9 +193,12 @@ private: RigStatisticsDataCache* statistics( const RigEclipseResultAddress& resVarAddr ); + 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.cpp b/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.cpp new file mode 100644 index 0000000000..08e3b4965a --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.cpp @@ -0,0 +1,103 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigEclipseAllenFaultsStatCalc.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigNNCData.h" +#include "RigStatisticsMath.h" +#include "RigWeightedMeanCalc.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigEclipseAllenFaultsStatCalc::RigEclipseAllenFaultsStatCalc( RigNNCData* cellResultsData, + const RigEclipseResultAddress& scalarResultIndex ) + : m_caseData( cellResultsData ) + , m_resultAddress( scalarResultIndex ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseAllenFaultsStatCalc::minMaxCellScalarValues( size_t timeStepIndex, double& min, double& max ) +{ + MinMaxAccumulator acc( min, max ); + traverseCells( acc, timeStepIndex ); + min = acc.min; + max = acc.max; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseAllenFaultsStatCalc::posNegClosestToZero( size_t timeStepIndex, double& pos, double& neg ) +{ + PosNegAccumulator acc( pos, neg ); + traverseCells( acc, timeStepIndex ); + pos = acc.pos; + neg = acc.neg; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseAllenFaultsStatCalc::valueSumAndSampleCount( size_t timeStepIndex, double& valueSum, size_t& sampleCount ) +{ + SumCountAccumulator acc( valueSum, sampleCount ); + traverseCells( acc, timeStepIndex ); + valueSum = acc.valueSum; + sampleCount = acc.sampleCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseAllenFaultsStatCalc::addDataToHistogramCalculator( size_t timeStepIndex, + RigHistogramCalculator& histogramCalculator ) +{ + traverseCells( histogramCalculator, timeStepIndex ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseAllenFaultsStatCalc::uniqueValues( size_t timeStepIndex, std::set& values ) +{ + UniqueValueAccumulator acc; + traverseCells( acc, timeStepIndex ); + values = acc.uniqueValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigEclipseAllenFaultsStatCalc::timeStepCount() +{ + return (size_t)1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseAllenFaultsStatCalc::mobileVolumeWeightedMean( size_t timeStepIndex, double& result ) {} diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h b/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h new file mode 100644 index 0000000000..8f5f394c22 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigNNCData.h" + +#include "cvfArray.h" + +class RigEclipseAllenFaultsStatCalc : public RigStatisticsCalculator +{ +public: + RigEclipseAllenFaultsStatCalc( RigNNCData* cellResultsData, const RigEclipseResultAddress& scalarResultIndex ); + + void minMaxCellScalarValues( size_t timeStepIndex, double& min, double& max ) override; + void posNegClosestToZero( size_t timeStepIndex, double& pos, double& neg ) override; + void valueSumAndSampleCount( size_t timeStepIndex, double& valueSum, size_t& sampleCount ) override; + void addDataToHistogramCalculator( size_t timeStepIndex, RigHistogramCalculator& histogramCalculator ) override; + void uniqueValues( size_t timeStepIndex, std::set& values ) override; + size_t timeStepCount() override; + void mobileVolumeWeightedMean( size_t timeStepIndex, double& result ) override; + +private: + RigNNCData* m_caseData; + RigEclipseResultAddress m_resultAddress; + + template + void traverseCells( StatisticsAccumulator& accumulator, size_t timeStepIndex ) + { + const std::vector* values = m_caseData->staticConnectionScalarResult( m_resultAddress ); + + if ( values && !values->empty() ) + { + for ( const auto& v : *values ) + { + 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