mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-27 05:37:21 -05:00
Migrate all assert macros in ApplicationLibCode to CAF_ASSERT and remove every use of cvfAssert.h. CVF_ASSERT is replaced one to one. CVF_TIGHT_ASSERT is also replaced by CAF_ASSERT, which is semantically exact: CVF_ENABLE_TIGHT_ASSERTS is 1 only under _DEBUG, and that is what CAF_ASSERT now does. The two CVF_FAIL_MSG sites become CAF_ASSERT( false && "message" ), preserving the message with the idiom already used elsewhere in the code base. Counts before and after: CVF_ASSERT 1044 to 0, CVF_TIGHT_ASSERT 66 to 0, CVF_FAIL_MSG 2 to 0, cvfAssert.h references 154 to 0. Include handling: files that included cvfAssert.h directly now include cafAssert.h instead, includes left dead by the migration are removed, and files that were relying on cvfAssert.h transitively get an explicit cafAssert.h. Files that reach cafAssert.h through another caf header are left unchanged; a missing include here is a compile error, not a silently disabled assert. ResultStatisticsCache links only LibCore and therefore had no path to cafAssert.h. Add the cafPdmCore directory as a private include path rather than linking the library, since cafAssert.h is header only. Note that this stops these asserts from firing in Release and RelWithDebInfo, where CVF_ASSERT was previously active.
1076 lines
47 KiB
C++
1076 lines
47 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 "RimEclipseStatisticsCase.h"
|
|
|
|
#include "RiaOptionItemFactory.h"
|
|
#include "RiaResultNames.h"
|
|
|
|
#include "RicNewViewFeature.h"
|
|
#include "RicfCommandObject.h"
|
|
|
|
#include "RigCaseCellResultsData.h"
|
|
#include "RigEclipseCaseData.h"
|
|
#include "RigEclipseResultAddress.h"
|
|
#include "Well/RigSimWellData.h"
|
|
|
|
#include "RimCaseCollection.h"
|
|
#include "RimEclipseCellColors.h"
|
|
#include "RimEclipseStatisticsCaseEvaluator.h"
|
|
#include "RimEclipseView.h"
|
|
#include "RimGridCalculationCollection.h"
|
|
#include "RimIntersectionCollection.h"
|
|
#include "RimProject.h"
|
|
#include "RimReservoirCellResultsStorage.h"
|
|
#include "RimReservoirGridEnsembleBase.h"
|
|
#include "RimSimWellInViewCollection.h"
|
|
|
|
#include "RiuMainWindow.h"
|
|
|
|
#include "cafPdmFieldScriptingCapability.h"
|
|
#include "cafPdmUiTextEditor.h"
|
|
#include "cafPdmUiTreeSelectionEditor.h"
|
|
#include "cafProgressInfo.h"
|
|
|
|
namespace caf
|
|
{
|
|
template <>
|
|
void caf::AppEnum<RimEclipseStatisticsCase::PercentileCalcType>::setUp()
|
|
{
|
|
addItem( RimEclipseStatisticsCase::PercentileCalcType::NEAREST_OBSERVATION, "NearestObservationPercentile", "Nearest Observation" );
|
|
addItem( RimEclipseStatisticsCase::PercentileCalcType::HISTOGRAM_ESTIMATED, "HistogramEstimatedPercentile", "Histogram based estimate" );
|
|
addItem( RimEclipseStatisticsCase::PercentileCalcType::INTERPOLATED_OBSERVATION,
|
|
"InterpolatedObservationPercentile",
|
|
"Interpolated Observation" );
|
|
setDefault( RimEclipseStatisticsCase::PercentileCalcType::INTERPOLATED_OBSERVATION );
|
|
}
|
|
template <>
|
|
void caf::AppEnum<RimEclipseStatisticsCase::DataSourceType>::setUp()
|
|
{
|
|
addItem( RimEclipseStatisticsCase::DataSourceType::GRID_CALCULATION, "GridCalculation", "Grid Calculation" );
|
|
addItem( RimEclipseStatisticsCase::DataSourceType::CASE_PROPERTY, "CaseProperty", "Case Property" );
|
|
setDefault( RimEclipseStatisticsCase::DataSourceType::CASE_PROPERTY );
|
|
}
|
|
} // namespace caf
|
|
|
|
CAF_PDM_SOURCE_INIT( RimEclipseStatisticsCase, "RimStatisticalCalculation" );
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimEclipseStatisticsCase::RimEclipseStatisticsCase()
|
|
: RimEclipseCase()
|
|
{
|
|
CAF_PDM_InitScriptableObject( "Case Group Statistics", ":/Histogram16x16.png" );
|
|
|
|
CAF_PDM_InitField( &m_selectionSummary, "SelectionSummary", QString( "" ), "Summary of Calculation Setup" );
|
|
m_selectionSummary.xmlCapability()->disableIO();
|
|
m_selectionSummary.uiCapability()->setUiReadOnly( true );
|
|
m_selectionSummary.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
|
|
m_selectionSummary.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_dataSourceForStatistics, "DataSourceForStatistics", "Data Source" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_gridCalculation, "GridCalculation", "Grid Calculation" );
|
|
CAF_PDM_InitFieldNoDefault( &m_gridCalculationFilterView, "GridCalculationFilterView", "Filter By View" );
|
|
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedTimeSteps, "SelectedTimeSteps", "Time Step Selection" );
|
|
m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
|
|
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_resultType, "ResultType", "Result Type" );
|
|
m_resultType.xmlCapability()->setIOWritable( false );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_porosityModel, "PorosityModel", "Porosity Model" );
|
|
m_porosityModel.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedDynamicProperties, "DynamicPropertiesToCalculate", "Dyn Prop" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedStaticProperties, "StaticPropertiesToCalculate", "Stat Prop" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedGeneratedProperties, "GeneratedPropertiesToCalculate", "" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedInputProperties, "InputPropertiesToCalculate", "" );
|
|
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedFractureDynamicProperties, "FractureDynamicPropertiesToCalculate", "" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedFractureStaticProperties, "FractureStaticPropertiesToCalculate", "" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedFractureGeneratedProperties, "FractureGeneratedPropertiesToCalculate", "" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_selectedFractureInputProperties, "FractureInputPropertiesToCalculate", "" );
|
|
|
|
m_selectedDynamicProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
m_selectedStaticProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
m_selectedGeneratedProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
m_selectedInputProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
|
|
m_selectedFractureDynamicProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
m_selectedFractureStaticProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
m_selectedFractureGeneratedProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
m_selectedFractureInputProperties.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
|
|
|
|
CAF_PDM_InitScriptableField( &m_calculatePercentiles, "CalculatePercentiles", true, "Calculate Percentiles" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_percentileCalculationType, "PercentileCalculationType", "Method" );
|
|
|
|
CAF_PDM_InitScriptableField( &m_lowPercentile, "LowPercentile", 10.0, "Low" );
|
|
CAF_PDM_InitScriptableField( &m_midPercentile, "MidPercentile", 50.0, "Mid" );
|
|
CAF_PDM_InitScriptableField( &m_highPercentile, "HighPercentile", 90.0, "High" );
|
|
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_wellDataSourceCase, "WellDataSourceCasePtr", "Well Data Source Case" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &obsoleteField_wellDataSourceCase, "WellDataSourceCase", "Well Data Source Case" );
|
|
obsoleteField_wellDataSourceCase.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitScriptableField( &m_useZeroAsInactiveCellValue, "UseZeroAsInactiveCellValue", false, "Use Zero as Inactive Cell Value" );
|
|
|
|
m_populateSelectionAfterLoadingGrid = false;
|
|
|
|
// These does not work properly for statistics case, so hide for now
|
|
m_flipXAxis.uiCapability()->setUiHidden( true );
|
|
m_flipYAxis.uiCapability()->setUiHidden( true );
|
|
m_activeFormationNames.uiCapability()->setUiHidden( true );
|
|
|
|
m_displayNameOption = RimCaseDisplayNameTools::DisplayName::CUSTOM;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimEclipseStatisticsCase::~RimEclipseStatisticsCase()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::initAfterRead()
|
|
{
|
|
RimEclipseCase::initAfterRead();
|
|
|
|
if ( !obsoleteField_wellDataSourceCase().isEmpty() && obsoleteField_wellDataSourceCase() != RiaResultNames::undefinedResultName() )
|
|
{
|
|
auto* owner = gridEnsembleBase();
|
|
if ( owner )
|
|
{
|
|
for ( auto* sourceCase : owner->sourceCases() )
|
|
{
|
|
if ( sourceCase->caseUserDescription() == obsoleteField_wellDataSourceCase() )
|
|
{
|
|
m_wellDataSourceCase = sourceCase;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
obsoleteField_wellDataSourceCase = "";
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::setMainGrid( RigMainGrid* mainGrid )
|
|
{
|
|
CAF_ASSERT( mainGrid );
|
|
CAF_ASSERT( eclipseCaseData() );
|
|
|
|
eclipseCaseData()->setMainGrid( mainGrid );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimEclipseStatisticsCase::openEclipseGridFile()
|
|
{
|
|
if ( eclipseCaseData() ) return true;
|
|
|
|
auto* ensembleBase = gridEnsembleBase();
|
|
if ( !ensembleBase ) return false;
|
|
|
|
RigMainGrid* mainGrid = ensembleBase->mainGrid();
|
|
if ( !mainGrid ) return false;
|
|
|
|
cvf::ref<RigEclipseCaseData> eclipseCase = new RigEclipseCaseData( this );
|
|
eclipseCase->setMainGrid( mainGrid );
|
|
|
|
eclipseCase->setActiveCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL,
|
|
ensembleBase->unionOfActiveCells( RiaDefines::PorosityModelType::MATRIX_MODEL ) );
|
|
eclipseCase->setActiveCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
|
ensembleBase->unionOfActiveCells( RiaDefines::PorosityModelType::FRACTURE_MODEL ) );
|
|
|
|
setReservoirData( eclipseCase.p() );
|
|
|
|
computeCachedData();
|
|
|
|
loadSimulationWellDataFromSourceCase();
|
|
|
|
if ( m_populateSelectionAfterLoadingGrid )
|
|
{
|
|
populateResultSelection();
|
|
|
|
m_populateSelectionAfterLoadingGrid = false;
|
|
}
|
|
|
|
initializeSelectedTimeSteps();
|
|
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimCaseCollection* RimEclipseStatisticsCase::parentStatisticsCaseCollection() const
|
|
{
|
|
return dynamic_cast<RimCaseCollection*>( parentField()->ownerObject() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::populateResultSelectionAfterLoadingGrid()
|
|
{
|
|
m_populateSelectionAfterLoadingGrid = true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::setSourceProperties( RiaDefines::ResultCatType propertyType, const std::vector<QString>& propertyNames )
|
|
{
|
|
switch ( propertyType )
|
|
{
|
|
case RiaDefines::ResultCatType::DYNAMIC_NATIVE:
|
|
m_selectedDynamicProperties = propertyNames;
|
|
break;
|
|
case RiaDefines::ResultCatType::STATIC_NATIVE:
|
|
m_selectedStaticProperties = propertyNames;
|
|
break;
|
|
case RiaDefines::ResultCatType::SOURSIMRL:
|
|
break;
|
|
case RiaDefines::ResultCatType::GENERATED:
|
|
m_selectedGeneratedProperties = propertyNames;
|
|
break;
|
|
case RiaDefines::ResultCatType::INPUT_PROPERTY:
|
|
m_selectedInputProperties = propertyNames;
|
|
break;
|
|
case RiaDefines::ResultCatType::FORMATION_NAMES:
|
|
break;
|
|
case RiaDefines::ResultCatType::ALLAN_DIAGRAMS:
|
|
break;
|
|
case RiaDefines::ResultCatType::FLOW_DIAGNOSTICS:
|
|
break;
|
|
case RiaDefines::ResultCatType::INJECTION_FLOODING:
|
|
break;
|
|
case RiaDefines::ResultCatType::REMOVED:
|
|
break;
|
|
case RiaDefines::ResultCatType::UNDEFINED:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::selectAllTimeSteps()
|
|
{
|
|
auto* ensembleBase = gridEnsembleBase();
|
|
if ( !ensembleBase ) return;
|
|
|
|
if ( RimEclipseCase* mainCase = ensembleBase->mainCase() )
|
|
{
|
|
int timeStepCount = mainCase->timeStepStrings().size();
|
|
|
|
if ( timeStepCount > 0 )
|
|
{
|
|
std::vector<int> allTimeSteps;
|
|
allTimeSteps.resize( timeStepCount );
|
|
std::iota( allTimeSteps.begin(), allTimeSteps.end(), 0 );
|
|
m_selectedTimeSteps = allTimeSteps;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::setWellDataSourceCase( RimEclipseCase* sourceCase )
|
|
{
|
|
m_wellDataSourceCase = sourceCase;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::computeStatistics()
|
|
{
|
|
if ( eclipseCaseData() == nullptr )
|
|
{
|
|
openEclipseGridFile();
|
|
}
|
|
|
|
auto* ensembleBase = gridEnsembleBase();
|
|
if ( !ensembleBase ) return;
|
|
|
|
ensembleBase->computeUnionOfActiveCells();
|
|
|
|
std::vector<RimEclipseCase*> sourceCases = getSourceCases();
|
|
|
|
if ( m_dataSourceForStatistics() == DataSourceType::GRID_CALCULATION && m_gridCalculation() )
|
|
{
|
|
auto proj = RimProject::current();
|
|
auto calcColl = proj->gridCalculationCollection();
|
|
|
|
auto dependentCalculations = calcColl->dependentCalculations( m_gridCalculation() );
|
|
if ( dependentCalculations.empty() )
|
|
{
|
|
// No calculations found, usually triggered by a circular dependency of calculations. Error message displayed by
|
|
// dependentCalculations().
|
|
return;
|
|
}
|
|
|
|
std::vector<size_t> timeStepIndices( m_selectedTimeSteps().begin(), m_selectedTimeSteps().end() );
|
|
|
|
for ( auto calc : dependentCalculations )
|
|
{
|
|
cvf::UByteArray* inputValueVisibilityFilter = nullptr;
|
|
if ( m_gridCalculationFilterView() )
|
|
{
|
|
inputValueVisibilityFilter = m_gridCalculationFilterView()->currentTotalCellVisibility().p();
|
|
}
|
|
|
|
bool evaluateDependentCalculations = false;
|
|
calc->calculateForCases( sourceCases, inputValueVisibilityFilter, timeStepIndices, evaluateDependentCalculations );
|
|
}
|
|
}
|
|
|
|
if ( sourceCases.empty() || !sourceCases.at( 0 )->results( RiaDefines::PorosityModelType::MATRIX_MODEL ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
RimStatisticsConfig statisticsConfig;
|
|
|
|
statisticsConfig.m_calculatePercentiles = m_calculatePercentiles();
|
|
statisticsConfig.m_pMaxPos = m_highPercentile();
|
|
statisticsConfig.m_pMidPos = m_midPercentile();
|
|
statisticsConfig.m_pMinPos = m_lowPercentile();
|
|
statisticsConfig.m_pValMethod = m_percentileCalculationType();
|
|
|
|
auto timeStepIndices = m_selectedTimeSteps();
|
|
|
|
// If no dynamic data is present, we might end up with no time steps. Make sure we have at least one.
|
|
if ( timeStepIndices.empty() )
|
|
{
|
|
timeStepIndices.push_back( 0 );
|
|
}
|
|
|
|
RigEclipseCaseData* resultCase = eclipseCaseData();
|
|
|
|
QList<RimEclipseStatisticsCaseEvaluator::ResSpec> resultSpecification;
|
|
|
|
if ( m_dataSourceForStatistics() == DataSourceType::CASE_PROPERTY )
|
|
{
|
|
for ( size_t pIdx = 0; pIdx < m_selectedDynamicProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::MATRIX_MODEL,
|
|
RiaDefines::ResultCatType::DYNAMIC_NATIVE,
|
|
m_selectedDynamicProperties()[pIdx] ) );
|
|
}
|
|
|
|
for ( size_t pIdx = 0; pIdx < m_selectedStaticProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::MATRIX_MODEL,
|
|
RiaDefines::ResultCatType::STATIC_NATIVE,
|
|
m_selectedStaticProperties()[pIdx] ) );
|
|
}
|
|
|
|
for ( size_t pIdx = 0; pIdx < m_selectedGeneratedProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::MATRIX_MODEL,
|
|
RiaDefines::ResultCatType::GENERATED,
|
|
m_selectedGeneratedProperties()[pIdx] ) );
|
|
}
|
|
|
|
for ( size_t pIdx = 0; pIdx < m_selectedInputProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::MATRIX_MODEL,
|
|
RiaDefines::ResultCatType::INPUT_PROPERTY,
|
|
m_selectedInputProperties()[pIdx] ) );
|
|
}
|
|
|
|
for ( size_t pIdx = 0; pIdx < m_selectedFractureDynamicProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
|
RiaDefines::ResultCatType::DYNAMIC_NATIVE,
|
|
m_selectedFractureDynamicProperties()[pIdx] ) );
|
|
}
|
|
|
|
for ( size_t pIdx = 0; pIdx < m_selectedFractureStaticProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
|
RiaDefines::ResultCatType::STATIC_NATIVE,
|
|
m_selectedFractureStaticProperties()[pIdx] ) );
|
|
}
|
|
|
|
for ( size_t pIdx = 0; pIdx < m_selectedFractureGeneratedProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
|
RiaDefines::ResultCatType::GENERATED,
|
|
m_selectedFractureGeneratedProperties()[pIdx] ) );
|
|
}
|
|
|
|
for ( size_t pIdx = 0; pIdx < m_selectedFractureInputProperties().size(); ++pIdx )
|
|
{
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
|
RiaDefines::ResultCatType::INPUT_PROPERTY,
|
|
m_selectedFractureInputProperties()[pIdx] ) );
|
|
}
|
|
}
|
|
else if ( m_dataSourceForStatistics() == DataSourceType::GRID_CALCULATION && m_gridCalculation() )
|
|
{
|
|
auto calculationName = m_gridCalculation->shortName();
|
|
|
|
resultSpecification.append( RimEclipseStatisticsCaseEvaluator::ResSpec( RiaDefines::PorosityModelType::MATRIX_MODEL,
|
|
RiaDefines::ResultCatType::GENERATED,
|
|
calculationName ) );
|
|
}
|
|
|
|
bool clearGridCalculationMemory = m_dataSourceForStatistics() == DataSourceType::GRID_CALCULATION;
|
|
RimEclipseStatisticsCaseEvaluator stat( sourceCases,
|
|
timeStepIndices,
|
|
statisticsConfig,
|
|
resultCase,
|
|
ensembleBase->unionOfActiveCells( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
|
ensembleBase->unionOfActiveCells( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
|
clearGridCalculationMemory );
|
|
|
|
if ( m_useZeroAsInactiveCellValue )
|
|
{
|
|
stat.useZeroAsValueForInActiveCellsBasedOnUnionOfActiveCells();
|
|
}
|
|
|
|
stat.evaluateForResults( resultSpecification, m_gridCalculationFilterView() );
|
|
}
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::scheduleACTIVEGeometryRegenOnReservoirViews()
|
|
{
|
|
for ( RimEclipseView* reservoirView : reservoirViews() )
|
|
{
|
|
CAF_ASSERT( reservoirView );
|
|
reservoirView->scheduleGeometryRegen( ACTIVE );
|
|
}
|
|
}
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<RimEclipseCase*> RimEclipseStatisticsCase::getSourceCases() const
|
|
{
|
|
auto* ensembleBase = gridEnsembleBase();
|
|
if ( !ensembleBase ) return {};
|
|
|
|
return ensembleBase->sourceCases();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimReservoirGridEnsembleBase* RimEclipseStatisticsCase::gridEnsembleBase() const
|
|
{
|
|
if ( RimCaseCollection* parentCollection = parentStatisticsCaseCollection() )
|
|
{
|
|
return parentCollection->parentGridEnsembleBase();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
|
{
|
|
updateSelectionSummaryLabel();
|
|
updateSelectionListVisibilities();
|
|
updatePercentileUiVisibility();
|
|
|
|
uiOrdering.add( &m_caseUserDescription );
|
|
uiOrdering.add( &m_caseId );
|
|
|
|
QString buttonText = hasComputedStatistics() ? "Edit (Will DELETE current results)" : "Compute";
|
|
uiOrdering.addNewButton( buttonText,
|
|
[this]()
|
|
{
|
|
if ( hasComputedStatistics() )
|
|
{
|
|
clearComputedStatistics();
|
|
}
|
|
else
|
|
{
|
|
computeStatisticsAndUpdateViews();
|
|
}
|
|
} );
|
|
|
|
{
|
|
caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Summary of Calculation Setup" );
|
|
group->add( &m_useZeroAsInactiveCellValue );
|
|
m_useZeroAsInactiveCellValue.uiCapability()->setUiHidden( hasComputedStatistics() );
|
|
group->add( &m_selectionSummary );
|
|
}
|
|
|
|
{
|
|
auto group = uiOrdering.addNewGroup( "Properties to consider" );
|
|
group->setUiHidden( hasComputedStatistics() );
|
|
group->add( &m_dataSourceForStatistics );
|
|
|
|
if ( m_dataSourceForStatistics() == DataSourceType::GRID_CALCULATION )
|
|
{
|
|
group->add( &m_gridCalculation );
|
|
group->add( &m_gridCalculationFilterView );
|
|
}
|
|
else
|
|
{
|
|
group->add( &m_resultType );
|
|
group->add( &m_porosityModel );
|
|
group->add( &m_selectedDynamicProperties );
|
|
group->add( &m_selectedStaticProperties );
|
|
group->add( &m_selectedGeneratedProperties );
|
|
group->add( &m_selectedInputProperties );
|
|
group->add( &m_selectedFractureDynamicProperties );
|
|
group->add( &m_selectedFractureStaticProperties );
|
|
group->add( &m_selectedFractureGeneratedProperties );
|
|
group->add( &m_selectedFractureInputProperties );
|
|
}
|
|
}
|
|
|
|
{
|
|
auto group = uiOrdering.addNewGroup( "Time Step Selection" );
|
|
group->setCollapsedByDefault();
|
|
group->add( &m_selectedTimeSteps );
|
|
}
|
|
|
|
{
|
|
auto group = uiOrdering.addNewGroup( "Percentile setup" );
|
|
group->setUiHidden( hasComputedStatistics() );
|
|
group->add( &m_calculatePercentiles );
|
|
group->add( &m_percentileCalculationType );
|
|
group->add( &m_lowPercentile );
|
|
group->add( &m_midPercentile );
|
|
group->add( &m_highPercentile );
|
|
}
|
|
|
|
{
|
|
auto group = uiOrdering.addNewGroup( "Case Options" );
|
|
group->add( &m_wellDataSourceCase );
|
|
group->add( &m_activeFormationNames );
|
|
group->add( &m_flipXAxis );
|
|
group->add( &m_flipYAxis );
|
|
}
|
|
|
|
uiOrdering.skipRemainingFields();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QList<caf::PdmOptionItemInfo> RimEclipseStatisticsCase::toOptionList( const QStringList& varList )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> optionList;
|
|
int i;
|
|
for ( i = 0; i < varList.size(); ++i )
|
|
{
|
|
optionList.push_back( caf::PdmOptionItemInfo( varList[i], varList[i] ) );
|
|
}
|
|
return optionList;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QList<caf::PdmOptionItemInfo> RimEclipseStatisticsCase::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
|
|
{
|
|
auto* ensembleBase = gridEnsembleBase();
|
|
if ( !ensembleBase ) return {};
|
|
|
|
RimEclipseCase* mainCase = ensembleBase->mainCase();
|
|
if ( !( mainCase && mainCase->eclipseCaseData() ) )
|
|
{
|
|
return {};
|
|
}
|
|
|
|
if ( &m_dataSourceForStatistics == fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
{
|
|
caf::IconProvider iconProvider( ":/Case48x48.png" );
|
|
options.push_back( caf::PdmOptionItemInfo( caf::AppEnum<DataSourceType>::uiText( DataSourceType::CASE_PROPERTY ),
|
|
DataSourceType::CASE_PROPERTY,
|
|
false,
|
|
iconProvider ) );
|
|
}
|
|
{
|
|
caf::IconProvider iconProvider( ":/Calculator.svg" );
|
|
options.push_back( caf::PdmOptionItemInfo( caf::AppEnum<DataSourceType>::uiText( DataSourceType::GRID_CALCULATION ),
|
|
DataSourceType::GRID_CALCULATION,
|
|
false,
|
|
iconProvider ) );
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
if ( &m_gridCalculation == fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
for ( auto calc : RimProject::current()->gridCalculationCollection()->calculations() )
|
|
{
|
|
options.push_back( caf::PdmOptionItemInfo( calc->shortName(), calc ) );
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
RigEclipseCaseData* caseData = mainCase->eclipseCaseData();
|
|
|
|
if ( &m_selectedTimeSteps == fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
const auto timeStepStrings = mainCase->timeStepStrings();
|
|
|
|
int index = 0;
|
|
for ( const auto& text : timeStepStrings )
|
|
{
|
|
options.push_back( caf::PdmOptionItemInfo( text, index++ ) );
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
if ( &m_gridCalculationFilterView == fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) );
|
|
|
|
for ( const auto& view : views() )
|
|
{
|
|
RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName( view, &options );
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
if ( &m_selectedDynamicProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->resultNames( RiaDefines::ResultCatType::DYNAMIC_NATIVE );
|
|
return toOptionList( varList );
|
|
}
|
|
else if ( &m_selectedStaticProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->resultNames( RiaDefines::ResultCatType::STATIC_NATIVE );
|
|
return toOptionList( varList );
|
|
}
|
|
else if ( &m_selectedGeneratedProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->resultNames( RiaDefines::ResultCatType::GENERATED );
|
|
return toOptionList( varList );
|
|
}
|
|
else if ( &m_selectedInputProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->resultNames( RiaDefines::ResultCatType::INPUT_PROPERTY );
|
|
return toOptionList( varList );
|
|
}
|
|
else if ( &m_selectedFractureDynamicProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->resultNames( RiaDefines::ResultCatType::DYNAMIC_NATIVE );
|
|
return toOptionList( varList );
|
|
}
|
|
else if ( &m_selectedFractureStaticProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->resultNames( RiaDefines::ResultCatType::STATIC_NATIVE );
|
|
return toOptionList( varList );
|
|
}
|
|
else if ( &m_selectedFractureGeneratedProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->resultNames( RiaDefines::ResultCatType::GENERATED );
|
|
return toOptionList( varList );
|
|
}
|
|
else if ( &m_selectedFractureInputProperties == fieldNeedingOptions )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->resultNames( RiaDefines::ResultCatType::INPUT_PROPERTY );
|
|
return toOptionList( varList );
|
|
}
|
|
|
|
else if ( &m_wellDataSourceCase == fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
options.push_back( caf::PdmOptionItemInfo( RiaResultNames::undefinedResultName(), nullptr ) );
|
|
|
|
for ( auto* sourceCase : ensembleBase->sourceCases() )
|
|
{
|
|
options.push_back( caf::PdmOptionItemInfo( sourceCase->caseUserDescription(), sourceCase ) );
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
return RimEclipseCase::calculateValueOptions( fieldNeedingOptions );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
|
{
|
|
RimEclipseCase::fieldChangedByUi( changedField, oldValue, newValue );
|
|
|
|
if ( &m_resultType == changedField || &m_porosityModel == changedField )
|
|
{
|
|
}
|
|
|
|
if ( &m_dataSourceForStatistics == changedField && m_gridCalculation() == nullptr )
|
|
{
|
|
auto calculations = RimProject::current()->gridCalculationCollection()->calculations();
|
|
if ( !calculations.empty() )
|
|
{
|
|
m_gridCalculation = dynamic_cast<RimGridCalculation*>( calculations.front() );
|
|
}
|
|
}
|
|
|
|
if ( &m_wellDataSourceCase == changedField )
|
|
{
|
|
loadSimulationWellDataFromSourceCase();
|
|
|
|
caf::ProgressInfo progInfo( reservoirViews().size() + 1, "Updating Well Data for Views" );
|
|
|
|
// Update views
|
|
for ( RimEclipseView* reservoirView : reservoirViews() )
|
|
{
|
|
CAF_ASSERT( reservoirView );
|
|
|
|
reservoirView->wellCollection()->wells.deleteChildren();
|
|
reservoirView->updateDisplayModelForWellResults();
|
|
reservoirView->wellCollection()->updateConnectedEditors();
|
|
|
|
progInfo.incrementProgress();
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::loadSimulationWellDataFromSourceCase()
|
|
{
|
|
RimEclipseCase* sourceResultCase = m_wellDataSourceCase();
|
|
if ( sourceResultCase )
|
|
{
|
|
sourceResultCase->openEclipseGridFile();
|
|
|
|
// Propagate well info to statistics case
|
|
if ( sourceResultCase->eclipseCaseData() )
|
|
{
|
|
const cvf::Collection<RigSimWellData>& sourceCaseSimWellData = sourceResultCase->eclipseCaseData()->wellResults();
|
|
|
|
eclipseCaseData()->setSimWellData( sourceCaseSimWellData );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cvf::Collection<RigSimWellData> sourceCaseWellResults;
|
|
eclipseCaseData()->setSimWellData( sourceCaseWellResults );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void addPropertySetToHtmlText( QString& html, const QString& heading, const std::vector<QString>& varNames )
|
|
{
|
|
if ( !varNames.empty() )
|
|
{
|
|
html += "<p><b>" + heading + "</b></p>";
|
|
html += "<p class=indent>";
|
|
for ( size_t pIdx = 0; pIdx < varNames.size(); ++pIdx )
|
|
{
|
|
html += varNames[pIdx];
|
|
if ( ( pIdx + 1 ) % 6 == 0 )
|
|
html += "<br>";
|
|
else if ( pIdx != varNames.size() - 1 )
|
|
html += ", ";
|
|
}
|
|
html += "</p>";
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::updateSelectionSummaryLabel()
|
|
{
|
|
QString html;
|
|
|
|
html += "<style> "
|
|
"p{ margin-top:0px; margin-bottom:0px;} "
|
|
"p.indent{margin-left:20px; margin-top:0px;} "
|
|
"p.indent2{margin-left:40px; margin-top:0px;} "
|
|
"</style>";
|
|
|
|
html += "<p><b>Statistical variables to compute:</b></p>";
|
|
html += "<p class=indent>";
|
|
html += "Min, Max, Sum, Range, Mean, Std.dev";
|
|
;
|
|
if ( m_calculatePercentiles() )
|
|
{
|
|
html += "<br>";
|
|
html += "Percentiles for : " + QString::number( m_lowPercentile() ) + ", " + QString::number( m_midPercentile() ) + ", " +
|
|
QString::number( m_highPercentile() );
|
|
}
|
|
html += "</p>";
|
|
|
|
if ( m_dataSourceForStatistics() == DataSourceType::CASE_PROPERTY )
|
|
{
|
|
addPropertySetToHtmlText( html, "Dynamic properties", m_selectedDynamicProperties() );
|
|
addPropertySetToHtmlText( html, "Static properties", m_selectedStaticProperties() );
|
|
addPropertySetToHtmlText( html, "Generated properties", m_selectedGeneratedProperties() );
|
|
addPropertySetToHtmlText( html, "Input properties", m_selectedInputProperties() );
|
|
|
|
addPropertySetToHtmlText( html, "Dynamic properties, fracture model", m_selectedFractureDynamicProperties() );
|
|
addPropertySetToHtmlText( html, "Static properties, fracture model", m_selectedFractureStaticProperties() );
|
|
addPropertySetToHtmlText( html, "Generated properties, fracture model", m_selectedFractureGeneratedProperties() );
|
|
addPropertySetToHtmlText( html, "Input properties, fracture model", m_selectedFractureInputProperties() );
|
|
}
|
|
|
|
if ( m_dataSourceForStatistics() == DataSourceType::GRID_CALCULATION && m_gridCalculation() )
|
|
{
|
|
html += "<p><b>Grid calculation:</b></p>";
|
|
html += "<p class=indent>";
|
|
html += m_gridCalculation()->shortName();
|
|
html += "</p>";
|
|
}
|
|
|
|
m_selectionSummary = html;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
|
{
|
|
if ( &m_selectionSummary == field )
|
|
{
|
|
caf::PdmUiTextEditorAttribute* textEditAttrib = dynamic_cast<caf::PdmUiTextEditorAttribute*>( attribute );
|
|
if ( textEditAttrib )
|
|
{
|
|
textEditAttrib->textMode = caf::PdmUiTextEditorAttribute::HTML;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::initializeSelectedTimeSteps()
|
|
{
|
|
if ( RimProject::current()->isProjectFileVersionEqualOrOlderThan( "2023.10.0" ) )
|
|
{
|
|
selectAllTimeSteps();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::updateSelectionListVisibilities()
|
|
{
|
|
bool isLocked = hasComputedStatistics();
|
|
m_resultType.uiCapability()->setUiHidden( isLocked );
|
|
m_porosityModel.uiCapability()->setUiHidden( isLocked );
|
|
|
|
m_selectedDynamicProperties.uiCapability()->setUiHidden( isLocked || m_porosityModel() != RiaDefines::PorosityModelType::MATRIX_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::DYNAMIC_NATIVE );
|
|
m_selectedStaticProperties.uiCapability()->setUiHidden( isLocked || m_porosityModel() != RiaDefines::PorosityModelType::MATRIX_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::STATIC_NATIVE );
|
|
m_selectedGeneratedProperties.uiCapability()->setUiHidden( isLocked || m_porosityModel() != RiaDefines::PorosityModelType::MATRIX_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::GENERATED );
|
|
m_selectedInputProperties.uiCapability()->setUiHidden( isLocked || m_porosityModel() != RiaDefines::PorosityModelType::MATRIX_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::INPUT_PROPERTY );
|
|
|
|
m_selectedFractureDynamicProperties.uiCapability()->setUiHidden( isLocked ||
|
|
m_porosityModel() != RiaDefines::PorosityModelType::FRACTURE_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::DYNAMIC_NATIVE );
|
|
m_selectedFractureStaticProperties.uiCapability()->setUiHidden( isLocked ||
|
|
m_porosityModel() != RiaDefines::PorosityModelType::FRACTURE_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::STATIC_NATIVE );
|
|
m_selectedFractureGeneratedProperties.uiCapability()->setUiHidden( isLocked ||
|
|
m_porosityModel() != RiaDefines::PorosityModelType::FRACTURE_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::GENERATED );
|
|
m_selectedFractureInputProperties.uiCapability()->setUiHidden( isLocked ||
|
|
m_porosityModel() != RiaDefines::PorosityModelType::FRACTURE_MODEL ||
|
|
m_resultType() != RiaDefines::ResultCatType::INPUT_PROPERTY );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::updatePercentileUiVisibility()
|
|
{
|
|
bool isLocked = hasComputedStatistics();
|
|
m_calculatePercentiles.uiCapability()->setUiHidden( isLocked );
|
|
m_percentileCalculationType.uiCapability()->setUiHidden( isLocked || !m_calculatePercentiles() );
|
|
m_lowPercentile.uiCapability()->setUiHidden( isLocked || !m_calculatePercentiles() );
|
|
m_midPercentile.uiCapability()->setUiHidden( isLocked || !m_calculatePercentiles() );
|
|
m_highPercentile.uiCapability()->setUiHidden( isLocked || !m_calculatePercentiles() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimEclipseStatisticsCase::hasComputedStatistics() const
|
|
{
|
|
return eclipseCaseData() && ( !eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->existingResults().empty() ||
|
|
!eclipseCaseData()->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->existingResults().empty() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::updateConnectedEditorsAndReservoirViews()
|
|
{
|
|
auto views = reservoirViews();
|
|
for ( RimEclipseView* view : reservoirViews() )
|
|
{
|
|
// As new result might have been introduced, update all editors connected
|
|
view->cellResult()->updateConnectedEditors();
|
|
|
|
// It is usually not needed to create new display model, but if any derived geometry based on generated data
|
|
// (from Octave) a full display model rebuild is required
|
|
view->scheduleCreateDisplayModelAndRedraw();
|
|
view->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews();
|
|
}
|
|
|
|
updateConnectedEditors();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::clearComputedStatistics()
|
|
{
|
|
if ( eclipseCaseData() && eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL ) )
|
|
{
|
|
eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->clearAllResults();
|
|
}
|
|
|
|
if ( eclipseCaseData() && eclipseCaseData()->results( RiaDefines::PorosityModelType::FRACTURE_MODEL ) )
|
|
{
|
|
eclipseCaseData()->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->clearAllResults();
|
|
}
|
|
|
|
updateConnectedEditorsAndReservoirViews();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::computeStatisticsAndUpdateViews()
|
|
{
|
|
if ( getSourceCases().empty() ) return;
|
|
|
|
computeStatistics();
|
|
scheduleACTIVEGeometryRegenOnReservoirViews();
|
|
updateConnectedEditorsAndReservoirViews();
|
|
|
|
if ( reservoirViews().empty() )
|
|
{
|
|
RicNewViewFeature::addReservoirView( this, nullptr, viewCollection() );
|
|
}
|
|
|
|
if ( reservoirViews().size() == 1 )
|
|
{
|
|
// If only one view, set the first result as active
|
|
|
|
if ( auto cellResultsData = results( RiaDefines::PorosityModelType::MATRIX_MODEL ) )
|
|
{
|
|
auto firstView = reservoirViews()[0];
|
|
|
|
std::vector<RigEclipseResultAddress> resAddresses = cellResultsData->existingResults();
|
|
if ( firstView && !resAddresses.empty() )
|
|
{
|
|
firstView->cellResult()->setFromEclipseResultAddress( resAddresses[0] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimEclipseStatisticsCase::populateResultSelection()
|
|
{
|
|
auto* ensembleBase = gridEnsembleBase();
|
|
if ( !ensembleBase ) return;
|
|
|
|
RimEclipseCase* mainCase = ensembleBase->mainCase();
|
|
if ( !( mainCase && mainCase->eclipseCaseData() ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
RigEclipseCaseData* caseData = mainCase->eclipseCaseData();
|
|
|
|
if ( m_selectedDynamicProperties().empty() )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->resultNames( RiaDefines::ResultCatType::DYNAMIC_NATIVE );
|
|
if ( varList.contains( RiaResultNames::soil() ) ) m_selectedDynamicProperties.v().push_back( RiaResultNames::soil() );
|
|
if ( varList.contains( "PRESSURE" ) ) m_selectedDynamicProperties.v().push_back( "PRESSURE" );
|
|
}
|
|
|
|
if ( m_selectedStaticProperties().empty() )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->resultNames( RiaDefines::ResultCatType::STATIC_NATIVE );
|
|
if ( varList.contains( "PERMX" ) ) m_selectedStaticProperties.v().push_back( "PERMX" );
|
|
if ( varList.contains( "PORO" ) ) m_selectedStaticProperties.v().push_back( "PORO" );
|
|
}
|
|
|
|
if ( m_selectedFractureDynamicProperties().empty() )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->resultNames( RiaDefines::ResultCatType::DYNAMIC_NATIVE );
|
|
if ( varList.contains( RiaResultNames::soil() ) ) m_selectedFractureDynamicProperties.v().push_back( RiaResultNames::soil() );
|
|
if ( varList.contains( "PRESSURE" ) ) m_selectedFractureDynamicProperties.v().push_back( "PRESSURE" );
|
|
}
|
|
|
|
if ( m_selectedFractureStaticProperties().empty() )
|
|
{
|
|
QStringList varList =
|
|
caseData->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->resultNames( RiaDefines::ResultCatType::STATIC_NATIVE );
|
|
if ( varList.contains( "PERMX" ) ) m_selectedFractureStaticProperties.v().push_back( "PERMX" );
|
|
if ( varList.contains( "PORO" ) ) m_selectedFractureStaticProperties.v().push_back( "PORO" );
|
|
}
|
|
}
|