mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-31 09:14:11 -05:00
Fix crashes reported by crash telemetry
* Recompute well cell arrays when the grids change computeWellCellsPrGrid() returned early whenever the arrays had been computed once, so the size check below it was unreachable and a stale array was kept when the grids changed. The too-short array triggered an assert in RivReservoirViewPartMgr::computeNativeVisibility. Return early only when the cached arrays still match the current set of grids. * Guard against missing GUI application when applying style sheet RiaGuiApplication::instance() does a dynamic_cast and returns null outside a GUI context. The assert guarding this is compiled out in release, so the null pointer was dereferenced. * Guard against missing case in flow characteristics plot field change The case field can be set to nothing from the UI. RimEclipseResultCase::defaultFlowDiagSolution() and reservoirViews() were then called on a null pointer. * Guard against missing case and out of range time steps when updating flow characteristics plot onLoadDataAndUpdate() dereferenced the case without checking, although the same function handles a missing case further down. The time step indices come from the flow diagnostics solution, and were used to index arrays sized by the number of case time steps without a range check.
This commit is contained in:
1 parent
ebf75c09a1
commit
318659e130
5 files changed
+70
-12
No files matched your search
@@ -563,9 +563,10 @@ void RimFlowCharacteristicsPlot::fieldChangedByUi( const caf::PdmFieldHandle* ch
|
||||
|
||||
if ( &m_case == changedField )
|
||||
{
|
||||
m_flowDiagSolution = m_case->defaultFlowDiagSolution();
|
||||
// The case field can be set to nothing from the UI
|
||||
m_flowDiagSolution = m_case() ? m_case()->defaultFlowDiagSolution() : nullptr;
|
||||
m_currentlyPlottedTimeSteps.clear();
|
||||
if ( !m_case()->reservoirViews().empty() )
|
||||
if ( m_case() && !m_case()->reservoirViews().empty() )
|
||||
{
|
||||
m_cellFilterView = m_case()->reservoirViews()[0];
|
||||
}
|
||||
@@ -607,9 +608,15 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
|
||||
m_currentlyPlottedTimeSteps = calculatedTimesteps;
|
||||
}
|
||||
|
||||
std::vector<QDateTime> timeStepDates = m_case->timeStepDates();
|
||||
QStringList timeStepStrings = m_case->timeStepStrings();
|
||||
std::vector<double> lorenzVals( timeStepDates.size(), HUGE_VAL );
|
||||
// The case can be missing, as the case field can be set to nothing from the UI
|
||||
std::vector<QDateTime> timeStepDates;
|
||||
QStringList timeStepStrings;
|
||||
if ( m_case() )
|
||||
{
|
||||
timeStepDates = m_case()->timeStepDates();
|
||||
timeStepStrings = m_case()->timeStepStrings();
|
||||
}
|
||||
std::vector<double> lorenzVals( timeStepDates.size(), HUGE_VAL );
|
||||
|
||||
m_flowCharPlotWidget->removeAllCurves();
|
||||
|
||||
@@ -660,7 +667,11 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
|
||||
m_maxTof() );
|
||||
timeStepToFlowResultMap[timeStepIdx] = flowCharResults;
|
||||
}
|
||||
lorenzVals[timeStepIdx] = timeStepToFlowResultMap[timeStepIdx].m_lorenzCoefficient;
|
||||
// The time step indices are given by the flow diagnostics solution, and can be out of range for the case
|
||||
if ( timeStepIdx >= 0 && static_cast<size_t>( timeStepIdx ) < lorenzVals.size() )
|
||||
{
|
||||
lorenzVals[timeStepIdx] = timeStepToFlowResultMap[timeStepIdx].m_lorenzCoefficient;
|
||||
}
|
||||
}
|
||||
|
||||
m_timeStepToFlowResultMap = timeStepToFlowResultMap;
|
||||
@@ -678,6 +689,8 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
|
||||
|
||||
for ( int timeStepIdx : m_currentlyPlottedTimeSteps )
|
||||
{
|
||||
if ( timeStepIdx < 0 || static_cast<size_t>( timeStepIdx ) >= timeStepDates.size() ) continue;
|
||||
|
||||
const auto& flowCharResults = timeStepToFlowResultMap[timeStepIdx];
|
||||
|
||||
m_flowCharPlotWidget->addFlowCapStorageCapCurve( timeStepDates[timeStepIdx],
|
||||
|
||||
@@ -185,17 +185,34 @@ size_t RigEclipseCaseData::gridCount() const
|
||||
return m_mainGrid->gridCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The cached well cell arrays are indexed by grid cell index, and are only valid as long as they
|
||||
/// have one array per grid sized to match the cell count of that grid.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigEclipseCaseData::isWellCellsPrGridUpToDate( const std::vector<RigGridBase*>& grids ) const
|
||||
{
|
||||
if ( m_wellCellsInGrid.size() != grids.size() ) return false;
|
||||
|
||||
for ( size_t gIdx = 0; gIdx < grids.size(); ++gIdx )
|
||||
{
|
||||
if ( m_wellCellsInGrid[gIdx].isNull() || m_wellCellsInGrid[gIdx]->size() != grids[gIdx]->cellCount() ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigEclipseCaseData::computeWellCellsPrGrid()
|
||||
{
|
||||
// If we have computed this already, return
|
||||
if ( !m_wellCellsInGrid.empty() ) return;
|
||||
|
||||
std::vector<RigGridBase*> grids;
|
||||
allGrids( &grids );
|
||||
|
||||
// If we have computed this already for the current set of grids, return. The cached arrays are indexed by grid
|
||||
// cell index, and must be recomputed if the grids have changed after the previous computation.
|
||||
if ( isWellCellsPrGridUpToDate( grids ) ) return;
|
||||
|
||||
// Debug code used to display grid names and grid sizes
|
||||
/*
|
||||
size_t totCellCount = 0;
|
||||
|
||||
@@ -130,6 +130,7 @@ public:
|
||||
private:
|
||||
void computeActiveCellIJKBBox();
|
||||
void computeWellCellsPrGrid();
|
||||
bool isWellCellsPrGridUpToDate( const std::vector<RigGridBase*>& grids ) const;
|
||||
void computeActiveCellsGeometryBoundingBoxSlow();
|
||||
void computeActiveCellsGeometryBoundingBoxOptimized();
|
||||
|
||||
|
||||
@@ -84,6 +84,30 @@ TEST( RigGridManager, EqualTests )
|
||||
EXPECT_TRUE( existingGrid.notNull() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The well cell arrays are cached, and must be recomputed if the grid changes size after the first
|
||||
/// computation. A stale array is shorter than the cell count of the grid it is used with.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigEclipseCaseDataTest, WellCellsInGridIsRecomputedWhenGridSizeChanges )
|
||||
{
|
||||
cvf::ref<RigMainGrid> mainGrid = new RigMainGrid;
|
||||
mainGrid->setCellCounts( cvf::Vec3st( 2, 2, 2 ) );
|
||||
|
||||
cvf::ref<RigEclipseCaseData> eclipseCase = new RigEclipseCaseData( nullptr );
|
||||
eclipseCase->setMainGrid( mainGrid.p() );
|
||||
|
||||
const cvf::UByteArray* wellCells = eclipseCase->wellCellsInGrid( 0 );
|
||||
ASSERT_TRUE( wellCells != nullptr );
|
||||
EXPECT_EQ( mainGrid->cellCount(), wellCells->size() );
|
||||
|
||||
// Grow the grid after the well cell arrays have been cached
|
||||
mainGrid->setCellCounts( cvf::Vec3st( 3, 3, 3 ) );
|
||||
|
||||
wellCells = eclipseCase->wellCellsInGrid( 0 );
|
||||
ASSERT_TRUE( wellCells != nullptr );
|
||||
EXPECT_EQ( mainGrid->cellCount(), wellCells->size() );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -381,10 +381,13 @@ bool RiuGuiTheme::applyStyleSheet( RiaDefines::ThemeEnum theme )
|
||||
{
|
||||
if ( styleSheetFile.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
RiaGuiApplication* app = RiaGuiApplication::instance();
|
||||
QString styleSheet = styleSheetFile.readAll();
|
||||
QString styleSheet = styleSheetFile.readAll();
|
||||
preparseStyleSheet( theme, styleSheet );
|
||||
app->setStyleSheet( styleSheet );
|
||||
|
||||
if ( RiaGuiApplication* app = RiaGuiApplication::instance() )
|
||||
{
|
||||
app->setStyleSheet( styleSheet );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user