diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp index 5f01a09600..0c86af6f23 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp @@ -1108,9 +1108,13 @@ std::vector const std::vector& mds = wellPathGeometry->measureDepths(); CVF_ASSERT( !coords.empty() && !mds.empty() ); - std::vector intersections = + std::vector intersectionsA = RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( eclipseCase->eclipseCaseData(), coords, mds ); + const RigMainGrid* mainGrid = eclipseCase->mainGrid(); + std::vector intersections = + RigWellPathIntersectionTools::buildContinuousIntersections( intersectionsA, mainGrid ); + if ( wellPath->perforationIntervalCollection()->mswParameters()->referenceMDType() == RimMswCompletionParameters::MANUAL_REFERENCE_MD ) { @@ -1219,11 +1223,19 @@ std::vector const RigMainGrid* grid = eclipseCase->mainGrid(); - extraIntersection.intersectionLengthsInCellCS = - RigWellPathIntersectionTools::calculateLengthInCell( grid, - intersection.globCellIndex, - intersectionPoint, - intersection.endPoint ); + if ( intersection.globCellIndex < grid->cellCount() ) + { + extraIntersection.intersectionLengthsInCellCS = + RigWellPathIntersectionTools::calculateLengthInCell( grid, + intersection.globCellIndex, + intersectionPoint, + intersection.endPoint ); + } + else + { + extraIntersection.intersectionLengthsInCellCS = cvf::Vec3d::ZERO; + } + filteredIntersections.push_back( extraIntersection ); } } diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp b/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp index bc446e3085..b893fe402f 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp @@ -150,3 +150,74 @@ cvf::Vec3d RigWellPathIntersectionTools::calculateLengthInCell( const RigMainGri return calculateLengthInCell( hexCorners, startPoint, endPoint ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellPathIntersectionTools::buildContinuousIntersections( + const std::vector& originalIntersections, + const cvf::StructGridInterface* grid ) +{ + std::vector intersectionsNoGap; + + for ( size_t i = 0; i < originalIntersections.size() - 1; i++ ) + { + const WellPathCellIntersectionInfo& current = originalIntersections[i]; + const WellPathCellIntersectionInfo& next = originalIntersections[i + 1]; + + double distance = std::fabs( current.endMD - next.startMD ); + double gapInGridThreshold = 0.1; + if ( distance > gapInGridThreshold ) + { + WellPathCellIntersectionInfo extraIntersection; + + QString ijkTextCurrent; + { + size_t i = 0, j = 0, k = 0; + if ( grid ) + { + grid->ijkFromCellIndex( current.globCellIndex, &i, &j, &k ); + } + ijkTextCurrent = QString( "(%1 %2 %3)" ).arg( i + 1 ).arg( j + 1 ).arg( k + 1 ); + } + QString ijkTextNext; + { + size_t i = 0, j = 0, k = 0; + if ( grid ) + { + grid->ijkFromCellIndex( next.globCellIndex, &i, &j, &k ); + } + ijkTextNext = QString( "(%1 %2 %3)" ).arg( i + 1 ).arg( j + 1 ).arg( k + 1 ); + } + + QString text = QString( "Gap detected : Distance diff : %1, epsilon = %2\n Global Cell Index 1 : %3, " + "IJK=%4, endMD : %5\n Global Cell Index 2 : %6, IJK=%7, startMD : %8" ) + .arg( distance ) + .arg( gapInGridThreshold ) + .arg( current.globCellIndex ) + .arg( ijkTextCurrent ) + .arg( current.endMD ) + .arg( next.globCellIndex ) + .arg( ijkTextNext ) + .arg( next.startMD ); + + RiaLogging::info( text ); + + extraIntersection.globCellIndex = std::numeric_limits::max(); + extraIntersection.startPoint = current.endPoint; + extraIntersection.endPoint = next.startPoint; + extraIntersection.startMD = current.endMD; + extraIntersection.endMD = next.startMD; + extraIntersection.intersectedCellFaceIn = + cvf::StructGridInterface::oppositeFace( current.intersectedCellFaceOut ); + extraIntersection.intersectedCellFaceOut = cvf::StructGridInterface::oppositeFace( next.intersectedCellFaceIn ); + extraIntersection.intersectionLengthsInCellCS = cvf::Vec3d::ZERO; + + intersectionsNoGap.push_back( extraIntersection ); + } + + intersectionsNoGap.push_back( current ); + } + + return intersectionsNoGap; +} diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.h b/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.h index c565d74620..bea8ce77f8 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.h +++ b/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.h @@ -29,6 +29,11 @@ class RigEclipseCaseData; struct HexIntersectionInfo; struct WellPathCellIntersectionInfo; +namespace cvf +{ +class StructGridInterface; +}; + //================================================================================================== /// //================================================================================================== @@ -55,4 +60,9 @@ public: size_t cellIndex, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint ); + + // Insert dummy intersections used to represent gap in grid + static std::vector + buildContinuousIntersections( const std::vector& originalIntersections, + const cvf::StructGridInterface* grid ); };