mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 14:40:26 -05:00
Simulation Input: Refactor border conditions to use in-memory results.
This commit is contained in:
1 parent
55a4863436
commit
cfcdd67255
6 files changed
+241
-261
No files matched your search
@@ -107,9 +107,9 @@ void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName,
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void generateBorderResult( RimEclipseCase* eclipseCase, cvf::ref<cvf::UByteArray> customVisibility, const QString& resultName )
|
std::vector<int> generateBorderResult( RimEclipseCase* eclipseCase, cvf::ref<cvf::UByteArray> customVisibility )
|
||||||
{
|
{
|
||||||
if ( eclipseCase == nullptr || customVisibility.isNull() ) return;
|
if ( eclipseCase == nullptr || customVisibility.isNull() ) return {};
|
||||||
|
|
||||||
auto activeReservoirCellIdxs =
|
auto activeReservoirCellIdxs =
|
||||||
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
|
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
|
||||||
@@ -147,17 +147,15 @@ void generateBorderResult( RimEclipseCase* eclipseCase, cvf::ref<cvf::UByteArray
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RigEclipseResultTools::createResultVector( *eclipseCase, resultName, result );
|
return result;
|
||||||
|
|
||||||
eclipseCase->updateConnectedEditors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
int generateOperNumResult( RimEclipseCase* eclipseCase, int borderCellValue )
|
std::vector<int> generateOperNumResult( RimEclipseCase* eclipseCase, const std::vector<int>& borderResult, int borderCellValue )
|
||||||
{
|
{
|
||||||
if ( eclipseCase == nullptr ) return 0;
|
if ( eclipseCase == nullptr ) return {};
|
||||||
|
|
||||||
// Auto-determine border cell value if not specified
|
// Auto-determine border cell value if not specified
|
||||||
if ( borderCellValue == -1 )
|
if ( borderCellValue == -1 )
|
||||||
@@ -211,32 +209,21 @@ int generateOperNumResult( RimEclipseCase* eclipseCase, int borderCellValue )
|
|||||||
borderCellValue = 2;
|
borderCellValue = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if BORDNUM exists to modify border cells
|
if ( !borderResult.empty() )
|
||||||
RigEclipseResultAddress bordNumAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, RiaResultNames::bordnum() );
|
|
||||||
if ( resultsData->hasResultEntry( bordNumAddr ) )
|
|
||||||
{
|
{
|
||||||
resultsData->ensureKnownResultLoaded( bordNumAddr );
|
result.resize( borderResult.size(), 1 );
|
||||||
auto bordNumValues = resultsData->cellScalarResults( bordNumAddr, 0 );
|
|
||||||
if ( !bordNumValues.empty() )
|
|
||||||
{
|
|
||||||
result.resize( bordNumValues.size(), 1 );
|
|
||||||
|
|
||||||
for ( auto activeCellIdx : activeReservoirCellIdxs )
|
for ( auto activeCellIdx : activeReservoirCellIdxs )
|
||||||
|
{
|
||||||
|
// If BORDNUM = 1 (BORDER_CELL), assign the border cell value
|
||||||
|
if ( borderResult[activeCellIdx.value()] == BorderType::BORDER_CELL )
|
||||||
{
|
{
|
||||||
// If BORDNUM = 1 (BORDER_CELL), assign the border cell value
|
result[activeCellIdx.value()] = borderCellValue;
|
||||||
if ( static_cast<int>( bordNumValues[activeCellIdx.value()] ) == BorderType::BORDER_CELL )
|
|
||||||
{
|
|
||||||
result[activeCellIdx.value()] = borderCellValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RigEclipseResultTools::createResultVector( *eclipseCase, RiaResultNames::opernum(), result );
|
return result;
|
||||||
|
|
||||||
eclipseCase->updateConnectedEditors();
|
|
||||||
|
|
||||||
return borderCellValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -262,28 +249,22 @@ int findMaxBcconValue( RimEclipseCase* eclipseCase )
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void generateBcconResult( RimEclipseCase* eclipseCase, const caf::VecIjk0& min, const caf::VecIjk0& max )
|
std::vector<int> generateBcconResult( RimEclipseCase* eclipseCase,
|
||||||
|
const std::vector<int>& borderResult,
|
||||||
|
const caf::VecIjk0& min,
|
||||||
|
const caf::VecIjk0& max )
|
||||||
{
|
{
|
||||||
if ( eclipseCase == nullptr ) return;
|
if ( eclipseCase == nullptr ) return {};
|
||||||
|
|
||||||
auto resultsData = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
|
||||||
if ( !resultsData ) return;
|
|
||||||
|
|
||||||
auto grid = eclipseCase->eclipseCaseData()->mainGrid();
|
auto grid = eclipseCase->eclipseCaseData()->mainGrid();
|
||||||
if ( !grid ) return;
|
if ( !grid ) return {};
|
||||||
|
|
||||||
// Check if BORDNUM result exists
|
if ( borderResult.empty() )
|
||||||
RigEclipseResultAddress bordNumAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, RiaResultNames::bordnum() );
|
|
||||||
if ( !resultsData->hasResultEntry( bordNumAddr ) )
|
|
||||||
{
|
{
|
||||||
RiaLogging::warning( "BORDNUM result not found - cannot generate BCCON result" );
|
RiaLogging::warning( "Border result is empty - cannot generate BCCON result" );
|
||||||
return;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
resultsData->ensureKnownResultLoaded( bordNumAddr );
|
|
||||||
auto bordNumValues = resultsData->cellScalarResults( bordNumAddr, 0 );
|
|
||||||
if ( bordNumValues.empty() ) return;
|
|
||||||
|
|
||||||
auto activeReservoirCellIdxs =
|
auto activeReservoirCellIdxs =
|
||||||
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
|
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
|
||||||
|
|
||||||
@@ -295,7 +276,7 @@ void generateBcconResult( RimEclipseCase* eclipseCase, const caf::VecIjk0& min,
|
|||||||
for ( auto activeCellIdx : activeReservoirCellIdxs )
|
for ( auto activeCellIdx : activeReservoirCellIdxs )
|
||||||
{
|
{
|
||||||
// Check if this cell is a border cell
|
// Check if this cell is a border cell
|
||||||
int borderValue = static_cast<int>( bordNumValues[activeCellIdx.value()] );
|
int borderValue = borderResult[activeCellIdx.value()];
|
||||||
if ( borderValue != BorderType::BORDER_CELL ) continue;
|
if ( borderValue != BorderType::BORDER_CELL ) continue;
|
||||||
|
|
||||||
// Get IJK indices for this cell
|
// Get IJK indices for this cell
|
||||||
@@ -334,38 +315,22 @@ void generateBcconResult( RimEclipseCase* eclipseCase, const caf::VecIjk0& min,
|
|||||||
result[activeCellIdx.value()] = bcconValue;
|
result[activeCellIdx.value()] = bcconValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RigEclipseResultTools::createResultVector( *eclipseCase, "BCCON", result );
|
return result;
|
||||||
|
|
||||||
eclipseCase->updateConnectedEditors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase )
|
std::vector<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase,
|
||||||
|
const std::vector<int>& borderResult,
|
||||||
|
const std::vector<int>& bcconResult )
|
||||||
{
|
{
|
||||||
if ( eclipseCase == nullptr ) return {};
|
if ( eclipseCase == nullptr ) return {};
|
||||||
|
|
||||||
auto resultsData = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
|
||||||
if ( !resultsData ) return {};
|
|
||||||
|
|
||||||
auto grid = eclipseCase->eclipseCaseData()->mainGrid();
|
auto grid = eclipseCase->eclipseCaseData()->mainGrid();
|
||||||
if ( !grid ) return {};
|
if ( !grid ) return {};
|
||||||
|
|
||||||
// Check if BORDNUM result exists
|
if ( borderResult.empty() || bcconResult.empty() ) return {};
|
||||||
RigEclipseResultAddress bordNumAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, RiaResultNames::bordnum() );
|
|
||||||
if ( !resultsData->hasResultEntry( bordNumAddr ) ) return {}; // BORDNUM not generated yet
|
|
||||||
|
|
||||||
resultsData->ensureKnownResultLoaded( bordNumAddr );
|
|
||||||
auto bordNumValues = resultsData->cellScalarResults( bordNumAddr, 0 );
|
|
||||||
if ( bordNumValues.empty() ) return {};
|
|
||||||
|
|
||||||
// Check if BCCON result exists to get boundary condition values
|
|
||||||
RigEclipseResultAddress bcconAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, "BCCON" );
|
|
||||||
if ( !resultsData->hasResultEntry( bcconAddr ) ) return {};
|
|
||||||
|
|
||||||
resultsData->ensureKnownResultLoaded( bcconAddr );
|
|
||||||
std::vector<double> bcconValues = resultsData->cellScalarResults( bcconAddr, 0 );
|
|
||||||
|
|
||||||
auto activeReservoirCellIdxs =
|
auto activeReservoirCellIdxs =
|
||||||
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
|
eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
|
||||||
@@ -376,7 +341,7 @@ std::vector<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase
|
|||||||
for ( auto activeCellIdx : activeReservoirCellIdxs )
|
for ( auto activeCellIdx : activeReservoirCellIdxs )
|
||||||
{
|
{
|
||||||
// Check if this cell is a border cell
|
// Check if this cell is a border cell
|
||||||
int borderValue = static_cast<int>( bordNumValues[activeCellIdx.value()] );
|
int borderValue = borderResult[activeCellIdx.value()];
|
||||||
if ( borderValue != BorderType::BORDER_CELL ) continue;
|
if ( borderValue != BorderType::BORDER_CELL ) continue;
|
||||||
|
|
||||||
// Get IJK indices for this cell
|
// Get IJK indices for this cell
|
||||||
@@ -403,11 +368,11 @@ std::vector<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase
|
|||||||
if ( it == activeReservoirCellIdxs.end() ) continue; // Neighbor not active
|
if ( it == activeReservoirCellIdxs.end() ) continue; // Neighbor not active
|
||||||
|
|
||||||
// Check if neighbor is an interior cell
|
// Check if neighbor is an interior cell
|
||||||
int neighborBorderValue = static_cast<int>( bordNumValues[neighborReservoirIdx] );
|
int neighborBorderValue = borderResult[neighborReservoirIdx];
|
||||||
if ( neighborBorderValue == BorderType::INTERIOR_CELL )
|
if ( neighborBorderValue == BorderType::INTERIOR_CELL )
|
||||||
{
|
{
|
||||||
// Get boundary condition value from BCCON grid property
|
// Get boundary condition value from BCCON grid property
|
||||||
int boundaryCondition = static_cast<int>( bcconValues[activeCellIdx.value()] );
|
int boundaryCondition = bcconResult[activeCellIdx.value()];
|
||||||
if ( boundaryCondition > 0 )
|
if ( boundaryCondition > 0 )
|
||||||
{
|
{
|
||||||
// Add this face to the result
|
// Add this face to the result
|
||||||
|
|||||||
@@ -46,16 +46,21 @@ struct BorderCellFace
|
|||||||
|
|
||||||
void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector<int>& intValues );
|
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" );
|
std::vector<int> generateBorderResult( RimEclipseCase* eclipseCase, cvf::ref<cvf::UByteArray> customVisibility );
|
||||||
|
|
||||||
int generateOperNumResult( RimEclipseCase* eclipseCase, int borderCellValue = -1 );
|
std::vector<int> generateOperNumResult( RimEclipseCase* eclipseCase, const std::vector<int>& borderResult, int borderCellValue = -1 );
|
||||||
|
|
||||||
int findMaxOperNumValue( RimEclipseCase* eclipseCase );
|
int findMaxOperNumValue( RimEclipseCase* eclipseCase );
|
||||||
|
|
||||||
int findMaxBcconValue( RimEclipseCase* eclipseCase );
|
int findMaxBcconValue( RimEclipseCase* eclipseCase );
|
||||||
|
|
||||||
void generateBcconResult( RimEclipseCase* eclipseCase, const caf::VecIjk0& min, const caf::VecIjk0& max );
|
std::vector<int> generateBcconResult( RimEclipseCase* eclipseCase,
|
||||||
|
const std::vector<int>& borderResult,
|
||||||
|
const caf::VecIjk0& min,
|
||||||
|
const caf::VecIjk0& max );
|
||||||
|
|
||||||
std::vector<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase );
|
std::vector<BorderCellFace> generateBorderCellFaces( RimEclipseCase* eclipseCase,
|
||||||
|
const std::vector<int>& borderResult,
|
||||||
|
const std::vector<int>& bcconResult );
|
||||||
|
|
||||||
} // namespace RigEclipseResultTools
|
} // namespace RigEclipseResultTools
|
||||||
@@ -20,9 +20,6 @@
|
|||||||
|
|
||||||
#include "RiaLogging.h"
|
#include "RiaLogging.h"
|
||||||
|
|
||||||
#include "RiaResultNames.h"
|
|
||||||
#include "RigSimulationInputSettings.h"
|
|
||||||
|
|
||||||
#include "RifEclipseInputFileTools.h"
|
#include "RifEclipseInputFileTools.h"
|
||||||
#include "RifOpmDeckTools.h"
|
#include "RifOpmDeckTools.h"
|
||||||
#include "RifOpmFlowDeckFile.h"
|
#include "RifOpmFlowDeckFile.h"
|
||||||
@@ -35,6 +32,7 @@
|
|||||||
#include "RigEclipseResultTools.h"
|
#include "RigEclipseResultTools.h"
|
||||||
#include "RigGridExportAdapter.h"
|
#include "RigGridExportAdapter.h"
|
||||||
#include "RigResdataGridConverter.h"
|
#include "RigResdataGridConverter.h"
|
||||||
|
#include "RigSimulationInputSettings.h"
|
||||||
#include "Well/RigSimWellData.h"
|
#include "Well/RigSimWellData.h"
|
||||||
#include "Well/RigWellResultFrame.h"
|
#include "Well/RigWellResultFrame.h"
|
||||||
#include "Well/RigWellResultPoint.h"
|
#include "Well/RigWellResultPoint.h"
|
||||||
@@ -82,28 +80,6 @@ std::expected<void, QString> RigSimulationInputTool::exportSimulationInput( RimE
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate BORDNUM result based on visibility
|
|
||||||
if ( visibility && visibility->size() > 0 )
|
|
||||||
{
|
|
||||||
RigEclipseResultTools::generateBorderResult( &eclipseCase, visibility, RiaResultNames::bordnum() );
|
|
||||||
if ( settings.boundaryCondition() == RiaModelExportDefines::BoundaryCondition::BCCON_BCPROP )
|
|
||||||
{
|
|
||||||
// Generate BCCON result to assign values 1-6 based on which face of the box the border cells are on
|
|
||||||
RigEclipseResultTools::generateBcconResult( &eclipseCase, settings.min(), settings.max() );
|
|
||||||
}
|
|
||||||
else if ( settings.boundaryCondition() == RiaModelExportDefines::BoundaryCondition::OPERNUM_OPERATER )
|
|
||||||
{
|
|
||||||
// Generate OPERNUM result based on BORDNUM (border cells get max existing OPERNUM + 1)
|
|
||||||
int operNumRegion = RigEclipseResultTools::generateOperNumResult( &eclipseCase );
|
|
||||||
|
|
||||||
if ( auto result = addOperNumRegionAndOperater( &eclipseCase, settings, deckFile, operNumRegion, settings.porvMultiplier() );
|
|
||||||
!result )
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( auto result = replaceKeywordValuesInDeckFile( &eclipseCase, settings, deckFile ); !result )
|
if ( auto result = replaceKeywordValuesInDeckFile( &eclipseCase, settings, deckFile ); !result )
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
@@ -144,7 +120,7 @@ std::expected<void, QString> RigSimulationInputTool::exportSimulationInput( RimE
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( auto result = addBorderBoundaryConditions( &eclipseCase, settings, deckFile ); !result )
|
if ( auto result = addBorderBoundaryConditions( &eclipseCase, settings, visibility, deckFile ); !result )
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -311,59 +287,115 @@ std::expected<void, QString> RigSimulationInputTool::replaceKeywordValuesInDeckF
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::expected<void, QString> RigSimulationInputTool::addBorderBoundaryConditions( RimEclipseCase* eclipseCase,
|
std::expected<void, QString> RigSimulationInputTool::addBorderBoundaryConditions( RimEclipseCase* eclipseCase,
|
||||||
const RigSimulationInputSettings& settings,
|
const RigSimulationInputSettings& settings,
|
||||||
|
cvf::ref<cvf::UByteArray> visibility,
|
||||||
RifOpmFlowDeckFile& deckFile )
|
RifOpmFlowDeckFile& deckFile )
|
||||||
{
|
{
|
||||||
// Generate border cell faces
|
// Return early if no visibility
|
||||||
auto borderCellFaces = RigEclipseResultTools::generateBorderCellFaces( eclipseCase );
|
if ( visibility.isNull() || visibility->size() == 0 )
|
||||||
|
|
||||||
if ( !borderCellFaces.empty() )
|
|
||||||
{
|
{
|
||||||
// Transform border cell face coordinates to sector-relative coordinates
|
RiaLogging::info( "No visibility provided - skipping boundary conditions" );
|
||||||
for ( auto& face : borderCellFaces )
|
return {};
|
||||||
{
|
}
|
||||||
auto transformResult =
|
|
||||||
RigGridExportAdapter::transformIjkToSectorCoordinates( face.ijk, settings.min(), settings.max(), settings.refinement(), true );
|
|
||||||
|
|
||||||
if ( !transformResult )
|
// Generate border result (BORDNUM) in memory
|
||||||
|
auto borderResult = RigEclipseResultTools::generateBorderResult( eclipseCase, visibility );
|
||||||
|
|
||||||
|
if ( borderResult.empty() )
|
||||||
|
{
|
||||||
|
RiaLogging::warning( "Failed to generate border result - skipping boundary conditions" );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle boundary condition based on settings
|
||||||
|
if ( settings.boundaryCondition() == RiaModelExportDefines::BoundaryCondition::BCCON_BCPROP )
|
||||||
|
{
|
||||||
|
// Generate BCCON result in memory
|
||||||
|
auto bcconResult = RigEclipseResultTools::generateBcconResult( eclipseCase, borderResult, settings.min(), settings.max() );
|
||||||
|
|
||||||
|
if ( bcconResult.empty() )
|
||||||
|
{
|
||||||
|
RiaLogging::warning( "Failed to generate BCCON result - skipping boundary conditions" );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate border cell faces using in-memory results
|
||||||
|
auto borderCellFaces = RigEclipseResultTools::generateBorderCellFaces( eclipseCase, borderResult, bcconResult );
|
||||||
|
|
||||||
|
if ( !borderCellFaces.empty() )
|
||||||
|
{
|
||||||
|
// Transform border cell face coordinates to sector-relative coordinates
|
||||||
|
for ( auto& face : borderCellFaces )
|
||||||
{
|
{
|
||||||
RiaLogging::warning( QString( "Failed to transform border cell face at (%1, %2, %3): %4" )
|
auto transformResult =
|
||||||
.arg( face.ijk.x() )
|
RigGridExportAdapter::transformIjkToSectorCoordinates( face.ijk, settings.min(), settings.max(), settings.refinement(), true );
|
||||||
.arg( face.ijk.y() )
|
|
||||||
.arg( face.ijk.z() )
|
if ( !transformResult )
|
||||||
.arg( transformResult.error() ) );
|
{
|
||||||
continue;
|
RiaLogging::warning( QString( "Failed to transform border cell face at (%1, %2, %3): %4" )
|
||||||
|
.arg( face.ijk.x() )
|
||||||
|
.arg( face.ijk.y() )
|
||||||
|
.arg( face.ijk.z() )
|
||||||
|
.arg( transformResult.error() ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the IJK coordinates to sector-relative (1-based Eclipse coordinates)
|
||||||
|
// Note: RigGridExportAdapter::transformIjkToSectorCoordinates returns 1-based coordinates, but we need to convert back to
|
||||||
|
// 0-based for the BorderCellFace struct
|
||||||
|
face.ijk = transformResult->toZeroBased();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the IJK coordinates to sector-relative (1-based Eclipse coordinates)
|
// Create BCCON keyword using the factory
|
||||||
// Note: RigGridExportAdapter::transformIjkToSectorCoordinates returns 1-based coordinates, but we need to convert back to
|
Opm::DeckKeyword bcconKw = RimKeywordFactory::bcconKeyword( borderCellFaces );
|
||||||
// 0-based for the BorderCellFace struct
|
|
||||||
face.ijk = transformResult->toZeroBased();
|
// Replace BCCON keyword in GRID section
|
||||||
|
if ( !deckFile.replaceKeyword( "GRID", bcconKw ) )
|
||||||
|
{
|
||||||
|
return std::unexpected( "Failed to replace BCCON keyword in deck file" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build BCPROP records from the settings configuration
|
||||||
|
std::vector<Opm::DeckRecord> bcpropRecords = settings.bcpropKeywords();
|
||||||
|
|
||||||
|
// Create BCPROP keyword using the factory
|
||||||
|
Opm::DeckKeyword bcpropKw = RimKeywordFactory::bcpropKeyword( borderCellFaces, bcpropRecords );
|
||||||
|
|
||||||
|
// Replace BCPROP keyword in GRID section
|
||||||
|
if ( !deckFile.replaceKeyword( Opm::ParserKeywords::SCHEDULE::keywordName, bcpropKw ) )
|
||||||
|
{
|
||||||
|
return std::unexpected( "Failed to replace BCPROP keyword in deck file" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// Create BCCON keyword using the factory
|
|
||||||
Opm::DeckKeyword bcconKw = RimKeywordFactory::bcconKeyword( borderCellFaces );
|
|
||||||
|
|
||||||
// Replace BCCON keyword in GRID section
|
|
||||||
if ( !deckFile.replaceKeyword( "GRID", bcconKw ) )
|
|
||||||
{
|
{
|
||||||
return std::unexpected( "Failed to replace BCCON keyword in deck file" );
|
RiaLogging::warning( "No border cells found - skipping BCCON/BCPROP keyword generation" );
|
||||||
}
|
|
||||||
|
|
||||||
// Build BCPROP records from the settings configuration
|
|
||||||
std::vector<Opm::DeckRecord> bcpropRecords = settings.bcpropKeywords();
|
|
||||||
|
|
||||||
// Create BCPROP keyword using the factory
|
|
||||||
Opm::DeckKeyword bcpropKw = RimKeywordFactory::bcpropKeyword( borderCellFaces, bcpropRecords );
|
|
||||||
|
|
||||||
// Replace BCPROP keyword in GRID section
|
|
||||||
if ( !deckFile.replaceKeyword( Opm::ParserKeywords::SCHEDULE::keywordName, bcpropKw ) )
|
|
||||||
{
|
|
||||||
return std::unexpected( "Failed to replace BCPROP keyword in deck file" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if ( settings.boundaryCondition() == RiaModelExportDefines::BoundaryCondition::OPERNUM_OPERATER )
|
||||||
{
|
{
|
||||||
RiaLogging::warning( "No border cells found - skipping BCCON/BCPROP keyword generation" );
|
// Generate OPERNUM result based on border result (border cells get max existing OPERNUM + 1)
|
||||||
|
auto operNumResult = RigEclipseResultTools::generateOperNumResult( eclipseCase, borderResult );
|
||||||
|
|
||||||
|
// Find the border cell value used
|
||||||
|
int operNumRegion = -1;
|
||||||
|
for ( size_t i = 0; i < operNumResult.size(); i++ )
|
||||||
|
{
|
||||||
|
if ( borderResult[i] == RigEclipseResultTools::BorderType::BORDER_CELL )
|
||||||
|
{
|
||||||
|
operNumRegion = operNumResult[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( operNumRegion != -1 )
|
||||||
|
{
|
||||||
|
if ( auto result =
|
||||||
|
addOperNumRegionAndOperater( eclipseCase, settings, deckFile, operNumResult, operNumRegion, settings.porvMultiplier() );
|
||||||
|
!result )
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@@ -1431,6 +1463,7 @@ std::expected<void, QString> RigSimulationInputTool::filterAndUpdateWellKeywords
|
|||||||
std::expected<void, QString> RigSimulationInputTool::addOperNumRegionAndOperater( RimEclipseCase* eclipseCase,
|
std::expected<void, QString> RigSimulationInputTool::addOperNumRegionAndOperater( RimEclipseCase* eclipseCase,
|
||||||
const RigSimulationInputSettings& settings,
|
const RigSimulationInputSettings& settings,
|
||||||
RifOpmFlowDeckFile& deckFile,
|
RifOpmFlowDeckFile& deckFile,
|
||||||
|
const std::vector<int>& operNumResult,
|
||||||
int operNumRegion,
|
int operNumRegion,
|
||||||
double porvMultiplier )
|
double porvMultiplier )
|
||||||
{
|
{
|
||||||
@@ -1483,33 +1516,56 @@ std::expected<void, QString> RigSimulationInputTool::addOperNumRegionAndOperater
|
|||||||
Opm::DeckKeyword newKw( ( Opm::ParserKeywords::OPERNUM() ) );
|
Opm::DeckKeyword newKw( ( Opm::ParserKeywords::OPERNUM() ) );
|
||||||
deckFile.addKeyword( "GRID", newKw );
|
deckFile.addKeyword( "GRID", newKw );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to extract keyword data
|
// Export OPERNUM data for the sector (with refinement)
|
||||||
auto result = RifEclipseInputFileTools::extractKeywordData( eclipseCase->eclipseCaseData(),
|
auto mainGrid = eclipseCase->eclipseCaseData()->mainGrid();
|
||||||
"OPERNUM",
|
auto activeCells = eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||||
settings.min(),
|
auto refinementV = settings.refinement();
|
||||||
settings.max(),
|
auto min = settings.min();
|
||||||
settings.refinement() );
|
auto max = settings.max();
|
||||||
if ( result )
|
|
||||||
|
std::vector<double> exportedData;
|
||||||
|
cvf::Vec3st refinedMin( min.x() * refinementV.x(), min.y() * refinementV.y(), min.z() * refinementV.z() );
|
||||||
|
cvf::Vec3st refinedMax( ( max.x() + 1 ) * refinementV.x(), ( max.y() + 1 ) * refinementV.y(), ( max.z() + 1 ) * refinementV.z() );
|
||||||
|
|
||||||
|
for ( size_t k = refinedMin.z(); k < refinedMax.z(); ++k )
|
||||||
|
{
|
||||||
|
size_t mainK = k / refinementV.z();
|
||||||
|
for ( size_t j = refinedMin.y(); j < refinedMax.y(); ++j )
|
||||||
{
|
{
|
||||||
// Replace keyword values in deck with extracted data
|
size_t mainJ = j / refinementV.y();
|
||||||
if ( deckFile.replaceKeywordData( "OPERNUM", result.value() ) )
|
for ( size_t i = refinedMin.x(); i < refinedMax.x(); ++i )
|
||||||
{
|
{
|
||||||
RiaLogging::info( "Added replaced opernum value in existing position." );
|
size_t mainI = i / refinementV.x();
|
||||||
}
|
size_t reservoirCellIndex = mainGrid->cellIndexFromIJK( mainI, mainJ, mainK );
|
||||||
else
|
size_t resIndex = activeCells->cellResultIndex( reservoirCellIndex );
|
||||||
{
|
|
||||||
return std::unexpected( "Unable to replace OPERNUM values" );
|
if ( resIndex != cvf::UNDEFINED_SIZE_T && reservoirCellIndex < operNumResult.size() )
|
||||||
|
{
|
||||||
|
exportedData.push_back( static_cast<double>( operNumResult[reservoirCellIndex] ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exportedData.push_back( 1.0 ); // Default value for inactive cells
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
return std::unexpected( "No OPERNUM result found." );
|
if ( exportedData.empty() )
|
||||||
}
|
{
|
||||||
|
return std::unexpected( "Failed to export OPERNUM data for sector" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace keyword values in deck with exported data
|
||||||
|
if ( deckFile.replaceKeywordData( "OPERNUM", exportedData ) )
|
||||||
|
{
|
||||||
|
RiaLogging::info( "Added replaced opernum value in existing position." );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RiaLogging::info( "OPERNUM keyword already exists in deck, skipping INCLUDE" );
|
return std::unexpected( "Unable to replace OPERNUM values" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create OPERATER keyword to multiply pore volume in border region
|
// Create OPERATER keyword to multiply pore volume in border region
|
||||||
|
|||||||
@@ -83,8 +83,10 @@ private:
|
|||||||
static std::expected<void, QString>
|
static std::expected<void, QString>
|
||||||
updateWelldimsKeyword( RimEclipseCase* eclipseCase, const RigSimulationInputSettings& settings, RifOpmFlowDeckFile& deckFile );
|
updateWelldimsKeyword( RimEclipseCase* eclipseCase, const RigSimulationInputSettings& settings, RifOpmFlowDeckFile& deckFile );
|
||||||
|
|
||||||
static std::expected<void, QString>
|
static std::expected<void, QString> addBorderBoundaryConditions( RimEclipseCase* eclipseCase,
|
||||||
addBorderBoundaryConditions( RimEclipseCase* eclipseCase, const RigSimulationInputSettings& settings, RifOpmFlowDeckFile& deckFile );
|
const RigSimulationInputSettings& settings,
|
||||||
|
cvf::ref<cvf::UByteArray> visibility,
|
||||||
|
RifOpmFlowDeckFile& deckFile );
|
||||||
|
|
||||||
static std::expected<void, QString>
|
static std::expected<void, QString>
|
||||||
replaceEqualsKeywordIndices( RimEclipseCase* eclipseCase, const RigSimulationInputSettings& settings, RifOpmFlowDeckFile& deckFile );
|
replaceEqualsKeywordIndices( RimEclipseCase* eclipseCase, const RigSimulationInputSettings& settings, RifOpmFlowDeckFile& deckFile );
|
||||||
@@ -113,6 +115,7 @@ private:
|
|||||||
static std::expected<void, QString> addOperNumRegionAndOperater( RimEclipseCase* eclipseCase,
|
static std::expected<void, QString> addOperNumRegionAndOperater( RimEclipseCase* eclipseCase,
|
||||||
const RigSimulationInputSettings& settings,
|
const RigSimulationInputSettings& settings,
|
||||||
RifOpmFlowDeckFile& deckFile,
|
RifOpmFlowDeckFile& deckFile,
|
||||||
|
const std::vector<int>& operNumResult,
|
||||||
int operNumRegion,
|
int operNumRegion,
|
||||||
double porvMultiplier );
|
double porvMultiplier );
|
||||||
|
|
||||||
|
|||||||
@@ -460,33 +460,24 @@ TEST( RigEclipseCaseDataToolsTest, GenerateBorderResultFromIjkBounds )
|
|||||||
auto visibility = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), minIjk, maxIjk );
|
auto visibility = RigEclipseCaseDataTools::createVisibilityFromIjkBounds( eclipseCase.p(), minIjk, maxIjk );
|
||||||
ASSERT_FALSE( visibility.isNull() ) << "Visibility should be created successfully";
|
ASSERT_FALSE( visibility.isNull() ) << "Visibility should be created successfully";
|
||||||
|
|
||||||
// Generate border result using the custom visibility
|
// Generate border result using the custom visibility (returns vector)
|
||||||
RigEclipseResultTools::generateBorderResult( resultCase.get(), visibility, RiaResultNames::bordnum() );
|
auto borderResult = RigEclipseResultTools::generateBorderResult( resultCase.get(), visibility );
|
||||||
|
|
||||||
// Verify that the result was created
|
// Verify that the result was generated
|
||||||
auto resultsData = resultCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
ASSERT_GT( borderResult.size(), 0 ) << "Border result should not be empty";
|
||||||
ASSERT_NE( resultsData, nullptr ) << "Results data should not be null";
|
|
||||||
|
|
||||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, RiaResultNames::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
|
// Count cells with different values
|
||||||
int invisibleCells = 0;
|
int invisibleCells = 0;
|
||||||
int borderCells = 0;
|
int borderCells = 0;
|
||||||
int interiorCells = 0;
|
int interiorCells = 0;
|
||||||
|
|
||||||
for ( double value : resultVector )
|
for ( int value : borderResult )
|
||||||
{
|
{
|
||||||
int intValue = static_cast<int>( value );
|
if ( value == RigEclipseResultTools::BorderType::INVISIBLE_CELL )
|
||||||
if ( intValue == RigEclipseResultTools::BorderType::INVISIBLE_CELL )
|
|
||||||
invisibleCells++;
|
invisibleCells++;
|
||||||
else if ( intValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
else if ( value == RigEclipseResultTools::BorderType::BORDER_CELL )
|
||||||
borderCells++;
|
borderCells++;
|
||||||
else if ( intValue == RigEclipseResultTools::BorderType::INTERIOR_CELL )
|
else if ( value == RigEclipseResultTools::BorderType::INTERIOR_CELL )
|
||||||
interiorCells++;
|
interiorCells++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,9 +486,9 @@ TEST( RigEclipseCaseDataToolsTest, GenerateBorderResultFromIjkBounds )
|
|||||||
ASSERT_GT( borderCells, 0 ) << "Should have border cells (value 1)";
|
ASSERT_GT( borderCells, 0 ) << "Should have border cells (value 1)";
|
||||||
ASSERT_GE( interiorCells, 0 ) << "May have interior cells (value 2)";
|
ASSERT_GE( interiorCells, 0 ) << "May have interior cells (value 2)";
|
||||||
|
|
||||||
// The total should match the number of active cells
|
// The total should match the result vector size
|
||||||
int totalCells = invisibleCells + borderCells + interiorCells;
|
int totalCells = invisibleCells + borderCells + interiorCells;
|
||||||
ASSERT_EQ( totalCells, static_cast<int>( resultVector.size() ) ) << "Total should match result vector size";
|
ASSERT_EQ( totalCells, static_cast<int>( borderResult.size() ) ) << "Total should match result vector size";
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -532,42 +523,27 @@ TEST( RigEclipseCaseDataToolsTest, GenerateOperNumResultFromBorderResult )
|
|||||||
ASSERT_FALSE( visibility.isNull() ) << "Visibility should be created successfully";
|
ASSERT_FALSE( visibility.isNull() ) << "Visibility should be created successfully";
|
||||||
|
|
||||||
// Generate border result first (required for OPERNUM generation)
|
// Generate border result first (required for OPERNUM generation)
|
||||||
RigEclipseResultTools::generateBorderResult( resultCase.get(), visibility, RiaResultNames::bordnum() );
|
auto borderResult = RigEclipseResultTools::generateBorderResult( resultCase.get(), visibility );
|
||||||
|
|
||||||
// Verify BORDNUM was created
|
// Verify border result was generated
|
||||||
auto resultsData = resultCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
ASSERT_GT( borderResult.size(), 0 ) << "Border result should not be empty";
|
||||||
ASSERT_NE( resultsData, nullptr ) << "Results data should not be null";
|
|
||||||
|
|
||||||
RigEclipseResultAddress bordnumAddress( RiaDefines::ResultCatType::GENERATED,
|
// Test case 1: Generate OPERNUM with automatic border cell value (no existing OPERNUM, should get 2)
|
||||||
RiaDefines::ResultDataType::INTEGER,
|
auto opernumResult = RigEclipseResultTools::generateOperNumResult( resultCase.get(), borderResult );
|
||||||
RiaResultNames::bordnum() );
|
|
||||||
ASSERT_TRUE( resultsData->hasResultEntry( bordnumAddress ) ) << "BORDNUM result should exist";
|
|
||||||
|
|
||||||
// Test case 1: Generate OPERNUM with automatic border cell value (no existing OPERNUM, should get 1)
|
// Verify OPERNUM was generated
|
||||||
RigEclipseResultTools::generateOperNumResult( resultCase.get() );
|
ASSERT_EQ( borderResult.size(), opernumResult.size() ) << "BORDNUM and OPERNUM should have same size";
|
||||||
|
ASSERT_GT( opernumResult.size(), 0 ) << "OPERNUM vector should not be empty";
|
||||||
// Verify OPERNUM was created
|
|
||||||
RigEclipseResultAddress opernumAddress( RiaDefines::ResultCatType::GENERATED,
|
|
||||||
RiaDefines::ResultDataType::INTEGER,
|
|
||||||
RiaResultNames::opernum() );
|
|
||||||
ASSERT_TRUE( resultsData->hasResultEntry( opernumAddress ) ) << "OPERNUM result should exist";
|
|
||||||
|
|
||||||
// Get the result data
|
|
||||||
const std::vector<double>& bordnumVector = resultsData->cellScalarResults( bordnumAddress, 0 );
|
|
||||||
const std::vector<double>& opernumVector = resultsData->cellScalarResults( opernumAddress, 0 );
|
|
||||||
|
|
||||||
ASSERT_EQ( bordnumVector.size(), opernumVector.size() ) << "BORDNUM and OPERNUM should have same size";
|
|
||||||
ASSERT_GT( opernumVector.size(), 0 ) << "OPERNUM vector should not be empty";
|
|
||||||
|
|
||||||
// Count cells with different values and verify the logic
|
// Count cells with different values and verify the logic
|
||||||
int borderCellsWithOperValue = 0; // BORDNUM=1 cells that should get OPERNUM=1 (max 0 + 1)
|
int borderCellsWithOperValue = 0; // BORDNUM=1 cells that should get OPERNUM=2 (max 0 + 1, then default 2)
|
||||||
int defaultOperCells = 0; // BORDNUM!=1 cells that should get OPERNUM=0
|
int defaultOperCells = 0; // BORDNUM!=1 cells that should get OPERNUM=1
|
||||||
int borderCellsTotal = 0; // Total BORDNUM=1 cells
|
int borderCellsTotal = 0; // Total BORDNUM=1 cells
|
||||||
|
|
||||||
for ( size_t i = 0; i < bordnumVector.size(); ++i )
|
for ( size_t i = 0; i < borderResult.size(); ++i )
|
||||||
{
|
{
|
||||||
int bordnumValue = static_cast<int>( bordnumVector[i] );
|
int bordnumValue = borderResult[i];
|
||||||
int opernumValue = static_cast<int>( opernumVector[i] );
|
int opernumValue = opernumResult[i];
|
||||||
|
|
||||||
if ( bordnumValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
if ( bordnumValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
||||||
{
|
{
|
||||||
@@ -610,19 +586,16 @@ TEST( RigEclipseCaseDataToolsTest, GenerateOperNumResultFromBorderResult )
|
|||||||
ASSERT_EQ( maxOperValue, 15 ) << "Max OPERNUM value should be 15";
|
ASSERT_EQ( maxOperValue, 15 ) << "Max OPERNUM value should be 15";
|
||||||
|
|
||||||
// Now generate OPERNUM again - should use max value + 1 = 16 for border cells
|
// Now generate OPERNUM again - should use max value + 1 = 16 for border cells
|
||||||
RigEclipseResultTools::generateOperNumResult( resultCase.get() );
|
auto updatedOpernumResult = RigEclipseResultTools::generateOperNumResult( resultCase.get(), borderResult );
|
||||||
|
|
||||||
// Get updated result
|
|
||||||
const std::vector<double>& updatedOpernumVector = resultsData->cellScalarResults( opernumAddress, 0 );
|
|
||||||
|
|
||||||
// Verify the behavior
|
// Verify the behavior
|
||||||
int preservedValues = 0;
|
int preservedValues = 0;
|
||||||
int modifiedValues = 0;
|
int modifiedValues = 0;
|
||||||
|
|
||||||
for ( size_t i = 0; i < bordnumVector.size(); ++i )
|
for ( size_t i = 0; i < borderResult.size(); ++i )
|
||||||
{
|
{
|
||||||
int bordnumValue = static_cast<int>( bordnumVector[i] );
|
int bordnumValue = borderResult[i];
|
||||||
int opernumValue = static_cast<int>( updatedOpernumVector[i] );
|
int opernumValue = updatedOpernumResult[i];
|
||||||
|
|
||||||
if ( bordnumValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
if ( bordnumValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
||||||
{
|
{
|
||||||
@@ -647,5 +620,5 @@ TEST( RigEclipseCaseDataToolsTest, GenerateOperNumResultFromBorderResult )
|
|||||||
|
|
||||||
// Total should match vector size
|
// Total should match vector size
|
||||||
int totalChecked = modifiedValues + preservedValues;
|
int totalChecked = modifiedValues + preservedValues;
|
||||||
ASSERT_EQ( totalChecked, static_cast<int>( updatedOpernumVector.size() ) ) << "Should check all cells";
|
ASSERT_EQ( totalChecked, static_cast<int>( updatedOpernumResult.size() ) ) << "Should check all cells";
|
||||||
}
|
}
|
||||||
@@ -27,11 +27,10 @@
|
|||||||
|
|
||||||
#include "ProjectDataModel/Jobs/RimKeywordFactory.h"
|
#include "ProjectDataModel/Jobs/RimKeywordFactory.h"
|
||||||
|
|
||||||
#include "RigActiveCellInfo.h"
|
|
||||||
#include "RigCaseCellResultsData.h"
|
#include "RigCaseCellResultsData.h"
|
||||||
#include "RigEclipseCaseData.h"
|
#include "RigEclipseCaseData.h"
|
||||||
#include "RigEclipseResultAddress.h"
|
|
||||||
#include "RigMainGrid.h"
|
#include "RigMainGrid.h"
|
||||||
|
#include "RigSimulationInputTool.h"
|
||||||
#include "RimEclipseResultCase.h"
|
#include "RimEclipseResultCase.h"
|
||||||
|
|
||||||
#include "opm/input/eclipse/Deck/DeckKeyword.hpp"
|
#include "opm/input/eclipse/Deck/DeckKeyword.hpp"
|
||||||
@@ -108,32 +107,28 @@ TEST( RigEclipseResultToolsTest, BorderCellBcconGeneration )
|
|||||||
{
|
{
|
||||||
size_t cellIndex = grid->cellIndexFromIJK( i, j, k );
|
size_t cellIndex = grid->cellIndexFromIJK( i, j, k );
|
||||||
( *customVisibility )[cellIndex] = 1;
|
( *customVisibility )[cellIndex] = 1;
|
||||||
|
|
||||||
// Set bccon==1 for half of the cells
|
|
||||||
if ( i > grid->cellCountI() / 2 )
|
|
||||||
{
|
|
||||||
bcconValues[cellIndex] = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Generate BORDNUM result
|
// Step 3: Generate BORDNUM result (returns vector, doesn't store)
|
||||||
RigEclipseResultTools::generateBorderResult( testCase.get(), customVisibility, "BORDNUM" );
|
auto borderResult = RigEclipseResultTools::generateBorderResult( testCase.get(), customVisibility );
|
||||||
|
|
||||||
// Verify BORDNUM was created
|
// Verify border result values
|
||||||
auto resultsData = testCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
EXPECT_EQ( borderResult.size(), cellCount );
|
||||||
ASSERT_NE( resultsData, nullptr );
|
|
||||||
|
|
||||||
RigEclipseResultAddress bordNumAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, "BORDNUM" );
|
// Step 4: Generate BCCON result (takes border result as input, returns vector)
|
||||||
ASSERT_TRUE( resultsData->hasResultEntry( bordNumAddr ) ) << "BORDNUM result not created";
|
caf::VecIjk0 min( startI, startJ, startK );
|
||||||
|
caf::VecIjk0 max( endI - 1, endJ - 1, endK - 1 );
|
||||||
|
auto bcconResult = RigEclipseResultTools::generateBcconResult( testCase.get(), borderResult, min, max );
|
||||||
|
|
||||||
RigEclipseResultTools::createResultVector( *testCase, "BCCON", bcconValues );
|
// Verify BCCON values
|
||||||
|
EXPECT_EQ( bcconResult.size(), cellCount );
|
||||||
|
|
||||||
// Step 4: Generate border cell faces
|
// Step 5: Generate border cell faces using in-memory results
|
||||||
auto borderCellFaces = RigEclipseResultTools::generateBorderCellFaces( testCase.get() );
|
auto borderCellFaces = RigEclipseResultTools::generateBorderCellFaces( testCase.get(), borderResult, bcconResult );
|
||||||
|
|
||||||
// Step 5: Verify results
|
// Step 6: Verify results
|
||||||
EXPECT_GT( borderCellFaces.size(), 0 ) << "No border cell faces generated";
|
EXPECT_GT( borderCellFaces.size(), 0 ) << "No border cell faces generated";
|
||||||
|
|
||||||
// Verify that all faces are within the visible region boundaries
|
// Verify that all faces are within the visible region boundaries
|
||||||
@@ -150,11 +145,11 @@ TEST( RigEclipseResultToolsTest, BorderCellBcconGeneration )
|
|||||||
EXPECT_GE( static_cast<int>( face.faceType ), static_cast<int>( cvf::StructGridInterface::POS_I ) );
|
EXPECT_GE( static_cast<int>( face.faceType ), static_cast<int>( cvf::StructGridInterface::POS_I ) );
|
||||||
EXPECT_LT( static_cast<int>( face.faceType ), static_cast<int>( cvf::StructGridInterface::NO_FACE ) );
|
EXPECT_LT( static_cast<int>( face.faceType ), static_cast<int>( cvf::StructGridInterface::NO_FACE ) );
|
||||||
|
|
||||||
// Verify boundary condition (should be 1 if no BCCON grid property exists)
|
// Verify boundary condition value is set
|
||||||
EXPECT_EQ( face.boundaryCondition, 1 );
|
EXPECT_GT( face.boundaryCondition, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6: Create OPM deck file and add BCCON keyword
|
// Step 7: Create OPM deck file and add BCCON keyword
|
||||||
QTemporaryDir tempDir;
|
QTemporaryDir tempDir;
|
||||||
ASSERT_TRUE( tempDir.isValid() ) << "Failed to create temporary directory";
|
ASSERT_TRUE( tempDir.isValid() ) << "Failed to create temporary directory";
|
||||||
|
|
||||||
@@ -184,7 +179,7 @@ TEST( RigEclipseResultToolsTest, BorderCellBcconGeneration )
|
|||||||
bool bcconAdded = deckFile.replaceKeyword( "GRID", bcconKw );
|
bool bcconAdded = deckFile.replaceKeyword( "GRID", bcconKw );
|
||||||
ASSERT_TRUE( bcconAdded ) << "Failed to replace BCCON keyword";
|
ASSERT_TRUE( bcconAdded ) << "Failed to replace BCCON keyword";
|
||||||
|
|
||||||
// Step 7: Save deck and verify format
|
// Step 8: Save deck and verify format
|
||||||
QString outputDeckPath = tempDir.filePath( "output_bccon.DATA" );
|
QString outputDeckPath = tempDir.filePath( "output_bccon.DATA" );
|
||||||
bool deckSaved = deckFile.saveDeck( tempDir.path().toStdString(), "output_bccon.DATA" );
|
bool deckSaved = deckFile.saveDeck( tempDir.path().toStdString(), "output_bccon.DATA" );
|
||||||
ASSERT_TRUE( deckSaved ) << "Failed to save deck file";
|
ASSERT_TRUE( deckSaved ) << "Failed to save deck file";
|
||||||
@@ -276,32 +271,15 @@ TEST( RigEclipseResultToolsTest, BcconResultWithFaceNumbering )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Generate BORDNUM result
|
// Step 3: Generate BORDNUM result (returns vector)
|
||||||
RigEclipseResultTools::generateBorderResult( testCase.get(), customVisibility, "BORDNUM" );
|
auto borderResult = RigEclipseResultTools::generateBorderResult( testCase.get(), customVisibility );
|
||||||
|
|
||||||
// Verify BORDNUM was created
|
ASSERT_FALSE( borderResult.empty() ) << "Border result is empty";
|
||||||
auto resultsData = testCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
|
||||||
ASSERT_NE( resultsData, nullptr );
|
|
||||||
|
|
||||||
RigEclipseResultAddress bordNumAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, "BORDNUM" );
|
// Step 4: Generate BCCON result (returns vector)
|
||||||
ASSERT_TRUE( resultsData->hasResultEntry( bordNumAddr ) ) << "BORDNUM result not created";
|
auto bcconResult = RigEclipseResultTools::generateBcconResult( testCase.get(), borderResult, min, max );
|
||||||
|
|
||||||
// Step 4: Generate BCCON result
|
ASSERT_FALSE( bcconResult.empty() ) << "BCCON result is empty";
|
||||||
RigEclipseResultTools::generateBcconResult( testCase.get(), min, max );
|
|
||||||
|
|
||||||
// Verify BCCON was created
|
|
||||||
RigEclipseResultAddress bcconAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, "BCCON" );
|
|
||||||
ASSERT_TRUE( resultsData->hasResultEntry( bcconAddr ) ) << "BCCON result not created";
|
|
||||||
|
|
||||||
// Get BCCON and BORDNUM values
|
|
||||||
resultsData->ensureKnownResultLoaded( bcconAddr );
|
|
||||||
resultsData->ensureKnownResultLoaded( bordNumAddr );
|
|
||||||
|
|
||||||
auto bcconValues = resultsData->cellScalarResults( bcconAddr, 0 );
|
|
||||||
auto bordNumValues = resultsData->cellScalarResults( bordNumAddr, 0 );
|
|
||||||
|
|
||||||
ASSERT_FALSE( bcconValues.empty() ) << "BCCON values are empty";
|
|
||||||
ASSERT_FALSE( bordNumValues.empty() ) << "BORDNUM values are empty";
|
|
||||||
|
|
||||||
// Step 5: Verify BCCON values are correct
|
// Step 5: Verify BCCON values are correct
|
||||||
int countI_minus = 0, countI_plus = 0;
|
int countI_minus = 0, countI_plus = 0;
|
||||||
@@ -316,8 +294,8 @@ TEST( RigEclipseResultToolsTest, BcconResultWithFaceNumbering )
|
|||||||
{
|
{
|
||||||
size_t cellIndex = grid->cellIndexFromIJK( i, j, k );
|
size_t cellIndex = grid->cellIndexFromIJK( i, j, k );
|
||||||
|
|
||||||
int borderValue = static_cast<int>( bordNumValues[cellIndex] );
|
int borderValue = borderResult[cellIndex];
|
||||||
int bcconValue = static_cast<int>( bcconValues[cellIndex] );
|
int bcconValue = bcconResult[cellIndex];
|
||||||
|
|
||||||
// Only check border cells
|
// Only check border cells
|
||||||
if ( borderValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
if ( borderValue == RigEclipseResultTools::BorderType::BORDER_CELL )
|
||||||
|
|||||||
Reference in new issue
Block a user