diff --git a/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp b/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp index 4ba2d3810c..2fb877995a 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp @@ -635,6 +635,7 @@ std::vector RimGridCalculation::getActiveCellValues( const QString& size_t gridIndex = 0; auto resultAccessor = RigResultAccessorFactory::createFromResultAddress( eclipseCaseData, gridIndex, porosityModel, timeStepToUse, resAddr ); + if ( resultAccessor.isNull() ) return {}; #pragma omp parallel for for ( int i = 0; i < static_cast( activeReservoirCells.size() ); i++ ) diff --git a/ApplicationLibCode/ReservoirDataModel/ResultAccessors/RigAllGridCellsResultAccessor.cpp b/ApplicationLibCode/ReservoirDataModel/ResultAccessors/RigAllGridCellsResultAccessor.cpp index 59d71eec21..24488b4bbb 100644 --- a/ApplicationLibCode/ReservoirDataModel/ResultAccessors/RigAllGridCellsResultAccessor.cpp +++ b/ApplicationLibCode/ReservoirDataModel/ResultAccessors/RigAllGridCellsResultAccessor.cpp @@ -21,8 +21,6 @@ #include "RigGridBase.h" -#include "cafAssert.h" - #include //-------------------------------------------------------------------------------------------------- @@ -42,9 +40,9 @@ double RigAllGridCellsResultAccessor::cellScalar( size_t gridLocalCellIndex ) co if ( m_reservoirResultValues->empty() ) return HUGE_VAL; size_t reservoirCellIndex = m_grid->reservoirCellIndex( gridLocalCellIndex ); - CAF_ASSERT( reservoirCellIndex < m_reservoirResultValues->size() ); + if ( reservoirCellIndex >= m_reservoirResultValues->size() ) return HUGE_VAL; - return m_reservoirResultValues->at( reservoirCellIndex ); + return ( *m_reservoirResultValues )[reservoirCellIndex]; } //-------------------------------------------------------------------------------------------------- @@ -62,9 +60,11 @@ double RigAllGridCellsResultAccessor::cellScalarGlobIdx( size_t globCellIndex ) { if ( m_reservoirResultValues->empty() ) return HUGE_VAL; - CAF_ASSERT( globCellIndex < m_reservoirResultValues->size() ); + // The cell index can come from another case, see RimGridCalculation::getActiveCellValues(). Avoid at(), which throws: an + // exception escaping an OpenMP loop calls std::terminate. + if ( globCellIndex >= m_reservoirResultValues->size() ) return HUGE_VAL; - return m_reservoirResultValues->at( globCellIndex ); + return ( *m_reservoirResultValues )[globCellIndex]; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/UnitTests/CMakeLists.txt b/ApplicationLibCode/UnitTests/CMakeLists.txt index 6a9e74ea07..8e075b09b5 100644 --- a/ApplicationLibCode/UnitTests/CMakeLists.txt +++ b/ApplicationLibCode/UnitTests/CMakeLists.txt @@ -160,6 +160,7 @@ set(SOURCE_UNITTEST_FILES ${CMAKE_CURRENT_LIST_DIR}/RicWellPathExportMswGeometryPath-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RicMswBranchBuilder-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RigMswTableData-Test.cpp + ${CMAKE_CURRENT_LIST_DIR}/RigAllGridCellsResultAccessor-Test.cpp ) if(RESINSIGHT_ENABLE_GRPC) diff --git a/ApplicationLibCode/UnitTests/RigAllGridCellsResultAccessor-Test.cpp b/ApplicationLibCode/UnitTests/RigAllGridCellsResultAccessor-Test.cpp new file mode 100644 index 0000000000..e2dc4fc9df --- /dev/null +++ b/ApplicationLibCode/UnitTests/RigAllGridCellsResultAccessor-Test.cpp @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2026 Equinor ASA +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "gtest/gtest.h" + +#include "ResultAccessors/RigAllGridCellsResultAccessor.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// The grid is only used by cellScalar(), the global index accessors read the result vector directly. +//-------------------------------------------------------------------------------------------------- +TEST( RigAllGridCellsResultAccessorTest, CellScalarGlobIdxReturnsValueForValidIndex ) +{ + std::vector values = { 1.0, 2.0, 3.0 }; + + RigAllGridCellsResultAccessor accessor( nullptr, &values ); + + EXPECT_DOUBLE_EQ( 1.0, accessor.cellScalarGlobIdx( 0 ) ); + EXPECT_DOUBLE_EQ( 3.0, accessor.cellScalarGlobIdx( 2 ) ); +} + +//-------------------------------------------------------------------------------------------------- +/// A cell index beyond the result vector must not throw. The accessor is called from OpenMP loops, +/// where an escaping exception terminates the application. +//-------------------------------------------------------------------------------------------------- +TEST( RigAllGridCellsResultAccessorTest, CellScalarGlobIdxIsUndefinedForIndexBeyondResultVector ) +{ + std::vector values = { 1.0, 2.0, 3.0 }; + + RigAllGridCellsResultAccessor accessor( nullptr, &values ); + + EXPECT_NO_THROW( accessor.cellScalarGlobIdx( 3 ) ); + EXPECT_DOUBLE_EQ( HUGE_VAL, accessor.cellScalarGlobIdx( 3 ) ); + EXPECT_DOUBLE_EQ( HUGE_VAL, accessor.cellScalarGlobIdx( 1000 ) ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RigAllGridCellsResultAccessorTest, CellScalarGlobIdxIsUndefinedForEmptyResultVector ) +{ + std::vector values; + + RigAllGridCellsResultAccessor accessor( nullptr, &values ); + + EXPECT_DOUBLE_EQ( HUGE_VAL, accessor.cellScalarGlobIdx( 0 ) ); +}