///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2020 Equinor 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 "RimHistogramCalculator.h" #include "RiaResultNames.h" #include "ContourMap/RigContourMapProjection.h" #include "RigEclipseMultiPropertyStatCalc.h" #include "RigEclipseNativeVisibleCellsStatCalc.h" #include "RigFemNativeVisibleCellsStatCalc.h" #include "RigFemPartResultsCollection.h" #include "RigFemResultAddress.h" #include "RigFlowDiagResults.h" #include "RigFlowDiagVisibleCellsStatCalc.h" #include "RigGeoMechCaseData.h" #include "RigStatisticsMath.h" #include #include "ContourMap/RimEclipseContourMapProjection.h" #include "ContourMap/RimEclipseContourMapView.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" #include "RimGeoMechCase.h" #include "RimGeoMechContourMapView.h" #include "RimGeoMechResultDefinition.h" #include "RimGeoMechView.h" #include "cafAssert.h" namespace caf { template <> void caf::AppEnum::setUp() { addItem( RimHistogramCalculator::StatisticsTimeRangeType::ALL_TIMESTEPS, "ALL_TIMESTEPS", "All Time Steps" ); addItem( RimHistogramCalculator::StatisticsTimeRangeType::CURRENT_TIMESTEP, "CURRENT_TIMESTEP", "Current Time Step" ); setDefault( RimHistogramCalculator::StatisticsTimeRangeType::ALL_TIMESTEPS ); } } // namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- namespace caf { template <> void caf::AppEnum::setUp() { addItem( RimHistogramCalculator::StatisticsCellRangeType::ALL_CELLS, "ALL_CELLS", "All Active Cells" ); addItem( RimHistogramCalculator::StatisticsCellRangeType::VISIBLE_CELLS, "VISIBLE_CELLS", "Visible Cells" ); setDefault( RimHistogramCalculator::StatisticsCellRangeType::ALL_CELLS ); } } // namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimHistogramCalculator::RimHistogramCalculator() : m_isVisCellStatUpToDate( false ) , m_numBins( RigStatisticsDataCache::defaultNumBins() ) , m_doComputeMobileVolumeWeightedMean( true ) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimHistogramCalculator::setNumBins( size_t numBins ) { m_numBins = numBins; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimHistogramCalculator::setBinningParameters( RigHistogramCalculator::BinningMode binningMode, RigHistogramCalculator::OutOfRangeHandling outOfRangeHandling, std::optional> customBinRange ) { m_binningMode = binningMode; m_outOfRangeHandling = outOfRangeHandling; m_customBinRange = customBinRange; } //-------------------------------------------------------------------------------------------------- /// Recompute the histogram with non-default binning (logarithmic and/or a custom bin range) directly /// from the underlying data. The statistics cached for other consumers are left untouched. //-------------------------------------------------------------------------------------------------- void RimHistogramCalculator::applyCustomBinning( RigStatisticsDataCache* statisticsCache, std::optional timeStepIndex, RigHistogramData& histData ) { const bool useCustomBinning = ( m_binningMode != RigHistogramCalculator::BinningMode::LINEAR ) || m_customBinRange.has_value(); if ( !useCustomBinning || !statisticsCache ) return; double binMin = m_customBinRange ? m_customBinRange->first : histData.min; double binMax = m_customBinRange ? m_customBinRange->second : histData.max; if ( m_binningMode == RigHistogramCalculator::BinningMode::LOGARITHMIC && binMin <= 0.0 ) { // Use the smallest positive value as the logarithmic range minimum. HUGE_VAL when there are none. double pos = HUGE_VAL; double neg = -HUGE_VAL; if ( timeStepIndex.has_value() ) statisticsCache->posNegClosestToZero( *timeStepIndex, pos, neg ); else statisticsCache->posNegClosestToZero( pos, neg ); binMin = pos; } histData.histogram.clear(); if ( binMin <= binMax && RigStatisticsTools::isValidNumber( binMin ) && RigStatisticsTools::isValidNumber( binMax ) ) { RigHistogramCalculator histCalc( binMin, binMax, m_numBins, &histData.histogram, m_binningMode, m_outOfRangeHandling ); if ( timeStepIndex.has_value() ) statisticsCache->computeHistogram( *timeStepIndex, histCalc ); else statisticsCache->computeHistogram( histCalc ); // Let the plot draw bin edges that match the histogram histData.min = binMin; histData.max = binMax; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimHistogramCalculator::setDoComputeMobileVolumeWeightedMean( bool enable ) { m_doComputeMobileVolumeWeightedMean = enable; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimHistogramCalculator::invalidateVisibleCellsCache() { m_isVisCellStatUpToDate = false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigHistogramData RimHistogramCalculator::histogramData( RimEclipseContourMapView* contourMap ) { RigHistogramData histData; if ( contourMap && contourMap->contourMapProjection() && contourMap->contourMapProjection()->mapProjection() ) { auto mapProjection = contourMap->contourMapProjection()->mapProjection(); bool isResultsInfoRelevant = mapProjection->numberOfValidCells() > 0u; if ( isResultsInfoRelevant ) { histData.min = mapProjection->minValue(); histData.max = mapProjection->maxValue(); histData.mean = mapProjection->meanValue(); histData.sum = mapProjection->sumAllValues(); RigHistogramCalculator histCalc( histData.min, histData.max, m_numBins, &histData.histogram ); for ( double value : mapProjection->aggregatedResults() ) { if ( value != std::numeric_limits::infinity() ) histCalc.addValue( value ); } } } return histData; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigHistogramData RimHistogramCalculator::histogramData( RimGeoMechContourMapView* contourMap ) { RigHistogramData histData; if ( contourMap && contourMap->contourMapProjection() && contourMap->contourMapProjection()->mapProjection() ) { auto mapProjection = contourMap->contourMapProjection()->mapProjection(); bool isResultsInfoRelevant = mapProjection->numberOfValidCells() > 0u; if ( isResultsInfoRelevant ) { histData.min = mapProjection->minValue(); histData.max = mapProjection->maxValue(); histData.mean = mapProjection->meanValue(); histData.sum = mapProjection->sumAllValues(); RigHistogramCalculator histCalc( histData.min, histData.max, m_numBins, &histData.histogram ); for ( double value : mapProjection->aggregatedResults() ) { if ( value != std::numeric_limits::infinity() ) histCalc.addValue( value ); } } } return histData; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigHistogramData RimHistogramCalculator::histogramData( RimEclipseView* eclipseView, StatisticsCellRangeType cellRange, StatisticsTimeRangeType timeRange ) { if ( eclipseView ) { RimEclipseResultDefinition* eclResultDefinition = eclipseView->cellResult(); bool isResultsInfoRelevant = eclResultDefinition->hasResult(); if ( isResultsInfoRelevant ) { RigEclipseResultAddress eclResAddr = eclResultDefinition->eclipseResultAddress(); if ( eclResAddr.isValid() ) { int currentTimeStep = eclipseView->currentTimeStep(); if ( eclipseView->cellResult()->hasStaticResult() ) { currentTimeStep = 0; } return histogramData( eclipseView, eclResultDefinition, cellRange, timeRange, currentTimeStep ); } } } // RigHistogramData data; return data; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigHistogramData RimHistogramCalculator::histogramData( RimEclipseView* eclipseView, RimEclipseResultDefinition* eclResultDefinition, StatisticsCellRangeType cellRange, StatisticsTimeRangeType timeRange, int timeStep ) { CAF_ASSERT( eclResultDefinition ); RigHistogramData histData; RigStatisticsDataCache* statisticsCache = nullptr; std::optional timeStepContext; eclResultDefinition->loadResult(); if ( eclResultDefinition->isFlowDiagOrInjectionFlooding() ) { if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP ) { if ( cellRange == StatisticsCellRangeType::ALL_CELLS ) { RigFlowDiagResults* fldResults = eclResultDefinition->flowDiagSolution()->flowDiagResults(); RigFlowDiagResultAddress resAddr = eclResultDefinition->flowDiagResAddress(); fldResults->setStatisticsDataCacheNumBins( resAddr, m_numBins ); fldResults->minMaxScalarValues( resAddr, timeStep, &histData.min, &histData.max ); fldResults->p10p90ScalarValues( resAddr, timeStep, &histData.p10, &histData.p90 ); fldResults->meanScalarValue( resAddr, timeStep, &histData.mean ); fldResults->sumScalarValue( resAddr, timeStep, &histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) fldResults->mobileVolumeWeightedMean( resAddr, timeStep, &histData.weightedMean ); histData.histogram = fldResults->scalarValuesHistogram( resAddr, timeStep ); statisticsCache = fldResults->statistics( resAddr ); timeStepContext = static_cast( timeStep ); } else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS ) { CAF_ASSERT( eclipseView ); updateVisCellStatsIfNeeded( eclipseView, eclResultDefinition ); m_visibleCellStatistics->setNumBins( m_numBins ); m_visibleCellStatistics->meanCellScalarValues( timeStep, histData.mean ); m_visibleCellStatistics->minMaxCellScalarValues( timeStep, histData.min, histData.max ); m_visibleCellStatistics->p10p90CellScalarValues( timeStep, histData.p10, histData.p90 ); m_visibleCellStatistics->sumCellScalarValues( timeStep, histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) m_visibleCellStatistics->mobileVolumeWeightedMean( timeStep, histData.weightedMean ); histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram( timeStep ); statisticsCache = m_visibleCellStatistics.p(); timeStepContext = static_cast( timeStep ); } } else if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS ) { if ( cellRange == StatisticsCellRangeType::ALL_CELLS ) { RigFlowDiagResults* fldResults = eclResultDefinition->flowDiagSolution()->flowDiagResults(); RigFlowDiagResultAddress resAddr = eclResultDefinition->flowDiagResAddress(); fldResults->setStatisticsDataCacheNumBins( resAddr, m_numBins ); fldResults->minMaxScalarValues( resAddr, &histData.min, &histData.max ); fldResults->p10p90ScalarValues( resAddr, &histData.p10, &histData.p90 ); fldResults->meanScalarValue( resAddr, &histData.mean ); fldResults->sumScalarValue( resAddr, &histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) fldResults->mobileVolumeWeightedMean( resAddr, &histData.weightedMean ); histData.histogram = fldResults->scalarValuesHistogram( resAddr ); statisticsCache = fldResults->statistics( resAddr ); } else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS ) { CAF_ASSERT( eclipseView ); updateVisCellStatsIfNeeded( eclipseView, eclResultDefinition ); m_visibleCellStatistics->setNumBins( m_numBins ); m_visibleCellStatistics->meanCellScalarValues( histData.mean ); m_visibleCellStatistics->minMaxCellScalarValues( histData.min, histData.max ); m_visibleCellStatistics->p10p90CellScalarValues( histData.p10, histData.p90 ); m_visibleCellStatistics->sumCellScalarValues( histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) m_visibleCellStatistics->mobileVolumeWeightedMean( histData.weightedMean ); histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram(); statisticsCache = m_visibleCellStatistics.p(); } } } else if ( cellRange == StatisticsCellRangeType::ALL_CELLS ) { RigEclipseResultAddress eclResAddr = eclResultDefinition->eclipseResultAddress(); RigCaseCellResultsData* cellResults = eclResultDefinition->currentGridCellResults(); if ( cellResults && eclResAddr.isValid() && cellResults->hasResultEntry( eclResAddr ) ) { if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS ) { cellResults->setStatisticsDataCacheNumBins( eclResAddr, m_numBins ); cellResults->minMaxCellScalarValues( eclResAddr, histData.min, histData.max ); cellResults->p10p90CellScalarValues( eclResAddr, histData.p10, histData.p90 ); cellResults->meanCellScalarValues( eclResAddr, histData.mean ); cellResults->sumCellScalarValues( eclResAddr, histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) cellResults->mobileVolumeWeightedMean( eclResAddr, histData.weightedMean ); histData.histogram = cellResults->cellScalarValuesHistogram( eclResAddr ); statisticsCache = cellResults->statistics( eclResAddr ); } else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP ) { cellResults->setStatisticsDataCacheNumBins( eclResAddr, m_numBins ); cellResults->minMaxCellScalarValues( eclResAddr, timeStep, histData.min, histData.max ); cellResults->p10p90CellScalarValues( eclResAddr, timeStep, histData.p10, histData.p90 ); cellResults->meanCellScalarValues( eclResAddr, timeStep, histData.mean ); cellResults->sumCellScalarValues( eclResAddr, timeStep, histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) cellResults->mobileVolumeWeightedMean( eclResAddr, timeStep, histData.weightedMean ); histData.histogram = cellResults->cellScalarValuesHistogram( eclResAddr, timeStep ); statisticsCache = cellResults->statistics( eclResAddr ); timeStepContext = static_cast( timeStep ); } } } else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS ) { CAF_ASSERT( eclipseView ); updateVisCellStatsIfNeeded( eclipseView, eclResultDefinition ); if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS ) { // TODO: Only valid if we have no dynamic property filter m_visibleCellStatistics->setNumBins( m_numBins ); m_visibleCellStatistics->meanCellScalarValues( histData.mean ); m_visibleCellStatistics->minMaxCellScalarValues( histData.min, histData.max ); m_visibleCellStatistics->p10p90CellScalarValues( histData.p10, histData.p90 ); m_visibleCellStatistics->sumCellScalarValues( histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) m_visibleCellStatistics->mobileVolumeWeightedMean( histData.weightedMean ); histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram(); statisticsCache = m_visibleCellStatistics.p(); } else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP ) { m_visibleCellStatistics->setNumBins( m_numBins ); m_visibleCellStatistics->meanCellScalarValues( timeStep, histData.mean ); m_visibleCellStatistics->minMaxCellScalarValues( timeStep, histData.min, histData.max ); m_visibleCellStatistics->p10p90CellScalarValues( timeStep, histData.p10, histData.p90 ); m_visibleCellStatistics->sumCellScalarValues( timeStep, histData.sum ); if ( m_doComputeMobileVolumeWeightedMean ) m_visibleCellStatistics->mobileVolumeWeightedMean( timeStep, histData.weightedMean ); histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram( timeStep ); statisticsCache = m_visibleCellStatistics.p(); timeStepContext = static_cast( timeStep ); } } applyCustomBinning( statisticsCache, timeStepContext, histData ); return histData; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigHistogramData RimHistogramCalculator::histogramData( RimGeoMechView* geoMechView, StatisticsCellRangeType cellRange, StatisticsTimeRangeType timeRange ) { RigHistogramData histData; if ( geoMechView ) { RimGeoMechCase* geoMechCase = geoMechView->geoMechCase(); RigGeoMechCaseData* caseData = geoMechCase ? geoMechCase->geoMechData() : nullptr; bool isResultsInfoRelevant = caseData && geoMechView->cellResultResultDefinition()->hasResult(); if ( isResultsInfoRelevant ) { RigFemResultAddress resAddress = geoMechView->cellResultResultDefinition()->resultAddress(); if ( cellRange == StatisticsCellRangeType::ALL_CELLS ) { if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS ) { caseData->femPartResults()->meanScalarValue( resAddress, &histData.mean ); caseData->femPartResults()->minMaxScalarValues( resAddress, &histData.min, &histData.max ); caseData->femPartResults()->p10p90ScalarValues( resAddress, &histData.p10, &histData.p90 ); caseData->femPartResults()->sumScalarValue( resAddress, &histData.sum ); histData.histogram = caseData->femPartResults()->scalarValuesHistogram( resAddress ); } else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP ) { auto [timeStepIdx, frameIdx] = geoMechView->currentStepAndDataFrame(); caseData->femPartResults()->meanScalarValue( resAddress, timeStepIdx, frameIdx, &histData.mean ); caseData->femPartResults()->minMaxScalarValues( resAddress, timeStepIdx, frameIdx, &histData.min, &histData.max ); caseData->femPartResults()->p10p90ScalarValues( resAddress, timeStepIdx, frameIdx, &histData.p10, &histData.p90 ); caseData->femPartResults()->sumScalarValue( resAddress, timeStepIdx, frameIdx, &histData.sum ); histData.histogram = caseData->femPartResults()->scalarValuesHistogram( resAddress, timeStepIdx, frameIdx ); } } else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS ) { updateVisCellStatsIfNeeded( geoMechView ); if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS ) { // TODO: Only valid if we have no dynamic property filter m_visibleCellStatistics->meanCellScalarValues( histData.mean ); m_visibleCellStatistics->minMaxCellScalarValues( histData.min, histData.max ); m_visibleCellStatistics->p10p90CellScalarValues( histData.p10, histData.p90 ); m_visibleCellStatistics->sumCellScalarValues( histData.sum ); histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram(); } else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP ) { int timeStepIdx = geoMechView->currentTimeStep(); m_visibleCellStatistics->meanCellScalarValues( timeStepIdx, histData.mean ); m_visibleCellStatistics->minMaxCellScalarValues( timeStepIdx, histData.min, histData.max ); m_visibleCellStatistics->p10p90CellScalarValues( timeStepIdx, histData.p10, histData.p90 ); m_visibleCellStatistics->sumCellScalarValues( timeStepIdx, histData.sum ); histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram( timeStepIdx ); } } } } return histData; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimHistogramCalculator::updateVisCellStatsIfNeeded( RimGeoMechView* geoMechView ) { if ( m_isVisCellStatUpToDate ) return; cvf::ref calc; if ( geoMechView ) { RigFemResultAddress resAddress = geoMechView->cellResultResultDefinition()->resultAddress(); calc = new RigFemNativeVisibleCellsStatCalc( geoMechView->geoMechCase()->geoMechData(), resAddress, geoMechView->currentTotalCellVisibility().p() ); } m_visibleCellStatistics = new RigStatisticsDataCache( calc.p() ); m_isVisCellStatUpToDate = true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimHistogramCalculator::updateVisCellStatsIfNeeded( RimEclipseView* eclipseView, RimEclipseResultDefinition* eclResultDefinition ) { CAF_ASSERT( eclipseView ); CAF_ASSERT( eclResultDefinition ); if ( m_isVisCellStatUpToDate ) return; eclipseView->cellResult()->loadResult(); cvf::ref calc; if ( eclResultDefinition->isFlowDiagOrInjectionFlooding() ) { RigFlowDiagResultAddress resAddr = eclResultDefinition->flowDiagResAddress(); RigFlowDiagResults* fldResults = eclResultDefinition->flowDiagSolution()->flowDiagResults(); calc = new RigFlowDiagVisibleCellsStatCalc( fldResults, resAddr, eclipseView->currentTotalCellVisibility().p() ); } else { RigEclipseResultAddress resAddr = eclResultDefinition->eclipseResultAddress(); QString resultName = resAddr.resultName(); std::vector addresses = sourcesForMultiPropertyResults( resultName ); if ( !addresses.empty() ) { cvf::ref multicalc = new RigEclipseMultiPropertyStatCalc(); for ( RigEclipseResultAddress& compResAddr : addresses ) { cvf::ref singleCalc = new RigEclipseNativeVisibleCellsStatCalc( eclResultDefinition->currentGridCellResults(), compResAddr, eclipseView->currentTotalCellVisibility().p() ); multicalc->addStatisticsCalculator( singleCalc.p() ); } calc = multicalc; } else { calc = new RigEclipseNativeVisibleCellsStatCalc( eclResultDefinition->currentGridCellResults(), resAddr, eclipseView->currentTotalCellVisibility().p() ); } } m_visibleCellStatistics = new RigStatisticsDataCache( calc.p() ); m_isVisCellStatUpToDate = true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimHistogramCalculator::sourcesForMultiPropertyResults( const QString& resultName ) { static const std::map> resultsWithMultiPropertySource = { { RiaResultNames::combinedTransmissibilityResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANX" ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANY" ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANZ" ) } }, { RiaResultNames::combinedMultResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX" ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX-" ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY" ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY-" ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ" ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ-" ) } }, { RiaResultNames::combinedRiTranResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranXResultName() ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranYResultName() ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranZResultName() ) } }, { RiaResultNames::combinedRiMultResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultXResultName() ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultYResultName() ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultZResultName() ) } }, { RiaResultNames::combinedRiAreaNormTranResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranXResultName() ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranYResultName() ), RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranZResultName() ) } }, { RiaResultNames::combinedWaterFluxResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATI+" ), RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATJ+" ), RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATK+" ) } }, { RiaResultNames::combinedOilFluxResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILI+" ), RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILJ+" ), RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILK+" ) } }, { RiaResultNames::combinedGasFluxResultName(), { RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASI+" ), RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASJ+" ), RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASK+" ) } } }; auto resNameResultAddrsPairIt = resultsWithMultiPropertySource.find( resultName ); if ( resNameResultAddrsPairIt != resultsWithMultiPropertySource.end() ) { return resNameResultAddrsPairIt->second; } else if ( resultName.endsWith( "IJK" ) ) { std::vector resultAddrs; QString baseName = resultName.left( resultName.size() - 3 ); QStringList endings = { "I", "J", "K" }; for ( QString ending : endings ) { resultAddrs.emplace_back( RigEclipseResultAddress( RiaDefines::ResultCatType::GENERATED, baseName + ending ) ); } return resultAddrs; } else { return std::vector(); } }