Work in progress

This commit is contained in:
Jon Jenssen 2024-12-17 19:35:51 +01:00
parent 220d66cfdc
commit 65f1f0b009
7 changed files with 150 additions and 60 deletions

View File

@ -561,7 +561,10 @@ void RimEclipseStatisticsCase::defineUiOrdering( QString uiConfigName, caf::PdmU
uiOrdering.skipRemainingFields();
}
QList<caf::PdmOptionItemInfo> toOptionList( const QStringList& varList )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimEclipseStatisticsCase::toOptionList( const QStringList& varList )
{
QList<caf::PdmOptionItemInfo> optionList;
int i;
@ -904,9 +907,7 @@ void RimEclipseStatisticsCase::updateSelectionListVisibilities()
{
bool isLocked = hasComputedStatistics();
m_resultType.uiCapability()->setUiHidden( isLocked );
m_porosityModel.uiCapability()->setUiHidden(
isLocked ); // ||
// !caseGroup()->mainCase()->reservoirData()->results(RiaDefines::FRACTURE_MODEL)->resultCount()
m_porosityModel.uiCapability()->setUiHidden( isLocked );
m_selectedDynamicProperties.uiCapability()->setUiHidden( isLocked || m_porosityModel() != RiaDefines::PorosityModelType::MATRIX_MODEL ||
m_resultType() != RiaDefines::ResultCatType::DYNAMIC_NATIVE );

View File

@ -106,6 +106,8 @@ private:
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
void initializeSelectedTimeSteps();
static QList<caf::PdmOptionItemInfo> toOptionList( const QStringList& varList );
private:
caf::PdmField<caf::AppEnum<DataSourceType>> m_dataSourceForStatistics;

View File

@ -43,6 +43,7 @@
#include "cafCmdFeatureMenuBuilder.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include "cafProgressInfo.h"
#include <limits>
@ -79,7 +80,8 @@ RimStatisticsContourMap::RimStatisticsContourMap()
CAF_PDM_InitFieldNoDefault( &m_resultAggregation, "ResultAggregation", "Result Aggregation" );
CAF_PDM_InitField( &m_timeStep, "TimeStep", 0, "Time Step" );
CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "SelectedTimeSteps", "Time Step Selection" );
m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitFieldNoDefault( &m_resultDefinition, "ResultDefinition", "" );
m_resultDefinition.uiCapability()->setUiTreeChildrenHidden( true );
@ -104,7 +106,13 @@ void RimStatisticsContourMap::defineUiOrdering( QString uiConfigName, caf::PdmUi
{
uiOrdering.add( nameField() );
uiOrdering.add( &m_resultAggregation );
uiOrdering.add( &m_timeStep );
{
auto group = uiOrdering.addNewGroup( "Time Step Selection" );
group->setCollapsedByDefault();
group->add( &m_selectedTimeSteps );
}
uiOrdering.add( &m_relativeSampleSpacing );
uiOrdering.add( &m_boundingBoxExpPercent );
@ -150,14 +158,23 @@ QList<caf::PdmOptionItemInfo> RimStatisticsContourMap::calculateValueOptions( co
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_timeStep )
auto eCase = m_resultDefinition->eclipseCase();
if ( eCase == nullptr ) return options;
if ( &m_selectedTimeSteps == fieldNeedingOptions )
{
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
if ( ensemble && !ensemble->cases().empty() )
QList<caf::PdmOptionItemInfo> options;
const auto timeStepStrings = eCase->timeStepStrings();
int index = 0;
for ( const auto& text : timeStepStrings )
{
RimEclipseCase* firstEclipseCase = ensemble->cases().front();
RimTools::timeStepsForCase( firstEclipseCase, &options );
options.push_back( caf::PdmOptionItemInfo( text, index++ ) );
}
return options;
}
return options;
@ -252,7 +269,10 @@ void RimStatisticsContourMap::computeStatistics()
caf::ProgressInfo progInfo( ensemble->cases().size() + 1, "Reading Eclipse Ensemble" );
std::vector<std::vector<double>> results;
// std::vector<std::vector<double>> results;
std::map<size_t, std::vector<std::vector<double>>> timestep_results;
for ( RimEclipseCase* eclipseCase : ensemble->cases() )
{
if ( eclipseCase->ensureReservoirCaseIsOpen() )
@ -265,57 +285,76 @@ void RimStatisticsContourMap::computeStatistics()
RigEclipseContourMapProjection contourMapProjection( *contourMapGrid, *eclipseCaseData, *resultData );
contourMapProjection.generateGridMapping( resultAggregation, {} );
std::vector<double> result =
contourMapProjection.generateResults( m_resultDefinition()->eclipseResultAddress(), resultAggregation, m_timeStep() );
results.push_back( result );
if ( m_resultDefinition()->hasDynamicResult() )
{
for ( auto ts : m_selectedTimeSteps() )
{
std::vector<double> result =
contourMapProjection.generateResults( m_resultDefinition()->eclipseResultAddress(), resultAggregation, ts );
timestep_results[ts].push_back( result );
}
}
else
{
std::vector<double> result =
contourMapProjection.generateResults( m_resultDefinition()->eclipseResultAddress(), resultAggregation, 0 );
timestep_results[0].push_back( result );
}
}
progInfo.incrementProgress();
}
if ( !results.empty() )
m_contourMapGrid = std::move( contourMapGrid );
m_timeResults.clear();
for ( auto [timeStep, results] : timestep_results )
{
int nCells = static_cast<int>( results[0].size() );
std::vector<double> p10Results( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> p50Results( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> p90Results( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> meanResults( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> minResults( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> maxResults( nCells, std::numeric_limits<double>::infinity() );
if ( !results.empty() )
{
int nCells = static_cast<int>( results[0].size() );
std::vector<double> p10Results( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> p50Results( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> p90Results( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> meanResults( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> minResults( nCells, std::numeric_limits<double>::infinity() );
std::vector<double> maxResults( nCells, std::numeric_limits<double>::infinity() );
#pragma omp parallel for
for ( int i = 0; i < nCells; i++ )
{
size_t numSamples = results.size();
std::vector<double> samples( numSamples, 0.0 );
for ( size_t s = 0; s < numSamples; s++ )
samples[s] = results[s][i];
for ( int i = 0; i < nCells; i++ )
{
size_t numSamples = results.size();
std::vector<double> samples( numSamples, 0.0 );
for ( size_t s = 0; s < numSamples; s++ )
samples[s] = results[s][i];
double p10 = std::numeric_limits<double>::infinity();
double p50 = std::numeric_limits<double>::infinity();
double p90 = std::numeric_limits<double>::infinity();
double mean = std::numeric_limits<double>::infinity();
double p10 = std::numeric_limits<double>::infinity();
double p50 = std::numeric_limits<double>::infinity();
double p90 = std::numeric_limits<double>::infinity();
double mean = std::numeric_limits<double>::infinity();
RigStatisticsMath::calculateStatisticsCurves( samples, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED );
RigStatisticsMath::calculateStatisticsCurves( samples, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED );
if ( RiaStatisticsTools::isValidNumber( p10 ) ) p10Results[i] = p10;
if ( RiaStatisticsTools::isValidNumber( p50 ) ) p50Results[i] = p50;
if ( RiaStatisticsTools::isValidNumber( p90 ) ) p90Results[i] = p90;
if ( RiaStatisticsTools::isValidNumber( mean ) ) meanResults[i] = mean;
if ( RiaStatisticsTools::isValidNumber( p10 ) ) p10Results[i] = p10;
if ( RiaStatisticsTools::isValidNumber( p50 ) ) p50Results[i] = p50;
if ( RiaStatisticsTools::isValidNumber( p90 ) ) p90Results[i] = p90;
if ( RiaStatisticsTools::isValidNumber( mean ) ) meanResults[i] = mean;
double minValue = RiaStatisticsTools::minimumValue( samples );
if ( RiaStatisticsTools::isValidNumber( minValue ) && minValue < std::numeric_limits<double>::max() ) minResults[i] = minValue;
double minValue = RiaStatisticsTools::minimumValue( samples );
if ( RiaStatisticsTools::isValidNumber( minValue ) && minValue < std::numeric_limits<double>::max() )
minResults[i] = minValue;
double maxValue = RiaStatisticsTools::maximumValue( samples );
if ( RiaStatisticsTools::isValidNumber( maxValue ) && maxValue > -std::numeric_limits<double>::max() ) maxResults[i] = maxValue;
double maxValue = RiaStatisticsTools::maximumValue( samples );
if ( RiaStatisticsTools::isValidNumber( maxValue ) && maxValue > -std::numeric_limits<double>::max() )
maxResults[i] = maxValue;
}
m_timeResults[timeStep][StatisticsType::P10] = p10Results;
m_timeResults[timeStep][StatisticsType::P50] = p50Results;
m_timeResults[timeStep][StatisticsType::P90] = p90Results;
m_timeResults[timeStep][StatisticsType::MEAN] = meanResults;
m_timeResults[timeStep][StatisticsType::MIN] = minResults;
m_timeResults[timeStep][StatisticsType::MAX] = maxResults;
}
m_contourMapGrid = std::move( contourMapGrid );
m_result[StatisticsType::P10] = p10Results;
m_result[StatisticsType::P50] = p50Results;
m_result[StatisticsType::P90] = p90Results;
m_result[StatisticsType::MEAN] = meanResults;
m_result[StatisticsType::MIN] = minResults;
m_result[StatisticsType::MAX] = maxResults;
}
}
@ -349,10 +388,21 @@ RigContourMapGrid* RimStatisticsContourMap::contourMapGrid() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimStatisticsContourMap::result( StatisticsType statisticsType ) const
int RimStatisticsContourMap::maxTimeStepCount() const
{
if ( auto it = m_result.find( statisticsType ); it != m_result.end() ) return it->second;
return {};
return m_selectedTimeSteps().size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimStatisticsContourMap::result( size_t timeStep, StatisticsType statisticsType ) const
{
if ( !m_timeResults.contains( timeStep ) ) return {};
if ( !m_timeResults.at( timeStep ).contains( statisticsType ) ) return {};
return m_timeResults.at( timeStep ).at( statisticsType );
}
//--------------------------------------------------------------------------------------------------

View File

@ -60,7 +60,7 @@ public:
RimEclipseCaseEnsemble* ensemble() const;
RigContourMapGrid* contourMapGrid() const;
std::vector<double> result( StatisticsType statisticsType ) const;
std::vector<double> result( size_t timeStep, StatisticsType statisticsType ) const;
void addView( RimStatisticsContourMapView* view );
@ -73,6 +73,8 @@ public:
double sampleSpacingFactor() const;
bool isColumnResult() const;
int maxTimeStepCount() const;
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
@ -84,16 +86,18 @@ protected:
private:
void computeStatistics();
caf::PdmField<double> m_boundingBoxExpPercent;
caf::PdmField<double> m_relativeSampleSpacing;
caf::PdmField<RimContourMapProjection::ResultAggregation> m_resultAggregation;
caf::PdmField<int> m_timeStep;
caf::PdmField<double> m_boundingBoxExpPercent;
caf::PdmField<std::vector<int>> m_selectedTimeSteps;
caf::PdmChildField<RimEclipseResultDefinition*> m_resultDefinition;
caf::PdmField<bool> m_computeStatisticsButton;
std::unique_ptr<RigContourMapGrid> m_contourMapGrid;
std::map<StatisticsType, std::vector<double>> m_result;
std::unique_ptr<RigContourMapGrid> m_contourMapGrid;
// std::map<StatisticsType, std::vector<double>> m_result;
std::map<size_t, std::map<StatisticsType, std::vector<double>>> m_timeResults;
std::vector<std::vector<std::pair<size_t, double>>> m_gridMapping;
caf::PdmChildArrayField<RimStatisticsContourMapView*> m_views;

View File

@ -165,7 +165,7 @@ void RimStatisticsContourMapProjection::generateAndSaveResults( int timeStep )
if ( auto statistics = statisticsContourMap() )
{
dynamic_cast<RigStatisticsContourMapProjection*>( m_contourMapProjection.get() )
->generateAndSaveResults( statistics->result( m_statisticsType() ) );
->generateAndSaveResults( statistics->result( timeStep, m_statisticsType() ) );
}
}
@ -260,7 +260,8 @@ std::pair<double, double> RimStatisticsContourMapProjection::minmaxValuesAllTime
{
clearTimeStepRange();
std::vector<double> aggregatedResults = statisticsContourMap()->result( m_statisticsType() );
// TODO - step through all time steps here!
std::vector<double> aggregatedResults = statisticsContourMap()->result( 0, m_statisticsType() );
m_minResultAllTimeSteps = RigContourMapProjection::minValue( aggregatedResults );
m_maxResultAllTimeSteps = RigContourMapProjection::maxValue( aggregatedResults );
}

View File

@ -210,3 +210,32 @@ RimStatisticsContourMap* RimStatisticsContourMapView::statisticsContourMap() con
{
return m_statisticsContourMap;
}
//--------------------------------------------------------------------------------------------------
/// Clamp the current timestep to actual possibilities
//--------------------------------------------------------------------------------------------------
void RimStatisticsContourMapView::onClampCurrentTimestep()
{
if ( statisticsContourMap() )
{
if ( m_currentTimeStep() >= statisticsContourMap()->maxTimeStepCount() )
{
m_currentTimeStep = statisticsContourMap()->maxTimeStepCount() - 1;
}
}
if ( m_currentTimeStep < 0 ) m_currentTimeStep = 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimStatisticsContourMapView::onTimeStepCountRequested()
{
if ( statisticsContourMap() )
{
return (size_t)statisticsContourMap()->maxTimeStepCount();
}
return 0;
}

View File

@ -39,6 +39,9 @@ protected:
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void onClampCurrentTimestep() override;
size_t onTimeStepCountRequested() override;
// void createContourMapGeometry();
void onUpdateLegends() override;