mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-27 05:37:21 -05:00
Support generating border result based on current visibility
This commit is contained in:
committed by
Magne Sjaastad
parent
3ff9ac3336
commit
4c0d4b3d1d
@@ -135,6 +135,8 @@ public:
|
||||
|
||||
void updateResultAddressCollection();
|
||||
|
||||
void setReservoirData( RigEclipseCaseData* eclipseCase );
|
||||
|
||||
protected:
|
||||
void initAfterRead() override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
@@ -145,7 +147,6 @@ protected:
|
||||
// Internal methods
|
||||
protected:
|
||||
void computeCachedData();
|
||||
void setReservoirData( RigEclipseCaseData* eclipseCase );
|
||||
std::vector<QString> additionalFiles() const;
|
||||
RimEclipseViewCollection* globalViewCollection() const;
|
||||
void addViewsFromViewCollection( std::vector<RimEclipseView*>& views, const RimEclipseViewCollection* viewColl ) const;
|
||||
|
||||
@@ -23,6 +23,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseNativeVisibleCellsStatCalc.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseResultAddress.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseResultInfo.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseResultTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigElasticProperties.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEnsembleFractureStatisticsCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEnsembleParameter.h
|
||||
@@ -109,6 +110,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseNativeVisibleCellsStatCalc.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseResultAddress.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseResultInfo.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseResultTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigElasticProperties.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEnsembleFractureStatisticsCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEnsembleParameter.cpp
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Well/RigSimulationWellCenterLineCalculator.h"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@@ -199,3 +200,39 @@ std::pair<cvf::Vec3st, cvf::Vec3st> RigEclipseCaseDataTools::expandBoundingBoxIj
|
||||
|
||||
return { cvf::Vec3st( expandedMinI, expandedMinJ, expandedMinK ), cvf::Vec3st( expandedMaxI, expandedMaxJ, expandedMaxK ) };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::UByteArray> RigEclipseCaseDataTools::createVisibilityFromIjkBounds( RigEclipseCaseData* eclipseCaseData,
|
||||
const cvf::Vec3st& minIjk,
|
||||
const cvf::Vec3st& maxIjk )
|
||||
{
|
||||
if ( !eclipseCaseData || minIjk.isUndefined() || maxIjk.isUndefined() ) return nullptr;
|
||||
|
||||
auto mainGrid = eclipseCaseData->mainGrid();
|
||||
if ( !mainGrid ) return nullptr;
|
||||
|
||||
// Create visibility array sized for the total number of reservoir cells
|
||||
size_t totalCellCount = mainGrid->cellCount();
|
||||
cvf::ref<cvf::UByteArray> visibility = new cvf::UByteArray( totalCellCount );
|
||||
visibility->setAll( false ); // Initialize all cells as invisible
|
||||
|
||||
// Mark cells within the IJK bounds as visible
|
||||
for ( size_t i = minIjk.x(); i <= maxIjk.x() && i < mainGrid->cellCountI(); ++i )
|
||||
{
|
||||
for ( size_t j = minIjk.y(); j <= maxIjk.y() && j < mainGrid->cellCountJ(); ++j )
|
||||
{
|
||||
for ( size_t k = minIjk.z(); k <= maxIjk.z() && k < mainGrid->cellCountK(); ++k )
|
||||
{
|
||||
size_t cellIndex = mainGrid->cellIndexFromIJK( i, j, k );
|
||||
if ( cellIndex < totalCellCount )
|
||||
{
|
||||
visibility->set( cellIndex, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return visibility;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "QString"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <utility>
|
||||
@@ -56,4 +57,7 @@ public:
|
||||
|
||||
static std::pair<cvf::Vec3st, cvf::Vec3st>
|
||||
expandBoundingBoxIjk( RigEclipseCaseData* eclipseCaseData, const cvf::Vec3st& minIjk, const cvf::Vec3st& maxIjk, size_t numPadding );
|
||||
|
||||
static cvf::ref<cvf::UByteArray>
|
||||
createVisibilityFromIjkBounds( RigEclipseCaseData* eclipseCaseData, const cvf::Vec3st& minIjk, const cvf::Vec3st& maxIjk );
|
||||
};
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RigEclipseResultTools.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaPorosityModel.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseResultAddress.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimEclipseView.h"
|
||||
|
||||
namespace RigEclipseResultTools
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector<int>& intValues )
|
||||
{
|
||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, resultName );
|
||||
|
||||
auto resultsData = eclipseCase.results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
|
||||
resultsData->addStaticScalarResult( RiaDefines::ResultCatType::GENERATED, resultName, false, intValues.size() );
|
||||
|
||||
std::vector<double>* resultVector = resultsData->modifiableCellScalarResult( resultAddress, 0 );
|
||||
resultVector->resize( intValues.size() );
|
||||
|
||||
for ( size_t idx = 0; idx < intValues.size(); idx++ )
|
||||
{
|
||||
resultVector->at( idx ) = 1.0 * intValues[idx];
|
||||
}
|
||||
|
||||
resultsData->recalculateStatistics( resultAddress );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void generateBorderResult( RimEclipseCase* eclipseCase, cvf::ref<cvf::UByteArray> customVisibility, const QString& resultName )
|
||||
{
|
||||
if ( eclipseCase == nullptr || customVisibility.isNull() ) return;
|
||||
|
||||
auto activeReservoirCellIdxs =
|
||||
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
|
||||
int numActiveCells = static_cast<int>( activeReservoirCellIdxs.size() );
|
||||
|
||||
std::vector<int> result;
|
||||
result.resize( numActiveCells, BorderType::INVISIBLE_CELL );
|
||||
|
||||
auto grid = eclipseCase->eclipseCaseData()->mainGrid();
|
||||
|
||||
// go through all cells, only check those visible
|
||||
#pragma omp parallel for
|
||||
for ( int i = 0; i < numActiveCells; i++ )
|
||||
{
|
||||
auto cellIdx = activeReservoirCellIdxs[i];
|
||||
if ( customVisibility->val( cellIdx ) )
|
||||
{
|
||||
auto neighbors = grid->neighborCells( cellIdx, true /*ignore invalid k layers*/ );
|
||||
|
||||
int nVisibleNeighbors = 0;
|
||||
for ( auto nIdx : neighbors )
|
||||
{
|
||||
if ( customVisibility->val( nIdx ) ) nVisibleNeighbors++;
|
||||
}
|
||||
|
||||
if ( nVisibleNeighbors == 6 )
|
||||
{
|
||||
result[i] = BorderType::INTERIOR_CELL;
|
||||
}
|
||||
else
|
||||
{
|
||||
result[i] = BorderType::BORDER_CELL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RigEclipseResultTools::createResultVector( *eclipseCase, resultName, result );
|
||||
|
||||
eclipseCase->updateConnectedEditors();
|
||||
}
|
||||
|
||||
} // namespace RigEclipseResultTools
|
||||
@@ -0,0 +1,42 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <QString>
|
||||
#include <vector>
|
||||
|
||||
#include "cvfArray.h"
|
||||
|
||||
class RimEclipseCase;
|
||||
class RimEclipseView;
|
||||
|
||||
namespace RigEclipseResultTools
|
||||
{
|
||||
enum BorderType : int
|
||||
{
|
||||
INVISIBLE_CELL = 0,
|
||||
BORDER_CELL = 1,
|
||||
INTERIOR_CELL = 2
|
||||
};
|
||||
|
||||
void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector<int>& intValues );
|
||||
|
||||
void generateBorderResult( RimEclipseCase* eclipseCase, cvf::ref<cvf::UByteArray> customVisibility, const QString& resultName = "BORDER" );
|
||||
|
||||
} // namespace RigEclipseResultTools
|
||||
@@ -504,6 +504,58 @@ cvf::BoundingBox RigGridBase::boundingBox()
|
||||
return m_boundingBox;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<size_t> RigGridBase::neighborCells( size_t cellIndex, bool ignoreInvalidKLayers ) const
|
||||
{
|
||||
auto ijk = ijkFromCellIndex( cellIndex );
|
||||
if ( !ijk.has_value() ) return {};
|
||||
auto& ijkVec = ijk.value();
|
||||
|
||||
std::vector<size_t> neighbors;
|
||||
|
||||
for ( auto face : { FaceType::NEG_I, FaceType::NEG_J, FaceType::NEG_K, FaceType::POS_I, FaceType::POS_J, FaceType::POS_K } )
|
||||
{
|
||||
size_t ni, nj, nk;
|
||||
neighborIJKAtCellFace( ijkVec.i(), ijkVec.j(), ijkVec.k(), face, &ni, &nj, &nk );
|
||||
if ( nk > cellCountK() ) continue;
|
||||
if ( isCellValid( ni, nj, nk ) )
|
||||
{
|
||||
auto neighborIdx = cellIndexFromIJKUnguarded( ni, nj, nk );
|
||||
neighbors.push_back( neighborIdx );
|
||||
}
|
||||
else if ( face == FaceType::NEG_K )
|
||||
{
|
||||
while ( ignoreInvalidKLayers && ( nk > 1 ) )
|
||||
{
|
||||
nk--;
|
||||
if ( isCellValid( ni, nj, nk ) )
|
||||
{
|
||||
auto neighborIdx = cellIndexFromIJKUnguarded( ni, nj, nk );
|
||||
neighbors.push_back( neighborIdx );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( face == FaceType::POS_K )
|
||||
{
|
||||
while ( ignoreInvalidKLayers && ( nk < cellCountK() ) )
|
||||
{
|
||||
nk++;
|
||||
if ( isCellValid( ni, nj, nk ) )
|
||||
{
|
||||
auto neighborIdx = cellIndexFromIJKUnguarded( ni, nj, nk );
|
||||
neighbors.push_back( neighborIdx );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -114,6 +114,8 @@ public:
|
||||
bool cellIJKNeighbor( size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const override;
|
||||
void cellIJKNeighborUnguarded( size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const;
|
||||
|
||||
std::vector<size_t> neighborCells( size_t cellIndex, bool ignoreInvalidKLayers = false ) const;
|
||||
|
||||
protected:
|
||||
size_t m_indexToStartOfCells; ///< Index into the global cell array stored in main-grid where this grids cells starts.
|
||||
size_t m_cellCountIJK;
|
||||
|
||||
@@ -25,8 +25,11 @@
|
||||
|
||||
#include "RimEclipseResultCase.h"
|
||||
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseCaseDataTools.h"
|
||||
#include "RigEclipseResultAddress.h"
|
||||
#include "RigEclipseResultTools.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "Well/RigSimWellData.h"
|
||||
|
||||
@@ -290,3 +293,206 @@ TEST( RigEclipseCaseDataToolsTest, ExpandBoundingBoxIjkWithPadding )
|
||||
ASSERT_LE( expandedMin3.y(), expandedMax3.y() ) << "Upper boundary expanded Min J should be <= Max J";
|
||||
ASSERT_LE( expandedMin3.z(), expandedMax3.z() ) << "Upper boundary expanded Min K should be <= Max K";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigEclipseCaseDataToolsTest, CreateVisibilityFromIjkBounds )
|
||||
{
|
||||
// Load the BRUGGE test model using RifReaderEclipseOutput
|
||||
QDir baseFolder( TEST_MODEL_DIR );
|
||||
bool subFolderExists = baseFolder.cd( "Case_with_10_timesteps/Real0" );
|
||||
ASSERT_TRUE( subFolderExists ) << "Could not find test model directory";
|
||||
|
||||
QString filename( "BRUGGE_0000.EGRID" );
|
||||
QString filePath = baseFolder.absoluteFilePath( filename );
|
||||
ASSERT_TRUE( QFile::exists( filePath ) ) << "BRUGGE test model file does not exist: " << filePath.toStdString();
|
||||
|
||||
std::unique_ptr<RimEclipseResultCase> resultCase( new RimEclipseResultCase );
|
||||
cvf::ref<RigEclipseCaseData> eclipseCase = new RigEclipseCaseData( resultCase.get() );
|
||||
|
||||
cvf::ref<RifReaderEclipseOutput> readerInterfaceEcl = new RifReaderEclipseOutput;
|
||||
bool success = readerInterfaceEcl->open( filePath, eclipseCase.p() );
|
||||
ASSERT_TRUE( success ) << "Could not load BRUGGE test model";
|
||||
|
||||
ASSERT_NE( eclipseCase->mainGrid(), nullptr ) << "Main grid should not be null";
|
||||
ASSERT_GT( eclipseCase->mainGrid()->cellCount(), 0 ) << "Grid should contain cells";
|
||||
|
||||
// Get grid dimensions for test validation
|
||||
size_t gridCellCountI = eclipseCase->mainGrid()->cellCountI();
|
||||
size_t gridCellCountJ = eclipseCase->mainGrid()->cellCountJ();
|
||||
size_t gridCellCountK = eclipseCase->mainGrid()->cellCountK();
|
||||
size_t totalCellCount = eclipseCase->mainGrid()->cellCount();
|
||||
|
||||
// Test case 1: Basic visibility generation with small bounds
|
||||
cvf::Vec3st minIjk( 5, 5, 5 );
|
||||
cvf::Vec3st maxIjk( 10, 10, 8 );
|
||||
|
||||
auto visibility = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), minIjk, maxIjk );
|
||||
|
||||
ASSERT_FALSE( visibility.isNull() ) << "Visibility array should not be null";
|
||||
ASSERT_EQ( visibility->size(), totalCellCount ) << "Visibility array should match total cell count";
|
||||
|
||||
// Count visible cells and verify they match expected IJK range
|
||||
size_t expectedVisibleCells = ( maxIjk.x() - minIjk.x() + 1 ) * ( maxIjk.y() - minIjk.y() + 1 ) * ( maxIjk.z() - minIjk.z() + 1 );
|
||||
size_t actualVisibleCells = 0;
|
||||
|
||||
for ( size_t i = 0; i < totalCellCount; ++i )
|
||||
{
|
||||
if ( visibility->val( i ) )
|
||||
{
|
||||
actualVisibleCells++;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ( actualVisibleCells, expectedVisibleCells ) << "Number of visible cells should match IJK range volume";
|
||||
|
||||
// Test case 2: Verify specific cells within bounds are visible
|
||||
for ( size_t i = minIjk.x(); i <= maxIjk.x(); ++i )
|
||||
{
|
||||
for ( size_t j = minIjk.y(); j <= maxIjk.y(); ++j )
|
||||
{
|
||||
for ( size_t k = minIjk.z(); k <= maxIjk.z(); ++k )
|
||||
{
|
||||
size_t cellIndex = eclipseCase->mainGrid()->cellIndexFromIJK( i, j, k );
|
||||
ASSERT_TRUE( visibility->val( cellIndex ) ) << "Cell at IJK (" << i << "," << j << "," << k << ") should be visible";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test case 3: Verify cells outside bounds are invisible
|
||||
for ( size_t i = 0; i < std::min( minIjk.x(), size_t( 3 ) ); ++i )
|
||||
{
|
||||
for ( size_t j = 0; j < std::min( minIjk.y(), size_t( 3 ) ); ++j )
|
||||
{
|
||||
for ( size_t k = 0; k < std::min( minIjk.z(), size_t( 3 ) ); ++k )
|
||||
{
|
||||
size_t cellIndex = eclipseCase->mainGrid()->cellIndexFromIJK( i, j, k );
|
||||
ASSERT_FALSE( visibility->val( cellIndex ) ) << "Cell at IJK (" << i << "," << j << "," << k << ") should be invisible";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test case 4: Edge case - single cell bounds
|
||||
cvf::Vec3st singleCellMin( 2, 2, 2 );
|
||||
cvf::Vec3st singleCellMax( 2, 2, 2 );
|
||||
|
||||
auto singleCellVisibility = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), singleCellMin, singleCellMax );
|
||||
|
||||
ASSERT_FALSE( singleCellVisibility.isNull() ) << "Single cell visibility should not be null";
|
||||
|
||||
size_t singleCellVisibleCount = 0;
|
||||
for ( size_t i = 0; i < totalCellCount; ++i )
|
||||
{
|
||||
if ( singleCellVisibility->val( i ) )
|
||||
{
|
||||
singleCellVisibleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ( singleCellVisibleCount, 1 ) << "Exactly one cell should be visible for single cell bounds";
|
||||
|
||||
// Verify the correct single cell is visible
|
||||
size_t expectedSingleCellIndex = eclipseCase->mainGrid()->cellIndexFromIJK( 2, 2, 2 );
|
||||
ASSERT_TRUE( singleCellVisibility->val( expectedSingleCellIndex ) ) << "The specified single cell should be visible";
|
||||
|
||||
// Test case 5: Error handling - invalid inputs
|
||||
auto invalidVisibility1 = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( nullptr, minIjk, maxIjk );
|
||||
ASSERT_TRUE( invalidVisibility1.isNull() ) << "Null case data should return null visibility";
|
||||
|
||||
auto invalidVisibility2 = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), cvf::Vec3st::UNDEFINED, maxIjk );
|
||||
ASSERT_TRUE( invalidVisibility2.isNull() ) << "Undefined minIjk should return null visibility";
|
||||
|
||||
auto invalidVisibility3 = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), minIjk, cvf::Vec3st::UNDEFINED );
|
||||
ASSERT_TRUE( invalidVisibility3.isNull() ) << "Undefined maxIjk should return null visibility";
|
||||
|
||||
// Test case 6: Boundary conditions - bounds at grid limits
|
||||
cvf::Vec3st gridMinBounds( 0, 0, 0 );
|
||||
cvf::Vec3st gridMaxBounds( gridCellCountI - 1, gridCellCountJ - 1, gridCellCountK - 1 );
|
||||
|
||||
auto fullGridVisibility = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), gridMinBounds, gridMaxBounds );
|
||||
|
||||
ASSERT_FALSE( fullGridVisibility.isNull() ) << "Full grid visibility should not be null";
|
||||
|
||||
size_t fullGridVisibleCount = 0;
|
||||
for ( size_t i = 0; i < totalCellCount; ++i )
|
||||
{
|
||||
if ( fullGridVisibility->val( i ) )
|
||||
{
|
||||
fullGridVisibleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ( fullGridVisibleCount, totalCellCount ) << "All cells should be visible when using full grid bounds";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigEclipseCaseDataToolsTest, GenerateBorderResultFromIjkBounds )
|
||||
{
|
||||
// Load the BRUGGE test model using RifReaderEclipseOutput
|
||||
QDir baseFolder( TEST_MODEL_DIR );
|
||||
bool subFolderExists = baseFolder.cd( "Case_with_10_timesteps/Real0" );
|
||||
ASSERT_TRUE( subFolderExists ) << "Could not find test model directory";
|
||||
|
||||
QString filename( "BRUGGE_0000.EGRID" );
|
||||
QString filePath = baseFolder.absoluteFilePath( filename );
|
||||
ASSERT_TRUE( QFile::exists( filePath ) ) << "BRUGGE test model file does not exist: " << filePath.toStdString();
|
||||
|
||||
std::unique_ptr<RimEclipseResultCase> resultCase( new RimEclipseResultCase );
|
||||
cvf::ref<RigEclipseCaseData> eclipseCase = new RigEclipseCaseData( resultCase.get() );
|
||||
|
||||
cvf::ref<RifReaderEclipseOutput> readerInterfaceEcl = new RifReaderEclipseOutput;
|
||||
bool success = readerInterfaceEcl->open( filePath, eclipseCase.p() );
|
||||
ASSERT_TRUE( success ) << "Could not load BRUGGE test model";
|
||||
|
||||
resultCase->setReservoirData( eclipseCase.p() );
|
||||
|
||||
// Define IJK bounds for testing
|
||||
cvf::Vec3st minIjk( 20, 20, 5 );
|
||||
cvf::Vec3st maxIjk( 30, 30, 8 );
|
||||
|
||||
// Create visibility from IJK bounds
|
||||
auto visibility = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), minIjk, maxIjk );
|
||||
ASSERT_FALSE( visibility.isNull() ) << "Visibility should be created successfully";
|
||||
|
||||
// Generate border result using the custom visibility
|
||||
RigEclipseResultTools::generateBorderResult( resultCase.get(), visibility, "BORDNUM" );
|
||||
|
||||
// Verify that the result was created
|
||||
auto resultsData = resultCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
ASSERT_NE( resultsData, nullptr ) << "Results data should not be null";
|
||||
|
||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, "BORDNUM" );
|
||||
ASSERT_TRUE( resultsData->hasResultEntry( resultAddress ) ) << "BORDNUM result should exist";
|
||||
|
||||
// Get the result data and verify it contains expected values
|
||||
const std::vector<double>& resultVector = resultsData->cellScalarResults( resultAddress, 0 );
|
||||
ASSERT_GT( resultVector.size(), 0 ) << "Result vector should not be empty";
|
||||
|
||||
// Count cells with different values
|
||||
int invisibleCells = 0;
|
||||
int borderCells = 0;
|
||||
int interiorCells = 0;
|
||||
|
||||
for ( double value : resultVector )
|
||||
{
|
||||
int intValue = static_cast<int>( value );
|
||||
if ( intValue == RigEclipseResultTools::BorderType::INVISIBLE_CELL )
|
||||
invisibleCells++;
|
||||
else if ( intValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
||||
borderCells++;
|
||||
else if ( intValue == RigEclipseResultTools::BorderType::INTERIOR_CELL )
|
||||
interiorCells++;
|
||||
}
|
||||
|
||||
// Verify that we have all three types of cells
|
||||
ASSERT_GT( invisibleCells, 0 ) << "Should have invisible cells (value 0)";
|
||||
ASSERT_GT( borderCells, 0 ) << "Should have border cells (value 1)";
|
||||
ASSERT_GE( interiorCells, 0 ) << "May have interior cells (value 2)";
|
||||
|
||||
// The total should match the number of active cells
|
||||
int totalCells = invisibleCells + borderCells + interiorCells;
|
||||
ASSERT_EQ( totalCells, static_cast<int>( resultVector.size() ) ) << "Total should match result vector size";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user