mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-24 22:27:55 -05:00
Refactor: extract common code for converting sector box
This commit is contained in:
1 parent
ab708f5e0e
commit
101b4f4926
2 files changed
+193
-391
No files matched your search
@@ -761,6 +761,96 @@ std::expected<Opm::DeckRecord, QString> RigSimulationInputTool::processCompsegsR
|
||||
return Opm::DeckRecord{ std::move( items ) };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to transform bounding box from global to sector coordinates
|
||||
/// Performs intersection, clamping, and coordinate transformation
|
||||
/// Returns bounding box with 0-based sector-relative coordinates
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<RigBoundingBoxIjk, QString> RigSimulationInputTool::transformBoxToSectorCoordinates( const RigBoundingBoxIjk& inputBox,
|
||||
const caf::VecIjk0& sectorMin,
|
||||
const caf::VecIjk0& sectorMax,
|
||||
const cvf::Vec3st& refinement,
|
||||
const QString& keywordName,
|
||||
const QString& recordIdentifier )
|
||||
{
|
||||
// Create sector bounding box
|
||||
RigBoundingBoxIjk sectorBox( cvf::Vec3st( sectorMin.x(), sectorMin.y(), sectorMin.z() ),
|
||||
cvf::Vec3st( sectorMax.x(), sectorMax.y(), sectorMax.z() ) );
|
||||
|
||||
// Check if boxes overlap and get intersection
|
||||
auto intersection = inputBox.intersection( sectorBox );
|
||||
if ( !intersection )
|
||||
{
|
||||
// No overlap with sector - skip this record
|
||||
const auto& origMin = inputBox.min();
|
||||
const auto& origMax = inputBox.max();
|
||||
RiaLogging::info( QString( "%1 record%2 [%3-%4, %5-%6, %7-%8] does not overlap with sector - skipping" )
|
||||
.arg( keywordName )
|
||||
.arg( recordIdentifier.isEmpty() ? "" : " " + recordIdentifier )
|
||||
.arg( origMin.x() + 1 )
|
||||
.arg( origMax.x() + 1 )
|
||||
.arg( origMin.y() + 1 )
|
||||
.arg( origMax.y() + 1 )
|
||||
.arg( origMin.z() + 1 )
|
||||
.arg( origMax.z() + 1 ) );
|
||||
return std::unexpected( QString( "%1 record does not overlap with sector" ).arg( keywordName ) );
|
||||
}
|
||||
|
||||
// Get the clamped coordinates from the intersection
|
||||
cvf::Vec3st clampedMin = intersection->min();
|
||||
cvf::Vec3st clampedMax = intersection->max();
|
||||
|
||||
// Log if clamping occurred (partial overlap)
|
||||
const auto& origMin = inputBox.min();
|
||||
const auto& origMax = inputBox.max();
|
||||
if ( origMin.x() != clampedMin.x() || origMax.x() != clampedMax.x() || origMin.y() != clampedMin.y() || origMax.y() != clampedMax.y() ||
|
||||
origMin.z() != clampedMin.z() || origMax.z() != clampedMax.z() )
|
||||
{
|
||||
RiaLogging::info(
|
||||
QString( "%1 record%2 partially overlaps sector, clamped from [%3-%4, %5-%6, %7-%8] to [%9-%10, %11-%12, %13-%14]" )
|
||||
.arg( keywordName )
|
||||
.arg( recordIdentifier.isEmpty() ? "" : " " + recordIdentifier )
|
||||
.arg( origMin.x() + 1 )
|
||||
.arg( origMax.x() + 1 )
|
||||
.arg( origMin.y() + 1 )
|
||||
.arg( origMax.y() + 1 )
|
||||
.arg( origMin.z() + 1 )
|
||||
.arg( origMax.z() + 1 )
|
||||
.arg( clampedMin.x() + 1 )
|
||||
.arg( clampedMax.x() + 1 )
|
||||
.arg( clampedMin.y() + 1 )
|
||||
.arg( clampedMax.y() + 1 )
|
||||
.arg( clampedMin.z() + 1 )
|
||||
.arg( clampedMax.z() + 1 ) );
|
||||
}
|
||||
|
||||
// Transform clamped coordinates to sector-relative coordinates
|
||||
auto transformResult1 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( clampedMin.x(), clampedMin.y(), clampedMin.z() ),
|
||||
sectorMin,
|
||||
sectorMax,
|
||||
refinement );
|
||||
auto transformResult2 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( clampedMax.x(), clampedMax.y(), clampedMax.z() ),
|
||||
sectorMin,
|
||||
sectorMax,
|
||||
refinement );
|
||||
|
||||
if ( !transformResult1 )
|
||||
{
|
||||
return std::unexpected( QString( "%1 min coordinate is out of sector bounds: %2" ).arg( keywordName ).arg( transformResult1.error() ) );
|
||||
}
|
||||
|
||||
if ( !transformResult2 )
|
||||
{
|
||||
return std::unexpected( QString( "%1 max coordinate is out of sector bounds: %2" ).arg( keywordName ).arg( transformResult2.error() ) );
|
||||
}
|
||||
|
||||
// Return bounding box with 0-based sector-relative coordinates
|
||||
return RigBoundingBoxIjk( cvf::Vec3st( transformResult1->x() - 1, transformResult1->y() - 1, transformResult1->z() - 1 ),
|
||||
cvf::Vec3st( transformResult2->x() - 1, transformResult2->y() - 1, transformResult2->z() - 1 ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -794,77 +884,27 @@ std::expected<Opm::DeckRecord, QString> RigSimulationInputTool::processEqualsRec
|
||||
int origK1 = record.getItem( 6 ).get<int>( 0 ) - 1;
|
||||
int origK2 = record.getItem( 7 ).get<int>( 0 ) - 1;
|
||||
|
||||
// Create bounding boxes (both use inclusive min/max coordinates)
|
||||
RigBoundingBoxIjk equalsBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
RigBoundingBoxIjk sectorBox( cvf::Vec3st( min.x(), min.y(), min.z() ), cvf::Vec3st( max.x(), max.y(), max.z() ) );
|
||||
// Create input bounding box (0-based, inclusive)
|
||||
RigBoundingBoxIjk inputBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
|
||||
// Check if boxes overlap and get intersection
|
||||
auto intersection = equalsBox.intersection( sectorBox );
|
||||
if ( !intersection )
|
||||
// Get field name for logging
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
QString recordIdent = QString( "for field '%1'" ).arg( fieldName );
|
||||
|
||||
// Transform box to sector coordinates
|
||||
auto transformResult = transformBoxToSectorCoordinates( inputBox, min, max, refinement, "EQUALS", recordIdent );
|
||||
if ( !transformResult )
|
||||
{
|
||||
// No overlap with sector - skip this record
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info( QString( "EQUALS record for field '%1' [%2-%3, %4-%5, %6-%7] does not overlap with sector - skipping" )
|
||||
.arg( fieldName )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 ) );
|
||||
return std::unexpected( "EQUALS record does not overlap with sector" );
|
||||
}
|
||||
|
||||
// Get the clamped coordinates from the intersection
|
||||
cvf::Vec3st corner1 = intersection->min();
|
||||
cvf::Vec3st corner2 = intersection->max();
|
||||
|
||||
// Log if clamping occurred (partial overlap)
|
||||
if ( origI1 != static_cast<int>( corner1.x() ) || origI2 != static_cast<int>( corner2.x() ) ||
|
||||
origJ1 != static_cast<int>( corner1.y() ) || origJ2 != static_cast<int>( corner2.y() ) ||
|
||||
origK1 != static_cast<int>( corner1.z() ) || origK2 != static_cast<int>( corner2.z() ) )
|
||||
{
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info(
|
||||
QString( "EQUALS record for field '%1' partially overlaps sector, clamped from [%2-%3, %4-%5, %6-%7] to [%8-%9, %10-%11, "
|
||||
"%12-%13]" )
|
||||
.arg( fieldName )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 )
|
||||
.arg( corner1.x() + 1 )
|
||||
.arg( corner2.x() + 1 )
|
||||
.arg( corner1.y() + 1 )
|
||||
.arg( corner2.y() + 1 )
|
||||
.arg( corner1.z() + 1 )
|
||||
.arg( corner2.z() + 1 ) );
|
||||
}
|
||||
|
||||
auto transformResult1 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner1.x(), corner1.y(), corner1.z() ), min, max, refinement );
|
||||
auto transformResult2 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner2.x(), corner2.y(), corner2.z() ), min, max, refinement );
|
||||
|
||||
if ( !transformResult1 )
|
||||
{
|
||||
return std::unexpected( QString( "EQUALS I1,J1,K1 coordinate is out of sector bounds: %1" ).arg( transformResult1.error() ) );
|
||||
}
|
||||
|
||||
if ( !transformResult2 )
|
||||
{
|
||||
return std::unexpected( QString( "EQUALS I2,J2,K2 coordinate is out of sector bounds: %1" ).arg( transformResult2.error() ) );
|
||||
return std::unexpected( transformResult.error() );
|
||||
}
|
||||
|
||||
using E = Opm::ParserKeywords::EQUALS;
|
||||
items.push_back( RifOpmDeckTools::item( E::I1::itemName, static_cast<int>( transformResult1->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::I2::itemName, static_cast<int>( transformResult2->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::J1::itemName, static_cast<int>( transformResult1->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::J2::itemName, static_cast<int>( transformResult2->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::K1::itemName, static_cast<int>( transformResult1->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::K2::itemName, static_cast<int>( transformResult2->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::I1::itemName, static_cast<int>( transformResult->min().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::I2::itemName, static_cast<int>( transformResult->max().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::J1::itemName, static_cast<int>( transformResult->min().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::J2::itemName, static_cast<int>( transformResult->max().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::K1::itemName, static_cast<int>( transformResult->min().z() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( E::K2::itemName, static_cast<int>( transformResult->max().z() + 1 ) ) );
|
||||
}
|
||||
|
||||
return Opm::DeckRecord{ std::move( items ) };
|
||||
@@ -903,77 +943,27 @@ std::expected<Opm::DeckRecord, QString> RigSimulationInputTool::processMultiplyR
|
||||
int origK1 = record.getItem( 6 ).get<int>( 0 ) - 1;
|
||||
int origK2 = record.getItem( 7 ).get<int>( 0 ) - 1;
|
||||
|
||||
// Create bounding boxes (both use inclusive min/max coordinates)
|
||||
RigBoundingBoxIjk multiplyBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
RigBoundingBoxIjk sectorBox( cvf::Vec3st( min.x(), min.y(), min.z() ), cvf::Vec3st( max.x(), max.y(), max.z() ) );
|
||||
// Create input bounding box (0-based, inclusive)
|
||||
RigBoundingBoxIjk inputBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
|
||||
// Check if boxes overlap and get intersection
|
||||
auto intersection = multiplyBox.intersection( sectorBox );
|
||||
if ( !intersection )
|
||||
// Get field name for logging
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
QString recordIdent = QString( "for field '%1'" ).arg( fieldName );
|
||||
|
||||
// Transform box to sector coordinates
|
||||
auto transformResult = transformBoxToSectorCoordinates( inputBox, min, max, refinement, "MULTIPLY", recordIdent );
|
||||
if ( !transformResult )
|
||||
{
|
||||
// No overlap with sector - skip this record
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info( QString( "MULTIPLY record for field '%1' [%2-%3, %4-%5, %6-%7] does not overlap with sector - skipping" )
|
||||
.arg( fieldName )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 ) );
|
||||
return std::unexpected( "MULTIPLY record does not overlap with sector" );
|
||||
}
|
||||
|
||||
// Get the clamped coordinates from the intersection
|
||||
cvf::Vec3st corner1 = intersection->min();
|
||||
cvf::Vec3st corner2 = intersection->max();
|
||||
|
||||
// Log if clamping occurred (partial overlap)
|
||||
if ( origI1 != static_cast<int>( corner1.x() ) || origI2 != static_cast<int>( corner2.x() ) ||
|
||||
origJ1 != static_cast<int>( corner1.y() ) || origJ2 != static_cast<int>( corner2.y() ) ||
|
||||
origK1 != static_cast<int>( corner1.z() ) || origK2 != static_cast<int>( corner2.z() ) )
|
||||
{
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info(
|
||||
QString( "MULTIPLY record for field '%1' partially overlaps sector, clamped from [%2-%3, %4-%5, %6-%7] to [%8-%9, %10-%11, "
|
||||
"%12-%13]" )
|
||||
.arg( fieldName )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 )
|
||||
.arg( corner1.x() + 1 )
|
||||
.arg( corner2.x() + 1 )
|
||||
.arg( corner1.y() + 1 )
|
||||
.arg( corner2.y() + 1 )
|
||||
.arg( corner1.z() + 1 )
|
||||
.arg( corner2.z() + 1 ) );
|
||||
}
|
||||
|
||||
auto transformResult1 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner1.x(), corner1.y(), corner1.z() ), min, max, refinement );
|
||||
auto transformResult2 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner2.x(), corner2.y(), corner2.z() ), min, max, refinement );
|
||||
|
||||
if ( !transformResult1 )
|
||||
{
|
||||
return std::unexpected( QString( "MULTIPLY I1,J1,K1 coordinate is out of sector bounds: %1" ).arg( transformResult1.error() ) );
|
||||
}
|
||||
|
||||
if ( !transformResult2 )
|
||||
{
|
||||
return std::unexpected( QString( "MULTIPLY I2,J2,K2 coordinate is out of sector bounds: %1" ).arg( transformResult2.error() ) );
|
||||
return std::unexpected( transformResult.error() );
|
||||
}
|
||||
|
||||
using M = Opm::ParserKeywords::MULTIPLY;
|
||||
items.push_back( RifOpmDeckTools::item( M::I1::itemName, static_cast<int>( transformResult1->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::I2::itemName, static_cast<int>( transformResult2->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::J1::itemName, static_cast<int>( transformResult1->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::J2::itemName, static_cast<int>( transformResult2->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::K1::itemName, static_cast<int>( transformResult1->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::K2::itemName, static_cast<int>( transformResult2->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::I1::itemName, static_cast<int>( transformResult->min().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::I2::itemName, static_cast<int>( transformResult->max().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::J1::itemName, static_cast<int>( transformResult->min().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::J2::itemName, static_cast<int>( transformResult->max().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::K1::itemName, static_cast<int>( transformResult->min().z() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( M::K2::itemName, static_cast<int>( transformResult->max().z() + 1 ) ) );
|
||||
}
|
||||
|
||||
return Opm::DeckRecord{ std::move( items ) };
|
||||
@@ -1012,76 +1002,27 @@ std::expected<Opm::DeckRecord, QString> RigSimulationInputTool::processAddRecord
|
||||
int origK1 = record.getItem( 6 ).get<int>( 0 ) - 1;
|
||||
int origK2 = record.getItem( 7 ).get<int>( 0 ) - 1;
|
||||
|
||||
// Create bounding boxes (both use inclusive min/max coordinates)
|
||||
RigBoundingBoxIjk addBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
RigBoundingBoxIjk sectorBox( cvf::Vec3st( min.x(), min.y(), min.z() ), cvf::Vec3st( max.x(), max.y(), max.z() ) );
|
||||
// Create input bounding box (0-based, inclusive)
|
||||
RigBoundingBoxIjk inputBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
|
||||
// Check if boxes overlap and get intersection
|
||||
auto intersection = addBox.intersection( sectorBox );
|
||||
if ( !intersection )
|
||||
// Get field name for logging
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
QString recordIdent = QString( "for field '%1'" ).arg( fieldName );
|
||||
|
||||
// Transform box to sector coordinates
|
||||
auto transformResult = transformBoxToSectorCoordinates( inputBox, min, max, refinement, "ADD", recordIdent );
|
||||
if ( !transformResult )
|
||||
{
|
||||
// No overlap with sector - skip this record
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info( QString( "ADD record for field '%1' [%2-%3, %4-%5, %6-%7] does not overlap with sector - skipping" )
|
||||
.arg( fieldName )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 ) );
|
||||
return std::unexpected( "ADD record does not overlap with sector" );
|
||||
}
|
||||
|
||||
// Get the clamped coordinates from the intersection
|
||||
cvf::Vec3st corner1 = intersection->min();
|
||||
cvf::Vec3st corner2 = intersection->max();
|
||||
|
||||
// Log if clamping occurred (partial overlap)
|
||||
if ( origI1 != static_cast<int>( corner1.x() ) || origI2 != static_cast<int>( corner2.x() ) ||
|
||||
origJ1 != static_cast<int>( corner1.y() ) || origJ2 != static_cast<int>( corner2.y() ) ||
|
||||
origK1 != static_cast<int>( corner1.z() ) || origK2 != static_cast<int>( corner2.z() ) )
|
||||
{
|
||||
QString fieldName = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info( QString( "ADD record for field '%1' partially overlaps sector, clamped from [%2-%3, %4-%5, %6-%7] to [%8-%9, "
|
||||
"%10-%11, %12-%13]" )
|
||||
.arg( fieldName )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 )
|
||||
.arg( corner1.x() + 1 )
|
||||
.arg( corner2.x() + 1 )
|
||||
.arg( corner1.y() + 1 )
|
||||
.arg( corner2.y() + 1 )
|
||||
.arg( corner1.z() + 1 )
|
||||
.arg( corner2.z() + 1 ) );
|
||||
}
|
||||
|
||||
auto transformResult1 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner1.x(), corner1.y(), corner1.z() ), min, max, refinement );
|
||||
auto transformResult2 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner2.x(), corner2.y(), corner2.z() ), min, max, refinement );
|
||||
|
||||
if ( !transformResult1 )
|
||||
{
|
||||
return std::unexpected( QString( "ADD I1,J1,K1 coordinate is out of sector bounds: %1" ).arg( transformResult1.error() ) );
|
||||
}
|
||||
|
||||
if ( !transformResult2 )
|
||||
{
|
||||
return std::unexpected( QString( "ADD I2,J2,K2 coordinate is out of sector bounds: %1" ).arg( transformResult2.error() ) );
|
||||
return std::unexpected( transformResult.error() );
|
||||
}
|
||||
|
||||
using A = Opm::ParserKeywords::ADD;
|
||||
items.push_back( RifOpmDeckTools::item( A::I1::itemName, static_cast<int>( transformResult1->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::I2::itemName, static_cast<int>( transformResult2->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J1::itemName, static_cast<int>( transformResult1->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J2::itemName, static_cast<int>( transformResult2->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K1::itemName, static_cast<int>( transformResult1->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K2::itemName, static_cast<int>( transformResult2->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::I1::itemName, static_cast<int>( transformResult->min().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::I2::itemName, static_cast<int>( transformResult->max().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J1::itemName, static_cast<int>( transformResult->min().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J2::itemName, static_cast<int>( transformResult->max().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K1::itemName, static_cast<int>( transformResult->min().z() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K2::itemName, static_cast<int>( transformResult->max().z() + 1 ) ) );
|
||||
}
|
||||
|
||||
return Opm::DeckRecord{ std::move( items ) };
|
||||
@@ -1119,77 +1060,27 @@ std::expected<Opm::DeckRecord, QString> RigSimulationInputTool::processAquconRec
|
||||
int origK1 = record.getItem( 5 ).get<int>( 0 ) - 1;
|
||||
int origK2 = record.getItem( 6 ).get<int>( 0 ) - 1;
|
||||
|
||||
// Create bounding boxes (both use inclusive min/max coordinates)
|
||||
RigBoundingBoxIjk aquconBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
RigBoundingBoxIjk sectorBox( cvf::Vec3st( min.x(), min.y(), min.z() ), cvf::Vec3st( max.x(), max.y(), max.z() ) );
|
||||
// Create input bounding box (0-based, inclusive)
|
||||
RigBoundingBoxIjk inputBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
|
||||
// Check if boxes overlap and get intersection
|
||||
auto intersection = aquconBox.intersection( sectorBox );
|
||||
if ( !intersection )
|
||||
// Get aquifer ID for logging
|
||||
int aquiferId = record.getItem( 0 ).get<int>( 0 );
|
||||
QString recordIdent = QString( "for aquifer %1" ).arg( aquiferId );
|
||||
|
||||
// Transform box to sector coordinates
|
||||
auto transformResult = transformBoxToSectorCoordinates( inputBox, min, max, refinement, "AQUCON", recordIdent );
|
||||
if ( !transformResult )
|
||||
{
|
||||
// No overlap with sector - skip this record
|
||||
int aquiferId = record.getItem( 0 ).get<int>( 0 );
|
||||
RiaLogging::info( QString( "AQUCON record for aquifer %1 [%2-%3, %4-%5, %6-%7] does not overlap with sector - skipping" )
|
||||
.arg( aquiferId )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 ) );
|
||||
return std::unexpected( "AQUCON record does not overlap with sector" );
|
||||
}
|
||||
|
||||
// Get the clamped coordinates from the intersection
|
||||
cvf::Vec3st corner1 = intersection->min();
|
||||
cvf::Vec3st corner2 = intersection->max();
|
||||
|
||||
// Log if clamping occurred (partial overlap)
|
||||
if ( origI1 != static_cast<int>( corner1.x() ) || origI2 != static_cast<int>( corner2.x() ) ||
|
||||
origJ1 != static_cast<int>( corner1.y() ) || origJ2 != static_cast<int>( corner2.y() ) ||
|
||||
origK1 != static_cast<int>( corner1.z() ) || origK2 != static_cast<int>( corner2.z() ) )
|
||||
{
|
||||
int aquiferId = record.getItem( 0 ).get<int>( 0 );
|
||||
RiaLogging::info(
|
||||
QString( "AQUCON record for aquifer %1 partially overlaps sector, clamped from [%2-%3, %4-%5, %6-%7] to [%8-%9, "
|
||||
"%10-%11, %12-%13]" )
|
||||
.arg( aquiferId )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 )
|
||||
.arg( corner1.x() + 1 )
|
||||
.arg( corner2.x() + 1 )
|
||||
.arg( corner1.y() + 1 )
|
||||
.arg( corner2.y() + 1 )
|
||||
.arg( corner1.z() + 1 )
|
||||
.arg( corner2.z() + 1 ) );
|
||||
}
|
||||
|
||||
auto transformResult1 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner1.x(), corner1.y(), corner1.z() ), min, max, refinement );
|
||||
auto transformResult2 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner2.x(), corner2.y(), corner2.z() ), min, max, refinement );
|
||||
|
||||
if ( !transformResult1 )
|
||||
{
|
||||
return std::unexpected( QString( "AQUCON I1,J1,K1 coordinate is out of sector bounds: %1" ).arg( transformResult1.error() ) );
|
||||
}
|
||||
|
||||
if ( !transformResult2 )
|
||||
{
|
||||
return std::unexpected( QString( "AQUCON I2,J2,K2 coordinate is out of sector bounds: %1" ).arg( transformResult2.error() ) );
|
||||
return std::unexpected( transformResult.error() );
|
||||
}
|
||||
|
||||
using A = Opm::ParserKeywords::AQUCON;
|
||||
items.push_back( RifOpmDeckTools::item( A::I1::itemName, static_cast<int>( transformResult1->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::I2::itemName, static_cast<int>( transformResult2->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J1::itemName, static_cast<int>( transformResult1->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J2::itemName, static_cast<int>( transformResult2->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K1::itemName, static_cast<int>( transformResult1->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K2::itemName, static_cast<int>( transformResult2->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::I1::itemName, static_cast<int>( transformResult->min().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::I2::itemName, static_cast<int>( transformResult->max().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J1::itemName, static_cast<int>( transformResult->min().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::J2::itemName, static_cast<int>( transformResult->max().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K1::itemName, static_cast<int>( transformResult->min().z() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( A::K2::itemName, static_cast<int>( transformResult->max().z() + 1 ) ) );
|
||||
|
||||
// Copy remaining items (CONNECT_FACE and other parameters)
|
||||
for ( size_t i = 7; i < record.size(); ++i )
|
||||
@@ -1243,80 +1134,28 @@ std::expected<Opm::DeckRecord, QString> RigSimulationInputTool::processCopyRecor
|
||||
int origK1 = record.getItem( 6 ).get<int>( 0 ) - 1;
|
||||
int origK2 = record.getItem( 7 ).get<int>( 0 ) - 1;
|
||||
|
||||
// Create bounding boxes (both use inclusive min/max coordinates)
|
||||
RigBoundingBoxIjk copyBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
RigBoundingBoxIjk sectorBox( cvf::Vec3st( min.x(), min.y(), min.z() ), cvf::Vec3st( max.x(), max.y(), max.z() ) );
|
||||
// Create input bounding box (0-based, inclusive)
|
||||
RigBoundingBoxIjk inputBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
|
||||
// Check if boxes overlap and get intersection
|
||||
auto intersection = copyBox.intersection( sectorBox );
|
||||
if ( !intersection )
|
||||
// Get array names for logging
|
||||
QString srcArray = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
QString targetArray = QString::fromStdString( record.getItem( 1 ).get<std::string>( 0 ) );
|
||||
QString recordIdent = QString( "for %1->%2" ).arg( srcArray ).arg( targetArray );
|
||||
|
||||
// Transform box to sector coordinates
|
||||
auto transformResult = transformBoxToSectorCoordinates( inputBox, min, max, refinement, "COPY", recordIdent );
|
||||
if ( !transformResult )
|
||||
{
|
||||
// No overlap with sector - skip this record
|
||||
QString srcArray = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
QString targetArray = QString::fromStdString( record.getItem( 1 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info( QString( "COPY record for %1->%2 [%3-%4, %5-%6, %7-%8] does not overlap with sector - skipping" )
|
||||
.arg( srcArray )
|
||||
.arg( targetArray )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 ) );
|
||||
return std::unexpected( "COPY record does not overlap with sector" );
|
||||
}
|
||||
|
||||
// Get the clamped coordinates from the intersection
|
||||
cvf::Vec3st corner1 = intersection->min();
|
||||
cvf::Vec3st corner2 = intersection->max();
|
||||
|
||||
// Log if clamping occurred (partial overlap)
|
||||
if ( origI1 != static_cast<int>( corner1.x() ) || origI2 != static_cast<int>( corner2.x() ) ||
|
||||
origJ1 != static_cast<int>( corner1.y() ) || origJ2 != static_cast<int>( corner2.y() ) ||
|
||||
origK1 != static_cast<int>( corner1.z() ) || origK2 != static_cast<int>( corner2.z() ) )
|
||||
{
|
||||
QString srcArray = QString::fromStdString( record.getItem( 0 ).get<std::string>( 0 ) );
|
||||
QString targetArray = QString::fromStdString( record.getItem( 1 ).get<std::string>( 0 ) );
|
||||
RiaLogging::info( QString( "COPY record for %1->%2 partially overlaps sector, clamped from [%3-%4, %5-%6, %7-%8] to [%9-%10, "
|
||||
"%11-%12, %13-%14]" )
|
||||
.arg( srcArray )
|
||||
.arg( targetArray )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 )
|
||||
.arg( corner1.x() + 1 )
|
||||
.arg( corner2.x() + 1 )
|
||||
.arg( corner1.y() + 1 )
|
||||
.arg( corner2.y() + 1 )
|
||||
.arg( corner1.z() + 1 )
|
||||
.arg( corner2.z() + 1 ) );
|
||||
}
|
||||
|
||||
auto transformResult1 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner1.x(), corner1.y(), corner1.z() ), min, max, refinement );
|
||||
auto transformResult2 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner2.x(), corner2.y(), corner2.z() ), min, max, refinement );
|
||||
|
||||
if ( !transformResult1 )
|
||||
{
|
||||
return std::unexpected( QString( "COPY I1,J1,K1 coordinate is out of sector bounds: %1" ).arg( transformResult1.error() ) );
|
||||
}
|
||||
|
||||
if ( !transformResult2 )
|
||||
{
|
||||
return std::unexpected( QString( "COPY I2,J2,K2 coordinate is out of sector bounds: %1" ).arg( transformResult2.error() ) );
|
||||
return std::unexpected( transformResult.error() );
|
||||
}
|
||||
|
||||
using C = Opm::ParserKeywords::COPY;
|
||||
items.push_back( RifOpmDeckTools::item( C::I1::itemName, static_cast<int>( transformResult1->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::I2::itemName, static_cast<int>( transformResult2->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::J1::itemName, static_cast<int>( transformResult1->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::J2::itemName, static_cast<int>( transformResult2->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::K1::itemName, static_cast<int>( transformResult1->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::K2::itemName, static_cast<int>( transformResult2->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::I1::itemName, static_cast<int>( transformResult->min().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::I2::itemName, static_cast<int>( transformResult->max().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::J1::itemName, static_cast<int>( transformResult->min().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::J2::itemName, static_cast<int>( transformResult->max().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::K1::itemName, static_cast<int>( transformResult->min().z() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( C::K2::itemName, static_cast<int>( transformResult->max().z() + 1 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1357,70 +1196,23 @@ std::expected<Opm::DeckRecord, QString> RigSimulationInputTool::processBoxRecord
|
||||
int origK1 = record.getItem( 4 ).get<int>( 0 ) - 1;
|
||||
int origK2 = record.getItem( 5 ).get<int>( 0 ) - 1;
|
||||
|
||||
// Create bounding boxes (both use inclusive min/max coordinates)
|
||||
RigBoundingBoxIjk boxBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
RigBoundingBoxIjk sectorBox( cvf::Vec3st( min.x(), min.y(), min.z() ), cvf::Vec3st( max.x(), max.y(), max.z() ) );
|
||||
// Create input bounding box (0-based, inclusive)
|
||||
RigBoundingBoxIjk inputBox( cvf::Vec3st( origI1, origJ1, origK1 ), cvf::Vec3st( origI2, origJ2, origK2 ) );
|
||||
|
||||
// Check if boxes overlap and get intersection
|
||||
auto intersection = boxBox.intersection( sectorBox );
|
||||
if ( !intersection )
|
||||
// Transform box to sector coordinates
|
||||
auto transformResult = transformBoxToSectorCoordinates( inputBox, min, max, refinement, "BOX", "" );
|
||||
if ( !transformResult )
|
||||
{
|
||||
// No overlap with sector - skip this record
|
||||
RiaLogging::info( QString( "BOX record [%1-%2, %3-%4, %5-%6] does not overlap with sector - skipping" )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 ) );
|
||||
return std::unexpected( "BOX record does not overlap with sector" );
|
||||
}
|
||||
|
||||
// Get the clamped coordinates from the intersection
|
||||
cvf::Vec3st corner1 = intersection->min();
|
||||
cvf::Vec3st corner2 = intersection->max();
|
||||
|
||||
// Log if clamping occurred (partial overlap)
|
||||
if ( origI1 != static_cast<int>( corner1.x() ) || origI2 != static_cast<int>( corner2.x() ) || origJ1 != static_cast<int>( corner1.y() ) ||
|
||||
origJ2 != static_cast<int>( corner2.y() ) || origK1 != static_cast<int>( corner1.z() ) || origK2 != static_cast<int>( corner2.z() ) )
|
||||
{
|
||||
RiaLogging::info( QString( "BOX record partially overlaps sector, clamped from [%1-%2, %3-%4, %5-%6] to [%7-%8, %9-%10, %11-%12]" )
|
||||
.arg( origI1 + 1 )
|
||||
.arg( origI2 + 1 )
|
||||
.arg( origJ1 + 1 )
|
||||
.arg( origJ2 + 1 )
|
||||
.arg( origK1 + 1 )
|
||||
.arg( origK2 + 1 )
|
||||
.arg( corner1.x() + 1 )
|
||||
.arg( corner2.x() + 1 )
|
||||
.arg( corner1.y() + 1 )
|
||||
.arg( corner2.y() + 1 )
|
||||
.arg( corner1.z() + 1 )
|
||||
.arg( corner2.z() + 1 ) );
|
||||
}
|
||||
|
||||
auto transformResult1 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner1.x(), corner1.y(), corner1.z() ), min, max, refinement );
|
||||
auto transformResult2 =
|
||||
RigGridExportAdapter::transformIjkToSectorCoordinates( caf::VecIjk0( corner2.x(), corner2.y(), corner2.z() ), min, max, refinement );
|
||||
|
||||
if ( !transformResult1 )
|
||||
{
|
||||
return std::unexpected( QString( "BOX I1,J1,K1 coordinate is out of sector bounds: %1" ).arg( transformResult1.error() ) );
|
||||
}
|
||||
|
||||
if ( !transformResult2 )
|
||||
{
|
||||
return std::unexpected( QString( "BOX I2,J2,K2 coordinate is out of sector bounds: %1" ).arg( transformResult2.error() ) );
|
||||
return std::unexpected( transformResult.error() );
|
||||
}
|
||||
|
||||
using B = Opm::ParserKeywords::BOX;
|
||||
items.push_back( RifOpmDeckTools::item( B::I1::itemName, static_cast<int>( transformResult1->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::I2::itemName, static_cast<int>( transformResult2->x() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::J1::itemName, static_cast<int>( transformResult1->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::J2::itemName, static_cast<int>( transformResult2->y() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::K1::itemName, static_cast<int>( transformResult1->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::K2::itemName, static_cast<int>( transformResult2->z() ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::I1::itemName, static_cast<int>( transformResult->min().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::I2::itemName, static_cast<int>( transformResult->max().x() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::J1::itemName, static_cast<int>( transformResult->min().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::J2::itemName, static_cast<int>( transformResult->max().y() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::K1::itemName, static_cast<int>( transformResult->min().z() + 1 ) ) );
|
||||
items.push_back( RifOpmDeckTools::item( B::K2::itemName, static_cast<int>( transformResult->max().z() + 1 ) ) );
|
||||
|
||||
return Opm::DeckRecord{ std::move( items ) };
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class RimEclipseCase;
|
||||
class RigSimulationInputSettings;
|
||||
class RifOpmFlowDeckFile;
|
||||
class RigSimWellData;
|
||||
class RigBoundingBoxIjk;
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
@@ -137,4 +138,13 @@ private:
|
||||
const RigSimulationInputSettings& settings,
|
||||
RifOpmFlowDeckFile& deckFile,
|
||||
RecordProcessorFunc processorFunc );
|
||||
|
||||
// Helper function to transform bounding box from global to sector coordinates
|
||||
// Returns bounding box with 0-based sector-relative coordinates
|
||||
static std::expected<RigBoundingBoxIjk, QString> transformBoxToSectorCoordinates( const RigBoundingBoxIjk& inputBox,
|
||||
const caf::VecIjk0& sectorMin,
|
||||
const caf::VecIjk0& sectorMax,
|
||||
const cvf::Vec3st& refinement,
|
||||
const QString& keywordName,
|
||||
const QString& recordIdentifier );
|
||||
};
|
||||
Reference in new issue
Block a user