#8989 Grid statistics: Improve precision of p10/p90.

This commit is contained in:
Kristian Bendiksen 2022-06-13 09:46:42 +02:00
parent 34a05ec5f4
commit 226ac4f2b6
9 changed files with 176 additions and 2 deletions

View File

@ -46,6 +46,39 @@ void RigEclipseNativeStatCalc::minMaxCellScalarValues( size_t timeStepIndex, dou
max = acc.max;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigEclipseNativeStatCalc::hasPreciseP10p90() const
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseNativeStatCalc::p10p90CellScalarValues( double& p10, double& p90 )
{
PercentilAccumulator acc;
for ( size_t timeStepIndex = 0; timeStepIndex < timeStepCount(); timeStepIndex++ )
{
traverseCells( acc, timeStepIndex );
}
acc.computep10p90( p10, p90 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseNativeStatCalc::p10p90CellScalarValues( size_t timeStepIndex, double& p10, double& p90 )
{
PercentilAccumulator acc;
traverseCells( acc, timeStepIndex );
acc.computep10p90( p10, p90 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -35,6 +35,9 @@ class RigEclipseNativeStatCalc : public RigStatisticsCalculator
public:
RigEclipseNativeStatCalc( RigCaseCellResultsData* cellResultsData, const RigEclipseResultAddress& eclipseResultAddress );
bool hasPreciseP10p90() const override;
void p10p90CellScalarValues( double& min, double& max ) override;
void p10p90CellScalarValues( size_t timeStepIndex, double& min, double& max ) override;
void minMaxCellScalarValues( size_t timeStepIndex, double& min, double& max ) override;
void posNegClosestToZero( size_t timeStepIndex, double& pos, double& neg ) override;
void valueSumAndSampleCount( size_t timeStepIndex, double& valueSum, size_t& sampleCount ) override;

View File

@ -49,6 +49,39 @@ void RigEclipseNativeVisibleCellsStatCalc::minMaxCellScalarValues( size_t timeSt
max = acc.max;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigEclipseNativeVisibleCellsStatCalc::hasPreciseP10p90() const
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseNativeVisibleCellsStatCalc::p10p90CellScalarValues( double& p10, double& p90 )
{
PercentilAccumulator acc;
for ( size_t timeStepIndex = 0; timeStepIndex < timeStepCount(); timeStepIndex++ )
{
traverseCells( acc, timeStepIndex );
}
acc.computep10p90( p10, p90 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseNativeVisibleCellsStatCalc::p10p90CellScalarValues( size_t timeStepIndex, double& p10, double& p90 )
{
PercentilAccumulator acc;
traverseCells( acc, timeStepIndex );
acc.computep10p90( p10, p90 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -36,6 +36,9 @@ public:
const RigEclipseResultAddress& scalarResultIndex,
const cvf::UByteArray* cellVisibilities );
bool hasPreciseP10p90() const override;
void p10p90CellScalarValues( double& min, double& max ) override;
void p10p90CellScalarValues( size_t timeStepIndex, double& min, double& max ) override;
void minMaxCellScalarValues( size_t timeStepIndex, double& min, double& max ) override;
void posNegClosestToZero( size_t timeStepIndex, double& pos, double& neg ) override;
void valueSumAndSampleCount( size_t timeStepIndex, double& valueSum, size_t& sampleCount ) override;

View File

@ -19,6 +19,7 @@
#include "RigStatisticsCalculator.h"
#include <cassert>
#include <cmath> // Needed for HUGE_VAL on Linux
//--------------------------------------------------------------------------------------------------
@ -135,3 +136,27 @@ void RigStatisticsCalculator::posNegClosestToZero( const std::vector<double>& va
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigStatisticsCalculator::hasPreciseP10p90() const
{
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigStatisticsCalculator::p10p90CellScalarValues( double& p10, double& p90 )
{
assert( false && "Precise p10/p90 not available" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigStatisticsCalculator::p10p90CellScalarValues( size_t timeStepIndex, double& p10, double& p90 )
{
assert( false && "Precise p10/p90 not available" );
}

View File

@ -46,6 +46,10 @@ public:
virtual void uniqueValues( size_t timeStepIndex, std::set<int>& values ) = 0;
virtual bool hasPreciseP10p90() const;
virtual void p10p90CellScalarValues( double& p10, double& p90 );
virtual void p10p90CellScalarValues( size_t timeStepIndex, double& p10, double& p90 );
virtual size_t timeStepCount() = 0;
void mobileVolumeWeightedMean( double& mean );

View File

@ -310,7 +310,23 @@ void RigStatisticsDataCache::mobileVolumeWeightedMean( double& mean )
//--------------------------------------------------------------------------------------------------
void RigStatisticsDataCache::p10p90CellScalarValues( double& p10, double& p90 )
{
computeHistogramStatisticsIfNeeded();
if ( !m_statsAllTimesteps.m_isp10p90Calculated )
{
if ( m_statisticsCalculator->hasPreciseP10p90() )
{
// Prefer precise p10/p90 calculation where available
m_statisticsCalculator->p10p90CellScalarValues( p10, p90 );
m_statsAllTimesteps.m_p10 = p10;
m_statsAllTimesteps.m_p90 = p90;
}
else
{
computeHistogramStatisticsIfNeeded();
}
m_statsAllTimesteps.m_isp10p90Calculated = true;
}
p10 = m_statsAllTimesteps.m_p10;
p90 = m_statsAllTimesteps.m_p90;
@ -321,7 +337,28 @@ void RigStatisticsDataCache::p10p90CellScalarValues( double& p10, double& p90 )
//--------------------------------------------------------------------------------------------------
void RigStatisticsDataCache::p10p90CellScalarValues( size_t timeStepIndex, double& p10, double& p90 )
{
computeHistogramStatisticsIfNeeded( timeStepIndex );
if ( timeStepIndex >= m_statsPrTs.size() )
{
m_statsPrTs.resize( timeStepIndex + 1 );
}
if ( !m_statsPrTs[timeStepIndex].m_isp10p90Calculated )
{
if ( m_statisticsCalculator->hasPreciseP10p90() )
{
// Prefer precise p10/p90 calculation where available
m_statisticsCalculator->p10p90CellScalarValues( timeStepIndex, p10, p90 );
m_statsPrTs[timeStepIndex].m_p10 = p10;
m_statsPrTs[timeStepIndex].m_p90 = p90;
}
else
{
computeHistogramStatisticsIfNeeded( timeStepIndex );
}
m_statsPrTs[timeStepIndex].m_isp10p90Calculated = true;
}
p10 = m_statsPrTs[timeStepIndex].m_p10;
p90 = m_statsPrTs[timeStepIndex].m_p90;

View File

@ -82,6 +82,7 @@ private:
m_isClosestToZeroCalculated = false;
m_p10 = HUGE_VAL;
m_p90 = HUGE_VAL;
m_isp10p90Calculated = false;
m_valueSum = 0.0;
m_isValueSumCalculated = false;
m_volumeWeightedMean = HUGE_VAL;
@ -101,6 +102,7 @@ private:
double m_p10;
double m_p90;
bool m_isp10p90Calculated;
double m_valueSum;
bool m_isValueSumCalculated;

View File

@ -130,6 +130,40 @@ public:
double min;
};
class PercentilAccumulator
{
public:
PercentilAccumulator() {}
void addData( const std::vector<double>& values )
{
for ( double val : values )
{
addValue( val );
}
}
void addData( const std::vector<float>& values )
{
for ( float val : values )
{
addValue( val );
}
}
void addValue( double value ) { values.push_back( value ); }
void computep10p90( double& p10, double& p90 )
{
double mean = HUGE_VAL;
double p50 = HUGE_VAL;
RigStatisticsMath::calculateStatisticsCurves( values, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED );
}
std::vector<double> values;
};
class PosNegAccumulator
{
public: