ResInsight/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultsData.cpp
Magne Sjaastad 891a2e7c29 #8375 Flow Vectors : Avoid recomputing NNCs when accessing flow data
Avoid include of RigNNCData.h in header files.
2021-12-20 10:23:52 +01:00

3497 lines
150 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// 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 <QDateTime>
#include "RigEclipseAllanFaultsStatCalc.h"
#include <algorithm>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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<size_t>& RigCaseCellResultsData::cellScalarValuesHistogram( const RigEclipseResultAddress& resVarAddr )
{
return statistics( resVarAddr )->cellScalarValuesHistogram();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<size_t>& 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<int>& 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<std::vector<double>>&
RigCaseCellResultsData::cellScalarResults( const RigEclipseResultAddress& resVarAddr ) const
{
size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr );
CVF_TIGHT_ASSERT( scalarResultIndex < resultCount() );
return m_cellScalarResults[scalarResultIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<double>>*
RigCaseCellResultsData::modifiableCellScalarResultTimesteps( const RigEclipseResultAddress& resVarAddr )
{
size_t scalarResultIndex = findScalarResultIndexFromAddress( resVarAddr );
CVF_TIGHT_ASSERT( scalarResultIndex < resultCount() );
return &( m_cellScalarResults[scalarResultIndex] );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>* 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<double>& 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<std::vector<double>>() );
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<RigStatisticsCalculator> statisticsCalculator;
if ( resultName == RiaResultNames::combinedTransmissibilityResultName() )
{
cvf::ref<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseMultiPropertyStatCalc> 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<RigEclipseAllanFaultsStatCalc> calc =
new RigEclipseAllanFaultsStatCalc( m_ownerMainGrid->nncData(), resVarAddr );
statisticsCalculator = calc;
}
else
{
statisticsCalculator = new RigEclipseNativeStatCalc( this, resVarAddr );
}
cvf::ref<RigStatisticsDataCache> dataCache = new RigStatisticsDataCache( statisticsCalculator.p() );
m_statisticsDataCache.push_back( dataCache.p() );
return scalarResultIndex;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RigCaseCellResultsData::resultNames( RiaDefines::ResultCatType resType ) const
{
QStringList varList;
std::vector<RigEclipseResultInfo>::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<QDateTime> RigCaseCellResultsData::allTimeStepDatesFromEclipseReader() const
{
const RifReaderEclipseOutput* rifReaderOutput = dynamic_cast<const RifReaderEclipseOutput*>( m_readerInterface.p() );
if ( rifReaderOutput )
{
return rifReaderOutput->allTimeSteps();
}
else
{
return std::vector<QDateTime>();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RigCaseCellResultsData::timeStepDates( const RigEclipseResultAddress& resVarAddr ) const
{
if ( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() )
{
return m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].dates();
}
else
return std::vector<QDateTime>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RigCaseCellResultsData::timeStepDates() const
{
RigEclipseResultAddress scalarResWithMostTimeSteps;
maxTimeStepCount( &scalarResWithMostTimeSteps );
return timeStepDates( scalarResWithMostTimeSteps );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigCaseCellResultsData::daysSinceSimulationStart() const
{
RigEclipseResultAddress scalarResWithMostTimeSteps;
maxTimeStepCount( &scalarResWithMostTimeSteps );
return daysSinceSimulationStart( scalarResWithMostTimeSteps );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigCaseCellResultsData::daysSinceSimulationStart( const RigEclipseResultAddress& resVarAddr ) const
{
if ( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() )
{
return m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].daysSinceSimulationStarts();
}
else
{
return std::vector<double>();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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<RigEclipseTimeStepInfo> RigCaseCellResultsData::timeStepInfos( const RigEclipseResultAddress& resVarAddr ) const
{
if ( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() )
return m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].timeStepInfos();
else
return std::vector<RigEclipseTimeStepInfo>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::setTimeStepInfos( const RigEclipseResultAddress& resVarAddr,
const std::vector<RigEclipseTimeStepInfo>& timeStepInfos )
{
CVF_ASSERT( findScalarResultIndexFromAddress( resVarAddr ) < m_resultInfos.size() );
m_resultInfos[findScalarResultIndexFromAddress( resVarAddr )].setTimeStepInfos( timeStepInfos );
std::vector<std::vector<double>>* 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<double> 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<double> 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<double>() );
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<double>*
RigCaseCellResultsData::getResultIndexableStaticResult( RigActiveCellInfo* actCellInfo,
RigCaseCellResultsData* gridCellResults,
QString resultName,
std::vector<double>& 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<double>* 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<RigEclipseResultInfo>& RigCaseCellResultsData::infoForEachResultIndex()
{
return m_resultInfos;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigCaseCellResultsData::mustBeCalculated( size_t scalarResultIndex ) const
{
std::vector<RigEclipseResultInfo>::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<RigEclipseResultInfo>::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<RigEclipseResultAddress> RigCaseCellResultsData::existingResults() const
{
std::vector<RigEclipseResultAddress> 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<RiaDefines::ResultCatType>& 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<RiaDefines::ResultCatType> 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<double>& 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<double>& 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<double>::infinity() );
assignValuesToTemporaryLgrs( resultName, values );
}
}
}
}
else if ( type == RiaDefines::ResultCatType::STATIC_NATIVE )
{
m_cellScalarResults[scalarResultIndex].resize( 1 );
std::vector<double>& 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<double>::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<RifReaderEclipseOutput*>( 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<double>& values = m_cellScalarResults[scalarResultIndex][i];
eclReader->sourSimRlResult( resultName, i, &values );
}
}
}
return scalarResultIndex;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigCaseCellResultsData::findOrLoadKnownScalarResultByResultTypeOrder(
const RigEclipseResultAddress& resVarAddr,
const std::vector<RiaDefines::ResultCatType>& resultCategorySearchOrder )
{
std::set<RiaDefines::ResultCatType> 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<RiaDefines::ResultCatType> 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<double>& 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<double>& 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<double>& 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<RifReaderEclipseOutput*>( m_readerInterface.p() );
if ( eclReader )
{
size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size();
m_cellScalarResults[scalarResultIndex].resize( timeStepCount );
std::vector<double>& 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<double>& 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<double>& 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<double>* swatForTimeStep = nullptr;
const std::vector<double>* sgasForTimeStep = nullptr;
const std::vector<double>* 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<double>* soilForTimeStep = this->modifiableCellScalarResult( SOILAddr, timeStepIndex );
#pragma omp parallel for
for ( int idx = 0; idx < static_cast<int>( 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<RiaDefines::PhaseType> 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<double>& values = m_cellScalarResults[scalarIndexSGAS][timeStepIndex];
if ( values.size() > 0 ) return;
}
size_t swatResultValueCount = 0;
size_t swatTimeStepCount = 0;
{
std::vector<double>& 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<double>* swatForTimeStep = nullptr;
{
swatForTimeStep = &( m_cellScalarResults[scalarIndexSWAT][timeStepIndex] );
if ( swatForTimeStep->size() == 0 )
{
swatForTimeStep = nullptr;
}
}
std::vector<double>& sgasForTimeStep = m_cellScalarResults[scalarIndexSGAS][timeStepIndex];
#pragma omp parallel for
for ( int idx = 0; idx < static_cast<int>( 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<std::vector<double>>& depth = m_cellScalarResults[depthResultIndex];
std::vector<std::vector<double>>& dx = m_cellScalarResults[dxResultIndex];
std::vector<std::vector<double>>& dy = m_cellScalarResults[dyResultIndex];
std::vector<std::vector<double>>& dz = m_cellScalarResults[dzResultIndex];
std::vector<std::vector<double>>& tops = m_cellScalarResults[topsResultIndex];
std::vector<std::vector<double>>& 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<double>::max() );
computeDepth = true;
}
if ( dx[0].size() < actCellCount )
{
dx[0].resize( actCellCount, std::numeric_limits<double>::max() );
computeDx = true;
}
if ( dy[0].size() < actCellCount )
{
dy[0].resize( actCellCount, std::numeric_limits<double>::max() );
computeDy = true;
}
if ( dz[0].size() < actCellCount )
{
dz[0].resize( actCellCount, std::numeric_limits<double>::max() );
computeDz = true;
}
if ( tops[0].size() < actCellCount )
{
tops[0].resize( actCellCount, std::numeric_limits<double>::max() );
computeTops = true;
}
if ( bottom[0].size() < actCellCount )
{
bottom[0].resize( actCellCount, std::numeric_limits<double>::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<std::vector<double>>& indexI = m_cellScalarResults[iResultIndex];
std::vector<std::vector<double>>& indexJ = m_cellScalarResults[jResultIndex];
std::vector<std::vector<double>>& indexK = m_cellScalarResults[kResultIndex];
{
if ( indexI[0].size() < reservoirCellCount )
{
indexI[0].resize( reservoirCellCount, std::numeric_limits<double>::infinity() );
computeIndexI = true;
}
if ( indexJ[0].size() < reservoirCellCount )
{
indexJ[0].resize( reservoirCellCount, std::numeric_limits<double>::infinity() );
computeIndexJ = true;
}
if ( indexK[0].size() < reservoirCellCount )
{
indexK[0].resize( reservoirCellCount, std::numeric_limits<double>::infinity() );
computeIndexK = true;
}
}
const std::vector<RigCell>& globalCellArray = m_ownerMainGrid->globalCellArray();
long long numCells = static_cast<long long>( 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<cvf::Vec3d>& nodes,
cvf::StructGridInterface::FaceType faceId,
cvf::Vec3d* faceAreaVec )
{
CVF_TIGHT_ASSERT( faceAreaVec );
*faceAreaVec = cvf::Vec3d::ZERO;
std::vector<size_t> polygon;
std::vector<cvf::Vec3d> intersections;
std::array<size_t, 4> face1;
std::array<size_t, 4> face2;
c1.faceIndices( faceId, &face1 );
c2.faceIndices( cvf::StructGridInterface::oppositeFace( faceId ), &face2 );
bool foundOverlap = cvf::GeometryTools::calculateOverlapPolygonOfTwoQuads( &polygon,
&intersections,
(cvf::EdgeIntersectStorage<size_t>*)nullptr,
cvf::wrapArrayConst( &nodes ),
face1.data(),
face2.data(),
1e-6 );
if ( foundOverlap )
{
std::vector<cvf::Vec3d> 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<double>& permResults = m_cellScalarResults[permResultIdx][0];
std::vector<double>& riTransResults = m_cellScalarResults[riTransResultIdx][0];
std::vector<double>* 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<cvf::Vec3d>& 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<double>& permXResults = m_cellScalarResults[permXResultIdx][0];
std::vector<double>& permYResults = m_cellScalarResults[permYResultIdx][0];
std::vector<double>& permZResults = m_cellScalarResults[permZResultIdx][0];
std::vector<double>& riCombTransResults =
m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult( RiaDefines::propertyNameRiCombTrans() );
m_ownerMainGrid->nncData()->setEclResultAddress( RiaDefines::propertyNameRiCombTrans(), riCombTransEclResAddr );
std::vector<double>* 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<cvf::StructGridInterface::FaceType>( nncConnections[connIdx].face() );
ResultIndexFunction permIdxFunc = nullptr;
std::vector<double>* 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<cvf::Vec3f>& 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<double>& riTransResults = m_cellScalarResults[riTransResultIdx][0];
const std::vector<double>& transResults = m_cellScalarResults[transResultIdx][0];
std::vector<double>& 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<double>* riTransResults =
m_ownerMainGrid->nncData()->staticConnectionScalarResult( riCombTransEclResAddr );
const std::vector<double>* transResults =
m_ownerMainGrid->nncData()->staticConnectionScalarResult( combTransEclResAddr );
if ( riTransResults && transResults && ( riTransResults->size() == transResults->size() ) )
{
std::vector<double>& 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<double>& transResults = m_cellScalarResults[tranCompScResIdx][0];
std::vector<double>& 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<cvf::Vec3d>& 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<double>* transResults =
m_ownerMainGrid->nncData()->staticConnectionScalarResult( combTransEclResAddr );
if ( !transResults ) return;
std::vector<double>& 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<cvf::Vec3f>& 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<double>& 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<double>& cellVolumeResults = m_cellScalarResults[cellVolIdx][0];
size_t cellResultCount = m_activeCellInfo->reservoirActiveCellCount();
cellVolumeResults.resize( cellResultCount, std::numeric_limits<double>::infinity() );
#pragma omp parallel for
for ( int nativeResvCellIndex = 0; nativeResvCellIndex < static_cast<int>( 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<double>& 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<double>& soilResults = m_cellScalarResults[soilIdx][timeStepIdx];
std::vector<double>& oilVolumeResults = m_cellScalarResults[oilVolIdx][timeStepIdx];
oilVolumeResults.resize( cellResultCount, 0u );
#pragma omp parallel for
for ( int nativeResvCellIndex = 0;
nativeResvCellIndex < static_cast<int>( 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<double> porvDataTemp;
std::vector<double> swcrDataTemp;
std::vector<double> multpvDataTemp;
const std::vector<double>* porvResults = nullptr;
const std::vector<double>* swcrResults = nullptr;
const std::vector<double>* 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<double>& 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<RifReaderEclipseOutput*>( 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<double>* 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<std::vector<double>>& 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<double>& valuesForAllReservoirCells )
{
CVF_ASSERT( m_activeCellInfo );
static std::vector<QString> 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<double>& fnAllanNncResults =
mainGrid->nncData()->makeStaticConnectionScalarResult( RiaResultNames::formationAllanResultName() );
std::vector<double>& 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<double>& 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<double>* alData = cellResultsData->modifiableCellScalarResult( fnAllanResultResAddr, 0 );
std::vector<double>* 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<std::pair<int, int>, 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<int>( 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<RimEclipseCase*> destinationCases )
{
std::vector<RigEclipseResultAddress> resAddresses = mainCaseResultsData->results( poroModel )->existingResults();
std::vector<RigEclipseTimeStepInfo> timeStepInfos =
mainCaseResultsData->results( poroModel )->timeStepInfos( resAddresses[0] );
const std::vector<RigEclipseResultInfo> resultInfos =
mainCaseResultsData->results( poroModel )->infoForEachResultIndex();
for ( size_t i = 0; i < destinationCases.size(); i++ )
{
RimEclipseResultCase* rimReservoir = dynamic_cast<RimEclipseResultCase*>( 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<std::vector<double>>* dataValues =
cellResultsStorage->modifiableCellScalarResultTimesteps( resVarAddr );
dataValues->resize( timeStepInfos.size() );
}
}
cellResultsStorage->createPlaceholderResultEntries();
}
}