Introduce type-safe cell index for active reservoir cell index.

This commit is contained in:
Kristian Bendiksen committed 2025-10-13 16:17:03 +02:00
1 parent fd56ae3e4d
commit a81229bad8
10 files changed
+112 -32

No files matched your search

@@ -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
@@ -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<int>( 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<size_t> candidateFaceIndices;
@@ -106,9 +106,9 @@ void RigIndexIjkResultCalculator::calculate( const RigEclipseResultAddress& resV
for ( int activeIndex = 0; activeIndex < static_cast<int>( 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();
@@ -84,7 +84,7 @@ void RigActiveCellInfo::setCellResultIndex( size_t reservoirCellIndex, size_t re
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RigActiveCellInfo::activeReservoirCellIndices() const
std::vector<ReservoirCellIndex> 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 ) );
}
}
}
@@ -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<size_t> 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<ReservoirCellIndex> activeReservoirCellIndices() const;
void setGridCount( size_t gridCount );
void setGridActiveCellCounts( size_t gridIndex, size_t activeCellCount );
@@ -71,8 +73,8 @@ private:
private:
std::vector<GridActiveCellCounts> m_perGridActiveCellInfo;
std::vector<size_t> m_cellIndexToResultIndex;
std::vector<size_t> m_activeCellIndices;
std::vector<size_t> m_cellIndexToResultIndex;
std::vector<ReservoirCellIndex> m_activeCellIndices;
size_t m_reservoirActiveCellCount;
@@ -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::ref<cvf::UByteArray
for ( int i = 0; i < numActiveCells; i++ )
{
auto cellIdx = activeReservoirCellIdxs[i];
if ( customVisibility->val( 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<cvf::UByteArray
if ( nVisibleNeighbors == 6 )
{
result[cellIdx] = BorderType::INTERIOR_CELL;
result[cellIdx.value()] = BorderType::INTERIOR_CELL;
}
else
{
result[cellIdx] = BorderType::BORDER_CELL;
result[cellIdx.value()] = BorderType::BORDER_CELL;
}
}
}
@@ -167,12 +168,12 @@ void generateOperNumResult( RimEclipseCase* eclipseCase, int borderCellValue )
if ( !bordNumValues.empty() )
{
if ( result.empty() ) result.resize( bordNumValues.size(), 0 );
for ( size_t activeCellIdx : activeReservoirCellIdxs )
for ( auto activeCellIdx : activeReservoirCellIdxs )
{
// If BORDNUM = 1 (BORDER_CELL), assign the border cell value
if ( static_cast<int>( bordNumValues[activeCellIdx] ) == BorderType::BORDER_CELL )
if ( static_cast<int>( bordNumValues[activeCellIdx.value()] ) == BorderType::BORDER_CELL )
{
result[activeCellIdx] = borderCellValue;
result[activeCellIdx.value()] = borderCellValue;
}
}
}
@@ -265,15 +266,15 @@ std::vector<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase
std::vector<BorderCellFace> 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<int>( bordNumValues[activeCellIdx] );
int borderValue = static_cast<int>( 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<cvf::StructGridInterface::FaceType> faces = cvf::StructGridInterface::validFaceTypes();
@@ -291,7 +292,7 @@ std::vector<BorderCellFace> 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<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase
if ( neighborBorderValue == BorderType::INTERIOR_CELL )
{
// Get boundary condition value from BCCON grid property
int boundaryCondition = static_cast<int>( bcconValues[activeCellIdx] );
int boundaryCondition = static_cast<int>( bcconValues[activeCellIdx.value()] );
if ( boundaryCondition > 0 )
{
// Add this face to the result
@@ -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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <cstddef>
#include <functional>
template <typename Tag>
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<ReservoirCellIndexTag>;
// Hash support for using in std::unordered_map, etc.
namespace std
{
template <typename Tag>
struct hash<TypeSafeIndex<Tag>>
{
size_t operator()( const TypeSafeIndex<Tag>& idx ) const noexcept { return hash<size_t>{}( idx.value() ); }
};
} // namespace std