#11562 RFT plots with nonproducing segments

Identify when we have a tubing segments that do not have a device segment connected. Mark the downstream device segment as non-continuous. When MD for device curve is created, add an extra MD for noncontinuous segments. Use inf as data value for this MD. This will ensure that no curve is displayed in this section of the device curve.
This commit is contained in:
Magne Sjaastad 2024-07-25 10:02:44 +02:00
parent 7c9db3d48b
commit 392a794393
3 changed files with 93 additions and 2 deletions

View File

@ -88,11 +88,25 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
{
auto data = segment.topology();
std::vector<size_t> nonContinuousSegmentIndices;
if ( rftAddress.segmentBranchType() == RiaDefines::RftBranchType::RFT_DEVICE )
{
nonContinuousSegmentIndices = segment.nonContinuousDeviceSegmentIndices( rftAddress.segmentBranchIndex() );
}
auto indices = segment.segmentIndicesForBranchIndex( rftAddress.segmentBranchIndex(), rftAddress.segmentBranchType() );
for ( const auto& i : indices )
{
CAF_ASSERT( i < data.size() );
values->push_back( data[i].segNo() );
if ( std::find( nonContinuousSegmentIndices.begin(), nonContinuousSegmentIndices.end(), i ) !=
nonContinuousSegmentIndices.end() )
{
// Use the same segment number for the dummy segment as the previous segment
values->push_back( values->back() );
}
}
return;
}
@ -123,6 +137,12 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
auto key = std::make_pair( wellName, RftDate{ y, m, d } );
auto segment = m_rftWellDateSegments[key];
std::vector<size_t> nonContinuousDeviceSegmentIndices;
if ( rftAddress.segmentBranchType() == RiaDefines::RftBranchType::RFT_DEVICE )
{
nonContinuousDeviceSegmentIndices = segment.nonContinuousDeviceSegmentIndices( rftAddress.segmentBranchIndex() );
}
if ( m_connectionResultItemCount.count( wellName ) && data.size() == m_connectionResultItemCount[wellName] )
{
// Connection results with size equal to length of result CONSEGNO. CONSEGNO defines the segment
@ -138,6 +158,16 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
size_t resultDataIndex = 0;
for ( int segmentNumber : segmentNumbers )
{
auto segmentIndex = segment.segmentIndexFromSegmentNumber( segmentNumber );
if ( std::find( nonContinuousDeviceSegmentIndices.begin(), nonContinuousDeviceSegmentIndices.end(), segmentIndex ) !=
nonContinuousDeviceSegmentIndices.end() )
{
// Insert an extra infinity value for segments that are not continuous. The number of values in the values
// vector must be equal to the number of x-values (measured depths)
values->push_back( std::numeric_limits<double>::infinity() );
}
if ( std::find( connnectionSegmentNumbers.begin(), connnectionSegmentNumbers.end(), segmentNumber ) !=
connnectionSegmentNumbers.end() )
{
@ -157,7 +187,25 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
for ( const auto& i : indices )
{
CAF_ASSERT( i < data.size() );
values->push_back( data[i] );
auto dataValue = data[i];
if ( std::find( nonContinuousDeviceSegmentIndices.begin(), nonContinuousDeviceSegmentIndices.end(), i ) !=
nonContinuousDeviceSegmentIndices.end() )
{
if ( rftAddress.segmentResultName() == RiaDefines::segmentEndDepthResultName() )
{
// Insert a depth value for segments that are not continuous. When infinity is assigned to this measured
// depth, no curve is drawn for this segment
values->push_back( dataValue - 0.1 );
}
else
{
// Use infinity to make sure no curve is drawn for this segment
values->push_back( std::numeric_limits<double>::infinity() );
}
}
values->push_back( dataValue );
}
}

View File

@ -383,3 +383,46 @@ int RifRftSegment::segmentIndexFromSegmentNumber( int segmentNumber ) const
return -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RifRftSegment::nonContinuousDeviceSegmentIndices( int branchIndex ) const
{
auto deviceSegmentNumbers = segmentNumbersForBranchIndex( branchIndex, RiaDefines::RftBranchType::RFT_DEVICE );
if ( deviceSegmentNumbers.size() < 2 ) return {};
// Find all device segments that are connected to a tubing segment with a upstream tubing segment that is not connected to a device
// segment.
//
// Device numbers : 50 51 52 53
// | | | |
// Tubing numbers : 1 - 2 - 3 - 4 - 5 - 6
//
// Device 53 is connected to tubing 5. There are tubing segments between device 52 and 51. We mark device 52 as non-continuous
// device segment.
std::vector<size_t> deviceSegmentIndices;
size_t i = deviceSegmentNumbers.size() - 1;
while ( i > 1 )
{
auto currentDeviceSegment = segmentData( deviceSegmentNumbers[i] );
if ( !currentDeviceSegment ) continue;
auto upstreamDeviceSegment = segmentData( deviceSegmentNumbers[i - 1] );
if ( !upstreamDeviceSegment ) continue;
auto tubingSegData = segmentData( currentDeviceSegment->segNext() );
if ( !tubingSegData ) continue;
auto upstreamTubingSegmentNumber = tubingSegData->segNext();
if ( upstreamDeviceSegment->segNext() != upstreamTubingSegmentNumber )
{
deviceSegmentIndices.push_back( segmentIndexFromSegmentNumber( deviceSegmentNumbers[i] ) );
}
i--;
}
return deviceSegmentIndices;
}

View File

@ -74,12 +74,12 @@ public:
std::vector<size_t> segmentIndicesForBranchNumber( int branchNumber ) const;
std::vector<size_t> segmentIndicesForBranchIndex( int branchIndex, RiaDefines::RftBranchType branchType ) const;
std::vector<size_t> packerSegmentIndicesOnAnnulus( int branchIndex ) const;
std::vector<size_t> nonContinuousDeviceSegmentIndices( int branchIndex ) const;
std::vector<int> segmentNumbersForBranchIndex( int oneBasedBranchIndex, RiaDefines::RftBranchType branchType ) const;
std::set<int> uniqueOneBasedBranchIndices( RiaDefines::RftBranchType branchType ) const;
private:
int segmentIndexFromSegmentNumber( int segmentNumber ) const;
private: