Import RFT segment data as well log curve (#8449)

Add reader for RFT data using opm-common
Extend RFT curve with support for RFT segment data
Adjustments related to horizontal well log plots

8581 Well Log Plot : Update of curve appearance does not update plot
This commit is contained in:
Magne Sjaastad
2022-02-23 13:57:02 +01:00
committed by GitHub
parent bb7f61ea56
commit f154f8c500
52 changed files with 1947 additions and 403 deletions

View File

@@ -71,6 +71,8 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RifEclipseKeywordContent.h
${CMAKE_CURRENT_LIST_DIR}/RifMultipleSummaryReaders.h
${CMAKE_CURRENT_LIST_DIR}/RifProjectSummaryDataWriter.h
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmRft.h
${CMAKE_CURRENT_LIST_DIR}/RifRftSegment.h
)
set(SOURCE_GROUP_SOURCE_FILES
@@ -143,6 +145,8 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RifEclipseTextFileReader.cpp
${CMAKE_CURRENT_LIST_DIR}/RifMultipleSummaryReaders.cpp
${CMAKE_CURRENT_LIST_DIR}/RifProjectSummaryDataWriter.cpp
${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmRft.cpp
${CMAKE_CURRENT_LIST_DIR}/RifRftSegment.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@@ -17,15 +17,19 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RifDataSourceForRftPlt.h"
#include "RifReaderEclipseRft.h"
#include "RimEclipseCase.h"
#include "RimEclipseResultCase.h"
#include "RimObservedFmuRftData.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimWellLogFile.h"
#include "RimEclipseResultCase.h"
#include "cafAppEnum.h"
#include "cvfAssert.h"
#include <QString>
#include <QTextStream>

View File

@@ -23,9 +23,103 @@
//--------------------------------------------------------------------------------------------------
RifEclipseRftAddress::RifEclipseRftAddress( QString wellName, QDateTime timeStep, RftWellLogChannelType wellLogChannelName )
: m_wellName( wellName )
, m_timeStep( timeStep )
, m_wellLogChannel( wellLogChannelName )
, m_segmentBranchNumber( -1 )
{
m_timeStep = timeStep;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifEclipseRftAddress RifEclipseRftAddress::createSegmentResult( const QString& wellName,
const QDateTime& dateTime,
const QString& resultName )
{
auto adr = RifEclipseRftAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES );
adr.setSegmentResultName( resultName );
return adr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseRftAddress::setSegmentResultName( const QString& resultName )
{
m_segmentResultName = resultName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RifEclipseRftAddress::segmentResultName() const
{
return m_segmentResultName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseRftAddress::setSegmentBranchNumber( int branchNumber )
{
m_segmentBranchNumber = branchNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifEclipseRftAddress::segmentBranchNumber() const
{
return m_segmentBranchNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString& RifEclipseRftAddress::wellName() const
{
return m_wellName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RifEclipseRftAddress::timeStep() const
{
return m_timeStep;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RifEclipseRftAddress::RifEclipseRftAddress::RftWellLogChannelType& RifEclipseRftAddress::wellLogChannel() const
{
return m_wellLogChannel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifEclipseRftAddress::rftPlotChannelTypes()
{
return { RifEclipseRftAddress::RftWellLogChannelType::PRESSURE,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90 };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseRftAddress::RifEclipseRftAddress::RftWellLogChannelType> RifEclipseRftAddress::pltPlotChannelTypes()
{
return { RifEclipseRftAddress::RftWellLogChannelType::ORAT,
RifEclipseRftAddress::RftWellLogChannelType::WRAT,
RifEclipseRftAddress::RftWellLogChannelType::GRAT };
}
//--------------------------------------------------------------------------------------------------
@@ -36,6 +130,8 @@ bool operator==( const RifEclipseRftAddress& first, const RifEclipseRftAddress&
if ( first.wellName() != second.wellName() ) return false;
if ( first.timeStep() != second.timeStep() ) return false;
if ( first.wellLogChannel() != second.wellLogChannel() ) return false;
if ( first.segmentResultName() != second.segmentResultName() ) return false;
if ( first.segmentBranchNumber() != second.segmentBranchNumber() ) return false;
return true;
}
@@ -49,6 +145,10 @@ bool operator<( const RifEclipseRftAddress& first, const RifEclipseRftAddress& s
if ( first.timeStep() != second.timeStep() ) return ( first.timeStep() < second.timeStep() );
if ( first.wellLogChannel() != second.wellLogChannel() )
return ( first.wellLogChannel() < second.wellLogChannel() );
if ( first.segmentResultName() != second.segmentResultName() )
return first.segmentResultName() < second.segmentResultName();
if ( first.segmentBranchNumber() != second.segmentBranchNumber() )
return first.segmentBranchNumber() < second.segmentBranchNumber();
return false;
}

View File

@@ -31,7 +31,7 @@
class RifEclipseRftAddress
{
public:
enum RftWellLogChannelType
enum class RftWellLogChannelType
{
NONE,
TVD,
@@ -47,35 +47,38 @@ public:
PRESSURE_P50,
PRESSURE_P90,
PRESSURE_MEAN,
PRESSURE_ERROR
PRESSURE_ERROR,
SEGMENT_VALUES
};
public:
RifEclipseRftAddress( QString wellName, QDateTime timeStep, RftWellLogChannelType wellLogChannel );
const QString& wellName() const { return m_wellName; }
QDateTime timeStep() const { return m_timeStep; }
const RftWellLogChannelType& wellLogChannel() const { return m_wellLogChannel; }
static RifEclipseRftAddress
createSegmentResult( const QString& wellName, const QDateTime& dateTime, const QString& resultName );
static std::set<RftWellLogChannelType> rftPlotChannelTypes()
{
return {RifEclipseRftAddress::PRESSURE,
RifEclipseRftAddress::PRESSURE_ERROR,
RifEclipseRftAddress::PRESSURE_MEAN,
RifEclipseRftAddress::PRESSURE_P10,
RifEclipseRftAddress::PRESSURE_P50,
RifEclipseRftAddress::PRESSURE_P90};
}
QString segmentResultName() const;
static std::set<RftWellLogChannelType> pltPlotChannelTypes()
{
return {RifEclipseRftAddress::ORAT, RifEclipseRftAddress::WRAT, RifEclipseRftAddress::GRAT};
}
void setSegmentBranchNumber( int branchNumber );
int segmentBranchNumber() const;
const QString& wellName() const;
QDateTime timeStep() const;
const RftWellLogChannelType& wellLogChannel() const;
static std::set<RftWellLogChannelType> rftPlotChannelTypes();
static std::set<RftWellLogChannelType> pltPlotChannelTypes();
private:
void setSegmentResultName( const QString& resultName );
private:
QString m_wellName;
QDateTime m_timeStep;
RftWellLogChannelType m_wellLogChannel;
QString m_segmentResultName;
int m_segmentBranchNumber;
};
bool operator==( const RifEclipseRftAddress& first, const RifEclipseRftAddress& second );

View File

@@ -89,39 +89,39 @@ void RifReaderEclipseRft::open()
QDateTime timeStep = RiaQDateTimeTools::createUtcDateTime();
timeStep.setTime_t( timeStepTime_t );
RifEclipseRftAddress addressPressure( wellName, timeStep, RifEclipseRftAddress::PRESSURE );
RifEclipseRftAddress addressPressure( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE );
m_eclipseRftAddresses.insert( addressPressure );
m_rftAddressToLibeclNodeIdx[addressPressure] = i;
RifEclipseRftAddress addressDepth( wellName, timeStep, RifEclipseRftAddress::TVD );
RifEclipseRftAddress addressDepth( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::TVD );
m_eclipseRftAddresses.insert( addressDepth );
m_rftAddressToLibeclNodeIdx[addressDepth] = i;
if ( ecl_rft_node_is_RFT( node ) )
{
RifEclipseRftAddress addressSwat( wellName, timeStep, RifEclipseRftAddress::SWAT );
RifEclipseRftAddress addressSwat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::SWAT );
m_eclipseRftAddresses.insert( addressSwat );
m_rftAddressToLibeclNodeIdx[addressSwat] = i;
RifEclipseRftAddress addressSoil( wellName, timeStep, RifEclipseRftAddress::SOIL );
RifEclipseRftAddress addressSoil( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::SOIL );
m_eclipseRftAddresses.insert( addressSoil );
m_rftAddressToLibeclNodeIdx[addressSoil] = i;
RifEclipseRftAddress addressSgas( wellName, timeStep, RifEclipseRftAddress::SGAS );
RifEclipseRftAddress addressSgas( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::SGAS );
m_eclipseRftAddresses.insert( addressSgas );
m_rftAddressToLibeclNodeIdx[addressSgas] = i;
}
else if ( ecl_rft_node_is_PLT( node ) )
{
RifEclipseRftAddress addressWrat( wellName, timeStep, RifEclipseRftAddress::WRAT );
RifEclipseRftAddress addressWrat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::WRAT );
m_eclipseRftAddresses.insert( addressWrat );
m_rftAddressToLibeclNodeIdx[addressWrat] = i;
RifEclipseRftAddress addressOrat( wellName, timeStep, RifEclipseRftAddress::ORAT );
RifEclipseRftAddress addressOrat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::ORAT );
m_eclipseRftAddresses.insert( addressOrat );
m_rftAddressToLibeclNodeIdx[addressOrat] = i;
RifEclipseRftAddress addressGrat( wellName, timeStep, RifEclipseRftAddress::GRAT );
RifEclipseRftAddress addressGrat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::GRAT );
m_eclipseRftAddresses.insert( addressGrat );
m_rftAddressToLibeclNodeIdx[addressGrat] = i;
}
@@ -166,7 +166,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
switch ( wellLogChannelName )
{
case RifEclipseRftAddress::TVD:
case RifEclipseRftAddress::RftWellLogChannelType::TVD:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -174,7 +174,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
}
break;
}
case RifEclipseRftAddress::PRESSURE:
case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -182,7 +182,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
}
break;
}
case RifEclipseRftAddress::SWAT:
case RifEclipseRftAddress::RftWellLogChannelType::SWAT:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -190,7 +190,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
}
break;
}
case RifEclipseRftAddress::SOIL:
case RifEclipseRftAddress::RftWellLogChannelType::SOIL:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -198,7 +198,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
}
break;
}
case RifEclipseRftAddress::SGAS:
case RifEclipseRftAddress::RftWellLogChannelType::SGAS:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -206,7 +206,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
}
break;
}
case RifEclipseRftAddress::WRAT:
case RifEclipseRftAddress::RftWellLogChannelType::WRAT:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -214,7 +214,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
}
break;
}
case RifEclipseRftAddress::ORAT:
case RifEclipseRftAddress::RftWellLogChannelType::ORAT:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -222,7 +222,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v
}
break;
}
case RifEclipseRftAddress::GRAT:
case RifEclipseRftAddress::RftWellLogChannelType::GRAT:
{
for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ )
{
@@ -351,7 +351,7 @@ std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::avail
if ( !pressureFound )
{
if ( name == RifEclipseRftAddress::PRESSURE )
if ( name == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE )
{
pressureFound = true;
if ( rftFound && pltFound ) break;
@@ -381,7 +381,7 @@ std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::avail
if ( pressureFound )
{
wellLogChannelNames.insert( RifEclipseRftAddress::PRESSURE );
wellLogChannelNames.insert( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE );
}
if ( rftFound )
{

View File

@@ -45,7 +45,7 @@ public:
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
void values( const RifEclipseRftAddress& rftAddress, std::vector<double>* values ) override;
void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices );
void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices ) override;
std::set<QDateTime> availableTimeSteps( const QString& wellName ) override;
std::set<QDateTime>

View File

@@ -53,16 +53,17 @@ std::set<RifEclipseRftAddress> RifReaderEnsembleStatisticsRft::eclipseRftAddress
std::set<RifEclipseRftAddress> statisticsAddresses;
for ( const RifEclipseRftAddress& regularAddress : allAddresses )
{
if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::TVD )
if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::TVD )
{
statisticsAddresses.insert( regularAddress );
}
else if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE )
else if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE )
{
std::set<RifEclipseRftAddress::RftWellLogChannelType> statChannels = { RifEclipseRftAddress::PRESSURE_P10,
RifEclipseRftAddress::PRESSURE_P50,
RifEclipseRftAddress::PRESSURE_P90,
RifEclipseRftAddress::PRESSURE_MEAN };
std::set<RifEclipseRftAddress::RftWellLogChannelType> statChannels =
{ RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN };
for ( auto channel : statChannels )
{
statisticsAddresses.insert(
@@ -78,12 +79,12 @@ std::set<RifEclipseRftAddress> RifReaderEnsembleStatisticsRft::eclipseRftAddress
//--------------------------------------------------------------------------------------------------
void RifReaderEnsembleStatisticsRft::values( const RifEclipseRftAddress& rftAddress, std::vector<double>* values )
{
CAF_ASSERT( rftAddress.wellLogChannel() == RifEclipseRftAddress::TVD ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_MEAN ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P10 ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P50 ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P90 ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_ERROR );
CAF_ASSERT( rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::TVD ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10 ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50 ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90 ||
rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR );
auto it = m_cachedValues.find( rftAddress );
if ( it == m_cachedValues.end() )
@@ -191,13 +192,13 @@ void RifReaderEnsembleStatisticsRft::calculateStatistics( const RifEclipseRftAdd
{
const QString& wellName = rftAddress.wellName();
const QDateTime& timeStep = rftAddress.timeStep();
RifEclipseRftAddress depthAddress( wellName, timeStep, RifEclipseRftAddress::TVD );
RifEclipseRftAddress pressAddress( wellName, timeStep, RifEclipseRftAddress::PRESSURE );
RifEclipseRftAddress depthAddress( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::TVD );
RifEclipseRftAddress pressAddress( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE );
RifEclipseRftAddress p10Address( wellName, timeStep, RifEclipseRftAddress::PRESSURE_P10 );
RifEclipseRftAddress p50Address( wellName, timeStep, RifEclipseRftAddress::PRESSURE_P50 );
RifEclipseRftAddress p90Address( wellName, timeStep, RifEclipseRftAddress::PRESSURE_P90 );
RifEclipseRftAddress meanAddress( wellName, timeStep, RifEclipseRftAddress::PRESSURE_MEAN );
RifEclipseRftAddress p10Address( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10 );
RifEclipseRftAddress p50Address( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50 );
RifEclipseRftAddress p90Address( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90 );
RifEclipseRftAddress meanAddress( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN );
RiaCurveMerger<double> curveMerger;

View File

@@ -194,10 +194,14 @@ std::set<RifEclipseRftAddress> RifReaderFmuRft::eclipseRftAddresses()
{
if ( observation.valid() )
{
RifEclipseRftAddress tvdAddress( wellName, dateTime, RifEclipseRftAddress::TVD );
RifEclipseRftAddress mdAddress( wellName, dateTime, RifEclipseRftAddress::MD );
RifEclipseRftAddress pressureAddress( wellName, dateTime, RifEclipseRftAddress::PRESSURE );
RifEclipseRftAddress pressureErrorAddress( wellName, dateTime, RifEclipseRftAddress::PRESSURE_ERROR );
RifEclipseRftAddress tvdAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::TVD );
RifEclipseRftAddress mdAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::MD );
RifEclipseRftAddress pressureAddress( wellName,
dateTime,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE );
RifEclipseRftAddress pressureErrorAddress( wellName,
dateTime,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR );
allAddresses.insert( tvdAddress );
allAddresses.insert( mdAddress );
allAddresses.insert( pressureAddress );
@@ -230,16 +234,16 @@ void RifReaderFmuRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
{
switch ( rftAddress.wellLogChannel() )
{
case RifEclipseRftAddress::TVD:
case RifEclipseRftAddress::RftWellLogChannelType::TVD:
values->push_back( observation.tvdmsl );
break;
case RifEclipseRftAddress::MD:
case RifEclipseRftAddress::RftWellLogChannelType::MD:
values->push_back( observation.mdrkb );
break;
case RifEclipseRftAddress::PRESSURE:
case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE:
values->push_back( observation.pressure );
break;
case RifEclipseRftAddress::PRESSURE_ERROR:
case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR:
values->push_back( observation.pressureError );
break;
default:
@@ -309,8 +313,9 @@ std::set<QDateTime>
RifReaderFmuRft::availableTimeSteps( const QString& wellName,
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName )
{
if ( wellLogChannelName == RifEclipseRftAddress::TVD || wellLogChannelName == RifEclipseRftAddress::MD ||
wellLogChannelName == RifEclipseRftAddress::PRESSURE )
if ( wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::TVD ||
wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::MD ||
wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE )
{
return availableTimeSteps( wellName );
}
@@ -342,8 +347,9 @@ std::set<QDateTime>
RifReaderFmuRft::availableTimeSteps( const QString& wellName,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& relevantChannels )
{
if ( relevantChannels.count( RifEclipseRftAddress::TVD ) || relevantChannels.count( RifEclipseRftAddress::MD ) ||
relevantChannels.count( RifEclipseRftAddress::PRESSURE ) )
if ( relevantChannels.count( RifEclipseRftAddress::RftWellLogChannelType::TVD ) ||
relevantChannels.count( RifEclipseRftAddress::RftWellLogChannelType::MD ) ||
relevantChannels.count( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) )
{
return availableTimeSteps( wellName );
}
@@ -362,7 +368,9 @@ std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderFmuRft::available
if ( !m_allWellObservations.empty() )
{
return { RifEclipseRftAddress::TVD, RifEclipseRftAddress::MD, RifEclipseRftAddress::PRESSURE };
return { RifEclipseRftAddress::RftWellLogChannelType::TVD,
RifEclipseRftAddress::RftWellLogChannelType::MD,
RifEclipseRftAddress::RftWellLogChannelType::PRESSURE };
}
return {};
}

View File

@@ -0,0 +1,488 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RifReaderOpmRft.h"
#include "RiaLogging.h"
#include "RiaQDateTimeTools.h"
#include "RiaRftDefines.h"
#include "RiaStdStringTools.h"
#include "opm/io/eclipse/ERft.hpp"
#include "cafAssert.h"
#include "cafVecIjk.h"
#include <iomanip>
#include <iostream>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderOpmRft::RifReaderOpmRft( const QString& fileName )
{
try
{
m_opm_rft = std::make_unique<Opm::EclIO::ERft>( fileName.toStdString() );
buildMetaData();
}
catch ( ... )
{
RiaLogging::error( QString( "Failed to open RFT file %1" ).arg( fileName ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseRftAddress> RifReaderOpmRft::eclipseRftAddresses()
{
return m_addresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vector<double>* values )
{
auto wellName = rftAddress.wellName().toStdString();
auto resultName = rftAddress.segmentResultName().toStdString();
auto qDate = rftAddress.timeStep().date();
int y = qDate.year();
int m = qDate.month();
int d = qDate.day();
if ( rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES )
{
auto key = std::make_pair( wellName, RftDate{ y, m, d } );
auto segment = m_rftWellDateSegments[key];
if ( rftAddress.segmentResultName() == RiaDefines::segmentNumberResultName() )
{
auto data = segment.topology();
auto indices = segment.indicesForBranchNumber( rftAddress.segmentBranchNumber() );
for ( const auto& i : indices )
{
CAF_ASSERT( i < data.size() );
values->push_back( data[i].segNo() );
}
}
else if ( rftAddress.segmentResultName() == RiaDefines::segmentBranchNumberResultName() )
{
auto branchNumbers = segment.branchIds();
for ( const auto& branchNumber : branchNumbers )
{
values->push_back( branchNumber );
}
}
}
if ( resultName.empty() )
{
resultName = RifReaderOpmRft::resultNameFromChannelType( rftAddress.wellLogChannel() );
}
try
{
auto data = m_opm_rft->getRft<float>( resultName, wellName, y, m, d );
if ( !data.empty() )
{
if ( rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES )
{
auto key = std::make_pair( wellName, RftDate{ y, m, d } );
auto segment = m_rftWellDateSegments[key];
auto indices = segment.indicesForBranchNumber( rftAddress.segmentBranchNumber() );
for ( const auto& i : indices )
{
CAF_ASSERT( i < data.size() );
values->push_back( data[i] );
}
}
else
{
values->insert( values->end(), data.begin(), data.end() );
}
}
}
catch ( ... )
{
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QDateTime> RifReaderOpmRft::availableTimeSteps( const QString& wellName )
{
std::set<QDateTime> timeSteps;
for ( const auto& address : m_addresses )
{
if ( address.wellName() == wellName )
{
timeSteps.insert( address.timeStep() );
}
}
return timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QDateTime>
RifReaderOpmRft::availableTimeSteps( const QString& wellName,
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName )
{
std::set<QDateTime> timeSteps;
for ( const auto& address : m_addresses )
{
if ( address.wellName() == wellName && address.wellLogChannel() == wellLogChannelName )
{
timeSteps.insert( address.timeStep() );
}
}
return timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QDateTime>
RifReaderOpmRft::availableTimeSteps( const QString& wellName,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& relevantChannels )
{
std::set<QDateTime> timeSteps;
for ( const auto& address : m_addresses )
{
if ( address.wellName() == wellName && relevantChannels.count( address.wellLogChannel() ) )
{
timeSteps.insert( address.timeStep() );
}
}
return timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderOpmRft::availableWellLogChannels( const QString& wellName )
{
std::set<RifEclipseRftAddress::RftWellLogChannelType> types;
for ( const auto& a : m_addresses )
{
if ( ( a.wellName() == wellName ) && ( a.wellLogChannel() != RifEclipseRftAddress::RftWellLogChannelType::NONE ) )
{
types.insert( a.wellLogChannel() );
}
}
return types;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QString> RifReaderOpmRft::wellNames()
{
return m_wellNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderOpmRft::cellIndices( const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices )
{
auto wellName = rftAddress.wellName().toStdString();
auto date = rftAddress.timeStep().date();
int y = date.year();
int m = date.month();
int d = date.day();
try
{
auto resultNameI = "CONIPOS";
auto dataI = m_opm_rft->getRft<int>( resultNameI, wellName, y, m, d );
auto resultNameJ = "CONJPOS";
auto dataJ = m_opm_rft->getRft<int>( resultNameJ, wellName, y, m, d );
auto resultNameK = "CONKPOS";
auto dataK = m_opm_rft->getRft<int>( resultNameK, wellName, y, m, d );
if ( !dataI.empty() && ( dataI.size() == dataJ.size() ) && ( dataI.size() == dataK.size() ) )
{
for ( size_t n = 0; n < dataI.size(); n++ )
{
// NB: Transform to zero-based cell indices
indices->push_back( caf::VecIjk( dataI[n] - 1, dataJ[n] - 1, dataK[n] - 1 ) );
}
}
}
catch ( ... )
{
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderOpmRft::buildMetaData()
{
// TODO: Assert better than return?
if ( !isOpen() ) return;
importWellNames();
auto reports = m_opm_rft->listOfRftReports();
for ( const auto& report : reports )
{
auto [wellName, reportDate, reportTime] = report;
auto rftVectors = m_opm_rft->listOfRftArrays( wellName, reportDate );
for ( const auto& rftVec : rftVectors )
{
auto [resultDataName, arrType, itemCount] = rftVec;
int y = std::get<0>( reportDate );
int m = std::get<1>( reportDate );
int d = std::get<2>( reportDate );
auto dt = RiaQDateTimeTools::createUtcDateTime( QDate( y, m, d ) );
auto channelTypes = identifyChannelType( resultDataName );
if ( channelTypes != RifEclipseRftAddress::RftWellLogChannelType::NONE )
{
auto adr = RifEclipseRftAddress( QString::fromStdString( wellName ), dt, channelTypes );
m_addresses.insert( adr );
}
}
}
buildSegmentData();
// Create segment result addresses
for ( const auto& segmentWellData : m_rftWellDateSegments )
{
auto [wellName, reportDate] = segmentWellData.first;
auto segmentData = segmentWellData.second;
auto resultNameAndSizes = segmentData.resultNameAndSize();
int y = std::get<0>( reportDate );
int m = std::get<1>( reportDate );
int d = std::get<2>( reportDate );
auto dt = RiaQDateTimeTools::createUtcDateTime( QDate( y, m, d ) );
auto segmentCount = segmentData.topology().size();
for ( const auto& resultNameAndSize : resultNameAndSizes )
{
auto resultValueCount = std::get<2>( resultNameAndSize );
if ( static_cast<size_t>( resultValueCount ) != segmentCount ) continue;
auto resultName = std::get<0>( resultNameAndSize );
auto adr = RifEclipseRftAddress::createSegmentResult( QString::fromStdString( wellName ),
dt,
QString::fromStdString( resultName ) );
m_addresses.insert( adr );
}
auto adr = RifEclipseRftAddress::createSegmentResult( QString::fromStdString( wellName ),
dt,
RiaDefines::segmentNumberResultName() );
m_addresses.insert( adr );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderOpmRft::buildSegmentData()
{
m_rftWellDateSegments.clear();
auto wellNames = m_opm_rft->listOfWells();
auto dates = m_opm_rft->listOfdates();
for ( const auto& wellName : wellNames )
{
for ( const auto& date : dates )
{
std::vector<RifRftSegmentData> segmentsForWellDate;
std::vector<int> segnxt = importWellData( wellName, "SEGNXT", date );
std::vector<int> segbrno = importWellData( wellName, "SEGBRNO", date );
std::vector<int> brnstValues = importWellData( wellName, "BRNST", date );
std::vector<int> brnenValues = importWellData( wellName, "BRNEN", date );
if ( segnxt.empty() ) continue;
if ( segnxt.size() != segbrno.size() ) continue;
if ( brnenValues.empty() || brnstValues.empty() ) continue;
std::vector<int> segNo;
for ( size_t i = 0; i < segnxt.size(); i++ )
{
int branchIndex = segbrno[i] - 1;
int nextBranchIndex = -1;
if ( i + 1 < segbrno.size() ) nextBranchIndex = segbrno[i + 1] - 1;
bool isLastSegmentOnBranch = branchIndex != nextBranchIndex;
int brnst = brnstValues[branchIndex];
int brnen = brnenValues[branchIndex];
int segmentId = -1;
if ( !isLastSegmentOnBranch )
{
if ( i + 1 < segnxt.size() ) segmentId = segnxt[i + 1];
}
else
{
segmentId = brnen;
}
segNo.push_back( segmentId );
segmentsForWellDate.emplace_back( RifRftSegmentData( segnxt[i], segbrno[i], brnst, brnen, segmentId ) );
}
if ( segmentsForWellDate.empty() ) continue;
RifRftSegment segment;
segment.setSegmentData( segmentsForWellDate );
auto arraysAtWellDate = m_opm_rft->listOfRftArrays( wellName, date );
for ( const auto& rftResultMetaData : arraysAtWellDate )
{
auto [name, arrayType, size] = rftResultMetaData;
if ( name.find( "SEG" ) == 0 )
{
segment.addResultNameAndSize( rftResultMetaData );
}
}
auto wellDateKey = std::make_pair( wellName, date );
m_rftWellDateSegments[wellDateKey] = segment;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderOpmRft::segmentDataDebugLog() const
{
for ( const auto& a : m_rftWellDateSegments )
{
auto [wellName, date] = a.first;
auto segmentData = a.second;
std::cout << "\nWell: " << wellName << "Date : " << std::get<0>( date ) << " " << std::get<1>( date ) << " "
<< std::get<2>( date ) << " \n";
for ( const auto& r : segmentData.topology() )
{
std::cout << "SEGNXT " << std::setw( 2 ) << r.segNext() << ", ";
std::cout << "SEGBRNO " << std::setw( 2 ) << r.segBrno() << ", ";
std::cout << "BNRST " << std::setw( 2 ) << r.segBrnst() << ", ";
std::cout << "BRNEN " << std::setw( 2 ) << r.segBrnen() << ", ";
std::cout << "SEGNO " << std::setw( 2 ) << r.segNo() << "\n";
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderOpmRft::isOpen() const
{
return m_opm_rft != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderOpmRft::importWellNames()
{
auto names = m_opm_rft->listOfWells();
for ( const auto& w : names )
{
m_wellNames.insert( QString::fromStdString( w ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int>
RifReaderOpmRft::importWellData( const std::string& wellName, const std::string& propertyName, const RftDate& date ) const
{
if ( m_opm_rft->hasArray( propertyName, wellName, date ) )
{
return m_opm_rft->getRft<int>( propertyName, wellName, date );
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifEclipseRftAddress::RftWellLogChannelType RifReaderOpmRft::identifyChannelType( const std::string& resultName )
{
if ( resultName == "DEPTH" ) return RifEclipseRftAddress::RftWellLogChannelType::TVD;
if ( resultName == "PRESSURE" ) return RifEclipseRftAddress::RftWellLogChannelType::PRESSURE;
if ( resultName == "SWAT" ) return RifEclipseRftAddress::RftWellLogChannelType::SWAT;
if ( resultName == "SOIL" ) return RifEclipseRftAddress::RftWellLogChannelType::SOIL;
if ( resultName == "SGAS" ) return RifEclipseRftAddress::RftWellLogChannelType::SGAS;
if ( resultName == "WRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::WRAT;
if ( resultName == "ORAT" ) return RifEclipseRftAddress::RftWellLogChannelType::ORAT;
if ( resultName == "GRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::GRAT;
return RifEclipseRftAddress::RftWellLogChannelType::NONE;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifReaderOpmRft::resultNameFromChannelType( RifEclipseRftAddress::RftWellLogChannelType channelType )
{
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::TVD ) return "DEPTH";
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) return "PRESSURE";
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SWAT ) return "SWAT";
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SOIL ) return "SOIL";
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SGAS ) return "SGAS";
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::WRAT ) return "WRAT";
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::ORAT ) return "ORAT";
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::GRAT ) return "GRAT";
return {};
}

View File

@@ -0,0 +1,80 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RifReaderEclipseRft.h"
#include "RifRftSegment.h"
#include "cvfObject.h"
#include <memory>
namespace Opm
{
namespace EclIO
{
class ERft;
} // namespace EclIO
} // namespace Opm
class RifReaderOpmRft : public RifReaderRftInterface, public cvf::Object
{
public:
RifReaderOpmRft( const QString& fileName );
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
void values( const RifEclipseRftAddress& rftAddress, std::vector<double>* values ) override;
std::set<QDateTime> availableTimeSteps( const QString& wellName ) override;
std::set<QDateTime> availableTimeSteps( const QString& wellName,
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName ) override;
std::set<QDateTime>
availableTimeSteps( const QString& wellName,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& relevantChannels ) override;
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels( const QString& wellName ) override;
std::set<QString> wellNames() override;
void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices ) override;
private:
// Segment data
// RftDate must be synced with definition in Opm::EclIO::ERft::RftDate
using RftDate = std::tuple<int, int, int>;
using RftSegmentKey = std::pair<std::string, RftDate>;
void buildMetaData();
void buildSegmentData();
void segmentDataDebugLog() const;
bool isOpen() const;
void importWellNames();
std::vector<int> importWellData( const std::string& wellName, const std::string& propertyName, const RftDate& date ) const;
static RifEclipseRftAddress::RftWellLogChannelType identifyChannelType( const std::string& resultName );
static std::string resultNameFromChannelType( RifEclipseRftAddress::RftWellLogChannelType channelType );
private:
std::unique_ptr<Opm::EclIO::ERft> m_opm_rft;
// RFT and PLT addresses
std::set<RifEclipseRftAddress> m_addresses;
std::set<QString> m_wellNames;
std::map<RftSegmentKey, RifRftSegment> m_rftWellDateSegments;
};

View File

@@ -34,3 +34,10 @@ std::set<RifEclipseRftAddress> RifReaderRftInterface::eclipseRftAddresses( const
}
return matchingAddresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderRftInterface::cellIndices( const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices )
{
}

View File

@@ -26,6 +26,11 @@
#include <set>
#include <vector>
namespace caf
{
class VecIjk;
};
class RifReaderRftInterface
{
public:
@@ -42,4 +47,6 @@ public:
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName ) = 0;
virtual std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels( const QString& wellName ) = 0;
virtual std::set<QString> wellNames() = 0;
virtual void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices );
};

View File

@@ -0,0 +1,147 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RifRftSegment.h"
#include <algorithm>
#include <unordered_set>
//--------------------------------------------------------------------------------------------------
/// segnxt : Int ID for the next segment
/// brno : Branch ID number
/// brnst : Branch ID number for start of segment
/// brnen : Branch ID number for end of segment
/// segNo : Segment ID number
///
//--------------------------------------------------------------------------------------------------
RifRftSegmentData::RifRftSegmentData( int segnxt, int brno, int brnst, int brnen, int segNo )
: m_segNext( segnxt )
, m_segbrno( brno )
, m_brnst( brnst )
, m_brnen( brnen )
, m_segmentNo( segNo )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifRftSegmentData::segNext() const
{
return m_segNext;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifRftSegmentData::segBrno() const
{
return m_segbrno;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifRftSegmentData::segBrnst() const
{
return m_brnst;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifRftSegmentData::segBrnen() const
{
return m_brnen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifRftSegmentData::segNo() const
{
return m_segmentNo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifRftSegment::setSegmentData( std::vector<RifRftSegmentData> segmentData )
{
m_topology = segmentData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RifRftSegmentData> RifRftSegment::topology() const
{
return m_topology;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifRftSegment::addResultNameAndSize( const Opm::EclIO::EclFile::EclEntry& resultNameAndSize )
{
m_resultNameAndSize.push_back( resultNameAndSize );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<Opm::EclIO::EclFile::EclEntry> RifRftSegment::resultNameAndSize() const
{
return m_resultNameAndSize;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int> RifRftSegment::branchIds() const
{
std::unordered_set<int> s;
for ( const auto& segData : m_topology )
{
s.insert( segData.segBrno() );
}
std::vector<int> v;
v.assign( s.begin(), s.end() );
std::sort( v.begin(), v.end() );
return v;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RifRftSegment::indicesForBranchNumber( int branchNumber ) const
{
std::vector<size_t> v;
for ( size_t i = 0; i < m_topology.size(); i++ )
{
auto segment = m_topology[i];
if ( branchNumber <= 0 || segment.segBrno() == branchNumber )
{
v.push_back( i );
}
}
return v;
}

View File

@@ -0,0 +1,62 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <string>
#include <tuple>
#include <vector>
#include "opm/io/eclipse/EclFile.hpp"
class RifRftSegmentData
{
public:
RifRftSegmentData( int segnxt, int brno, int brnst, int brnen, int segNo );
int segNext() const;
int segBrno() const;
int segBrnst() const;
int segBrnen() const;
int segNo() const;
private:
int m_segNext;
int m_segbrno;
int m_brnst;
int m_brnen;
int m_segmentNo;
};
class RifRftSegment
{
public:
void setSegmentData( std::vector<RifRftSegmentData> segmentData );
std::vector<RifRftSegmentData> topology() const;
void addResultNameAndSize( const Opm::EclIO::EclFile::EclEntry& resultNameAndSize );
std::vector<Opm::EclIO::EclFile::EclEntry> resultNameAndSize() const;
std::vector<int> branchIds() const;
std::vector<size_t> indicesForBranchNumber( int branchNumber ) const;
private:
std::vector<RifRftSegmentData> m_topology;
std::vector<Opm::EclIO::EclFile::EclEntry> m_resultNameAndSize;
};