Skip to content

Commit

Permalink
Add support for grid calculations as data source for statistics
Browse files Browse the repository at this point in the history
- add data source selection, either Case Property or Grid Calculation
- add Time Step Selection, can be used for both dynamic case properties and Grid Calculations
- optionally release grid calculation data when statistics is computed
- recursive grid calculations is supported
  • Loading branch information
magnesj committed Nov 8, 2023
1 parent 92d1bd9 commit 39fc9d5
Show file tree
Hide file tree
Showing 12 changed files with 565 additions and 282 deletions.
6 changes: 4 additions & 2 deletions ApplicationLibCode/Commands/RicCreateTemporaryLgrFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,16 +285,18 @@ void RicCreateTemporaryLgrFeature::deleteAllCachedData( RimEclipseCase* eclipseC
{
if ( eclipseCase )
{
std::vector<RiaDefines::ResultCatType> categoriesToExclude = { RiaDefines::ResultCatType::GENERATED };

RigCaseCellResultsData* cellResultsDataMatrix = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
if ( cellResultsDataMatrix )
{
cellResultsDataMatrix->freeAllocatedResultsData();
cellResultsDataMatrix->freeAllocatedResultsData( categoriesToExclude, std::nullopt );
}

RigCaseCellResultsData* cellResultsDataFracture = eclipseCase->results( RiaDefines::PorosityModelType::FRACTURE_MODEL );
if ( cellResultsDataFracture )
{
cellResultsDataFracture->freeAllocatedResultsData();
cellResultsDataFracture->freeAllocatedResultsData( categoriesToExclude, std::nullopt );
}

RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData();
Expand Down
372 changes: 269 additions & 103 deletions ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp

Large diffs are not rendered by default.

31 changes: 24 additions & 7 deletions ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class RigSimWellData;
class RimEclipseResultDefinition;
class RimEclipseStatisticsCaseCollection;
class RimIdenticalGridCaseGroup;
class RimGridCalculation;

//==================================================================================================
//
Expand All @@ -45,6 +46,20 @@ class RimEclipseStatisticsCase : public RimEclipseCase
{
CAF_PDM_HEADER_INIT;

public:
enum class PercentileCalcType
{
NEAREST_OBSERVATION,
HISTOGRAM_ESTIMATED,
INTERPOLATED_OBSERVATION
};

enum class DataSourceType
{
GRID_CALCULATION,
CASE_PROPERTY
};

public:
RimEclipseStatisticsCase();
~RimEclipseStatisticsCase() override;
Expand All @@ -63,18 +78,12 @@ class RimEclipseStatisticsCase : public RimEclipseCase

RimCaseCollection* parentStatisticsCaseCollection() const;

enum PercentileCalcType
{
NEAREST_OBSERVATION,
HISTOGRAM_ESTIMATED,
INTERPOLATED_OBSERVATION
};

caf::PdmField<bool> m_calculateEditCommand;

void populateResultSelectionAfterLoadingGrid();

void setSourceProperties( RiaDefines::ResultCatType propertyType, const std::vector<QString>& propertyNames );
void selectAllTimeSteps();

private:
void scheduleACTIVEGeometryRegenOnReservoirViews();
Expand All @@ -95,8 +104,16 @@ class RimEclipseStatisticsCase : public RimEclipseCase
void loadSimulationWellDataFromSourceCase();

void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
void initializeSelectedTimeSteps();

private:
caf::PdmField<caf::AppEnum<DataSourceType>> m_dataSourceForStatistics;

caf::PdmPtrField<RimGridCalculation*> m_gridCalculation;
caf::PdmField<bool> m_clearGridCalculationMemory;

caf::PdmField<std::vector<int>> m_selectedTimeSteps;

caf::PdmField<caf::AppEnum<RiaDefines::ResultCatType>> m_resultType;
caf::PdmField<caf::AppEnum<RiaDefines::PorosityModelType>> m_porosityModel;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,23 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>

for ( size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++ )
{
size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx];
auto timeStepIdx = m_timeStepIndices[timeIndicesIdx];

for ( size_t gridIdx = 0; gridIdx < m_destinationCase->gridCount(); gridIdx++ )
{
RigGridBase* grid = m_destinationCase->grid( gridIdx );

for ( int resSpecIdx = 0; resSpecIdx < resultSpecification.size(); resSpecIdx++ )
for ( const auto& resSpec : resultSpecification )
{
RiaDefines::PorosityModelType poroModel = resultSpecification[resSpecIdx].m_poroModel;
RiaDefines::ResultCatType resultType = resultSpecification[resSpecIdx].m_resType;
QString resultName = resultSpecification[resSpecIdx].m_resVarName;
RiaDefines::PorosityModelType poroModel = resSpec.m_poroModel;
RiaDefines::ResultCatType resultType = resSpec.m_resType;
QString resultName = resSpec.m_resVarName;

size_t activeCellCount = m_destinationCase->activeCellInfo( poroModel )->reservoirActiveCellCount();

if ( activeCellCount == 0 ) continue;

size_t dataAccessTimeStepIndex = timeStepIdx;
auto dataAccessTimeStepIndex = static_cast<size_t>( timeStepIdx );

// Always evaluate statistics once, and always use time step index zero
if ( resultType == RiaDefines::ResultCatType::STATIC_NATIVE )
Expand All @@ -145,10 +145,8 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>
// Build data access objects for source scalar results

cvf::Collection<RigResultAccessor> sourceDataAccessList;
for ( size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++ )
for ( RimEclipseCase* sourceCase : m_sourceCases )
{
RimEclipseCase* sourceCase = m_sourceCases.at( caseIdx );

// Trigger loading of dataset
// NB! Many other functions are based on loading of all time steps at the same time
// Use this concept carefully
Expand Down Expand Up @@ -184,21 +182,21 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>
statisticalResultNames[PMID] = createResultNamePVal( resultName, m_statisticsConfig.m_pMidPos );
statisticalResultNames[PMAX] = createResultNamePVal( resultName, m_statisticsConfig.m_pMaxPos );

for ( size_t stIdx = 0; stIdx < statisticalResultNames.size(); ++stIdx )
for ( const auto& statisticalResultName : statisticalResultNames )
{
cvf::ref<RigResultModifier> resultModifier =
RigResultModifierFactory::createResultModifier( m_destinationCase,
grid->gridIndex(),
poroModel,
dataAccessTimeStepIndex,
RigEclipseResultAddress( resultType, statisticalResultNames[stIdx] ) );
RigEclipseResultAddress( resultType, statisticalResultName ) );
destinationDataAccessList.push_back( resultModifier.p() );
}

std::vector<double> statParams( STAT_PARAM_COUNT, HUGE_VAL );
std::vector<double> values( sourceDataAccessList.size(), HUGE_VAL );

int cellCount = static_cast<int>( grid->cellCount() );
auto cellCount = static_cast<int>( grid->cellCount() );

// Loop over the cells in the grid, get the case values, and calculate the cell statistics
#pragma omp parallel for schedule( dynamic ) firstprivate( statParams, values )
Expand Down Expand Up @@ -245,7 +243,7 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>
// Calculate percentiles
if ( m_statisticsConfig.m_calculatePercentiles )
{
if ( m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::NEAREST_OBSERVATION )
if ( m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::PercentileCalcType::NEAREST_OBSERVATION )
{
std::vector<double> pValPoss;
pValPoss.push_back( m_statisticsConfig.m_pMinPos );
Expand All @@ -259,7 +257,7 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>
statParams[PMID] = pVals[1];
statParams[PMAX] = pVals[2];
}
else if ( m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::HISTOGRAM_ESTIMATED )
else if ( m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::PercentileCalcType::HISTOGRAM_ESTIMATED )
{
std::vector<size_t> histogram;
RigHistogramCalculator histCalc( statParams[MIN], statParams[MAX], 100, &histogram );
Expand All @@ -271,7 +269,8 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>
statParams[PMAX] = histCalc.calculatePercentil( m_statisticsConfig.m_pMaxPos / 100.0,
RigStatisticsMath::PercentileStyle::SWITCHED );
}
else if ( m_statisticsConfig.m_pValMethod == RimEclipseStatisticsCase::INTERPOLATED_OBSERVATION )
else if ( m_statisticsConfig.m_pValMethod ==
RimEclipseStatisticsCase::PercentileCalcType::INTERPOLATED_OBSERVATION )
{
std::vector<double> pValPoss;
pValPoss.push_back( m_statisticsConfig.m_pMinPos );
Expand Down Expand Up @@ -310,14 +309,15 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>
// Microsoft note: On Windows, the maximum number of files open at the same time is 512
// http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx

for ( size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++ )
{
RimEclipseCase* eclipseCase = m_sourceCases.at( caseIdx );
std::vector<RiaDefines::ResultCatType> categoriesToExclude;
if ( !m_clearGridCalculationMemory ) categoriesToExclude.push_back( RiaDefines::ResultCatType::GENERATED );

for ( RimEclipseCase* eclipseCase : m_sourceCases )
{
if ( eclipseCase->reservoirViews.empty() )
{
eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->freeAllocatedResultsData();
eclipseCase->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->freeAllocatedResultsData();
eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->freeAllocatedResultsData( categoriesToExclude, timeStepIdx );
eclipseCase->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->freeAllocatedResultsData( categoriesToExclude, timeStepIdx );
}
}

Expand All @@ -330,11 +330,11 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList<ResSpec>
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCaseEvaluator::addNamedResults( const QList<ResSpec>& resultSpecification )
{
for ( int i = 0; i < resultSpecification.size(); i++ )
for ( const auto& resSpec : resultSpecification )
{
RiaDefines::PorosityModelType poroModel = resultSpecification[i].m_poroModel;
RiaDefines::ResultCatType resultType = resultSpecification[i].m_resType;
QString resultName = resultSpecification[i].m_resVarName;
RiaDefines::PorosityModelType poroModel = resSpec.m_poroModel;
RiaDefines::ResultCatType resultType = resSpec.m_resType;
QString resultName = resSpec.m_resVarName;

size_t activeCellCount = m_destinationCase->activeCellInfo( poroModel )->reservoirActiveCellCount();
if ( activeCellCount == 0 ) continue;
Expand All @@ -361,9 +361,9 @@ void RimEclipseStatisticsCaseEvaluator::addNamedResults( const QList<ResSpec>& r
statisticalResultNames.push_back( createResultNamePVal( resultName, m_statisticsConfig.m_pMaxPos ) );
}

for ( size_t j = 0; j < statisticalResultNames.size(); ++j )
for ( const auto& statisticalResultName : statisticalResultNames )
{
addNamedResult( destCellResultsData, resultType, statisticalResultNames[j], activeCellCount );
addNamedResult( destCellResultsData, resultType, statisticalResultName, activeCellCount );
}
}
}
Expand All @@ -372,17 +372,19 @@ void RimEclipseStatisticsCaseEvaluator::addNamedResults( const QList<ResSpec>& r
///
//--------------------------------------------------------------------------------------------------
RimEclipseStatisticsCaseEvaluator::RimEclipseStatisticsCaseEvaluator( const std::vector<RimEclipseCase*>& sourceCases,
const std::vector<size_t>& timeStepIndices,
const std::vector<int>& timeStepIndices,
const RimStatisticsConfig& statisticsConfig,
RigEclipseCaseData* destinationCase,
RimIdenticalGridCaseGroup* identicalGridCaseGroup )
RimIdenticalGridCaseGroup* identicalGridCaseGroup,
bool clearGridCalculationMemory )
: m_sourceCases( sourceCases )
, m_statisticsConfig( statisticsConfig )
, m_destinationCase( destinationCase )
, m_reservoirCellCount( 0 )
, m_timeStepIndices( timeStepIndices )
, m_identicalGridCaseGroup( identicalGridCaseGroup )
, m_useZeroAsInactiveCellValue( false )
, m_clearGridCalculationMemory( clearGridCalculationMemory )
{
if ( !sourceCases.empty() )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class RimStatisticsConfig
, m_pMinPos( 10.0 )
, m_pMidPos( 50.0 )
, m_pMaxPos( 90.0 )
, m_pValMethod( RimEclipseStatisticsCase::INTERPOLATED_OBSERVATION )
, m_pValMethod( RimEclipseStatisticsCase::PercentileCalcType::INTERPOLATED_OBSERVATION )
{
}

Expand All @@ -54,10 +54,11 @@ class RimEclipseStatisticsCaseEvaluator
{
public:
RimEclipseStatisticsCaseEvaluator( const std::vector<RimEclipseCase*>& sourceCases,
const std::vector<size_t>& timeStepIndices,
const std::vector<int>& timeStepIndices,
const RimStatisticsConfig& statisticsConfig,
RigEclipseCaseData* destinationCase,
RimIdenticalGridCaseGroup* identicalGridCaseGroup );
RimIdenticalGridCaseGroup* identicalGridCaseGroup,
bool clearGridCalculationMemory );

struct ResSpec
{
Expand Down Expand Up @@ -105,11 +106,12 @@ class RimEclipseStatisticsCaseEvaluator

private:
std::vector<RimEclipseCase*> m_sourceCases;
std::vector<size_t> m_timeStepIndices;
std::vector<int> m_timeStepIndices;

size_t m_reservoirCellCount;
RimStatisticsConfig m_statisticsConfig;
RigEclipseCaseData* m_destinationCase;
RimIdenticalGridCaseGroup* m_identicalGridCaseGroup;
bool m_useZeroAsInactiveCellValue;
bool m_clearGridCalculationMemory;
};
Loading

0 comments on commit 39fc9d5

Please sign in to comment.