From 831b899091ae84380dfe37db07deeb1c50e50bb6 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 9 Dec 2019 08:02:14 +0100 Subject: [PATCH] #5200 Prototype of use of formation names for allen diagram --- ApplicationCode/Application/RiaDefines.cpp | 16 ++ ApplicationCode/Application/RiaDefines.h | 4 + .../RimEclipseResultDefinition.cpp | 6 + .../ReservoirDataModel/CMakeLists_files.cmake | 2 + .../RigCaseCellResultsData.cpp | 138 ++++++++++++++++++ .../RigCaseCellResultsData.h | 2 + .../RigEclipseAllenFaultsStatCalc.cpp | 103 +++++++++++++ .../RigEclipseAllenFaultsStatCalc.h | 64 ++++++++ 8 files changed, 335 insertions(+) create mode 100644 ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.cpp create mode 100644 ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h diff --git a/ApplicationCode/Application/RiaDefines.cpp b/ApplicationCode/Application/RiaDefines.cpp index ee46a7e81d..dfc80f6d5b 100644 --- a/ApplicationCode/Application/RiaDefines.cpp +++ b/ApplicationCode/Application/RiaDefines.cpp @@ -359,6 +359,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..d021389432 100644 --- a/ApplicationCode/Application/RiaDefines.h +++ b/ApplicationCode/Application/RiaDefines.h @@ -104,6 +104,10 @@ QString mobilePoreVolumeName(); QString completionTypeResultName(); +// Fault results +QString binaryAllenResultName(); +QString allCombinationsAllenResultName(); + // Mock model text identifiers QString mockModelBasic(); QString mockModelBasicWithResults(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 6921ff9c57..064b51e4cb 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -1379,6 +1379,12 @@ bool RimEclipseResultDefinition::hasCategoryResult() const if ( !this->hasStaticResult() ) return false; + if ( this->resultVariable() == RiaDefines::allCombinationsAllenResultName() || + this->resultVariable() == RiaDefines::binaryAllenResultName() ) + { + return true; + } + return RiaDefines::isNativeCategoryResult( this->resultVariable() ); } diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index c8ede2cc1b..424a018f1d 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -71,6 +71,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 ) @@ -139,6 +140,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/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 9f72fb8651..412b659a15 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -44,6 +44,7 @@ #include +#include "RigEclipseAllenFaultsStatCalc.h" #include #include @@ -422,6 +423,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 ); @@ -897,6 +905,17 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() false ); } + // Fault results + { + findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::STATIC_NATIVE, + RiaDefines::binaryAllenResultName() ), + false ); + + findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::STATIC_NATIVE, + RiaDefines::allCombinationsAllenResultName() ), + false ); + } + // FLUX { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::DYNAMIC_NATIVE, "FLRWATI+" ) ) && @@ -1203,6 +1222,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 ) { @@ -2954,6 +2978,120 @@ RigStatisticsDataCache* RigCaseCellResultsData::statistics( const RigEclipseResu return m_statisticsDataCache[scalarResultIndex].p(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::computeAllenResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid ) +{ + CVF_ASSERT( mainGrid ); + CVF_ASSERT( cellResultsData ); + + auto allAllenEclResAddr = RigEclipseResultAddress( RiaDefines::STATIC_NATIVE, + RiaDefines::allCombinationsAllenResultName() ); + + auto binaryAllenEclResAddr = RigEclipseResultAddress( RiaDefines::STATIC_NATIVE, RiaDefines::binaryAllenResultName() ); + + if ( mainGrid->nncData()->staticConnectionScalarResult( allAllenEclResAddr ) ) return; + + std::vector& allAllenResults = mainGrid->nncData()->makeStaticConnectionScalarResult( + RiaDefines::allCombinationsAllenResultName() ); + + std::vector& binaryAllenResults = mainGrid->nncData()->makeStaticConnectionScalarResult( + RiaDefines::binaryAllenResultName() ); + + mainGrid->nncData()->setEclResultAddress( RiaDefines::allCombinationsAllenResultName(), allAllenEclResAddr ); + mainGrid->nncData()->setEclResultAddress( RiaDefines::binaryAllenResultName(), binaryAllenEclResAddr ); + + bool hasFormationData = cellResultsData->hasResultEntry( + RigEclipseResultAddress( RiaDefines::FORMATION_NAMES, RiaDefines::activeFormationNamesResultName() ) ); + + if ( hasFormationData ) + { + const std::vector& fnData = + cellResultsData->cellScalarResults( RigEclipseResultAddress( RiaDefines::FORMATION_NAMES, + RiaDefines::activeFormationNamesResultName() ), + 0 ); + + std::map, int> formationCombinationToCategory; + + 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 ); + + int formation1 = (int)( fnData[globCellIdx1] ); + + size_t i2, j2, k2; + mainGrid->ijkFromCellIndex( globCellIdx2, &i2, &j2, &k2 ); + 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() ); + + formationCombinationToCategory[formationCombination] = category; + } + } + + if ( category < 0 ) + { + binaryAllenResults[i] = 0.0; + allAllenResults[i] = std::numeric_limits::max(); + } + else + { + binaryAllenResults[i] = 1.0; + allAllenResults[i] = category; + } + } + } + else + { + 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; + } + + allAllenResults[i] = k1; + binaryAllenResults[i] = binaryValue; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h index 6ed4806747..aa29fe5a67 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h @@ -191,6 +191,8 @@ private: RigStatisticsDataCache* statistics( const RigEclipseResultAddress& resVarAddr ); + static void computeAllenResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid ); + private: cvf::ref m_readerInterface; cvf::ref m_activeFormationNamesData; 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..2541f50edc --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigEclipseAllenFaultsStatCalc.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//================================================================================================== +/// +//================================================================================================== +#include "RigStatisticsCalculator.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" + +#include "cvfArray.h" + +class RigNNCData; + +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 ); + } + } + } +};