diff --git a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp index 40b96f5672..39122635a0 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp @@ -357,9 +357,9 @@ cvf::ref cvf::ref visibility = new cvf::UByteArray( totalCellCount ); visibility->setAll( false ); - for ( size_t activeCellIdx : activeReservoirCells ) + for ( auto activeCellIdx : activeReservoirCells ) { - visibility->set( activeCellIdx, true ); + visibility->set( activeCellIdx.value(), true ); } return visibility; } diff --git a/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp b/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp index ea91d24e0c..1570b40b81 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridCalculation.cpp @@ -665,7 +665,7 @@ std::vector RimGridCalculation::getActiveCellValues( const QString& #pragma omp parallel for for ( int i = 0; i < static_cast( activeReservoirCells.size() ); i++ ) { - values[i] = resultAccessor->cellScalarGlobIdx( activeReservoirCells[i] ); + values[i] = resultAccessor->cellScalarGlobIdx( activeReservoirCells[i].value() ); } if ( m_releaseMemoryAfterDataIsExtracted ) @@ -698,7 +698,7 @@ void RimGridCalculation::replaceFilteredValuesWithVector( const std::vectorval( reservoirCellIndex ) ) + if ( !visibility->val( reservoirCellIndex.value() ) ) { resultValues[i] = inputValues[i]; } @@ -723,7 +723,7 @@ void RimGridCalculation::replaceFilteredValuesWithDefaultValue( double for ( int i = 0; i < numActiveCells; i++ ) { const auto reservoirCellIndex = activeReservoirCellIndices[i]; - if ( !visibility->val( reservoirCellIndex ) ) + if ( !visibility->val( reservoirCellIndex.value() ) ) { resultValues[i] = defaultValue; } diff --git a/ApplicationLibCode/ProjectDataModel/RimWellTargetMapping.cpp b/ApplicationLibCode/ProjectDataModel/RimWellTargetMapping.cpp index 69b4d90b40..b8d5364a47 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellTargetMapping.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellTargetMapping.cpp @@ -588,7 +588,7 @@ std::vector RimWellTargetMapping::getVisibilityFilter() const for ( int i = 0; i < numActiveCells; i++ ) { const auto reservoirCellIndex = activeReservoirCellIndices[i]; - filter[i] = visibility->val( reservoirCellIndex ) ? 1.0 : 0.0; + filter[i] = visibility->val( reservoirCellIndex.value() ) ? 1.0 : 0.0; } } } diff --git a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake index 091a9d30b3..5f0e5f46c6 100644 --- a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake @@ -4,6 +4,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RigActiveCellGrid.h ${CMAKE_CURRENT_LIST_DIR}/RigActiveCellInfo.h ${CMAKE_CURRENT_LIST_DIR}/RigActiveCellLocalGrid.h + ${CMAKE_CURRENT_LIST_DIR}/RigTypeSafeIndex.h ${CMAKE_CURRENT_LIST_DIR}/RigAllanDiagramData.h ${CMAKE_CURRENT_LIST_DIR}/RigBasicPlane.h ${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultCalculator.h diff --git a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigFaultDistanceResultCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigFaultDistanceResultCalculator.cpp index 603e4de4c8..fbceff6591 100644 --- a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigFaultDistanceResultCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigFaultDistanceResultCalculator.cpp @@ -87,11 +87,11 @@ void RigFaultDistanceResultCalculator::calculate( const RigEclipseResultAddress& const auto activeCells = m_resultsData->activeCellInfo()->activeReservoirCellIndices(); for ( auto cellIdx : activeCells ) { - const RigCell& cell = mainGrid->cell( cellIdx ); + const RigCell& cell = mainGrid->cell( cellIdx.value() ); if ( cell.isInvalid() ) continue; for ( auto faceType : faceTypes ) { - if ( m_resultsData->m_ownerMainGrid->findFaultFromCellIndexAndCellFace( cellIdx, faceType ) ) + if ( m_resultsData->m_ownerMainGrid->findFaultFromCellIndexAndCellFace( cellIdx.value(), faceType ) ) faultFaceCenters.push_back( cell.faceCenter( faceType ) ); } } @@ -122,9 +122,9 @@ void RigFaultDistanceResultCalculator::calculate( const RigEclipseResultAddress& for ( int activeIndex = 0; activeIndex < static_cast( activeCells.size() ); activeIndex++ ) { auto cellIdx = activeCells[activeIndex]; - if ( cellIdx == cvf::UNDEFINED_SIZE_T ) continue; + if ( cellIdx.value() == cvf::UNDEFINED_SIZE_T ) continue; - const RigCell& cell = mainGrid->cell( cellIdx ); + const RigCell& cell = mainGrid->cell( cellIdx.value() ); if ( cell.isInvalid() ) continue; std::vector candidateFaceIndices; diff --git a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigIndexIjkResultCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigIndexIjkResultCalculator.cpp index 55a7d0d8dc..46bce40eac 100644 --- a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigIndexIjkResultCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigIndexIjkResultCalculator.cpp @@ -106,9 +106,9 @@ void RigIndexIjkResultCalculator::calculate( const RigEclipseResultAddress& resV for ( int activeIndex = 0; activeIndex < static_cast( activeReservoirCellIndices.size() ); activeIndex++ ) { auto cellIdx = activeReservoirCellIndices[activeIndex]; - if ( cellIdx == cvf::UNDEFINED_SIZE_T ) continue; + if ( cellIdx.value() == cvf::UNDEFINED_SIZE_T ) continue; - const RigCell& cell = mainGrid->cell( cellIdx ); + const RigCell& cell = mainGrid->cell( cellIdx.value() ); if ( cell.isInvalid() ) continue; bool isTemporaryGrid = cell.hostGrid()->isTempGrid(); diff --git a/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.cpp index 92fd87fe97..015324df2d 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -84,7 +84,7 @@ void RigActiveCellInfo::setCellResultIndex( size_t reservoirCellIndex, size_t re //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigActiveCellInfo::activeReservoirCellIndices() const +std::vector RigActiveCellInfo::activeReservoirCellIndices() const { return m_activeCellIndices; } @@ -123,7 +123,7 @@ void RigActiveCellInfo::computeDerivedData() { if ( m_cellIndexToResultIndex[i] != cvf::UNDEFINED_SIZE_T ) { - m_activeCellIndices.push_back( i ); + m_activeCellIndices.push_back( ReservoirCellIndex( i ) ); } } } diff --git a/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.h index 2ebf272b98..b9de8f7509 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.h +++ b/ApplicationLibCode/ReservoirDataModel/RigActiveCellInfo.h @@ -20,6 +20,8 @@ #pragma once +#include "RigTypeSafeIndex.h" + #include "cvfBoundingBox.h" #include "cvfObject.h" #include "cvfVector3.h" @@ -35,10 +37,10 @@ public: size_t reservoirCellCount() const; size_t reservoirActiveCellCount() const; - bool isActive( size_t reservoirCellIndex ) const; - size_t cellResultIndex( size_t reservoirCellIndex ) const; - void setCellResultIndex( size_t reservoirCellIndex, size_t globalResultCellIndex ); - std::vector activeReservoirCellIndices() const; + bool isActive( size_t reservoirCellIndex ) const; + size_t cellResultIndex( size_t reservoirCellIndex ) const; + void setCellResultIndex( size_t reservoirCellIndex, size_t globalResultCellIndex ); + std::vector activeReservoirCellIndices() const; void setGridCount( size_t gridCount ); void setGridActiveCellCounts( size_t gridIndex, size_t activeCellCount ); @@ -71,8 +73,8 @@ private: private: std::vector m_perGridActiveCellInfo; - std::vector m_cellIndexToResultIndex; - std::vector m_activeCellIndices; + std::vector m_cellIndexToResultIndex; + std::vector m_activeCellIndices; size_t m_reservoirActiveCellCount; diff --git a/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp b/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp index dbef57f08a..a4ba3f7b3c 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp @@ -28,6 +28,7 @@ #include "RigEclipseResultAddress.h" #include "RigMainGrid.h" +#include "RigTypeSafeIndex.h" #include "RimEclipseCase.h" #include "RimEclipseResultCase.h" #include "RimEclipseView.h" @@ -78,9 +79,9 @@ void generateBorderResult( RimEclipseCase* eclipseCase, cvf::refval( cellIdx ) ) + if ( customVisibility->val( cellIdx.value() ) ) { - auto neighbors = grid->neighborCells( cellIdx, true /*ignore invalid k layers*/ ); + auto neighbors = grid->neighborCells( cellIdx.value(), true /*ignore invalid k layers*/ ); int nVisibleNeighbors = 0; for ( auto nIdx : neighbors ) @@ -90,11 +91,11 @@ void generateBorderResult( RimEclipseCase* eclipseCase, cvf::ref( bordNumValues[activeCellIdx] ) == BorderType::BORDER_CELL ) + if ( static_cast( bordNumValues[activeCellIdx.value()] ) == BorderType::BORDER_CELL ) { - result[activeCellIdx] = borderCellValue; + result[activeCellIdx.value()] = borderCellValue; } } } @@ -265,15 +266,15 @@ std::vector generateBorderCellFaces( RimEclipseCase* eclipseCase std::vector borderCellFaces; // Iterate through all active cells - for ( size_t activeCellIdx : activeReservoirCellIdxs ) + for ( auto activeCellIdx : activeReservoirCellIdxs ) { // Check if this cell is a border cell - int borderValue = static_cast( bordNumValues[activeCellIdx] ); + int borderValue = static_cast( bordNumValues[activeCellIdx.value()] ); if ( borderValue != BorderType::BORDER_CELL ) continue; // Get IJK indices for this cell size_t i, j, k; - if ( !grid->ijkFromCellIndex( activeCellIdx, &i, &j, &k ) ) continue; + if ( !grid->ijkFromCellIndex( activeCellIdx.value(), &i, &j, &k ) ) continue; // Check all 6 faces std::vector faces = cvf::StructGridInterface::validFaceTypes(); @@ -291,7 +292,7 @@ std::vector generateBorderCellFaces( RimEclipseCase* eclipseCase size_t neighborReservoirIdx = grid->cellIndexFromIJK( ni, nj, nk ); // Find active cell index for neighbor - auto it = std::find( activeReservoirCellIdxs.begin(), activeReservoirCellIdxs.end(), neighborReservoirIdx ); + auto it = std::find( activeReservoirCellIdxs.begin(), activeReservoirCellIdxs.end(), ReservoirCellIndex( neighborReservoirIdx ) ); if ( it == activeReservoirCellIdxs.end() ) continue; // Neighbor not active // Check if neighbor is an interior cell @@ -299,7 +300,7 @@ std::vector generateBorderCellFaces( RimEclipseCase* eclipseCase if ( neighborBorderValue == BorderType::INTERIOR_CELL ) { // Get boundary condition value from BCCON grid property - int boundaryCondition = static_cast( bcconValues[activeCellIdx] ); + int boundaryCondition = static_cast( bcconValues[activeCellIdx.value()] ); if ( boundaryCondition > 0 ) { // Add this face to the result diff --git a/ApplicationLibCode/ReservoirDataModel/RigTypeSafeIndex.h b/ApplicationLibCode/ReservoirDataModel/RigTypeSafeIndex.h new file mode 100644 index 0000000000..5ca92026dd --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigTypeSafeIndex.h @@ -0,0 +1,76 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +template +class TypeSafeIndex +{ +public: + // Default constructor + constexpr TypeSafeIndex() noexcept + : m_value( 0 ) + { + } + + // Explicit constructor from size_t (prevents implicit conversion) + explicit constexpr TypeSafeIndex( size_t value ) noexcept + : m_value( value ) + { + } + + // Explicit conversion to size_t + explicit constexpr operator size_t() const noexcept { return m_value; } + + // Getter for when you need the value + constexpr size_t value() const noexcept { return m_value; } + + // Comparison operators + constexpr bool operator==( const TypeSafeIndex& other ) const noexcept = default; + constexpr auto operator<=>( const TypeSafeIndex& other ) const noexcept = default; + + // Arithmetic operators (if needed) + constexpr TypeSafeIndex& operator++() noexcept + { + ++m_value; + return *this; + } + +private: + size_t m_value; +}; + +// Define specific types using tag structs +struct ReservoirCellIndexTag +{ +}; + +using ReservoirCellIndex = TypeSafeIndex; + +// Hash support for using in std::unordered_map, etc. +namespace std +{ +template +struct hash> +{ + size_t operator()( const TypeSafeIndex& idx ) const noexcept { return hash{}( idx.value() ); } +}; +} // namespace std