///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011- Statoil ASA // Copyright (C) 2013- Ceetron Solutions AS // Copyright (C) 2011-2012 Ceetron 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 "RigCaseCellResultsData.h" #include "RiaApplication.h" #include "RiaEclipseUnitTools.h" #include "RiaLogging.h" #include "RiaResultNames.h" #include "RigAllanDiagramData.h" #include "RigCaseCellResultCalculator.h" #include "RigEclipseCaseData.h" #include "RigEclipseMultiPropertyStatCalc.h" #include "RigEclipseNativeStatCalc.h" #include "RigEclipseResultInfo.h" #include "RigFormationNames.h" #include "RigMainGrid.h" #include "RigStatisticsDataCache.h" #include "RigStatisticsMath.h" #include "RimCompletionCellIntersectionCalc.h" #include "RimEclipseCase.h" #include "RimProject.h" #include "RifReaderEclipseOutput.h" #include "cafProgressInfo.h" #include "cvfGeometryTools.h" #include #include "RigEclipseAllanFaultsStatCalc.h" #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigCaseCellResultsData::RigCaseCellResultsData( RigEclipseCaseData* ownerCaseData, RiaDefines::PorosityModelType porosityModel ) : m_activeCellInfo( nullptr ) , m_porosityModel( porosityModel ) { CVF_ASSERT( ownerCaseData != nullptr ); CVF_ASSERT( ownerCaseData->mainGrid() != nullptr ); m_ownerCaseData = ownerCaseData; m_ownerMainGrid = ownerCaseData->mainGrid(); m_allanDiagramData = new RigAllanDiagramData; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setMainGrid( RigMainGrid* ownerGrid ) { m_ownerMainGrid = ownerGrid; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setActiveCellInfo( RigActiveCellInfo* activeCellInfo ) { m_activeCellInfo = activeCellInfo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::minMaxCellScalarValues( const RigEclipseResultAddress& resVarAddr, double& min, double& max ) { statistics( resVarAddr )->minMaxCellScalarValues( min, max ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::minMaxCellScalarValues( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex, double& min, double& max ) { statistics( resVarAddr )->minMaxCellScalarValues( timeStepIndex, min, max ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::posNegClosestToZero( const RigEclipseResultAddress& resVarAddr, double& pos, double& neg ) { statistics( resVarAddr )->posNegClosestToZero( pos, neg ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::posNegClosestToZero( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex, double& pos, double& neg ) { statistics( resVarAddr )->posNegClosestToZero( timeStepIndex, pos, neg ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram( const RigEclipseResultAddress& resVarAddr ) { return statistics( resVarAddr )->cellScalarValuesHistogram(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex ) { return statistics( resVarAddr )->cellScalarValuesHistogram( timeStepIndex ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::p10p90CellScalarValues( const RigEclipseResultAddress& resVarAddr, double& p10, double& p90 ) { statistics( resVarAddr )->p10p90CellScalarValues( p10, p90 ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::p10p90CellScalarValues( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex, double& p10, double& p90 ) { statistics( resVarAddr )->p10p90CellScalarValues( timeStepIndex, p10, p90 ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::meanCellScalarValues( const RigEclipseResultAddress& resVarAddr, double& meanValue ) { statistics( resVarAddr )->meanCellScalarValues( meanValue ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::meanCellScalarValues( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex, double& meanValue ) { statistics( resVarAddr )->meanCellScalarValues( timeStepIndex, meanValue ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::uniqueCellScalarValues( const RigEclipseResultAddress& resVarAddr ) { return statistics( resVarAddr )->uniqueCellScalarValues(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::sumCellScalarValues( const RigEclipseResultAddress& resVarAddr, double& sumValue ) { statistics( resVarAddr )->sumCellScalarValues( sumValue ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::sumCellScalarValues( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex, double& sumValue ) { statistics( resVarAddr )->sumCellScalarValues( timeStepIndex, sumValue ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::mobileVolumeWeightedMean( const RigEclipseResultAddress& resVarAddr, double& meanValue ) { statistics( resVarAddr )->mobileVolumeWeightedMean( meanValue ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::mobileVolumeWeightedMean( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex, double& meanValue ) { statistics( resVarAddr )->mobileVolumeWeightedMean( timeStepIndex, meanValue ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::resultCount() const { return m_cellScalarResults.size(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::timeStepCount( const RigEclipseResultAddress& resVarAddr ) const { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); CVF_TIGHT_ASSERT( scalarResultIndex < resultCount() ); return m_cellScalarResults[scalarResultIndex].size(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector>& RigCaseCellResultsData::cellScalarResults( const RigEclipseResultAddress& resVarAddr ) const { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); CVF_TIGHT_ASSERT( scalarResultIndex < resultCount() ); return m_cellScalarResults[scalarResultIndex]; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector>* RigCaseCellResultsData::modifiableCellScalarResultTimesteps( const RigEclipseResultAddress& resVarAddr ) { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); CVF_TIGHT_ASSERT( scalarResultIndex < resultCount() ); return &( m_cellScalarResults[scalarResultIndex] ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector* RigCaseCellResultsData::modifiableCellScalarResult( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex ) { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); CVF_TIGHT_ASSERT( scalarResultIndex < resultCount() ); CVF_TIGHT_ASSERT( timeStepIndex < m_cellScalarResults[scalarResultIndex].size() ); return &( m_cellScalarResults[scalarResultIndex][timeStepIndex] ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::cellScalarResults( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex ) const { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); CVF_TIGHT_ASSERT( scalarResultIndex < resultCount() ); CVF_TIGHT_ASSERT( timeStepIndex < m_cellScalarResults[scalarResultIndex].size() ); return m_cellScalarResults[scalarResultIndex][timeStepIndex]; } //-------------------------------------------------------------------------------------------------- /// Adds an empty scalar set, and returns the scalarResultIndex to it. /// if resultName already exists, it just returns the scalarResultIndex to the existing result. //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findOrCreateScalarResultIndex( const RigEclipseResultAddress& resVarAddr, bool needsToBeStored ) { size_t scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddr ); // If the result exists, do nothing if ( scalarResultIndex != cvf::UNDEFINED_SIZE_T ) { return scalarResultIndex; } // Create the new empty result with metadata scalarResultIndex = this->resultCount(); m_cellScalarResults.push_back( std::vector>() ); RigEclipseResultInfo resInfo( resVarAddr, needsToBeStored, false, scalarResultIndex ); m_resultInfos.push_back( resInfo ); m_addressToResultIndexMap[resVarAddr] = scalarResultIndex; // Create statistics calculator and add statistics cache object // Todo: Move to a "factory" method QString resultName = resVarAddr.resultName(); cvf::ref statisticsCalculator; if ( resultName == RiaResultNames::combinedTransmissibilityResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANX" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANY" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANZ" ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::combinedMultResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX-" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY-" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ-" ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::combinedRiTranResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranXResultName() ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranYResultName() ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranZResultName() ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::combinedRiMultResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultXResultName() ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultYResultName() ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultZResultName() ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::combinedRiAreaNormTranResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranXResultName() ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranYResultName() ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranZResultName() ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::combinedWaterFluxResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATI+" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATJ+" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATK+" ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::combinedOilFluxResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILI+" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILJ+" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILK+" ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::combinedGasFluxResultName() ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASI+" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASJ+" ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASK+" ) ); statisticsCalculator = calc; } else if ( resultName.endsWith( "IJK" ) ) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); QString baseName = resultName.left( resultName.size() - 3 ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::GENERATED, QString( "%1I" ).arg( baseName ) ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::GENERATED, QString( "%1J" ).arg( baseName ) ) ); calc->addNativeStatisticsCalculator( this, RigEclipseResultAddress( RiaDefines::ResultCatType::GENERATED, QString( "%1K" ).arg( baseName ) ) ); statisticsCalculator = calc; } else if ( resultName == RiaResultNames::formationAllanResultName() || resultName == RiaResultNames::formationBinaryAllanResultName() ) { cvf::ref calc = new RigEclipseAllanFaultsStatCalc( m_ownerMainGrid->nncData(), resVarAddr ); statisticsCalculator = calc; } else { statisticsCalculator = new RigEclipseNativeStatCalc( this, resVarAddr ); } cvf::ref dataCache = new RigStatisticsDataCache( statisticsCalculator.p() ); m_statisticsDataCache.push_back( dataCache.p() ); return scalarResultIndex; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QStringList RigCaseCellResultsData::resultNames( RiaDefines::ResultCatType resType ) const { QStringList varList; std::vector::const_iterator it; for ( it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it ) { auto resultAddress = it->eclipseResultAddress(); if ( resultAddress.isDeltaTimeStepActive() || resultAddress.isDeltaCaseActive() || resultAddress.isDivideByCellFaceAreaActive() ) continue; if ( it->resultType() == resType ) { varList.push_back( it->resultName() ); } } return varList; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigActiveCellInfo* RigCaseCellResultsData::activeCellInfo() { return m_activeCellInfo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const RigActiveCellInfo* RigCaseCellResultsData::activeCellInfo() const { return m_activeCellInfo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::recalculateStatistics( const RigEclipseResultAddress& resVarAddr ) { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); if ( scalarResultIndex < m_cellScalarResults.size() ) { m_statisticsDataCache[scalarResultIndex]->clearAllStatistics(); } } //-------------------------------------------------------------------------------------------------- /// Returns whether the result data in question is addressed by Active Cell Index //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::isUsingGlobalActiveIndex( const RigEclipseResultAddress& resVarAddr ) const { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); CVF_TIGHT_ASSERT( scalarResultIndex < m_cellScalarResults.size() ); if ( !m_cellScalarResults[scalarResultIndex].size() ) return true; size_t firstTimeStepResultValueCount = m_cellScalarResults[scalarResultIndex][0].size(); if ( firstTimeStepResultValueCount == m_ownerMainGrid->globalCellArray().size() ) return false; return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::hasFlowDiagUsableFluxes() const { QStringList dynResVarNames = resultNames( RiaDefines::ResultCatType::DYNAMIC_NATIVE ); bool hasFlowFluxes = true; hasFlowFluxes = dynResVarNames.contains( "FLRWATI+" ); hasFlowFluxes = hasFlowFluxes && ( dynResVarNames.contains( "FLROILI+" ) || dynResVarNames.contains( "FLRGASI+" ) ); return hasFlowFluxes; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::allTimeStepDatesFromEclipseReader() const { const RifReaderEclipseOutput* rifReaderOutput = dynamic_cast( m_readerInterface.p() ); if ( rifReaderOutput ) { return rifReaderOutput->allTimeSteps(); } else { return std::vector(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::timeStepDates( const RigEclipseResultAddress& resVarAddr ) const { if ( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() ) { return m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].dates(); } else return std::vector(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::timeStepDates() const { RigEclipseResultAddress scalarResWithMostTimeSteps; maxTimeStepCount( &scalarResWithMostTimeSteps ); return timeStepDates( scalarResWithMostTimeSteps ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::daysSinceSimulationStart() const { RigEclipseResultAddress scalarResWithMostTimeSteps; maxTimeStepCount( &scalarResWithMostTimeSteps ); return daysSinceSimulationStart( scalarResWithMostTimeSteps ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::daysSinceSimulationStart( const RigEclipseResultAddress& resVarAddr ) const { if ( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() ) { return m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].daysSinceSimulationStarts(); } else { return std::vector(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- int RigCaseCellResultsData::reportStepNumber( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex ) const { if ( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() && m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].timeStepInfos().size() > timeStepIndex ) return m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].timeStepInfos()[timeStepIndex].m_reportNumber; else return -1; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::timeStepInfos( const RigEclipseResultAddress& resVarAddr ) const { if ( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() ) return m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].timeStepInfos(); else return std::vector(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setTimeStepInfos( const RigEclipseResultAddress& resVarAddr, const std::vector& timeStepInfos ) { CVF_ASSERT( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() ); m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].setTimeStepInfos( timeStepInfos ); std::vector>* dataValues = this->modifiableCellScalarResultTimesteps( resVarAddr ); dataValues->resize( timeStepInfos.size() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::maxTimeStepCount( RigEclipseResultAddress* resultAddressWithMostTimeSteps ) const { size_t maxTsCount = 0; RigEclipseResultAddress scalarResultIndexWithMaxTsCount; for ( size_t i = 0; i < m_resultInfos.size(); i++ ) { if ( m_resultInfos[i].timeStepInfos().size() > maxTsCount ) { maxTsCount = m_resultInfos[i].timeStepInfos().size(); if ( resultAddressWithMostTimeSteps ) { *resultAddressWithMostTimeSteps = m_resultInfos[i].eclipseResultAddress(); } } } return maxTsCount; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RigCaseCellResultsData::makeResultNameUnique( const QString& resultNameProposal ) const { QString newResultName = resultNameProposal; int nameNum = 1; int stringLength = newResultName.size(); while ( true ) { if ( !this->hasResultEntry( RigEclipseResultAddress( newResultName ) ) ) break; newResultName.truncate( stringLength ); newResultName += "_" + QString::number( nameNum ); ++nameNum; } return newResultName; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::clearScalarResult( RiaDefines::ResultCatType type, const QString& resultName ) { clearScalarResult( RigEclipseResultAddress( type, resultName ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::clearScalarResult( const RigEclipseResultAddress& resultAddress ) { size_t scalarResultIndex = findScalarResultIndexFromAddress( resultAddress ); if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) return; for ( size_t tsIdx = 0; tsIdx < m_cellScalarResults[scalarResultIndex].size(); ++tsIdx ) { std::vector empty; m_cellScalarResults[scalarResultIndex][tsIdx].swap( empty ); } recalculateStatistics( resultAddress ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::clearAllResults() { m_cellScalarResults.clear(); m_resultInfos.clear(); m_addressToResultIndexMap.clear(); m_statisticsDataCache.clear(); } //-------------------------------------------------------------------------------------------------- /// Removes all the actual numbers put into this object, and frees up the memory. /// Does not touch the metadata in any way //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::freeAllocatedResultsData() { for ( size_t resultIdx = 0; resultIdx < m_cellScalarResults.size(); ++resultIdx ) { for ( size_t tsIdx = 0; tsIdx < m_cellScalarResults[resultIdx].size(); ++tsIdx ) { // Using swap with an empty vector as that is the safest way to really get rid of the allocated data in a // vector std::vector empty; m_cellScalarResults[resultIdx][tsIdx].swap( empty ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::isResultLoaded( const RigEclipseResultAddress& resultAddr ) const { size_t scalarResultIndex = findScalarResultIndexFromAddress( resultAddr ); CVF_TIGHT_ASSERT( scalarResultIndex != cvf::UNDEFINED_SIZE_T ); if ( scalarResultIndex != cvf::UNDEFINED_SIZE_T ) { return isDataPresent( scalarResultIndex ); } return false; } //-------------------------------------------------------------------------------------------------- /// Make sure we have a result with given type and name, and make sure one "timestep" result vector // for the static result values are allocated //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::addStaticScalarResult( RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount ) { size_t resultIdx = findOrCreateScalarResultIndex( RigEclipseResultAddress( type, resultName ), needsToBeStored ); m_cellScalarResults[resultIdx].resize( 1, std::vector() ); m_cellScalarResults[resultIdx][0].resize( resultValueCount, HUGE_VAL ); return resultIdx; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::updateResultName( RiaDefines::ResultCatType resultType, const QString& oldName, const QString& newName ) { bool anyNameUpdated = false; for ( auto& it : m_resultInfos ) { if ( it.resultType() == resultType && it.resultName() == oldName ) { anyNameUpdated = true; it.setResultName( newName ); } } return anyNameUpdated; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector* RigCaseCellResultsData::getResultIndexableStaticResult( RigActiveCellInfo* actCellInfo, RigCaseCellResultsData* gridCellResults, QString resultName, std::vector& activeCellsResultsTempContainer ) { size_t resultCellCount = actCellInfo->reservoirActiveCellCount(); size_t reservoirCellCount = actCellInfo->reservoirCellCount(); RigEclipseResultAddress resVarAddr( RiaDefines::ResultCatType::STATIC_NATIVE, resultName ); size_t scalarResultIndexPorv = gridCellResults->findOrLoadKnownScalarResult( resVarAddr ); if ( scalarResultIndexPorv == cvf::UNDEFINED_SIZE_T ) return nullptr; const std::vector* porvResults = &( gridCellResults->cellScalarResults( resVarAddr, 0 ) ); if ( !gridCellResults->isUsingGlobalActiveIndex( resVarAddr ) ) { // PORV is given for all cells activeCellsResultsTempContainer.resize( resultCellCount, HUGE_VAL ); for ( size_t globalCellIndex = 0; globalCellIndex < reservoirCellCount; globalCellIndex++ ) { size_t resultIdx = actCellInfo->cellResultIndex( globalCellIndex ); if ( resultIdx != cvf::UNDEFINED_SIZE_T ) { activeCellsResultsTempContainer[resultIdx] = porvResults->at( globalCellIndex ); } } return &activeCellsResultsTempContainer; } else { return porvResults; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::infoForEachResultIndex() { return m_resultInfos; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::mustBeCalculated( size_t scalarResultIndex ) const { std::vector::const_iterator it; for ( it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it ) { if ( it->gridScalarResultIndex() == scalarResultIndex ) { return it->mustBeCalculated(); } } return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setMustBeCalculated( size_t scalarResultIndex ) { std::vector::iterator it; for ( it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it ) { if ( it->gridScalarResultIndex() == scalarResultIndex ) { it->setMustBeCalculated( true ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::eraseAllSourSimData() { for ( size_t i = 0; i < m_resultInfos.size(); i++ ) { RigEclipseResultInfo& ri = m_resultInfos[i]; if ( ri.resultType() == RiaDefines::ResultCatType::SOURSIMRL ) { ri.setResultType( RiaDefines::ResultCatType::REMOVED ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::createPlaceholderResultEntries() { // SOIL { if ( !hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SOIL" ) ) ) { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SWAT" ) ) || hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SGAS" ) ) ) { size_t soilIndex = findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SOIL" ), false ); this->setMustBeCalculated( soilIndex ); } } } // Oil Volume if ( RiaApplication::enableDevelopmentFeatures() ) { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SOIL" ) ) ) { findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::riOilVolumeResultName() ), false ); } } // Completion type { findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::completionTypeResultName() ), false ); } // Fault results { findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationBinaryAllanResultName() ), false ); findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationAllanResultName() ), false ); } // FLUX { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATI+" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATJ+" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATK+" ) ) ) { findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::combinedWaterFluxResultName() ), false ); } if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILI+" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILJ+" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILK+" ) ) ) { findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::combinedOilFluxResultName() ), false ); } if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASI+" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASJ+" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASK+" ) ) ) { findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::combinedGasFluxResultName() ), false ); } } // TRANSXYZ { if ( hasCompleteTransmissibilityResults() ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedTransmissibilityResultName(), false, 0 ); } } // MULTXYZ { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX-" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY-" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ-" ) ) ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedMultResultName(), false, 0 ); } } // riTRANSXYZ and X,Y,Z { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMX" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMY" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMZ" ) ) ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranXResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranYResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranZResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedRiTranResultName(), false, 0 ); } } // riMULTXYZ and X, Y, Z { if ( hasCompleteTransmissibilityResults() && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranXResultName() ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranYResultName() ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranZResultName() ) ) ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultXResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultYResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultZResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedRiMultResultName(), false, 0 ); } } // riTRANS X,Y,Z byArea { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANX" ) ) ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranXResultName(), false, 0 ); } if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANY" ) ) ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranYResultName(), false, 0 ); } if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANZ" ) ) ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranZResultName(), false, 0 ); } } // riTRANSXYZbyArea { if ( hasCompleteTransmissibilityResults() ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedRiAreaNormTranResultName(), false, 0 ); } } // Cell Volume { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riCellVolumeResultName(), false, 0 ); } // Mobile Pore Volume { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PORV" ) ) ) { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::mobilePoreVolumeName(), false, 0 ); } } // I/J/K indexes { addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexIResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexJResultName(), false, 0 ); addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexKResultName(), false, 0 ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::hasCompleteTransmissibilityResults() const { if ( hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANX" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANY" ) ) && hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANZ" ) ) ) { return true; } return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::existingResults() const { std::vector addresses; for ( const auto& ri : m_resultInfos ) { addresses.emplace_back( ri.eclipseResultAddress() ); } return addresses; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const RigEclipseResultInfo* RigCaseCellResultsData::resultInfo( const RigEclipseResultAddress& resVarAddr ) const { size_t index = findScalarResultIndexFromAddress( resVarAddr ); if ( index < m_resultInfos.size() ) { return &( m_resultInfos[index] ); } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::ensureKnownResultLoaded( const RigEclipseResultAddress& resultAddress ) { size_t resultIndex = findOrLoadKnownScalarResult( resultAddress ); return ( resultIndex != cvf::UNDEFINED_SIZE_T ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::findAndLoadResultByName( const QString& resultName, const std::vector& resultCategorySearchOrder ) { RigEclipseResultAddress adr( resultName ); size_t resultIndex = findOrLoadKnownScalarResultByResultTypeOrder( adr, resultCategorySearchOrder ); return ( resultIndex != cvf::UNDEFINED_SIZE_T ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::hasResultEntry( const RigEclipseResultAddress& resultAddress ) const { size_t resultIndex = findScalarResultIndexFromAddress( resultAddress ); return ( resultIndex != cvf::UNDEFINED_SIZE_T ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::createResultEntry( const RigEclipseResultAddress& resultAddress, bool needsToBeStored ) { findOrCreateScalarResultIndex( resultAddress, needsToBeStored ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findOrLoadKnownScalarResult( const RigEclipseResultAddress& resVarAddr ) { if ( !resVarAddr.isValid() ) { return cvf::UNDEFINED_SIZE_T; } else if ( resVarAddr.resultCatType() == RiaDefines::ResultCatType::UNDEFINED ) { std::vector searchOrder = { RiaDefines::ResultCatType::STATIC_NATIVE, RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaDefines::ResultCatType::SOURSIMRL, RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultCatType::INPUT_PROPERTY, RiaDefines::ResultCatType::FORMATION_NAMES }; size_t scalarResultIndex = this->findOrLoadKnownScalarResultByResultTypeOrder( resVarAddr, searchOrder ); return scalarResultIndex; } size_t scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddr ); if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) return cvf::UNDEFINED_SIZE_T; RiaDefines::ResultCatType type = resVarAddr.resultCatType(); QString resultName = resVarAddr.resultName(); if ( resVarAddr.isDeltaCaseActive() || resVarAddr.isDeltaTimeStepActive() ) { if ( !RigCaseCellResultCalculator::computeDifference( this->m_ownerCaseData, m_porosityModel, resVarAddr ) ) { return cvf::UNDEFINED_SIZE_T; } return scalarResultIndex; } if ( resVarAddr.isDivideByCellFaceAreaActive() ) { if ( !isDataPresent( scalarResultIndex ) ) { if ( !RigCaseCellResultCalculator::computeDivideByCellFaceArea( m_ownerMainGrid, this->m_ownerCaseData, m_porosityModel, resVarAddr ) ) { return cvf::UNDEFINED_SIZE_T; } } return scalarResultIndex; } // Load dependency data sets if ( type == RiaDefines::ResultCatType::STATIC_NATIVE ) { if ( resultName == RiaResultNames::combinedTransmissibilityResultName() ) { this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "TRANX" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "TRANY" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "TRANZ" ) ); } else if ( resultName == RiaResultNames::combinedMultResultName() ) { this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "MULTX" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "MULTX-" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "MULTY" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "MULTY-" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "MULTZ" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "MULTZ-" ) ); } else if ( resultName == RiaResultNames::combinedRiTranResultName() ) { computeRiTransComponent( RiaResultNames::riTranXResultName() ); computeRiTransComponent( RiaResultNames::riTranYResultName() ); computeRiTransComponent( RiaResultNames::riTranZResultName() ); computeNncCombRiTrans(); } else if ( resultName == RiaResultNames::riTranXResultName() || resultName == RiaResultNames::riTranYResultName() || resultName == RiaResultNames::riTranZResultName() ) { computeRiTransComponent( resultName ); } else if ( resultName == RiaResultNames::combinedRiMultResultName() ) { computeRiMULTComponent( RiaResultNames::riMultXResultName() ); computeRiMULTComponent( RiaResultNames::riMultYResultName() ); computeRiMULTComponent( RiaResultNames::riMultZResultName() ); computeNncCombRiTrans(); computeNncCombRiMULT(); } else if ( resultName == RiaResultNames::riMultXResultName() || resultName == RiaResultNames::riMultYResultName() || resultName == RiaResultNames::riMultZResultName() ) { computeRiMULTComponent( resultName ); } else if ( resultName == RiaResultNames::combinedRiAreaNormTranResultName() ) { computeRiTRANSbyAreaComponent( RiaResultNames::riAreaNormTranXResultName() ); computeRiTRANSbyAreaComponent( RiaResultNames::riAreaNormTranYResultName() ); computeRiTRANSbyAreaComponent( RiaResultNames::riAreaNormTranZResultName() ); computeNncCombRiTRANSbyArea(); } else if ( resultName == RiaResultNames::riAreaNormTranXResultName() || resultName == RiaResultNames::riAreaNormTranYResultName() || resultName == RiaResultNames::riAreaNormTranZResultName() ) { computeRiTRANSbyAreaComponent( resultName ); } else if ( resultName == RiaResultNames::formationAllanResultName() || resultName == RiaResultNames::formationBinaryAllanResultName() ) { bool includeInactiveCells = false; if ( m_readerInterface.notNull() ) { includeInactiveCells = m_readerInterface->includeInactiveCellsInFaultGeometry(); } computeAllanResults( this, m_ownerMainGrid, includeInactiveCells ); } else if ( resultName == RiaResultNames::indexIResultName() || resultName == RiaResultNames::indexJResultName() || resultName == RiaResultNames::indexKResultName() ) { computeIndexResults(); } } else if ( type == RiaDefines::ResultCatType::DYNAMIC_NATIVE ) { if ( resultName == RiaResultNames::combinedWaterFluxResultName() ) { this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLRWATI+" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLRWATJ+" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLRWATK+" ) ); } else if ( resultName == RiaResultNames::combinedOilFluxResultName() ) { this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLROILI+" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLROILJ+" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLROILK+" ) ); } else if ( resultName == RiaResultNames::combinedGasFluxResultName() ) { this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLRGASI+" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLRGASJ+" ) ); this->findOrLoadKnownScalarResult( RigEclipseResultAddress( type, "FLRGASK+" ) ); } } if ( isDataPresent( scalarResultIndex ) ) { return scalarResultIndex; } if ( resultName == "SOIL" ) { if ( this->mustBeCalculated( scalarResultIndex ) ) { // Trigger loading of SWAT, SGAS to establish time step count if no data has been loaded from file at // this point findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SWAT" ) ); findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SGAS" ) ); m_cellScalarResults[scalarResultIndex].resize( this->maxTimeStepCount() ); for ( size_t timeStepIdx = 0; timeStepIdx < this->maxTimeStepCount(); timeStepIdx++ ) { std::vector& values = m_cellScalarResults[scalarResultIndex][timeStepIdx]; if ( values.size() == 0 ) { computeSOILForTimeStep( timeStepIdx ); } } return scalarResultIndex; } } else if ( resultName == RiaResultNames::completionTypeResultName() ) { caf::ProgressInfo progressInfo( this->maxTimeStepCount(), "Calculate Completion Type Results" ); m_cellScalarResults[scalarResultIndex].resize( this->maxTimeStepCount() ); for ( size_t timeStepIdx = 0; timeStepIdx < this->maxTimeStepCount(); ++timeStepIdx ) { computeCompletionTypeForTimeStep( timeStepIdx ); progressInfo.incrementProgress(); } } else if ( resultName == RiaResultNames::mobilePoreVolumeName() ) { computeMobilePV(); } if ( type == RiaDefines::ResultCatType::GENERATED ) { return cvf::UNDEFINED_SIZE_T; } if ( m_readerInterface.notNull() ) { // Add one more result to result container size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); bool resultLoadingSuccess = true; size_t tempGridCellCount = m_ownerMainGrid->totalTemporaryGridCellCount(); if ( type == RiaDefines::ResultCatType::DYNAMIC_NATIVE && timeStepCount > 0 ) { m_cellScalarResults[scalarResultIndex].resize( timeStepCount ); size_t i; for ( i = 0; i < timeStepCount; i++ ) { std::vector& values = m_cellScalarResults[scalarResultIndex][i]; if ( !m_readerInterface->dynamicResult( resultName, m_porosityModel, i, &values ) ) { resultLoadingSuccess = false; } else if ( tempGridCellCount > 0 ) { if ( !values.empty() ) { values.resize( values.size() + tempGridCellCount, std::numeric_limits::infinity() ); assignValuesToTemporaryLgrs( resultName, values ); } } } } else if ( type == RiaDefines::ResultCatType::STATIC_NATIVE ) { m_cellScalarResults[scalarResultIndex].resize( 1 ); std::vector& values = m_cellScalarResults[scalarResultIndex][0]; if ( !m_readerInterface->staticResult( resultName, m_porosityModel, &values ) ) { resultLoadingSuccess = false; } else if ( tempGridCellCount > 0 ) { if ( !values.empty() ) { values.resize( values.size() + tempGridCellCount, std::numeric_limits::infinity() ); assignValuesToTemporaryLgrs( resultName, values ); } } } if ( !resultLoadingSuccess ) { // Remove last scalar result because loading of result failed m_cellScalarResults[scalarResultIndex].clear(); } } if ( resultName == RiaResultNames::riCellVolumeResultName() ) { computeCellVolumes(); } else if ( resultName == RiaResultNames::riOilVolumeResultName() ) { computeCellVolumes(); computeOilVolumes(); } // Allan results if ( resultName == RiaResultNames::formationAllanResultName() || resultName == RiaResultNames::formationBinaryAllanResultName() ) { bool includeInactiveCells = false; if ( m_readerInterface.notNull() ) { includeInactiveCells = m_readerInterface->includeInactiveCellsInFaultGeometry(); } computeAllanResults( this, m_ownerMainGrid, includeInactiveCells ); } // Handle SourSimRL reading if ( type == RiaDefines::ResultCatType::SOURSIMRL ) { RifReaderEclipseOutput* eclReader = dynamic_cast( m_readerInterface.p() ); if ( eclReader ) { size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); m_cellScalarResults[scalarResultIndex].resize( timeStepCount ); size_t i; for ( i = 0; i < timeStepCount; i++ ) { std::vector& values = m_cellScalarResults[scalarResultIndex][i]; eclReader->sourSimRlResult( resultName, i, &values ); } } } return scalarResultIndex; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findOrLoadKnownScalarResultByResultTypeOrder( const RigEclipseResultAddress& resVarAddr, const std::vector& resultCategorySearchOrder ) { std::set otherResultTypesToSearch = { RiaDefines::ResultCatType::STATIC_NATIVE, RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaDefines::ResultCatType::SOURSIMRL, RiaDefines::ResultCatType::INPUT_PROPERTY, RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultCatType::FORMATION_NAMES }; for ( const auto& resultType : resultCategorySearchOrder ) { otherResultTypesToSearch.erase( resultType ); } std::vector resultTypesOrdered = resultCategorySearchOrder; for ( const auto& resultType : otherResultTypesToSearch ) { resultTypesOrdered.push_back( resultType ); } for ( const auto& resultType : resultTypesOrdered ) { RigEclipseResultAddress resVarAddressWithType = resVarAddr; resVarAddressWithType.setResultCatType( resultType ); size_t scalarResultIndex = this->findOrLoadKnownScalarResult( resVarAddressWithType ); if ( scalarResultIndex != cvf::UNDEFINED_SIZE_T ) { return scalarResultIndex; } } return cvf::UNDEFINED_SIZE_T; } //-------------------------------------------------------------------------------------------------- /// This method is intended to be used for multicase cross statistical calculations, when /// we need process one timestep at a time, freeing memory as we go. //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findOrLoadKnownScalarResultForTimeStep( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex ) { RiaDefines::ResultCatType type = resVarAddr.resultCatType(); QString resultName = resVarAddr.resultName(); // Special handling for SOIL if ( type == RiaDefines::ResultCatType::DYNAMIC_NATIVE && resultName.toUpper() == "SOIL" ) { size_t soilScalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddr ); if ( this->mustBeCalculated( soilScalarResultIndex ) ) { m_cellScalarResults[soilScalarResultIndex].resize( this->maxTimeStepCount() ); std::vector& values = m_cellScalarResults[soilScalarResultIndex][timeStepIndex]; if ( values.size() == 0 ) { computeSOILForTimeStep( timeStepIndex ); } return soilScalarResultIndex; } } else if ( type == RiaDefines::ResultCatType::DYNAMIC_NATIVE && resultName == RiaResultNames::completionTypeResultName() ) { size_t completionTypeScalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddr ); computeCompletionTypeForTimeStep( timeStepIndex ); return completionTypeScalarResultIndex; } size_t scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddr ); if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) return cvf::UNDEFINED_SIZE_T; if ( type == RiaDefines::ResultCatType::GENERATED ) { return cvf::UNDEFINED_SIZE_T; } if ( m_readerInterface.notNull() ) { size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); bool resultLoadingSuccess = true; if ( type == RiaDefines::ResultCatType::DYNAMIC_NATIVE && timeStepCount > 0 ) { m_cellScalarResults[scalarResultIndex].resize( timeStepCount ); std::vector& values = m_cellScalarResults[scalarResultIndex][timeStepIndex]; if ( values.size() == 0 ) { if ( !m_readerInterface->dynamicResult( resultName, m_porosityModel, timeStepIndex, &values ) ) { resultLoadingSuccess = false; } } } else if ( type == RiaDefines::ResultCatType::STATIC_NATIVE ) { m_cellScalarResults[scalarResultIndex].resize( 1 ); std::vector& values = m_cellScalarResults[scalarResultIndex][0]; if ( !m_readerInterface->staticResult( resultName, m_porosityModel, &values ) ) { resultLoadingSuccess = false; } } if ( !resultLoadingSuccess ) { // Error logging CVF_ASSERT( false ); } } // Handle SourSimRL reading if ( type == RiaDefines::ResultCatType::SOURSIMRL ) { RifReaderEclipseOutput* eclReader = dynamic_cast( m_readerInterface.p() ); if ( eclReader ) { size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); m_cellScalarResults[scalarResultIndex].resize( timeStepCount ); std::vector& values = m_cellScalarResults[scalarResultIndex][timeStepIndex]; if ( values.size() == 0 ) { eclReader->sourSimRlResult( resultName, timeStepIndex, &values ); } } } return scalarResultIndex; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeSOILForTimeStep( size_t timeStepIndex ) { // Compute SGAS based on SWAT if the simulation contains no oil testAndComputeSgasForTimeStep( timeStepIndex ); RigEclipseResultAddress SWATAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SWAT" ); RigEclipseResultAddress SGASAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SGAS" ); RigEclipseResultAddress SSOLAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SSOL" ); size_t scalarIndexSWAT = findOrLoadKnownScalarResultForTimeStep( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SWAT" ), timeStepIndex ); size_t scalarIndexSGAS = findOrLoadKnownScalarResultForTimeStep( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SGAS" ), timeStepIndex ); size_t scalarIndexSSOL = findOrLoadKnownScalarResultForTimeStep( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SSOL" ), timeStepIndex ); // Early exit if none of SWAT or SGAS is present if ( scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T ) { return; } size_t soilResultValueCount = 0; size_t soilTimeStepCount = 0; if ( scalarIndexSWAT != cvf::UNDEFINED_SIZE_T ) { const std::vector& swatForTimeStep = this->cellScalarResults( SWATAddr, timeStepIndex ); if ( swatForTimeStep.size() > 0 ) { soilResultValueCount = swatForTimeStep.size(); soilTimeStepCount = this->infoForEachResultIndex()[scalarIndexSWAT].timeStepInfos().size(); } } if ( scalarIndexSGAS != cvf::UNDEFINED_SIZE_T ) { const std::vector& sgasForTimeStep = this->cellScalarResults( SGASAddr, timeStepIndex ); if ( sgasForTimeStep.size() > 0 ) { soilResultValueCount = qMax( soilResultValueCount, sgasForTimeStep.size() ); size_t sgasTimeStepCount = this->infoForEachResultIndex()[scalarIndexSGAS].timeStepInfos().size(); soilTimeStepCount = qMax( soilTimeStepCount, sgasTimeStepCount ); } } // Make sure memory is allocated for the new SOIL results RigEclipseResultAddress SOILAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SOIL" ); size_t soilResultScalarIndex = this->findScalarResultIndexFromAddress( SOILAddr ); m_cellScalarResults[soilResultScalarIndex].resize( soilTimeStepCount ); if ( this->cellScalarResults( SOILAddr, timeStepIndex ).size() > 0 ) { // Data is computed and allocated, nothing more to do return; } m_cellScalarResults[soilResultScalarIndex][timeStepIndex].resize( soilResultValueCount ); const std::vector* swatForTimeStep = nullptr; const std::vector* sgasForTimeStep = nullptr; const std::vector* ssolForTimeStep = nullptr; if ( scalarIndexSWAT != cvf::UNDEFINED_SIZE_T ) { swatForTimeStep = &( this->cellScalarResults( SWATAddr, timeStepIndex ) ); if ( swatForTimeStep->size() == 0 ) { swatForTimeStep = nullptr; } } if ( scalarIndexSGAS != cvf::UNDEFINED_SIZE_T ) { sgasForTimeStep = &( this->cellScalarResults( SGASAddr, timeStepIndex ) ); if ( sgasForTimeStep->size() == 0 ) { sgasForTimeStep = nullptr; } } if ( scalarIndexSSOL != cvf::UNDEFINED_SIZE_T ) { ssolForTimeStep = &( this->cellScalarResults( SSOLAddr, timeStepIndex ) ); if ( ssolForTimeStep->size() == 0 ) { ssolForTimeStep = nullptr; } } std::vector* soilForTimeStep = this->modifiableCellScalarResult( SOILAddr, timeStepIndex ); #pragma omp parallel for for ( int idx = 0; idx < static_cast( soilResultValueCount ); idx++ ) { double soilValue = 1.0; if ( sgasForTimeStep ) { soilValue -= sgasForTimeStep->at( idx ); } if ( swatForTimeStep ) { soilValue -= swatForTimeStep->at( idx ); } if ( ssolForTimeStep ) { soilValue -= ssolForTimeStep->at( idx ); } soilForTimeStep->at( idx ) = soilValue; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::testAndComputeSgasForTimeStep( size_t timeStepIndex ) { size_t scalarIndexSWAT = findOrLoadKnownScalarResultForTimeStep( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SWAT" ), timeStepIndex ); if ( scalarIndexSWAT == cvf::UNDEFINED_SIZE_T ) { return; } if ( m_readerInterface.isNull() ) return; std::set phases = m_readerInterface->availablePhases(); if ( phases.count( RiaDefines::PhaseType::GAS_PHASE ) == 0 ) return; if ( phases.count( RiaDefines::PhaseType::OIL_PHASE ) > 0 ) return; // Simulation type is gas and water. No SGAS is present, compute SGAS based on SWAT size_t scalarIndexSGAS = this->findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SGAS" ), false ); if ( m_cellScalarResults[scalarIndexSGAS].size() > timeStepIndex ) { std::vector& values = m_cellScalarResults[scalarIndexSGAS][timeStepIndex]; if ( values.size() > 0 ) return; } size_t swatResultValueCount = 0; size_t swatTimeStepCount = 0; { std::vector& swatForTimeStep = m_cellScalarResults[scalarIndexSWAT][timeStepIndex]; if ( swatForTimeStep.size() > 0 ) { swatResultValueCount = swatForTimeStep.size(); swatTimeStepCount = this->infoForEachResultIndex()[scalarIndexSWAT].timeStepInfos().size(); } } m_cellScalarResults[scalarIndexSGAS].resize( swatTimeStepCount ); if ( m_cellScalarResults[scalarIndexSGAS][timeStepIndex].size() > 0 ) { return; } m_cellScalarResults[scalarIndexSGAS][timeStepIndex].resize( swatResultValueCount ); std::vector* swatForTimeStep = nullptr; { swatForTimeStep = &( m_cellScalarResults[scalarIndexSWAT][timeStepIndex] ); if ( swatForTimeStep->size() == 0 ) { swatForTimeStep = nullptr; } } std::vector& sgasForTimeStep = m_cellScalarResults[scalarIndexSGAS][timeStepIndex]; #pragma omp parallel for for ( int idx = 0; idx < static_cast( swatResultValueCount ); idx++ ) { double sgasValue = 1.0; if ( swatForTimeStep ) { sgasValue -= swatForTimeStep->at( idx ); } sgasForTimeStep[idx] = sgasValue; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeDepthRelatedResults() { size_t actCellCount = activeCellInfo()->reservoirActiveCellCount(); if ( actCellCount == 0 ) return; size_t depthResultIndex = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "DEPTH" ) ); size_t dxResultIndex = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "DX" ) ); size_t dyResultIndex = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "DY" ) ); size_t dzResultIndex = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "DZ" ) ); size_t topsResultIndex = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TOPS" ) ); size_t bottomResultIndex = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "BOTTOM" ) ); bool computeDepth = false; bool computeDx = false; bool computeDy = false; bool computeDz = false; bool computeTops = false; bool computeBottom = false; if ( depthResultIndex == cvf::UNDEFINED_SIZE_T ) { depthResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, "DEPTH", false, actCellCount ); computeDepth = true; } if ( dxResultIndex == cvf::UNDEFINED_SIZE_T ) { dxResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, "DX", false, actCellCount ); computeDx = true; } if ( dyResultIndex == cvf::UNDEFINED_SIZE_T ) { dyResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, "DY", false, actCellCount ); computeDy = true; } if ( dzResultIndex == cvf::UNDEFINED_SIZE_T ) { dzResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, "DZ", false, actCellCount ); computeDz = true; } if ( topsResultIndex == cvf::UNDEFINED_SIZE_T ) { topsResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, "TOPS", false, actCellCount ); computeTops = true; } if ( bottomResultIndex == cvf::UNDEFINED_SIZE_T ) { bottomResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, "BOTTOM", false, actCellCount ); computeBottom = true; } std::vector>& depth = m_cellScalarResults[depthResultIndex]; std::vector>& dx = m_cellScalarResults[dxResultIndex]; std::vector>& dy = m_cellScalarResults[dyResultIndex]; std::vector>& dz = m_cellScalarResults[dzResultIndex]; std::vector>& tops = m_cellScalarResults[topsResultIndex]; std::vector>& bottom = m_cellScalarResults[bottomResultIndex]; // Make sure the size is at least active cells { if ( depth[0].size() < actCellCount ) { depth[0].resize( actCellCount, std::numeric_limits::max() ); computeDepth = true; } if ( dx[0].size() < actCellCount ) { dx[0].resize( actCellCount, std::numeric_limits::max() ); computeDx = true; } if ( dy[0].size() < actCellCount ) { dy[0].resize( actCellCount, std::numeric_limits::max() ); computeDy = true; } if ( dz[0].size() < actCellCount ) { dz[0].resize( actCellCount, std::numeric_limits::max() ); computeDz = true; } if ( tops[0].size() < actCellCount ) { tops[0].resize( actCellCount, std::numeric_limits::max() ); computeTops = true; } if ( bottom[0].size() < actCellCount ) { bottom[0].resize( actCellCount, std::numeric_limits::max() ); computeBottom = true; } } for ( size_t cellIdx = 0; cellIdx < m_ownerMainGrid->globalCellArray().size(); cellIdx++ ) { const RigCell& cell = m_ownerMainGrid->globalCellArray()[cellIdx]; size_t resultIndex = activeCellInfo()->cellResultIndex( cellIdx ); if ( resultIndex == cvf::UNDEFINED_SIZE_T ) continue; bool isTemporaryGrid = cell.hostGrid()->isTempGrid(); if ( computeDepth || isTemporaryGrid ) { depth[0][resultIndex] = cvf::Math::abs( cell.center().z() ); } if ( computeDx || isTemporaryGrid ) { cvf::Vec3d cellWidth = cell.faceCenter( cvf::StructGridInterface::NEG_I ) - cell.faceCenter( cvf::StructGridInterface::POS_I ); dx[0][resultIndex] = cellWidth.length(); } if ( computeDy || isTemporaryGrid ) { cvf::Vec3d cellWidth = cell.faceCenter( cvf::StructGridInterface::NEG_J ) - cell.faceCenter( cvf::StructGridInterface::POS_J ); dy[0][resultIndex] = cellWidth.length(); } if ( computeDz || isTemporaryGrid ) { cvf::Vec3d cellWidth = cell.faceCenter( cvf::StructGridInterface::NEG_K ) - cell.faceCenter( cvf::StructGridInterface::POS_K ); dz[0][resultIndex] = cellWidth.length(); } if ( computeTops || isTemporaryGrid ) { tops[0][resultIndex] = cvf::Math::abs( cell.faceCenter( cvf::StructGridInterface::NEG_K ).z() ); } if ( computeBottom || isTemporaryGrid ) { bottom[0][resultIndex] = cvf::Math::abs( cell.faceCenter( cvf::StructGridInterface::POS_K ).z() ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeIndexResults() { size_t reservoirCellCount = activeCellInfo()->reservoirCellCount(); if ( reservoirCellCount == 0 ) return; size_t iResultIndex = findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexIResultName() ), false ); size_t jResultIndex = findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexJResultName() ), false ); size_t kResultIndex = findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexKResultName() ), false ); bool computeIndexI = false; bool computeIndexJ = false; bool computeIndexK = false; if ( iResultIndex == cvf::UNDEFINED_SIZE_T ) { iResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexIResultName(), false, reservoirCellCount ); computeIndexI = true; } if ( jResultIndex == cvf::UNDEFINED_SIZE_T ) { jResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexJResultName(), false, reservoirCellCount ); computeIndexJ = true; } if ( kResultIndex == cvf::UNDEFINED_SIZE_T ) { kResultIndex = this->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::indexKResultName(), false, reservoirCellCount ); computeIndexK = true; } std::vector>& indexI = m_cellScalarResults[iResultIndex]; std::vector>& indexJ = m_cellScalarResults[jResultIndex]; std::vector>& indexK = m_cellScalarResults[kResultIndex]; { if ( indexI[0].size() < reservoirCellCount ) { indexI[0].resize( reservoirCellCount, std::numeric_limits::infinity() ); computeIndexI = true; } if ( indexJ[0].size() < reservoirCellCount ) { indexJ[0].resize( reservoirCellCount, std::numeric_limits::infinity() ); computeIndexJ = true; } if ( indexK[0].size() < reservoirCellCount ) { indexK[0].resize( reservoirCellCount, std::numeric_limits::infinity() ); computeIndexK = true; } } const std::vector& globalCellArray = m_ownerMainGrid->globalCellArray(); long long numCells = static_cast( globalCellArray.size() ); #pragma omp for for ( long long cellIdx = 0; cellIdx < numCells; cellIdx++ ) { const RigCell& cell = globalCellArray[cellIdx]; size_t resultIndex = cellIdx; if ( resultIndex == cvf::UNDEFINED_SIZE_T ) continue; bool isTemporaryGrid = cell.hostGrid()->isTempGrid(); size_t gridLocalNativeCellIndex = cell.gridLocalCellIndex(); RigGridBase* grid = cell.hostGrid(); size_t i, j, k; if ( grid->ijkFromCellIndex( gridLocalNativeCellIndex, &i, &j, &k ) ) { // I/J/K is 1-indexed when shown to user, thus "+ 1" if ( computeIndexI || isTemporaryGrid ) { indexI[0][resultIndex] = i + 1; } if ( computeIndexJ || isTemporaryGrid ) { indexJ[0][resultIndex] = j + 1; } if ( computeIndexK || isTemporaryGrid ) { indexK[0][resultIndex] = k + 1; } } } } namespace RigTransmissibilityCalcTools { void calculateConnectionGeometry( const RigCell& c1, const RigCell& c2, const std::vector& nodes, cvf::StructGridInterface::FaceType faceId, cvf::Vec3d* faceAreaVec ) { CVF_TIGHT_ASSERT( faceAreaVec ); *faceAreaVec = cvf::Vec3d::ZERO; std::vector polygon; std::vector intersections; std::array face1; std::array face2; c1.faceIndices( faceId, &face1 ); c2.faceIndices( cvf::StructGridInterface::oppositeFace( faceId ), &face2 ); bool foundOverlap = cvf::GeometryTools::calculateOverlapPolygonOfTwoQuads( &polygon, &intersections, (cvf::EdgeIntersectStorage*)nullptr, cvf::wrapArrayConst( &nodes ), face1.data(), face2.data(), 1e-6 ); if ( foundOverlap ) { std::vector realPolygon; for ( size_t pIdx = 0; pIdx < polygon.size(); ++pIdx ) { if ( polygon[pIdx] < nodes.size() ) realPolygon.push_back( nodes[polygon[pIdx]] ); else realPolygon.push_back( intersections[polygon[pIdx] - nodes.size()] ); } // Polygon area vector *faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D( realPolygon ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double halfCellTransmissibility( double perm, double ntg, const cvf::Vec3d& centerToFace, const cvf::Vec3d& faceAreaVec ) { return perm * ntg * ( faceAreaVec * centerToFace ) / ( centerToFace * centerToFace ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double newtran( double cdarchy, double mult, double halfCellTrans, double neighborHalfCellTrans ) { if ( cvf::Math::abs( halfCellTrans ) < 1e-15 || cvf::Math::abs( neighborHalfCellTrans ) < 1e-15 ) { return 0.0; } double result = cdarchy * mult / ( ( 1 / halfCellTrans ) + ( 1 / neighborHalfCellTrans ) ); CVF_TIGHT_ASSERT( result == result ); return result; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- typedef size_t ( *ResultIndexFunction )( const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t directReservoirCellIndex( const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex ) { return reservoirCellIndex; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t reservoirActiveCellIndex( const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex ) { return activeCellinfo->cellResultIndex( reservoirCellIndex ); } } // namespace RigTransmissibilityCalcTools using namespace RigTransmissibilityCalcTools; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeRiTransComponent( const QString& riTransComponentResultName ) { // Set up which component to compute cvf::StructGridInterface::FaceType faceId = cvf::StructGridInterface::NO_FACE; QString permCompName; if ( riTransComponentResultName == RiaResultNames::riTranXResultName() ) { permCompName = "PERMX"; faceId = cvf::StructGridInterface::POS_I; } else if ( riTransComponentResultName == RiaResultNames::riTranYResultName() ) { permCompName = "PERMY"; faceId = cvf::StructGridInterface::POS_J; } else if ( riTransComponentResultName == RiaResultNames::riTranZResultName() ) { permCompName = "PERMZ"; faceId = cvf::StructGridInterface::POS_K; } else { CVF_ASSERT( false ); } double cdarchy = darchysValue(); // Get the needed result indices we depend on size_t permResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, permCompName ) ); size_t ntgResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "NTG" ) ); bool hasNTGResults = ntgResultIdx != cvf::UNDEFINED_SIZE_T; // Get the result index of the output size_t riTransResultIdx = this->findScalarResultIndexFromAddress( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, riTransComponentResultName ) ); CVF_ASSERT( riTransResultIdx != cvf::UNDEFINED_SIZE_T ); // Get the result count, to handle that one of them might be globally defined size_t permxResultValueCount = m_cellScalarResults[permResultIdx][0].size(); size_t resultValueCount = permxResultValueCount; if ( hasNTGResults ) { size_t ntgResultValueCount = m_cellScalarResults[ntgResultIdx][0].size(); resultValueCount = std::min( permxResultValueCount, ntgResultValueCount ); } // Get all the actual result values const std::vector& permResults = m_cellScalarResults[permResultIdx][0]; std::vector& riTransResults = m_cellScalarResults[riTransResultIdx][0]; std::vector* ntgResults = nullptr; if ( hasNTGResults ) { ntgResults = &( m_cellScalarResults[ntgResultIdx][0] ); } // Set up output container to correct number of results riTransResults.resize( resultValueCount ); // Prepare how to index the result values: ResultIndexFunction riTranIdxFunc = nullptr; ResultIndexFunction permIdxFunc = nullptr; ResultIndexFunction ntgIdxFunc = nullptr; { bool isPermUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, permCompName ) ); bool isTransUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, riTransComponentResultName ) ); bool isNtgUsingResIdx = false; if ( hasNTGResults ) { isNtgUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "NTG" ) ); } // Set up result index function pointers riTranIdxFunc = isTransUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; permIdxFunc = isPermUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; if ( hasNTGResults ) { ntgIdxFunc = isNtgUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; } } const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); const std::vector& nodes = m_ownerMainGrid->nodes(); bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); for ( size_t nativeResvCellIndex = 0; nativeResvCellIndex < m_ownerMainGrid->globalCellArray().size(); nativeResvCellIndex++ ) { // Do nothing if we are only dealing with active cells, and this cell is not active: size_t tranResIdx = ( *riTranIdxFunc )( activeCellInfo, nativeResvCellIndex ); if ( tranResIdx == cvf::UNDEFINED_SIZE_T ) continue; const RigCell& nativeCell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; RigGridBase* grid = nativeCell.hostGrid(); size_t gridLocalNativeCellIndex = nativeCell.gridLocalCellIndex(); size_t i, j, k, gridLocalNeighborCellIdx; grid->ijkFromCellIndex( gridLocalNativeCellIndex, &i, &j, &k ); if ( grid->cellIJKNeighbor( i, j, k, faceId, &gridLocalNeighborCellIdx ) ) { size_t neighborResvCellIdx = grid->reservoirCellIndex( gridLocalNeighborCellIdx ); const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; // Do nothing if neighbor cell has no results size_t neighborCellPermResIdx = ( *permIdxFunc )( activeCellInfo, neighborResvCellIdx ); if ( neighborCellPermResIdx == cvf::UNDEFINED_SIZE_T ) continue; // Connection geometry const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace( nativeResvCellIndex, faceId ); bool isOnFault = fault; cvf::Vec3d faceAreaVec; cvf::Vec3d faceCenter; if ( isOnFault ) { calculateConnectionGeometry( nativeCell, neighborCell, nodes, faceId, &faceAreaVec ); } else { faceAreaVec = nativeCell.faceNormalWithAreaLength( faceId ); } if ( !isFaceNormalsOutwards ) faceAreaVec = -faceAreaVec; double halfCellTrans = 0; double neighborHalfCellTrans = 0; // Native cell half cell transm { cvf::Vec3d centerToFace = nativeCell.faceCenter( faceId ) - nativeCell.center(); size_t permResIdx = ( *permIdxFunc )( activeCellInfo, nativeResvCellIndex ); double perm = permResults[permResIdx]; double ntg = 1.0; if ( hasNTGResults && faceId != cvf::StructGridInterface::POS_K ) { size_t ntgResIdx = ( *ntgIdxFunc )( activeCellInfo, nativeResvCellIndex ); ntg = ( *ntgResults )[ntgResIdx]; } halfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, faceAreaVec ); } // Neighbor cell half cell transm { cvf::Vec3d centerToFace = neighborCell.faceCenter( cvf::StructGridInterface::oppositeFace( faceId ) ) - neighborCell.center(); double perm = permResults[neighborCellPermResIdx]; double ntg = 1.0; if ( hasNTGResults && faceId != cvf::StructGridInterface::POS_K ) { size_t ntgResIdx = ( *ntgIdxFunc )( activeCellInfo, neighborResvCellIdx ); ntg = ( *ntgResults )[ntgResIdx]; } neighborHalfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, -faceAreaVec ); } riTransResults[tranResIdx] = newtran( cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeNncCombRiTrans() { RigEclipseResultAddress riCombTransEclResAddr( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedRiTranResultName() ); if ( m_ownerMainGrid->nncData()->staticConnectionScalarResult( riCombTransEclResAddr ) ) return; double cdarchy = darchysValue(); // Get the needed result indices we depend on size_t permXResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMX" ) ); size_t permYResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMY" ) ); size_t permZResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMZ" ) ); size_t ntgResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "NTG" ) ); bool hasNTGResults = ntgResultIdx != cvf::UNDEFINED_SIZE_T; // Get all the actual result values std::vector& permXResults = m_cellScalarResults[permXResultIdx][0]; std::vector& permYResults = m_cellScalarResults[permYResultIdx][0]; std::vector& permZResults = m_cellScalarResults[permZResultIdx][0]; std::vector& riCombTransResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult( RiaDefines::propertyNameRiCombTrans() ); m_ownerMainGrid->nncData()->setEclResultAddress( RiaDefines::propertyNameRiCombTrans(), riCombTransEclResAddr ); std::vector* ntgResults = nullptr; if ( hasNTGResults ) { ntgResults = &( m_cellScalarResults[ntgResultIdx][0] ); } // Prepare how to index the result values: ResultIndexFunction permXIdxFunc = nullptr; ResultIndexFunction permYIdxFunc = nullptr; ResultIndexFunction permZIdxFunc = nullptr; ResultIndexFunction ntgIdxFunc = nullptr; { bool isPermXUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMX" ) ); bool isPermYUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMY" ) ); bool isPermZUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PERMZ" ) ); bool isNtgUsingResIdx = false; if ( hasNTGResults ) { isNtgUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "NTG" ) ); } // Set up result index function pointers permXIdxFunc = isPermXUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; permYIdxFunc = isPermYUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; permZIdxFunc = isPermZUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; if ( hasNTGResults ) { ntgIdxFunc = isNtgUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; } } const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); // NNC calculation const RigConnectionContainer& nncConnections = m_ownerMainGrid->nncData()->allConnections(); for ( size_t connIdx = 0; connIdx < nncConnections.size(); connIdx++ ) { size_t nativeResvCellIndex = nncConnections[connIdx].c1GlobIdx(); size_t neighborResvCellIdx = nncConnections[connIdx].c2GlobIdx(); cvf::StructGridInterface::FaceType faceId = static_cast( nncConnections[connIdx].face() ); ResultIndexFunction permIdxFunc = nullptr; std::vector* permResults = nullptr; switch ( faceId ) { case cvf::StructGridInterface::POS_I: case cvf::StructGridInterface::NEG_I: permIdxFunc = permXIdxFunc; permResults = &permXResults; break; case cvf::StructGridInterface::POS_J: case cvf::StructGridInterface::NEG_J: permIdxFunc = permYIdxFunc; permResults = &permYResults; break; case cvf::StructGridInterface::POS_K: case cvf::StructGridInterface::NEG_K: permIdxFunc = permZIdxFunc; permResults = &permZResults; break; default: break; } if ( !permIdxFunc ) continue; // Do nothing if we are only dealing with active cells, and this cell is not active: size_t nativeCellPermResIdx = ( *permIdxFunc )( activeCellInfo, nativeResvCellIndex ); if ( nativeCellPermResIdx == cvf::UNDEFINED_SIZE_T ) continue; // Do nothing if neighbor cell has no results size_t neighborCellPermResIdx = ( *permIdxFunc )( activeCellInfo, neighborResvCellIdx ); if ( neighborCellPermResIdx == cvf::UNDEFINED_SIZE_T ) continue; const RigCell& nativeCell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; // Connection geometry cvf::Vec3f faceAreaVec = cvf::Vec3f::ZERO; cvf::Vec3f faceCenter = cvf::Vec3f::ZERO; // Polygon center const std::vector& realPolygon = nncConnections[connIdx].polygon(); for ( size_t pIdx = 0; pIdx < realPolygon.size(); ++pIdx ) { faceCenter += realPolygon[pIdx]; } faceCenter *= 1.0 / realPolygon.size(); // Polygon area vector faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D( realPolygon ); if ( !isFaceNormalsOutwards ) faceAreaVec = -faceAreaVec; double halfCellTrans = 0; double neighborHalfCellTrans = 0; // Native cell half cell transm { cvf::Vec3d centerToFace = nativeCell.faceCenter( faceId ) - nativeCell.center(); double perm = ( *permResults )[nativeCellPermResIdx]; double ntg = 1.0; if ( hasNTGResults && faceId != cvf::StructGridInterface::POS_K ) { size_t ntgResIdx = ( *ntgIdxFunc )( activeCellInfo, nativeResvCellIndex ); ntg = ( *ntgResults )[ntgResIdx]; } halfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, cvf::Vec3d( faceAreaVec ) ); } // Neighbor cell half cell transm { cvf::Vec3d centerToFace = neighborCell.faceCenter( cvf::StructGridInterface::oppositeFace( faceId ) ) - neighborCell.center(); double perm = ( *permResults )[neighborCellPermResIdx]; double ntg = 1.0; if ( hasNTGResults && faceId != cvf::StructGridInterface::POS_K ) { size_t ntgResIdx = ( *ntgIdxFunc )( activeCellInfo, neighborResvCellIdx ); ntg = ( *ntgResults )[ntgResIdx]; } neighborHalfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, -cvf::Vec3d( faceAreaVec ) ); } double newtranTemp = newtran( cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans ); riCombTransResults[connIdx] = newtranTemp; } } double riMult( double transResults, double riTransResults ) { if ( transResults == HUGE_VAL || riTransResults == HUGE_VAL ) return HUGE_VAL; const double epsilon = 1e-9; if ( cvf::Math::abs( riTransResults ) < epsilon ) { if ( cvf::Math::abs( transResults ) < epsilon ) { return 0.0; } return HUGE_VAL; } double result = transResults / riTransResults; return result; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeRiMULTComponent( const QString& riMultCompName ) { // Set up which component to compute QString riTransCompName; QString transCompName; if ( riMultCompName == RiaResultNames::riMultXResultName() ) { riTransCompName = RiaResultNames::riTranXResultName(); transCompName = "TRANX"; } else if ( riMultCompName == RiaResultNames::riMultYResultName() ) { riTransCompName = RiaResultNames::riTranYResultName(); transCompName = "TRANY"; } else if ( riMultCompName == RiaResultNames::riMultZResultName() ) { riTransCompName = RiaResultNames::riTranZResultName(); transCompName = "TRANZ"; } else { CVF_ASSERT( false ); } // Get the needed result indices we depend on size_t transResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, transCompName ) ); size_t riTransResultIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, riTransCompName ) ); // Get the result index of the output size_t riMultResultIdx = this->findScalarResultIndexFromAddress( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, riMultCompName ) ); CVF_ASSERT( riMultResultIdx != cvf::UNDEFINED_SIZE_T ); // Get the result count, to handle that one of them might be globally defined CVF_ASSERT( m_cellScalarResults[riTransResultIdx][0].size() == m_cellScalarResults[transResultIdx][0].size() ); size_t resultValueCount = m_cellScalarResults[transResultIdx][0].size(); // Get all the actual result values const std::vector& riTransResults = m_cellScalarResults[riTransResultIdx][0]; const std::vector& transResults = m_cellScalarResults[transResultIdx][0]; std::vector& riMultResults = m_cellScalarResults[riMultResultIdx][0]; // Set up output container to correct number of results riMultResults.resize( resultValueCount ); for ( size_t vIdx = 0; vIdx < transResults.size(); ++vIdx ) { riMultResults[vIdx] = riMult( transResults[vIdx], riTransResults[vIdx] ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeNncCombRiMULT() { auto riCombMultEclResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedRiMultResultName() ); auto riCombTransEclResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedRiTranResultName() ); auto combTransEclResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedTransmissibilityResultName() ); if ( m_ownerMainGrid->nncData()->staticConnectionScalarResult( riCombMultEclResAddr ) ) return; const std::vector* riTransResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult( riCombTransEclResAddr ); const std::vector* transResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult( combTransEclResAddr ); if ( riTransResults && transResults && ( riTransResults->size() == transResults->size() ) ) { std::vector& riMultResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult( RiaDefines::propertyNameRiCombMult() ); m_ownerMainGrid->nncData()->setEclResultAddress( RiaDefines::propertyNameRiCombMult(), riCombMultEclResAddr ); for ( size_t nncConIdx = 0; nncConIdx < riMultResults.size(); ++nncConIdx ) { riMultResults[nncConIdx] = riMult( ( *transResults )[nncConIdx], ( *riTransResults )[nncConIdx] ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeRiTRANSbyAreaComponent( const QString& riTransByAreaCompResultName ) { // Set up which component to compute cvf::StructGridInterface::FaceType faceId = cvf::StructGridInterface::NO_FACE; QString transCompName; if ( riTransByAreaCompResultName == RiaResultNames::riAreaNormTranXResultName() ) { transCompName = "TRANX"; faceId = cvf::StructGridInterface::POS_I; } else if ( riTransByAreaCompResultName == RiaResultNames::riAreaNormTranYResultName() ) { transCompName = "TRANY"; faceId = cvf::StructGridInterface::POS_J; } else if ( riTransByAreaCompResultName == RiaResultNames::riAreaNormTranZResultName() ) { transCompName = "TRANZ"; faceId = cvf::StructGridInterface::POS_K; } else { CVF_ASSERT( false ); } // Get the needed result indices we depend on size_t tranCompScResIdx = findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, transCompName ) ); // Get the result index of the output size_t riTranByAreaScResIdx = this->findScalarResultIndexFromAddress( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, riTransByAreaCompResultName ) ); CVF_ASSERT( riTranByAreaScResIdx != cvf::UNDEFINED_SIZE_T ); // Get the result count, to handle that one of them might be globally defined size_t resultValueCount = m_cellScalarResults[tranCompScResIdx][0].size(); // Get all the actual result values const std::vector& transResults = m_cellScalarResults[tranCompScResIdx][0]; std::vector& riTransByAreaResults = m_cellScalarResults[riTranByAreaScResIdx][0]; // Set up output container to correct number of results riTransByAreaResults.resize( resultValueCount ); // Prepare how to index the result values: bool isUsingResIdx = this->isUsingGlobalActiveIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, transCompName ) ); // Set up result index function pointers ResultIndexFunction resValIdxFunc = isUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); const std::vector& nodes = m_ownerMainGrid->nodes(); for ( size_t nativeResvCellIndex = 0; nativeResvCellIndex < m_ownerMainGrid->globalCellArray().size(); nativeResvCellIndex++ ) { // Do nothing if we are only dealing with active cells, and this cell is not active: size_t nativeCellResValIdx = ( *resValIdxFunc )( activeCellInfo, nativeResvCellIndex ); if ( nativeCellResValIdx == cvf::UNDEFINED_SIZE_T ) continue; const RigCell& nativeCell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; RigGridBase* grid = nativeCell.hostGrid(); size_t gridLocalNativeCellIndex = nativeCell.gridLocalCellIndex(); size_t i, j, k, gridLocalNeighborCellIdx; grid->ijkFromCellIndex( gridLocalNativeCellIndex, &i, &j, &k ); if ( grid->cellIJKNeighbor( i, j, k, faceId, &gridLocalNeighborCellIdx ) ) { size_t neighborResvCellIdx = grid->reservoirCellIndex( gridLocalNeighborCellIdx ); const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; // Connection geometry const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace( nativeResvCellIndex, faceId ); bool isOnFault = fault; cvf::Vec3d faceAreaVec; if ( isOnFault ) { calculateConnectionGeometry( nativeCell, neighborCell, nodes, faceId, &faceAreaVec ); } else { faceAreaVec = nativeCell.faceNormalWithAreaLength( faceId ); } double areaOfOverlap = faceAreaVec.length(); double transCompValue = transResults[nativeCellResValIdx]; riTransByAreaResults[nativeCellResValIdx] = transCompValue / areaOfOverlap; } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeNncCombRiTRANSbyArea() { auto riCombTransByAreaEclResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedRiAreaNormTranResultName() ); auto combTransEclResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::combinedTransmissibilityResultName() ); if ( m_ownerMainGrid->nncData()->staticConnectionScalarResult( riCombTransByAreaEclResAddr ) ) return; const std::vector* transResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult( combTransEclResAddr ); if ( !transResults ) return; std::vector& riAreaNormTransResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult( RiaDefines::propertyNameRiCombTransByArea() ); m_ownerMainGrid->nncData()->setEclResultAddress( RiaDefines::propertyNameRiCombTransByArea(), riCombTransByAreaEclResAddr ); if ( transResults->size() != riAreaNormTransResults.size() ) return; const RigConnectionContainer& connections = m_ownerMainGrid->nncData()->allConnections(); for ( size_t nncConIdx = 0; nncConIdx < riAreaNormTransResults.size(); ++nncConIdx ) { const std::vector& realPolygon = connections[nncConIdx].polygon(); cvf::Vec3f faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D( realPolygon ); double areaOfOverlap = faceAreaVec.length(); riAreaNormTransResults[nncConIdx] = ( *transResults )[nncConIdx] / areaOfOverlap; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeCompletionTypeForTimeStep( size_t timeStep ) { size_t completionTypeResultIndex = this->findScalarResultIndexFromAddress( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::completionTypeResultName() ) ); if ( m_cellScalarResults[completionTypeResultIndex].size() < this->maxTimeStepCount() ) { m_cellScalarResults[completionTypeResultIndex].resize( this->maxTimeStepCount() ); } std::vector& completionTypeResult = m_cellScalarResults[completionTypeResultIndex][timeStep]; size_t resultValues = m_ownerMainGrid->globalCellArray().size(); if ( completionTypeResult.size() == resultValues ) { return; } completionTypeResult.resize( resultValues ); std::fill( completionTypeResult.begin(), completionTypeResult.end(), HUGE_VAL ); RimEclipseCase* eclipseCase = m_ownerCaseData->ownerCase(); if ( !eclipseCase ) return; RimCompletionCellIntersectionCalc::calculateCompletionTypeResult( eclipseCase, completionTypeResult, timeStep ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigCaseCellResultsData::darchysValue() { return RiaEclipseUnitTools::darcysConstant( m_ownerCaseData->unitsType() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeCellVolumes() { size_t cellVolIdx = this->findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riCellVolumeResultName() ), false ); if ( m_cellScalarResults[cellVolIdx].empty() ) { m_cellScalarResults[cellVolIdx].resize( 1 ); } std::vector& cellVolumeResults = m_cellScalarResults[cellVolIdx][0]; size_t cellResultCount = m_activeCellInfo->reservoirActiveCellCount(); cellVolumeResults.resize( cellResultCount, std::numeric_limits::infinity() ); #pragma omp parallel for for ( int nativeResvCellIndex = 0; nativeResvCellIndex < static_cast( m_ownerMainGrid->globalCellArray().size() ); nativeResvCellIndex++ ) { size_t resultIndex = activeCellInfo()->cellResultIndex( nativeResvCellIndex ); if ( resultIndex != cvf::UNDEFINED_SIZE_T ) { const RigCell& cell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; if ( !cell.subGrid() ) { cellVolumeResults[resultIndex] = cell.volume(); } } } // Clear oil volume so it will have to be recalculated. clearScalarResult( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::riOilVolumeResultName() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeOilVolumes() { size_t cellVolIdx = this->findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riCellVolumeResultName() ), false ); const std::vector& cellVolumeResults = m_cellScalarResults[cellVolIdx][0]; size_t soilIdx = this->findOrLoadKnownScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SOIL" ) ); size_t oilVolIdx = this->findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::riOilVolumeResultName() ), false ); m_cellScalarResults[oilVolIdx].resize( this->maxTimeStepCount() ); size_t cellResultCount = m_activeCellInfo->reservoirActiveCellCount(); for ( size_t timeStepIdx = 0; timeStepIdx < this->maxTimeStepCount(); timeStepIdx++ ) { const std::vector& soilResults = m_cellScalarResults[soilIdx][timeStepIdx]; std::vector& oilVolumeResults = m_cellScalarResults[oilVolIdx][timeStepIdx]; oilVolumeResults.resize( cellResultCount, 0u ); #pragma omp parallel for for ( int nativeResvCellIndex = 0; nativeResvCellIndex < static_cast( m_ownerMainGrid->globalCellArray().size() ); nativeResvCellIndex++ ) { size_t resultIndex = activeCellInfo()->cellResultIndex( nativeResvCellIndex ); if ( resultIndex != cvf::UNDEFINED_SIZE_T ) { if ( resultIndex < soilResults.size() && resultIndex < cellVolumeResults.size() ) { CVF_ASSERT( soilResults.at( resultIndex ) <= 1.01 ); oilVolumeResults[resultIndex] = std::max( 0.0, soilResults.at( resultIndex ) * cellVolumeResults.at( resultIndex ) ); } } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeMobilePV() { std::vector porvDataTemp; std::vector swcrDataTemp; std::vector multpvDataTemp; const std::vector* porvResults = nullptr; const std::vector* swcrResults = nullptr; const std::vector* multpvResults = nullptr; porvResults = RigCaseCellResultsData::getResultIndexableStaticResult( this->activeCellInfo(), this, "PORV", porvDataTemp ); if ( !porvResults || porvResults->empty() ) { RiaLogging::error( "Assumed PORV, but not data was found." ); return; } swcrResults = RigCaseCellResultsData::getResultIndexableStaticResult( this->activeCellInfo(), this, "SWCR", swcrDataTemp ); multpvResults = RigCaseCellResultsData::getResultIndexableStaticResult( this->activeCellInfo(), this, "MULTPV", multpvDataTemp ); size_t mobPVIdx = this->findOrCreateScalarResultIndex( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::mobilePoreVolumeName() ), false ); std::vector& mobPVResults = m_cellScalarResults[mobPVIdx][0]; // Set up output container to correct number of results mobPVResults.resize( porvResults->size() ); if ( multpvResults && swcrResults ) { for ( size_t vIdx = 0; vIdx < porvResults->size(); ++vIdx ) { mobPVResults[vIdx] = ( *multpvResults )[vIdx] * ( *porvResults )[vIdx] * ( 1.0 - ( *swcrResults )[vIdx] ); } } else if ( !multpvResults && swcrResults ) { for ( size_t vIdx = 0; vIdx < porvResults->size(); ++vIdx ) { mobPVResults[vIdx] = ( *porvResults )[vIdx] * ( 1.0 - ( *swcrResults )[vIdx] ); } } else if ( !swcrResults && multpvResults ) { for ( size_t vIdx = 0; vIdx < porvResults->size(); ++vIdx ) { mobPVResults[vIdx] = ( *multpvResults )[vIdx] * ( *porvResults )[vIdx]; } } else { mobPVResults.assign( porvResults->begin(), porvResults->end() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setReaderInterface( RifReaderInterface* readerInterface ) { m_readerInterface = readerInterface; if ( m_ownerMainGrid ) { m_readerInterface->updateFromGridCount( m_ownerMainGrid->gridCount() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const RifReaderInterface* RigCaseCellResultsData::readerInterface() const { return m_readerInterface.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setHdf5Filename( const QString& hdf5SourSimFilename ) { RifReaderEclipseOutput* rifReaderOutput = dynamic_cast( m_readerInterface.p() ); if ( rifReaderOutput ) { rifReaderOutput->setHdf5FileName( hdf5SourSimFilename ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setActiveFormationNames( RigFormationNames* activeFormationNames ) { m_activeFormationNamesData = activeFormationNames; size_t totalGlobCellCount = m_ownerMainGrid->globalCellArray().size(); this->addStaticScalarResult( RiaDefines::ResultCatType::FORMATION_NAMES, RiaResultNames::activeFormationNamesResultName(), false, totalGlobCellCount ); std::vector* fnData = this->modifiableCellScalarResult( RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES, RiaResultNames::activeFormationNamesResultName() ), 0 ); if ( m_activeFormationNamesData.isNull() ) { for ( size_t cIdx = 0; cIdx < totalGlobCellCount; ++cIdx ) { fnData->at( cIdx ) = HUGE_VAL; } } else { size_t localCellCount = m_ownerMainGrid->cellCount(); for ( size_t cIdx = 0; cIdx < localCellCount; ++cIdx ) { size_t i( cvf::UNDEFINED_SIZE_T ), j( cvf::UNDEFINED_SIZE_T ), k( cvf::UNDEFINED_SIZE_T ); if ( !m_ownerMainGrid->ijkFromCellIndex( cIdx, &i, &j, &k ) ) continue; int formNameIdx = activeFormationNames->formationIndexFromKLayerIdx( k ); if ( formNameIdx != -1 ) { fnData->at( cIdx ) = formNameIdx; } else { fnData->at( cIdx ) = HUGE_VAL; } } for ( size_t cIdx = localCellCount; cIdx < totalGlobCellCount; ++cIdx ) { size_t mgrdCellIdx = m_ownerMainGrid->globalCellArray()[cIdx].mainGridCellIndex(); size_t i( cvf::UNDEFINED_SIZE_T ), j( cvf::UNDEFINED_SIZE_T ), k( cvf::UNDEFINED_SIZE_T ); if ( !m_ownerMainGrid->ijkFromCellIndex( mgrdCellIdx, &i, &j, &k ) ) continue; int formNameIdx = activeFormationNames->formationIndexFromKLayerIdx( k ); if ( formNameIdx != -1 ) { fnData->at( cIdx ) = formNameIdx; } else { fnData->at( cIdx ) = HUGE_VAL; } } } // As the Allan formation diagram is depending on formation results, we need to clear the data set // Will be recomputed when required auto fnNamesResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationAllanResultName() ); clearScalarResult( fnNamesResAddr ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const RigFormationNames* RigCaseCellResultsData::activeFormationNames() const { return m_activeFormationNamesData.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigAllanDiagramData* RigCaseCellResultsData::allanDiagramData() { return m_allanDiagramData.p(); } //-------------------------------------------------------------------------------------------------- /// If we have any results on any time step, assume we have loaded results //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::isDataPresent( size_t scalarResultIndex ) const { if ( scalarResultIndex >= this->resultCount() ) { return false; } const std::vector>& data = m_cellScalarResults[scalarResultIndex]; for ( size_t tsIdx = 0; tsIdx < data.size(); ++tsIdx ) { if ( data[tsIdx].size() ) { return true; } } return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::assignValuesToTemporaryLgrs( const QString& resultName, std::vector& valuesForAllReservoirCells ) { CVF_ASSERT( m_activeCellInfo ); static std::vector excludedProperties = { "MOBPROV", "PORV", "FIPOIL", "FIPGAS", "FIPWAT", "FLROILI+", "FLROILJ+", "FLROILK+", "FLRGASI+", "FLRGASJ+", "FLRGASK+", "FLRWATI+", "FLRWATJ+", "FLRWATK+", "FLOOILI+", "FLOWATI+", "FLOGASI+", "FLOOILJ+", "FLOWATJ+", "FLOGASJ+", "FLOOILK+", "FLOWATK+", "FLOGASK+", "SFIPGAS", "SFIPOIL", "SFIPWAT", "AREAX", "AREAY", "AREAZ", "DIFFX", "DIFFY", "DIFFZ", "DZNET", "HEATTX", "HEATTY", "HEATTZ", "LX", "LY", "LZ", "MINPVV", "TRANX", "TRANY", "TRANZ", }; if ( std::find( excludedProperties.begin(), excludedProperties.end(), resultName ) != excludedProperties.end() ) { return; } bool invalidCellsDetected = false; for ( size_t gridIdx = 0; gridIdx < m_ownerMainGrid->gridCount(); gridIdx++ ) { const auto& grid = m_ownerMainGrid->gridByIndex( gridIdx ); if ( grid->isTempGrid() ) { for ( size_t localCellIdx = 0; localCellIdx < grid->cellCount(); localCellIdx++ ) { const RigCell& cell = grid->cell( localCellIdx ); size_t mainGridCellIndex = cell.mainGridCellIndex(); size_t reservoirCellIndex = grid->reservoirCellIndex( localCellIdx ); size_t mainGridCellResultIndex = m_activeCellInfo->cellResultIndex( mainGridCellIndex ); size_t cellResultIndex = m_activeCellInfo->cellResultIndex( reservoirCellIndex ); if ( mainGridCellResultIndex != cvf::UNDEFINED_SIZE_T && cellResultIndex != cvf::UNDEFINED_SIZE_T ) { double mainGridValue = valuesForAllReservoirCells[mainGridCellResultIndex]; valuesForAllReservoirCells[cellResultIndex] = mainGridValue; } else { invalidCellsDetected = true; } } } } if ( invalidCellsDetected ) { RiaLogging::warning( "Detected invalid/undefined cells when assigning result values to temporary LGRs" ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigStatisticsDataCache* RigCaseCellResultsData::statistics( const RigEclipseResultAddress& resVarAddr ) { size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr ); CAF_ASSERT( scalarResultIndex < m_statisticsDataCache.size() ); return m_statisticsDataCache[scalarResultIndex].p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeAllanResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid, bool includeInactiveCells ) { CVF_ASSERT( mainGrid ); CVF_ASSERT( cellResultsData ); if ( cellResultsData && cellResultsData->activeFormationNames() && !cellResultsData->activeFormationNames()->formationNames().empty() ) { auto fnNamesResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES, RiaResultNames::activeFormationNamesResultName() ); auto fnAllanResultResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationAllanResultName() ); auto fnBinAllanResAddr = RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationBinaryAllanResultName() ); // Create and retrieve nnc result arrays std::vector& fnAllanNncResults = mainGrid->nncData()->makeStaticConnectionScalarResult( RiaResultNames::formationAllanResultName() ); std::vector& fnBinAllanNncResults = mainGrid->nncData()->makeStaticConnectionScalarResult( RiaResultNames::formationBinaryAllanResultName() ); // Associate them with eclipse result address mainGrid->nncData()->setEclResultAddress( RiaResultNames::formationAllanResultName(), fnAllanResultResAddr ); mainGrid->nncData()->setEclResultAddress( RiaResultNames::formationBinaryAllanResultName(), fnBinAllanResAddr ); const std::vector& fnData = cellResultsData->cellScalarResults( fnNamesResAddr, 0 ); // Add a result entry for the special Allan grid data (used only for the grid cells without nnc coverage) cellResultsData->addStaticScalarResult( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationAllanResultName(), false, fnData.size() ); cellResultsData->addStaticScalarResult( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationBinaryAllanResultName(), false, fnData.size() ); std::vector* alData = cellResultsData->modifiableCellScalarResult( fnAllanResultResAddr, 0 ); std::vector* binAlData = cellResultsData->modifiableCellScalarResult( fnBinAllanResAddr, 0 ); ( *alData ) = fnData; for ( double& val : ( *binAlData ) ) { val = 0.0; } size_t formationCount = 0; if ( cellResultsData->activeFormationNames() ) { formationCount = cellResultsData->activeFormationNames()->formationNames().size(); } const RigConnectionContainer& nncConnections = mainGrid->nncData()->allConnections(); std::map, int> formationCombinationToCategory; for ( size_t i = 0; i < nncConnections.size(); i++ ) { const auto& c = nncConnections[i]; size_t globCellIdx1 = c.c1GlobIdx(); size_t globCellIdx2 = c.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; } fnBinAllanNncResults[i] = 1.0; } else { category = formation1; fnBinAllanNncResults[i] = 0.0; } fnAllanNncResults[i] = category; } cellResultsData->allanDiagramData()->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; } fnAllanNncResults[i] = k1; allAllanFormationResults[i] = k1; fnBinAllanNncResults[i] = binaryValue; } #endif } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findScalarResultIndexFromAddress( const RigEclipseResultAddress& resVarAddr ) const { if ( !resVarAddr.isValid() ) { return cvf::UNDEFINED_SIZE_T; } else if ( resVarAddr.resultCatType() == RiaDefines::ResultCatType::UNDEFINED ) { RigEclipseResultAddress resVarAddressWithType = resVarAddr; resVarAddressWithType.setResultCatType( RiaDefines::ResultCatType::STATIC_NATIVE ); size_t scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddressWithType ); if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) { resVarAddressWithType.setResultCatType( RiaDefines::ResultCatType::DYNAMIC_NATIVE ); scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddressWithType ); } if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) { resVarAddressWithType.setResultCatType( RiaDefines::ResultCatType::SOURSIMRL ); scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddressWithType ); } if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) { resVarAddressWithType.setResultCatType( RiaDefines::ResultCatType::GENERATED ); scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddressWithType ); } if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) { resVarAddressWithType.setResultCatType( RiaDefines::ResultCatType::INPUT_PROPERTY ); scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddressWithType ); } if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) { resVarAddressWithType.setResultCatType( RiaDefines::ResultCatType::FORMATION_NAMES ); scalarResultIndex = this->findScalarResultIndexFromAddress( resVarAddressWithType ); } return scalarResultIndex; } else { auto index = m_addressToResultIndexMap.find( resVarAddr ); if ( index != m_addressToResultIndexMap.end() ) { return index->second; } return cvf::UNDEFINED_SIZE_T; } } #include "RimEclipseResultCase.h" //-------------------------------------------------------------------------------------------------- /// Copy result meta data from main case to all other cases in grid case group /// This code was originally part of RimStatisticsCaseEvaluator, but moved here to be a general solution /// for all cases //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::copyResultsMetaDataFromMainCase( RigEclipseCaseData* mainCaseResultsData, RiaDefines::PorosityModelType poroModel, std::vector destinationCases ) { std::vector resAddresses = mainCaseResultsData->results( poroModel )->existingResults(); std::vector timeStepInfos = mainCaseResultsData->results( poroModel )->timeStepInfos( resAddresses[0] ); const std::vector resultInfos = mainCaseResultsData->results( poroModel )->infoForEachResultIndex(); for ( size_t i = 0; i < destinationCases.size(); i++ ) { RimEclipseResultCase* rimReservoir = dynamic_cast( destinationCases[i] ); if ( !rimReservoir ) continue; // Input reservoir if ( mainCaseResultsData == rimReservoir->eclipseCaseData() ) continue; // Do not copy ontop of itself RigCaseCellResultsData* cellResultsStorage = rimReservoir->results( poroModel ); for ( size_t resIdx = 0; resIdx < resultInfos.size(); resIdx++ ) { RigEclipseResultAddress resVarAddr = resultInfos[resIdx].eclipseResultAddress(); bool needsToBeStored = resultInfos[resIdx].needsToBeStored(); bool mustBeCalculated = resultInfos[resIdx].mustBeCalculated(); size_t scalarResultIndex = cellResultsStorage->findScalarResultIndexFromAddress( resVarAddr ); if ( scalarResultIndex == cvf::UNDEFINED_SIZE_T ) { cellResultsStorage->createResultEntry( resVarAddr, needsToBeStored ); if ( mustBeCalculated ) { scalarResultIndex = cellResultsStorage->findScalarResultIndexFromAddress( resVarAddr ); cellResultsStorage->setMustBeCalculated( scalarResultIndex ); } cellResultsStorage->setTimeStepInfos( resVarAddr, timeStepInfos ); std::vector>* dataValues = cellResultsStorage->modifiableCellScalarResultTimesteps( resVarAddr ); dataValues->resize( timeStepInfos.size() ); } } cellResultsStorage->createPlaceholderResultEntries(); } }