mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-03 20:20:48 -06:00
RFT: Support device and annulus branches (#9168)
* Add unit test used to read data from WSEGLINK * Add segment branch type * Add detection of device branches * Add data source stepping on branch type * parse wseglink data * add RFT case as child of RimFileSummaryCase
This commit is contained in:
parent
37d6a44b2a
commit
4cb26f69c5
@ -17,6 +17,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RiaRftDefines.h"
|
||||
#include "cafAppEnum.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@ -63,5 +64,26 @@ QString RiaDefines::allBranches()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::segmentBranchNumberResultName()
|
||||
{
|
||||
return "SegmenBranchNumber";
|
||||
return "SegmentBranchNumber";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::segmentOneBasedBranchIndexResultName()
|
||||
{
|
||||
return "SegmentOneBasedBranchIndex";
|
||||
}
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void caf::AppEnum<RiaDefines::RftBranchType>::setUp()
|
||||
{
|
||||
addItem( RiaDefines::RftBranchType::RFT_TUBING, "RFT_TUBING", "Tubing" );
|
||||
addItem( RiaDefines::RftBranchType::RFT_DEVICE, "RFT_DEVICE", "Device" );
|
||||
addItem( RiaDefines::RftBranchType::RFT_ANNULUS, "RFT_ANNULUS", "Annulus" );
|
||||
addItem( RiaDefines::RftBranchType::RFT_UNKNOWN, "RFT_UNKNOWN", "Unknown" );
|
||||
setDefault( RiaDefines::RftBranchType::RFT_TUBING );
|
||||
}
|
||||
} // namespace caf
|
||||
|
@ -29,12 +29,13 @@ QString segmentNumberResultName();
|
||||
|
||||
QString allBranches();
|
||||
QString segmentBranchNumberResultName();
|
||||
QString segmentOneBasedBranchIndexResultName();
|
||||
|
||||
enum class RftBranchType
|
||||
{
|
||||
RFT_TUBING,
|
||||
RFT_ANNULAR,
|
||||
RFT_DEVICE,
|
||||
RFT_ANNULUS,
|
||||
RFT_UNKNOWN
|
||||
};
|
||||
|
||||
|
@ -21,16 +21,18 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseRftAddress::RifEclipseRftAddress( const QString& wellName,
|
||||
const QDateTime& timeStep,
|
||||
RftWellLogChannelType wellLogChannelName,
|
||||
const QString& segmentResultName,
|
||||
int segmentBranchNumber )
|
||||
RifEclipseRftAddress::RifEclipseRftAddress( const QString& wellName,
|
||||
const QDateTime& timeStep,
|
||||
RftWellLogChannelType wellLogChannelName,
|
||||
const QString& segmentResultName,
|
||||
int segmentBranchIndex,
|
||||
RiaDefines::RftBranchType segmentBranchType )
|
||||
: m_wellName( wellName )
|
||||
, m_timeStep( timeStep )
|
||||
, m_wellLogChannel( wellLogChannelName )
|
||||
, m_segmentResultName( segmentResultName )
|
||||
, m_segmentBranchNumber( segmentBranchNumber )
|
||||
, m_segmentBranchIndex( segmentBranchIndex )
|
||||
, m_segmentBranchType( segmentBranchType )
|
||||
{
|
||||
}
|
||||
|
||||
@ -43,7 +45,31 @@ RifEclipseRftAddress RifEclipseRftAddress::createAddress( const QString&
|
||||
{
|
||||
auto segmentResultName = "";
|
||||
auto segmentBranchNumber = -1;
|
||||
auto adr = RifEclipseRftAddress( wellName, timeStep, wellLogChannel, segmentResultName, segmentBranchNumber );
|
||||
auto adr = RifEclipseRftAddress( wellName,
|
||||
timeStep,
|
||||
wellLogChannel,
|
||||
segmentResultName,
|
||||
segmentBranchNumber,
|
||||
RiaDefines::RftBranchType::RFT_UNKNOWN );
|
||||
|
||||
return adr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseRftAddress RifEclipseRftAddress::createBranchSegmentAddress( const QString& wellName,
|
||||
const QDateTime& dateTime,
|
||||
const QString& resultName,
|
||||
int segmentBranchIndex,
|
||||
RiaDefines::RftBranchType segmentBranchType )
|
||||
{
|
||||
auto adr = RifEclipseRftAddress( wellName,
|
||||
dateTime,
|
||||
RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES,
|
||||
resultName,
|
||||
segmentBranchIndex,
|
||||
segmentBranchType );
|
||||
|
||||
return adr;
|
||||
}
|
||||
@ -53,14 +79,14 @@ RifEclipseRftAddress RifEclipseRftAddress::createAddress( const QString&
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseRftAddress RifEclipseRftAddress::createSegmentAddress( const QString& wellName,
|
||||
const QDateTime& dateTime,
|
||||
const QString& resultName,
|
||||
int segmentBranchNumber )
|
||||
const QString& resultName )
|
||||
{
|
||||
auto adr = RifEclipseRftAddress( wellName,
|
||||
dateTime,
|
||||
RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES,
|
||||
resultName,
|
||||
segmentBranchNumber );
|
||||
-1,
|
||||
RiaDefines::RftBranchType::RFT_UNKNOWN );
|
||||
|
||||
return adr;
|
||||
}
|
||||
@ -76,9 +102,17 @@ QString RifEclipseRftAddress::segmentResultName() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RifEclipseRftAddress::segmentBranchNumber() const
|
||||
int RifEclipseRftAddress::segmentBranchIndex() const
|
||||
{
|
||||
return m_segmentBranchNumber;
|
||||
return m_segmentBranchIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaDefines::RftBranchType RifEclipseRftAddress::segmentBranchType() const
|
||||
{
|
||||
return m_segmentBranchType;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -137,7 +171,7 @@ bool operator==( const RifEclipseRftAddress& first, const RifEclipseRftAddress&
|
||||
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;
|
||||
if ( first.segmentBranchIndex() != second.segmentBranchIndex() ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -153,8 +187,8 @@ bool operator<( const RifEclipseRftAddress& first, const RifEclipseRftAddress& s
|
||||
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();
|
||||
if ( first.segmentBranchIndex() != second.segmentBranchIndex() )
|
||||
return first.segmentBranchIndex() < second.segmentBranchIndex();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaRftDefines.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -55,13 +57,18 @@ public:
|
||||
static RifEclipseRftAddress
|
||||
createAddress( const QString& wellName, const QDateTime& timeStep, RftWellLogChannelType wellLogChannel );
|
||||
|
||||
static RifEclipseRftAddress createSegmentAddress( const QString& wellName,
|
||||
const QDateTime& dateTime,
|
||||
const QString& resultName,
|
||||
int segmentBranchNumber );
|
||||
static RifEclipseRftAddress
|
||||
createSegmentAddress( const QString& wellName, const QDateTime& dateTime, const QString& resultName );
|
||||
|
||||
QString segmentResultName() const;
|
||||
int segmentBranchNumber() const;
|
||||
static RifEclipseRftAddress createBranchSegmentAddress( const QString& wellName,
|
||||
const QDateTime& dateTime,
|
||||
const QString& resultName,
|
||||
int segmentBranchIndex,
|
||||
RiaDefines::RftBranchType segmentBranchType );
|
||||
|
||||
QString segmentResultName() const;
|
||||
int segmentBranchIndex() const;
|
||||
RiaDefines::RftBranchType segmentBranchType() const;
|
||||
|
||||
const QString& wellName() const;
|
||||
QDateTime timeStep() const;
|
||||
@ -71,19 +78,21 @@ public:
|
||||
static std::set<RftWellLogChannelType> pltPlotChannelTypes();
|
||||
|
||||
private:
|
||||
RifEclipseRftAddress( const QString& wellName,
|
||||
const QDateTime& timeStep,
|
||||
RftWellLogChannelType wellLogChannel,
|
||||
const QString& segmentResultName,
|
||||
int segmentBranchNumber );
|
||||
RifEclipseRftAddress( const QString& wellName,
|
||||
const QDateTime& timeStep,
|
||||
RftWellLogChannelType wellLogChannel,
|
||||
const QString& segmentResultName,
|
||||
int segmentBranchIndex,
|
||||
RiaDefines::RftBranchType segmentBranchType );
|
||||
|
||||
private:
|
||||
QString m_wellName;
|
||||
QDateTime m_timeStep;
|
||||
RftWellLogChannelType m_wellLogChannel;
|
||||
|
||||
QString m_segmentResultName;
|
||||
int m_segmentBranchNumber;
|
||||
QString m_segmentResultName;
|
||||
int m_segmentBranchIndex;
|
||||
RiaDefines::RftBranchType m_segmentBranchType;
|
||||
};
|
||||
|
||||
bool operator==( const RifEclipseRftAddress& first, const RifEclipseRftAddress& second );
|
||||
|
@ -23,6 +23,10 @@
|
||||
#include "RiaRftDefines.h"
|
||||
#include "RiaStdStringTools.h"
|
||||
|
||||
#include "RiaOpmParserTools.h"
|
||||
|
||||
#include "opm/input/eclipse/Parser/Parser.hpp"
|
||||
#include "opm/input/eclipse/Parser/ParserKeywords/W.hpp"
|
||||
#include "opm/io/eclipse/ERft.hpp"
|
||||
|
||||
#include "cafAssert.h"
|
||||
@ -31,25 +35,20 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderOpmRft::RifReaderOpmRft( const QString& fileName, const QString& dataDeckFileName )
|
||||
{
|
||||
openFiles( fileName, dataDeckFileName );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderOpmRft::RifReaderOpmRft( const QString& fileName )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_opm_rft = std::make_unique<Opm::EclIO::ERft>( fileName.toStdString() );
|
||||
|
||||
buildMetaData();
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
RiaLogging::error( QString( "Failed to open RFT file %1\n%2" ).arg( fileName ).arg( e.what() ) );
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
RiaLogging::error( QString( "Failed to open RFT file %1" ).arg( fileName ) );
|
||||
}
|
||||
openFiles( fileName, "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -82,12 +81,13 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
|
||||
{
|
||||
auto data = segment.topology();
|
||||
|
||||
auto indices = segment.indicesForBranchNumber( rftAddress.segmentBranchNumber() );
|
||||
auto indices = segment.indicesForBranchIndex( rftAddress.segmentBranchIndex(), rftAddress.segmentBranchType() );
|
||||
for ( const auto& i : indices )
|
||||
{
|
||||
CAF_ASSERT( i < data.size() );
|
||||
values->push_back( data[i].segNo() );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( rftAddress.segmentResultName() == RiaDefines::segmentBranchNumberResultName() )
|
||||
{
|
||||
@ -96,6 +96,16 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
|
||||
{
|
||||
values->push_back( branchNumber );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( rftAddress.segmentResultName() == RiaDefines::segmentOneBasedBranchIndexResultName() )
|
||||
{
|
||||
auto branchIndices = segment.oneBasedBranchIndices();
|
||||
for ( const auto& branchNumber : branchIndices )
|
||||
{
|
||||
values->push_back( branchNumber );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +124,8 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
|
||||
auto key = std::make_pair( wellName, RftDate{ y, m, d } );
|
||||
auto segment = m_rftWellDateSegments[key];
|
||||
|
||||
auto indices = segment.indicesForBranchNumber( rftAddress.segmentBranchNumber() );
|
||||
auto indices =
|
||||
segment.indicesForBranchIndex( rftAddress.segmentBranchIndex(), rftAddress.segmentBranchType() );
|
||||
for ( const auto& i : indices )
|
||||
{
|
||||
CAF_ASSERT( i < data.size() );
|
||||
@ -253,6 +264,37 @@ void RifReaderOpmRft::cellIndices( const RifEclipseRftAddress& rftAddress, std::
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderOpmRft::readWseglink( const std::string& filePath )
|
||||
{
|
||||
m_wseglink = RiaOpmParserTools::extractWseglink( filePath );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderOpmRft::openFiles( const QString& fileName, const QString& dataDeckFileName )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_opm_rft = std::make_unique<Opm::EclIO::ERft>( fileName.toStdString() );
|
||||
|
||||
readWseglink( dataDeckFileName.toStdString() );
|
||||
|
||||
buildMetaData();
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
RiaLogging::error( QString( "Failed to open RFT file %1\n%2" ).arg( fileName ).arg( e.what() ) );
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
RiaLogging::error( QString( "Failed to open RFT file %1" ).arg( fileName ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -317,16 +359,14 @@ void RifReaderOpmRft::buildMetaData()
|
||||
auto resultName = std::get<0>( resultNameAndSize );
|
||||
auto adr = RifEclipseRftAddress::createSegmentAddress( QString::fromStdString( wellName ),
|
||||
dt,
|
||||
QString::fromStdString( resultName ),
|
||||
-1 );
|
||||
QString::fromStdString( resultName ) );
|
||||
|
||||
m_addresses.insert( adr );
|
||||
}
|
||||
|
||||
auto adr = RifEclipseRftAddress::createSegmentAddress( QString::fromStdString( wellName ),
|
||||
dt,
|
||||
RiaDefines::segmentNumberResultName(),
|
||||
-1 );
|
||||
RiaDefines::segmentNumberResultName() );
|
||||
|
||||
m_addresses.insert( adr );
|
||||
}
|
||||
@ -456,6 +496,17 @@ void RifReaderOpmRft::importWellNames()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderOpmRft::buildSegmentBranchTypes( const RftSegmentKey& segmentKey )
|
||||
{
|
||||
// A branch can have up to three layers of branches
|
||||
// Tubing branch
|
||||
// The inner most branch representing the tubing pipe
|
||||
//
|
||||
// Device branch
|
||||
// Layer between tubing branch and annulus branch or reservoir
|
||||
// The device segment is connected to a segment on the tubing branch
|
||||
//
|
||||
// Annulus branch
|
||||
// Layer between device branch and reservoir. The segment connection data is imported from WSEGLINK in the data deck
|
||||
|
||||
auto wellName = segmentKey.first;
|
||||
auto date = segmentKey.second;
|
||||
RifRftSegment& segmentRef = m_rftWellDateSegments[segmentKey];
|
||||
@ -469,8 +520,7 @@ void RifReaderOpmRft::buildSegmentBranchTypes( const RftSegmentKey& segmentKey )
|
||||
std::vector<double> seglenstValues;
|
||||
std::vector<double> seglenenValues;
|
||||
{
|
||||
auto resultName =
|
||||
RifEclipseRftAddress::createSegmentAddress( QString::fromStdString( wellName ), dt, "SEGLENST", -1 );
|
||||
auto resultName = RifEclipseRftAddress::createSegmentAddress( QString::fromStdString( wellName ), dt, "SEGLENST" );
|
||||
|
||||
values( resultName, &seglenstValues );
|
||||
|
||||
@ -480,37 +530,124 @@ void RifReaderOpmRft::buildSegmentBranchTypes( const RftSegmentKey& segmentKey )
|
||||
}
|
||||
}
|
||||
{
|
||||
auto resultName =
|
||||
RifEclipseRftAddress::createSegmentAddress( QString::fromStdString( wellName ), dt, "SEGLENEN", -1 );
|
||||
auto resultName = RifEclipseRftAddress::createSegmentAddress( QString::fromStdString( wellName ), dt, "SEGLENEN" );
|
||||
|
||||
values( resultName, &seglenenValues );
|
||||
}
|
||||
|
||||
int oneBasedBranchIndex = 1;
|
||||
|
||||
if ( !seglenenValues.empty() && !seglenstValues.empty() )
|
||||
{
|
||||
// Find tubing and annulus branch types
|
||||
|
||||
auto branchIds = segmentRef.branchIds();
|
||||
for ( auto id : branchIds )
|
||||
{
|
||||
double minimumMD = std::numeric_limits<double>::max();
|
||||
double maximumMD = std::numeric_limits<double>::min();
|
||||
|
||||
std::vector<int> segmentNumbers;
|
||||
|
||||
auto indices = segmentRef.indicesForBranchNumber( id );
|
||||
for ( auto i : indices )
|
||||
{
|
||||
minimumMD = std::min( minimumMD, seglenstValues[i] );
|
||||
maximumMD = std::max( maximumMD, seglenenValues[i] );
|
||||
segmentNumbers.push_back( segmentRef.topology()[i].segNo() );
|
||||
}
|
||||
|
||||
double length = maximumMD - minimumMD;
|
||||
|
||||
segmentRef.setBranchLength( id, length );
|
||||
|
||||
const double tubingThreshold = 1.0;
|
||||
RiaDefines::RftBranchType branchType = RiaDefines::RftBranchType::RFT_UNKNOWN;
|
||||
if ( length > tubingThreshold ) branchType = RiaDefines::RftBranchType::RFT_TUBING;
|
||||
RiaDefines::RftBranchType branchType = RiaDefines::RftBranchType::RFT_UNKNOWN;
|
||||
|
||||
bool hasFoundAnnulusBranch = false;
|
||||
|
||||
auto annulusSegments = annulusSegmentsForWell( wellName );
|
||||
|
||||
std::vector<int> matchingSegments;
|
||||
std::set_intersection( segmentNumbers.begin(),
|
||||
segmentNumbers.end(),
|
||||
annulusSegments.begin(),
|
||||
annulusSegments.end(),
|
||||
std::inserter( matchingSegments, matchingSegments.end() ) );
|
||||
|
||||
if ( !matchingSegments.empty() )
|
||||
{
|
||||
{
|
||||
branchType = RiaDefines::RftBranchType::RFT_ANNULUS;
|
||||
|
||||
// NOTE: Assign branch index after device branch is detected
|
||||
hasFoundAnnulusBranch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !hasFoundAnnulusBranch )
|
||||
{
|
||||
const double tubingThreshold = 1.0;
|
||||
if ( length > tubingThreshold )
|
||||
{
|
||||
branchType = RiaDefines::RftBranchType::RFT_TUBING;
|
||||
segmentRef.setOneBasedBranchIndex( id, oneBasedBranchIndex++ );
|
||||
}
|
||||
}
|
||||
|
||||
segmentRef.setBranchType( id, branchType );
|
||||
}
|
||||
|
||||
auto tubingBranchIds = segmentRef.tubingBranchIds();
|
||||
|
||||
for ( auto& segment : segmentRef.topology() )
|
||||
{
|
||||
auto segmentBranchId = segment.segBrno();
|
||||
auto it = std::find( tubingBranchIds.begin(), tubingBranchIds.end(), segmentBranchId );
|
||||
if ( it == tubingBranchIds.end() )
|
||||
{
|
||||
auto tubingSegmentNumber = segment.segNext();
|
||||
|
||||
auto tubingSegmentData = segmentRef.segmentData( tubingSegmentNumber );
|
||||
if ( tubingSegmentData != nullptr )
|
||||
{
|
||||
auto it = std::find( tubingBranchIds.begin(), tubingBranchIds.end(), tubingSegmentData->segBrno() );
|
||||
if ( it != tubingBranchIds.end() )
|
||||
{
|
||||
// Find all connected segments that is not assigned a branch type, and mark as device
|
||||
// layer
|
||||
|
||||
auto tubingBranchIndex = segmentRef.oneBasedBranchIndexForBranchId( tubingSegmentData->segBrno() );
|
||||
segmentRef.createDeviceBranch( segment.segNo(), tubingBranchIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assign branch index to annulus branches
|
||||
|
||||
for ( auto branchId : branchIds )
|
||||
{
|
||||
auto branchType = segmentRef.branchType( branchId );
|
||||
if ( branchType == RiaDefines::RftBranchType::RFT_ANNULUS )
|
||||
{
|
||||
auto segmentIndices = segmentRef.indicesForBranchNumber( branchId );
|
||||
if ( segmentIndices.empty() ) continue;
|
||||
|
||||
auto firstSegmentIndex = segmentIndices.front();
|
||||
auto firstSegment = segmentRef.topology()[firstSegmentIndex];
|
||||
auto candidateSegmentNumber = firstSegment.segNext();
|
||||
|
||||
auto candidateDeviceSeg = segmentRef.segmentData( candidateSegmentNumber );
|
||||
if ( candidateDeviceSeg )
|
||||
{
|
||||
auto branchIndex = segmentRef.oneBasedBranchIndexForBranchId( candidateDeviceSeg->segBrno() );
|
||||
if ( branchIndex >= 0 )
|
||||
{
|
||||
segmentRef.setOneBasedBranchIndex( branchId, branchIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -540,6 +677,35 @@ std::vector<int>
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::pair<int, int>> RifReaderOpmRft::annulusLinksForWell( const std::string& wellName ) const
|
||||
{
|
||||
auto it = m_wseglink.find( wellName );
|
||||
if ( it != m_wseglink.end() )
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> RifReaderOpmRft::annulusSegmentsForWell( const std::string& wellName ) const
|
||||
{
|
||||
std::vector<int> annulusSegments;
|
||||
|
||||
for ( auto it : annulusLinksForWell( wellName ) )
|
||||
{
|
||||
annulusSegments.push_back( it.first );
|
||||
}
|
||||
|
||||
return annulusSegments;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -37,6 +37,7 @@ class RifReaderOpmRft : public RifReaderRftInterface, public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderOpmRft( const QString& fileName );
|
||||
RifReaderOpmRft( const QString& fileName, const QString& dataDeckFileName );
|
||||
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
|
||||
void values( const RifEclipseRftAddress& rftAddress, std::vector<double>* values ) override;
|
||||
@ -58,6 +59,7 @@ private:
|
||||
using RftDate = std::tuple<int, int, int>;
|
||||
using RftSegmentKey = std::pair<std::string, RftDate>;
|
||||
|
||||
void openFiles( const QString& fileName, const QString& dataDeckFileName );
|
||||
void buildMetaData();
|
||||
void buildSegmentData();
|
||||
void segmentDataDebugLog() const;
|
||||
@ -67,6 +69,10 @@ private:
|
||||
|
||||
std::vector<int> importWellData( const std::string& wellName, const std::string& propertyName, const RftDate& date ) const;
|
||||
|
||||
void readWseglink( const std::string& filePath );
|
||||
std::vector<std::pair<int, int>> annulusLinksForWell( const std::string& wellName ) const;
|
||||
std::vector<int> annulusSegmentsForWell( const std::string& wellName ) const;
|
||||
|
||||
static RifEclipseRftAddress::RftWellLogChannelType identifyChannelType( const std::string& resultName );
|
||||
static std::string resultNameFromChannelType( RifEclipseRftAddress::RftWellLogChannelType channelType );
|
||||
|
||||
@ -79,4 +85,6 @@ private:
|
||||
|
||||
std::map<RftSegmentKey, RifRftSegment> m_rftWellDateSegments;
|
||||
std::set<QDateTime> m_rftSegmentTimeSteps;
|
||||
|
||||
std::map<std::string, std::vector<std::pair<int, int>>> m_wseglink;
|
||||
};
|
||||
|
@ -149,6 +149,62 @@ std::vector<int> RifRftSegment::branchIds() const
|
||||
return v;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<int> RifRftSegment::oneBasedBranchIndices() const
|
||||
{
|
||||
std::set<int> indices;
|
||||
|
||||
for ( auto b : m_oneBasedBranchIndexMap )
|
||||
{
|
||||
indices.insert( b.second );
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RifRftSegment::oneBasedBranchIndexForBranchId( int branchId ) const
|
||||
{
|
||||
if ( m_oneBasedBranchIndexMap.count( branchId ) > 0 ) return m_oneBasedBranchIndexMap.at( branchId );
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RifRftSegmentData* RifRftSegment::segmentData( int segmentNumber ) const
|
||||
{
|
||||
for ( const auto& segData : m_topology )
|
||||
{
|
||||
if ( segData.segNo() == segmentNumber ) return &segData;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifRftSegment::createDeviceBranch( int deviceBranchFirstSegmentNumber, int oneBasedBranchIndex )
|
||||
{
|
||||
for ( auto& segData : m_topology )
|
||||
{
|
||||
if ( segData.segNo() < deviceBranchFirstSegmentNumber ) continue;
|
||||
|
||||
auto branchNumber = segData.segBrno();
|
||||
if ( branchType( branchNumber ) != RiaDefines::RftBranchType::RFT_UNKNOWN ) return;
|
||||
|
||||
setOneBasedBranchIndex( segData.segBrno(), oneBasedBranchIndex );
|
||||
|
||||
setBranchType( segData.segBrno(), RiaDefines::RftBranchType::RFT_DEVICE );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -165,6 +221,24 @@ void RifRftSegment::setBranchType( int branchId, RiaDefines::RftBranchType branc
|
||||
m_branchType[branchId] = branchType;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifRftSegment::setOneBasedBranchIndex( int branchId, int oneBasedBranchIndex )
|
||||
{
|
||||
m_oneBasedBranchIndexMap[branchId] = oneBasedBranchIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaDefines::RftBranchType RifRftSegment::branchType( int branchId ) const
|
||||
{
|
||||
if ( m_branchType.count( branchId ) ) return m_branchType.at( branchId );
|
||||
|
||||
return RiaDefines::RftBranchType::RFT_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -182,3 +256,32 @@ std::vector<size_t> RifRftSegment::indicesForBranchNumber( int branchNumber ) co
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<size_t> RifRftSegment::indicesForBranchIndex( int branchIndex, RiaDefines::RftBranchType branchType ) const
|
||||
{
|
||||
std::vector<size_t> v;
|
||||
for ( size_t i = 0; i < m_topology.size(); i++ )
|
||||
{
|
||||
if ( branchIndex <= 0 )
|
||||
{
|
||||
v.push_back( i );
|
||||
continue;
|
||||
}
|
||||
|
||||
auto segment = m_topology[i];
|
||||
|
||||
auto it = m_oneBasedBranchIndexMap.find( segment.segBrno() );
|
||||
if ( it != m_oneBasedBranchIndexMap.end() )
|
||||
{
|
||||
if ( it->second == branchIndex && m_branchType.at( segment.segBrno() ) == branchType )
|
||||
{
|
||||
v.push_back( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
@ -18,13 +18,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaRftDefines.h"
|
||||
|
||||
#include "opm/io/eclipse/EclFile.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "RiaRftDefines.h"
|
||||
#include "opm/io/eclipse/EclFile.hpp"
|
||||
|
||||
class RifRftSegmentData
|
||||
{
|
||||
public:
|
||||
@ -53,13 +55,22 @@ public:
|
||||
void addResultNameAndSize( const Opm::EclIO::EclFile::EclEntry& resultNameAndSize );
|
||||
std::vector<Opm::EclIO::EclFile::EclEntry> resultNameAndSize() const;
|
||||
|
||||
std::vector<int> tubingBranchIds() const;
|
||||
std::vector<int> branchIds() const;
|
||||
std::vector<int> tubingBranchIds() const;
|
||||
std::vector<int> branchIds() const;
|
||||
std::set<int> oneBasedBranchIndices() const;
|
||||
int oneBasedBranchIndexForBranchId( int branchId ) const;
|
||||
const RifRftSegmentData* segmentData( int segmentNumber ) const;
|
||||
|
||||
void createDeviceBranch( int deviceBranchFirstSegmentNumber, int oneBasedBranchIndex );
|
||||
|
||||
void setBranchLength( int branchId, double length );
|
||||
void setBranchType( int branchId, RiaDefines::RftBranchType branchType );
|
||||
void setOneBasedBranchIndex( int branchId, int oneBasedBranchIndex );
|
||||
|
||||
RiaDefines::RftBranchType branchType( int branchId ) const;
|
||||
|
||||
std::vector<size_t> indicesForBranchNumber( int branchNumber ) const;
|
||||
std::vector<size_t> indicesForBranchIndex( int branchIndex, RiaDefines::RftBranchType branchType ) const;
|
||||
|
||||
private:
|
||||
std::vector<RifRftSegmentData> m_topology;
|
||||
@ -67,4 +78,5 @@ private:
|
||||
|
||||
std::map<int, double> m_branchLength;
|
||||
std::map<int, RiaDefines::RftBranchType> m_branchType;
|
||||
std::map<int, int> m_oneBasedBranchIndexMap;
|
||||
};
|
||||
|
@ -110,7 +110,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimColorLegendItem.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAbstractPlotCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPolylinePickerInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpTableExtractor.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaOpmParserTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCaseDisplayNameTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunctionCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunction.h
|
||||
@ -238,7 +238,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimColorLegendCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimColorLegend.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimColorLegendItem.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpTableExtractor.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaOpmParserTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCaseDisplayNameTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunctionCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunction.cpp
|
||||
|
@ -1,121 +1,188 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- 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 "RimVfpTableExtractor.h"
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafUtils.h"
|
||||
|
||||
#include "opm/input/eclipse/Deck/Deck.hpp"
|
||||
#include "opm/input/eclipse/Parser/Parser.hpp"
|
||||
#include "opm/input/eclipse/Parser/ParserKeywords/V.hpp"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<Opm::VFPInjTable> RimVfpTableExtractor::extractVfpInjectionTables( const std::string& filename )
|
||||
{
|
||||
std::vector<Opm::VFPInjTable> tables;
|
||||
|
||||
try
|
||||
{
|
||||
Opm::Parser parser( false );
|
||||
const ::Opm::ParserKeywords::VFPINJ kw1;
|
||||
const ::Opm::ParserKeywords::VFPIDIMS kw2;
|
||||
|
||||
parser.addParserKeyword( kw1 );
|
||||
parser.addParserKeyword( kw2 );
|
||||
|
||||
auto deck = parser.parseFile( filename );
|
||||
|
||||
std::string myKeyword = "VFPINJ";
|
||||
auto keywordList = deck.getKeywordList( myKeyword );
|
||||
|
||||
for ( auto kw : keywordList )
|
||||
{
|
||||
auto name = kw->name();
|
||||
|
||||
Opm::UnitSystem unitSystem;
|
||||
{
|
||||
const auto& header = kw->getRecord( 0 );
|
||||
|
||||
if ( header.getItem<Opm::ParserKeywords::VFPINJ::UNITS>().hasValue( 0 ) )
|
||||
{
|
||||
std::string units_string;
|
||||
units_string = header.getItem<Opm::ParserKeywords::VFPINJ::UNITS>().get<std::string>( 0 );
|
||||
unitSystem = Opm::UnitSystem( units_string );
|
||||
}
|
||||
}
|
||||
|
||||
Opm::VFPInjTable table( *kw, unitSystem );
|
||||
tables.push_back( table );
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<Opm::VFPProdTable> RimVfpTableExtractor::extractVfpProductionTables( const std::string& filename )
|
||||
{
|
||||
std::vector<Opm::VFPProdTable> tables;
|
||||
|
||||
try
|
||||
{
|
||||
Opm::Parser parser( false );
|
||||
const ::Opm::ParserKeywords::VFPPROD kw1;
|
||||
|
||||
parser.addParserKeyword( kw1 );
|
||||
|
||||
auto deck = parser.parseFile( filename );
|
||||
|
||||
std::string myKeyword = "VFPPROD";
|
||||
auto keywordList = deck.getKeywordList( myKeyword );
|
||||
|
||||
for ( auto kw : keywordList )
|
||||
{
|
||||
auto name = kw->name();
|
||||
|
||||
Opm::UnitSystem unitSystem;
|
||||
{
|
||||
const auto& header = kw->getRecord( 0 );
|
||||
|
||||
if ( header.getItem<Opm::ParserKeywords::VFPPROD::UNITS>().hasValue( 0 ) )
|
||||
{
|
||||
std::string units_string;
|
||||
units_string = header.getItem<Opm::ParserKeywords::VFPPROD::UNITS>().get<std::string>( 0 );
|
||||
unitSystem = Opm::UnitSystem( units_string );
|
||||
}
|
||||
}
|
||||
|
||||
bool gaslift_opt_active = false;
|
||||
Opm::VFPProdTable table( *kw, gaslift_opt_active, unitSystem );
|
||||
tables.push_back( table );
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- 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 "RiaOpmParserTools.h"
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafUtils.h"
|
||||
|
||||
#include "opm/input/eclipse/Deck/Deck.hpp"
|
||||
#include "opm/input/eclipse/Parser/ParseContext.hpp"
|
||||
#include "opm/input/eclipse/Parser/Parser.hpp"
|
||||
#include "opm/input/eclipse/Parser/ParserKeywords/V.hpp"
|
||||
#include "opm/input/eclipse/Parser/ParserKeywords/W.hpp"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<Opm::VFPInjTable> RiaOpmParserTools::extractVfpInjectionTables( const std::string& filename )
|
||||
{
|
||||
std::vector<Opm::VFPInjTable> tables;
|
||||
|
||||
try
|
||||
{
|
||||
Opm::Parser parser( false );
|
||||
const ::Opm::ParserKeywords::VFPINJ kw1;
|
||||
const ::Opm::ParserKeywords::VFPIDIMS kw2;
|
||||
|
||||
parser.addParserKeyword( kw1 );
|
||||
parser.addParserKeyword( kw2 );
|
||||
|
||||
auto deck = parser.parseFile( filename );
|
||||
|
||||
std::string myKeyword = "VFPINJ";
|
||||
auto keywordList = deck.getKeywordList( myKeyword );
|
||||
|
||||
for ( auto kw : keywordList )
|
||||
{
|
||||
auto name = kw->name();
|
||||
|
||||
Opm::UnitSystem unitSystem;
|
||||
{
|
||||
const auto& header = kw->getRecord( 0 );
|
||||
|
||||
if ( header.getItem<Opm::ParserKeywords::VFPINJ::UNITS>().hasValue( 0 ) )
|
||||
{
|
||||
std::string units_string;
|
||||
units_string = header.getItem<Opm::ParserKeywords::VFPINJ::UNITS>().get<std::string>( 0 );
|
||||
unitSystem = Opm::UnitSystem( units_string );
|
||||
}
|
||||
}
|
||||
|
||||
Opm::VFPInjTable table( *kw, unitSystem );
|
||||
tables.push_back( table );
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<Opm::VFPProdTable> RiaOpmParserTools::extractVfpProductionTables( const std::string& filename )
|
||||
{
|
||||
std::vector<Opm::VFPProdTable> tables;
|
||||
|
||||
try
|
||||
{
|
||||
Opm::Parser parser( false );
|
||||
const ::Opm::ParserKeywords::VFPPROD kw1;
|
||||
|
||||
parser.addParserKeyword( kw1 );
|
||||
|
||||
auto deck = parser.parseFile( filename );
|
||||
|
||||
std::string myKeyword = "VFPPROD";
|
||||
auto keywordList = deck.getKeywordList( myKeyword );
|
||||
|
||||
for ( auto kw : keywordList )
|
||||
{
|
||||
auto name = kw->name();
|
||||
|
||||
Opm::UnitSystem unitSystem;
|
||||
{
|
||||
const auto& header = kw->getRecord( 0 );
|
||||
|
||||
if ( header.getItem<Opm::ParserKeywords::VFPPROD::UNITS>().hasValue( 0 ) )
|
||||
{
|
||||
std::string units_string;
|
||||
units_string = header.getItem<Opm::ParserKeywords::VFPPROD::UNITS>().get<std::string>( 0 );
|
||||
unitSystem = Opm::UnitSystem( units_string );
|
||||
}
|
||||
}
|
||||
|
||||
bool gaslift_opt_active = false;
|
||||
Opm::VFPProdTable table( *kw, gaslift_opt_active, unitSystem );
|
||||
tables.push_back( table );
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::map<std::string, std::vector<std::pair<int, int>>> RiaOpmParserTools::extractWseglink( const std::string& filename )
|
||||
{
|
||||
if ( !std::filesystem::exists( filename ) ) return {};
|
||||
|
||||
Opm::Parser parser( false );
|
||||
const Opm::ParserKeywords::WSEGLINK kw1;
|
||||
|
||||
parser.addParserKeyword( kw1 );
|
||||
|
||||
std::stringstream ss;
|
||||
Opm::ParseContext parseContext( Opm::InputError::Action::WARN );
|
||||
auto deck = parser.parseFile( filename, parseContext );
|
||||
|
||||
std::string keyword = "WSEGLINK";
|
||||
auto keywordList = deck.getKeywordList( keyword );
|
||||
if ( keywordList.empty() ) return {};
|
||||
|
||||
std::map<std::string, std::vector<std::pair<int, int>>> wseglink;
|
||||
for ( auto kw : keywordList )
|
||||
{
|
||||
auto name = kw->name();
|
||||
|
||||
for ( size_t i = 0; i < kw->size(); i++ )
|
||||
{
|
||||
auto deckRecord = kw->getRecord( i );
|
||||
|
||||
std::string wellName;
|
||||
int segment1 = -1;
|
||||
int segment2 = -1;
|
||||
|
||||
{
|
||||
auto itemName = ::Opm::ParserKeywords::WSEGLINK::WELL::itemName;
|
||||
if ( deckRecord.hasItem( itemName ) && deckRecord.getItem( itemName ).hasValue( 0 ) )
|
||||
{
|
||||
wellName = deckRecord.getItem( itemName ).getTrimmedString( 0 );
|
||||
}
|
||||
}
|
||||
{
|
||||
auto itemName = ::Opm::ParserKeywords::WSEGLINK::SEGMENT1::itemName;
|
||||
if ( deckRecord.hasItem( itemName ) && deckRecord.getItem( itemName ).hasValue( 0 ) )
|
||||
{
|
||||
segment1 = deckRecord.getItem( itemName ).get<int>( 0 );
|
||||
}
|
||||
}
|
||||
{
|
||||
auto itemName = ::Opm::ParserKeywords::WSEGLINK::SEGMENT2::itemName;
|
||||
if ( deckRecord.hasItem( itemName ) && deckRecord.getItem( itemName ).hasValue( 0 ) )
|
||||
{
|
||||
segment2 = deckRecord.getItem( itemName ).get<int>( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( segment1 != -1 && segment2 != -1 )
|
||||
{
|
||||
wseglink[wellName].push_back( std::make_pair( segment1, segment2 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wseglink;
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -27,9 +28,11 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RimVfpTableExtractor
|
||||
class RiaOpmParserTools
|
||||
{
|
||||
public:
|
||||
static std::vector<Opm::VFPInjTable> extractVfpInjectionTables( const std::string& filename );
|
||||
static std::vector<Opm::VFPProdTable> extractVfpProductionTables( const std::string& filename );
|
||||
|
||||
static std::map<std::string, std::vector<std::pair<int, int>>> extractWseglink( const std::string& filename );
|
||||
};
|
@ -19,8 +19,8 @@
|
||||
#include "RimVfpPlot.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaOpmParserTools.h"
|
||||
#include "RimVfpDefines.h"
|
||||
#include "RimVfpTableExtractor.h"
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
@ -431,7 +431,7 @@ void RimVfpPlot::onLoadDataAndUpdate()
|
||||
|
||||
// Try to read the file as an prod table first (most common)
|
||||
const std::vector<Opm::VFPProdTable> tables =
|
||||
RimVfpTableExtractor::extractVfpProductionTables( filePath.toStdString() );
|
||||
RiaOpmParserTools::extractVfpProductionTables( filePath.toStdString() );
|
||||
if ( !tables.empty() )
|
||||
{
|
||||
m_prodTable = std::make_unique<Opm::VFPProdTable>( tables[0] );
|
||||
@ -446,7 +446,7 @@ void RimVfpPlot::onLoadDataAndUpdate()
|
||||
else
|
||||
{
|
||||
const std::vector<Opm::VFPInjTable> tables =
|
||||
RimVfpTableExtractor::extractVfpInjectionTables( filePath.toStdString() );
|
||||
RiaOpmParserTools::extractVfpInjectionTables( filePath.toStdString() );
|
||||
if ( !tables.empty() )
|
||||
{
|
||||
m_injectionTable = std::make_unique<Opm::VFPInjTable>( tables[0] );
|
||||
|
@ -47,6 +47,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotControls.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveInfoTextProvider.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSummaryAddressModifier.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRftCase.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@ -98,6 +99,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotControls.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveInfoTextProvider.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSummaryAddressModifier.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRftCase.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
@ -33,11 +33,13 @@
|
||||
#include "RifSummaryReaderMultipleFiles.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
#include "RimRftCase.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
#include "cafPdmUiFilePathEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
@ -63,6 +65,9 @@ RimFileSummaryCase::RimFileSummaryCase()
|
||||
"AdditionalSummaryFilePath",
|
||||
"Additional File Path (set invisible when ready)" );
|
||||
m_additionalSummaryFilePath.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftCase, "RftCase", "RFT Case" );
|
||||
m_rftCase = new RimRftCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -131,7 +136,19 @@ void RimFileSummaryCase::createSummaryReaderInterface()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFileSummaryCase::createRftReaderInterface()
|
||||
{
|
||||
m_summaryEclipseRftReader = RimFileSummaryCase::findRftDataAndCreateReader( this->summaryHeaderFilename() );
|
||||
QFileInfo fileInfo( summaryHeaderFilename() );
|
||||
QString folder = fileInfo.absolutePath();
|
||||
|
||||
QString rftFileName = folder + "/" + fileInfo.completeBaseName() + ".RFT";
|
||||
QFileInfo rftFileInfo( rftFileName );
|
||||
|
||||
if ( rftFileInfo.exists() )
|
||||
{
|
||||
m_rftCase()->setRftFileName( rftFileName );
|
||||
}
|
||||
|
||||
m_summaryEclipseRftReader =
|
||||
RimFileSummaryCase::findRftDataAndCreateReader( rftFileName, m_rftCase->dataDeckFilePath() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -186,17 +203,13 @@ RifSummaryReaderInterface* RimFileSummaryCase::findRelatedFilesAndCreateReader(
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderOpmRft* RimFileSummaryCase::findRftDataAndCreateReader( const QString& headerFileName )
|
||||
RifReaderOpmRft* RimFileSummaryCase::findRftDataAndCreateReader( const QString& rftFileName, const QString& dataDeckFileName )
|
||||
{
|
||||
QFileInfo fileInfo( headerFileName );
|
||||
QString folder = fileInfo.absolutePath();
|
||||
QFileInfo fi( rftFileName );
|
||||
|
||||
QString rftFileName = folder + "/" + fileInfo.completeBaseName() + ".RFT";
|
||||
QFileInfo rftFileInfo( rftFileName );
|
||||
|
||||
if ( rftFileInfo.exists() )
|
||||
if ( fi.exists() )
|
||||
{
|
||||
return new RifReaderOpmRft( rftFileInfo.filePath() );
|
||||
return new RifReaderOpmRft( rftFileName, dataDeckFileName );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -219,6 +232,15 @@ void RimFileSummaryCase::defineEditorAttribute( const caf::PdmFieldHandle* field
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFileSummaryCase::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= "" */ )
|
||||
{
|
||||
RimSummaryCase::defineUiTreeOrdering( uiTreeOrdering, uiConfigName );
|
||||
uiTreeOrdering.add( m_rftCase() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -29,6 +29,7 @@ class RiaThreadSafeLogger;
|
||||
class RifOpmCommonEclipseSummary;
|
||||
class RifEclipseSummaryAddress;
|
||||
class RifMultipleSummaryReaders;
|
||||
class RimRftCase;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@ -66,12 +67,14 @@ protected:
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
|
||||
|
||||
private:
|
||||
void openAndAttachAdditionalReader();
|
||||
QString additionalSummaryDataFilePath() const;
|
||||
static QString createAdditionalSummaryFileName();
|
||||
|
||||
static RifReaderOpmRft* findRftDataAndCreateReader( const QString& headerFileName );
|
||||
static RifReaderOpmRft* findRftDataAndCreateReader( const QString& rftFileName, const QString& dataDeckFileName );
|
||||
|
||||
private:
|
||||
cvf::ref<RifSummaryReaderInterface> m_fileSummaryReader;
|
||||
@ -81,4 +84,6 @@ private:
|
||||
|
||||
caf::PdmField<caf::FilePath> m_additionalSummaryFilePath;
|
||||
cvf::ref<RifOpmCommonEclipseSummary> m_additionalSummaryFileReader;
|
||||
|
||||
caf::PdmChildField<RimRftCase*> m_rftCase;
|
||||
};
|
||||
|
71
ApplicationLibCode/ProjectDataModel/Summary/RimRftCase.cpp
Normal file
71
ApplicationLibCode/ProjectDataModel/Summary/RimRftCase.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimRftCase.h"
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
CAF_PDM_SOURCE_INIT( RimRftCase, "RimRftCase" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRftCase::RimRftCase()
|
||||
{
|
||||
CAF_PDM_InitObject( "RFT Case ", ":/SummaryCases16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftFilePath, "RftFilePath", "Rft File" );
|
||||
m_rftFilePath.uiCapability()->setUiReadOnly( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_dataDeckFilePath, "DataDeckFilePath", "Data Deck File" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimRftCase::setDataDeckFileName( const QString& fileName )
|
||||
{
|
||||
m_dataDeckFilePath.v().setPath( fileName );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimRftCase::setRftFileName( const QString& fileName )
|
||||
{
|
||||
m_rftFilePath.v().setPath( fileName );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimRftCase::rftFilePath() const
|
||||
{
|
||||
return m_rftFilePath().path();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimRftCase::dataDeckFilePath() const
|
||||
{
|
||||
return m_dataDeckFilePath().path();
|
||||
}
|
45
ApplicationLibCode/ProjectDataModel/Summary/RimRftCase.h
Normal file
45
ApplicationLibCode/ProjectDataModel/Summary/RimRftCase.h
Normal file
@ -0,0 +1,45 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RimRftCase : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimRftCase();
|
||||
|
||||
void setDataDeckFileName( const QString& fileName );
|
||||
void setRftFileName( const QString& fileName );
|
||||
|
||||
QString rftFilePath() const;
|
||||
QString dataDeckFilePath() const;
|
||||
|
||||
private:
|
||||
caf::PdmField<caf::FilePath> m_rftFilePath;
|
||||
caf::PdmField<caf::FilePath> m_dataDeckFilePath;
|
||||
};
|
@ -140,9 +140,9 @@ QList<caf::PdmOptionItemInfo> RimRftTools::segmentResultNameOptions( RifReaderRf
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimRftTools::segmentBranchIdOptions( RifReaderRftInterface* readerRft,
|
||||
const QString& wellName,
|
||||
const QDateTime& timeStep )
|
||||
QList<caf::PdmOptionItemInfo> RimRftTools::segmentBranchIndexOptions( RifReaderRftInterface* readerRft,
|
||||
const QString& wellName,
|
||||
const QDateTime& timeStep )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
@ -152,8 +152,9 @@ QList<caf::PdmOptionItemInfo> RimRftTools::segmentBranchIdOptions( RifReaderRftI
|
||||
{
|
||||
std::vector<double> values;
|
||||
|
||||
auto adr =
|
||||
RifEclipseRftAddress::createSegmentAddress( wellName, timeStep, RiaDefines::segmentBranchNumberResultName(), -1 );
|
||||
auto adr = RifEclipseRftAddress::createSegmentAddress( wellName,
|
||||
timeStep,
|
||||
RiaDefines::segmentOneBasedBranchIndexResultName() );
|
||||
|
||||
readerRft->values( adr, &values );
|
||||
for ( const auto& v : values )
|
||||
|
@ -42,5 +42,5 @@ public:
|
||||
static QList<caf::PdmOptionItemInfo>
|
||||
segmentResultNameOptions( RifReaderRftInterface* readerRft, const QString& wellName, const QDateTime& timeStep );
|
||||
static QList<caf::PdmOptionItemInfo>
|
||||
segmentBranchIdOptions( RifReaderRftInterface* readerRft, const QString& wellName, const QDateTime& timeStep );
|
||||
segmentBranchIndexOptions( RifReaderRftInterface* readerRft, const QString& wellName, const QDateTime& timeStep );
|
||||
};
|
||||
|
@ -107,7 +107,8 @@ RimWellLogCurveCommonDataSource::RimWellLogCurveCommonDataSource()
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftTimeStep, "RftTimeStep", "RFT Time Step" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftWellName, "RftWellName", "RFT Well Name" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftSegmentBranchId, "SegmentBranchId", "RFT Segment Branch" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftSegmentBranchIndex, "SegmentBranchIndex", "RFT Branch" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftSegmentBranchType, "SegmentBranchType", "RFT Branch Type" );
|
||||
|
||||
m_case = nullptr;
|
||||
m_wellPath = nullptr;
|
||||
@ -310,7 +311,8 @@ void RimWellLogCurveCommonDataSource::resetDefaultOptions()
|
||||
|
||||
m_uniqueRftTimeSteps.clear();
|
||||
m_uniqueRftWellNames.clear();
|
||||
m_uniqueRftBranchIds.clear();
|
||||
m_uniqueRftBranchIndices.clear();
|
||||
m_uniqueRftBranchTypes.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -390,7 +392,8 @@ void RimWellLogCurveCommonDataSource::analyseCurvesAndTracks( const std::vector<
|
||||
{
|
||||
m_uniqueRftWellNames.insert( adr.wellName() );
|
||||
m_uniqueRftTimeSteps.insert( adr.timeStep() );
|
||||
m_uniqueRftBranchIds.insert( adr.segmentBranchNumber() );
|
||||
m_uniqueRftBranchIndices.insert( adr.segmentBranchIndex() );
|
||||
m_uniqueRftBranchTypes.insert( adr.segmentBranchType() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -479,10 +482,17 @@ void RimWellLogCurveCommonDataSource::analyseCurvesAndTracks( const std::vector<
|
||||
m_rftTimeStep = *( m_uniqueRftTimeSteps.begin() );
|
||||
}
|
||||
|
||||
if ( m_uniqueRftBranchIds.size() == 1u )
|
||||
if ( m_uniqueRftBranchIndices.size() == 1u )
|
||||
{
|
||||
m_rftSegmentBranchId = *( m_uniqueRftBranchIds.begin() );
|
||||
m_rftSegmentBranchIndex = *( m_uniqueRftBranchIndices.begin() );
|
||||
}
|
||||
|
||||
if ( m_uniqueRftBranchTypes.size() == 1u )
|
||||
{
|
||||
m_rftSegmentBranchType = *( m_uniqueRftBranchTypes.begin() );
|
||||
}
|
||||
else
|
||||
m_rftSegmentBranchType = RiaDefines::RftBranchType::RFT_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -616,9 +626,13 @@ void RimWellLogCurveCommonDataSource::applyDataSourceChanges( const std::vector<
|
||||
}
|
||||
else if ( rftCurve )
|
||||
{
|
||||
if ( m_summaryCase() ) rftCurve->setSummaryCase( m_summaryCase() );
|
||||
rftCurve->setTimeStep( m_rftTimeStep() );
|
||||
rftCurve->setWellName( m_rftWellName() );
|
||||
rftCurve->setSegmentBranchId( m_rftSegmentBranchId() );
|
||||
rftCurve->setSegmentBranchIndex( m_rftSegmentBranchIndex() );
|
||||
|
||||
if ( m_rftSegmentBranchType() != RiaDefines::RftBranchType::RFT_UNKNOWN )
|
||||
rftCurve->setSegmentBranchType( m_rftSegmentBranchType() );
|
||||
|
||||
RimWellLogPlot* parentPlot = nullptr;
|
||||
rftCurve->firstAncestorOrThisOfTypeAsserted( parentPlot );
|
||||
@ -794,7 +808,8 @@ std::vector<caf::PdmFieldHandle*> RimWellLogCurveCommonDataSource::fieldsToShowI
|
||||
if ( m_uniqueRftWellNames.size() == 1u ) fieldsToDisplay.push_back( &m_rftWellName );
|
||||
if ( m_uniqueTimeSteps.size() == 1u ) fieldsToDisplay.push_back( &m_timeStep );
|
||||
if ( m_uniqueRftTimeSteps.size() == 1u ) fieldsToDisplay.push_back( &m_rftTimeStep );
|
||||
if ( m_uniqueRftBranchIds.size() == 1u ) fieldsToDisplay.push_back( &m_rftSegmentBranchId );
|
||||
if ( m_uniqueRftBranchIndices.size() == 1u ) fieldsToDisplay.push_back( &m_rftSegmentBranchIndex );
|
||||
if ( m_uniqueRftBranchTypes.size() == 1u ) fieldsToDisplay.push_back( &m_rftSegmentBranchType );
|
||||
|
||||
return fieldsToDisplay;
|
||||
}
|
||||
@ -985,9 +1000,9 @@ QList<caf::PdmOptionItemInfo>
|
||||
{
|
||||
options = RimRftTools::wellNameOptions( rftReader() );
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_rftSegmentBranchId )
|
||||
else if ( fieldNeedingOptions == &m_rftSegmentBranchIndex )
|
||||
{
|
||||
options = RimRftTools::segmentBranchIdOptions( rftReader(), m_rftWellName(), m_rftTimeStep() );
|
||||
options = RimRftTools::segmentBranchIndexOptions( rftReader(), m_rftWellName(), m_rftTimeStep() );
|
||||
}
|
||||
|
||||
return options;
|
||||
@ -1047,7 +1062,8 @@ void RimWellLogCurveCommonDataSource::defineUiOrdering( QString uiConfigName, ca
|
||||
|
||||
if ( !m_uniqueRftTimeSteps.empty() ) group->add( &m_rftTimeStep );
|
||||
if ( !m_uniqueRftWellNames.empty() ) group->add( &m_rftWellName );
|
||||
if ( !m_uniqueRftBranchIds.empty() ) group->add( &m_rftSegmentBranchId );
|
||||
if ( !m_uniqueRftBranchIndices.empty() ) group->add( &m_rftSegmentBranchIndex );
|
||||
if ( !m_uniqueRftBranchTypes.empty() ) group->add( &m_rftSegmentBranchType );
|
||||
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
@ -1062,8 +1078,9 @@ void RimWellLogCurveCommonDataSource::defineEditorAttribute( const caf::PdmField
|
||||
auto* myAttr = dynamic_cast<caf::PdmUiComboBoxEditorAttribute*>( attribute );
|
||||
if ( myAttr )
|
||||
{
|
||||
if ( field == &m_case || field == &m_simWellName || field == &m_wellPath || field == &m_timeStep ||
|
||||
field == &m_rftTimeStep || field == &m_rftSegmentBranchId || field == &m_rftWellName )
|
||||
if ( field == &m_case || field == &m_summaryCase || field == &m_simWellName || field == &m_wellPath ||
|
||||
field == &m_timeStep || field == &m_rftTimeStep || field == &m_rftSegmentBranchIndex ||
|
||||
field == &m_rftWellName )
|
||||
{
|
||||
myAttr->showPreviousAndNextButtons = true;
|
||||
myAttr->nextIcon = QIcon( ":/ComboBoxDown.svg" );
|
||||
|
@ -19,6 +19,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaRftDefines.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
@ -125,9 +126,10 @@ private:
|
||||
caf::PdmField<caf::Tristate> m_wbsSmoothing;
|
||||
caf::PdmField<double> m_wbsSmoothingThreshold;
|
||||
|
||||
caf::PdmField<QDateTime> m_rftTimeStep;
|
||||
caf::PdmField<QString> m_rftWellName;
|
||||
caf::PdmField<int> m_rftSegmentBranchId;
|
||||
caf::PdmField<QDateTime> m_rftTimeStep;
|
||||
caf::PdmField<QString> m_rftWellName;
|
||||
caf::PdmField<int> m_rftSegmentBranchIndex;
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::RftBranchType>> m_rftSegmentBranchType;
|
||||
|
||||
std::set<RimCase*> m_uniqueCases;
|
||||
std::set<RimSummaryCase*> m_uniqueSummaryCases;
|
||||
@ -140,7 +142,8 @@ private:
|
||||
std::set<bool> m_uniqueWbsSmoothing;
|
||||
std::set<double, DoubleComparator> m_uniqueWbsSmoothingThreshold;
|
||||
|
||||
std::set<QDateTime> m_uniqueRftTimeSteps;
|
||||
std::set<QString> m_uniqueRftWellNames;
|
||||
std::set<int> m_uniqueRftBranchIds;
|
||||
std::set<QDateTime> m_uniqueRftTimeSteps;
|
||||
std::set<QString> m_uniqueRftWellNames;
|
||||
std::set<int> m_uniqueRftBranchIndices;
|
||||
std::set<RiaDefines::RftBranchType> m_uniqueRftBranchTypes;
|
||||
};
|
||||
|
@ -174,7 +174,8 @@ RimWellLogRftCurve::RimWellLogRftCurve()
|
||||
CAF_PDM_InitFieldNoDefault( &m_rftDataType, "RftDataType", "Data Type" );
|
||||
|
||||
CAF_PDM_InitField( &m_segmentResultName, "SegmentResultName", RiaResultNames::undefinedResultName(), "Segment Result Name" );
|
||||
CAF_PDM_InitField( &m_segmentBranchId, "SegmentBranchId", -1, "Segment Branch" );
|
||||
CAF_PDM_InitField( &m_segmentBranchIndex, "SegmentBranchIndex", -1, "Segment Branch" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_segmentBranchType, "SegmentBranchType", "Branch Type" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -235,9 +236,17 @@ QDateTime RimWellLogRftCurve::timeStep() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setSegmentBranchId( int branchId )
|
||||
void RimWellLogRftCurve::setSegmentBranchIndex( int branchIndex )
|
||||
{
|
||||
m_segmentBranchId = branchId;
|
||||
m_segmentBranchIndex = branchIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setSegmentBranchType( RiaDefines::RftBranchType branchType )
|
||||
{
|
||||
m_segmentBranchType = branchType;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -315,9 +324,9 @@ void RimWellLogRftCurve::setRftAddress( RifEclipseRftAddress address )
|
||||
|
||||
if ( address.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES )
|
||||
{
|
||||
m_rftDataType = RftDataType::RFT_SEGMENT_DATA;
|
||||
m_segmentResultName = address.segmentResultName();
|
||||
m_segmentBranchId = address.segmentBranchNumber();
|
||||
m_rftDataType = RftDataType::RFT_SEGMENT_DATA;
|
||||
m_segmentResultName = address.segmentResultName();
|
||||
m_segmentBranchIndex = address.segmentBranchIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -332,7 +341,11 @@ RifEclipseRftAddress RimWellLogRftCurve::rftAddress() const
|
||||
{
|
||||
if ( m_rftDataType == RftDataType::RFT_SEGMENT_DATA )
|
||||
{
|
||||
return RifEclipseRftAddress::createSegmentAddress( m_wellName, m_timeStep, m_segmentResultName(), m_segmentBranchId() );
|
||||
return RifEclipseRftAddress::createBranchSegmentAddress( m_wellName,
|
||||
m_timeStep,
|
||||
m_segmentResultName(),
|
||||
m_segmentBranchIndex(),
|
||||
m_segmentBranchType() );
|
||||
}
|
||||
|
||||
return RifEclipseRftAddress::createAddress( m_wellName, m_timeStep, m_wellLogChannelName() );
|
||||
@ -470,8 +483,10 @@ QString RimWellLogRftCurve::createCurveAutoName()
|
||||
{
|
||||
name.push_back( m_segmentResultName );
|
||||
|
||||
QString branchText = QString( "Branch %1" ).arg( m_segmentBranchId() );
|
||||
QString branchText = QString( "Branch %1" ).arg( m_segmentBranchIndex() );
|
||||
name.push_back( branchText );
|
||||
|
||||
name.push_back( m_segmentBranchType().uiText() );
|
||||
}
|
||||
|
||||
if ( !m_timeStep().isNull() )
|
||||
@ -694,7 +709,8 @@ void RimWellLogRftCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
|
||||
else
|
||||
{
|
||||
curveDataGroup->add( &m_segmentResultName );
|
||||
curveDataGroup->add( &m_segmentBranchId );
|
||||
curveDataGroup->add( &m_segmentBranchIndex );
|
||||
curveDataGroup->add( &m_segmentBranchType );
|
||||
}
|
||||
|
||||
caf::PdmUiGroup* stackingGroup = uiOrdering.addNewGroup( "Stacking" );
|
||||
@ -759,9 +775,9 @@ QList<caf::PdmOptionItemInfo> RimWellLogRftCurve::calculateValueOptions( const c
|
||||
{
|
||||
options = RimRftTools::segmentResultNameOptions( reader, m_wellName(), m_timeStep() );
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_segmentBranchId )
|
||||
else if ( fieldNeedingOptions == &m_segmentBranchIndex )
|
||||
{
|
||||
options = RimRftTools::segmentBranchIdOptions( reader, m_wellName(), m_timeStep() );
|
||||
options = RimRftTools::segmentBranchIndexOptions( reader, m_wellName(), m_timeStep() );
|
||||
}
|
||||
|
||||
return options;
|
||||
@ -811,8 +827,8 @@ void RimWellLogRftCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedFie
|
||||
}
|
||||
loadData = true;
|
||||
}
|
||||
else if ( changedField == &m_timeStep || changedField == &m_segmentResultName ||
|
||||
changedField == &m_segmentBranchId || changedField == &m_rftDataType )
|
||||
else if ( changedField == &m_timeStep || changedField == &m_segmentResultName || changedField == &m_segmentBranchIndex ||
|
||||
changedField == &m_rftDataType || changedField == &m_segmentBranchType )
|
||||
{
|
||||
loadData = true;
|
||||
}
|
||||
@ -999,8 +1015,11 @@ std::vector<double> RimWellLogRftCurve::xValues()
|
||||
|
||||
if ( m_rftDataType() == RftDataType::RFT_SEGMENT_DATA )
|
||||
{
|
||||
auto depthAddress =
|
||||
RifEclipseRftAddress::createSegmentAddress( m_wellName(), m_timeStep, m_segmentResultName(), segmentBranchId() );
|
||||
auto depthAddress = RifEclipseRftAddress::createBranchSegmentAddress( m_wellName(),
|
||||
m_timeStep,
|
||||
m_segmentResultName(),
|
||||
segmentBranchIndex(),
|
||||
m_segmentBranchType() );
|
||||
|
||||
reader->values( depthAddress, &values );
|
||||
|
||||
@ -1063,10 +1082,11 @@ std::vector<double> RimWellLogRftCurve::tvDepthValues()
|
||||
|
||||
if ( m_rftDataType() == RftDataType::RFT_SEGMENT_DATA )
|
||||
{
|
||||
auto depthAddress = RifEclipseRftAddress::createSegmentAddress( m_wellName(),
|
||||
m_timeStep,
|
||||
RiaDefines::segmentTvdDepthResultName(),
|
||||
segmentBranchId() );
|
||||
auto depthAddress = RifEclipseRftAddress::createBranchSegmentAddress( m_wellName(),
|
||||
m_timeStep,
|
||||
RiaDefines::segmentTvdDepthResultName(),
|
||||
segmentBranchIndex(),
|
||||
m_segmentBranchType() );
|
||||
|
||||
reader->values( depthAddress, &values );
|
||||
return values;
|
||||
@ -1108,10 +1128,12 @@ std::vector<double> RimWellLogRftCurve::measuredDepthValues()
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
if ( reader )
|
||||
{
|
||||
auto depthAddress = RifEclipseRftAddress::createSegmentAddress( m_wellName(),
|
||||
m_timeStep,
|
||||
RiaDefines::segmentStartDepthResultName(),
|
||||
segmentBranchId() );
|
||||
auto depthAddress =
|
||||
RifEclipseRftAddress::createBranchSegmentAddress( m_wellName(),
|
||||
m_timeStep,
|
||||
RiaDefines::segmentStartDepthResultName(),
|
||||
segmentBranchIndex(),
|
||||
m_segmentBranchType() );
|
||||
|
||||
reader->values( depthAddress, &values );
|
||||
|
||||
@ -1236,7 +1258,7 @@ bool RimWellLogRftCurve::deriveMeasuredDepthFromObservedData( const std::vector<
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimWellLogRftCurve::segmentBranchId() const
|
||||
int RimWellLogRftCurve::segmentBranchIndex() const
|
||||
{
|
||||
return m_segmentBranchId();
|
||||
return m_segmentBranchIndex();
|
||||
}
|
||||
|
@ -76,7 +76,8 @@ public:
|
||||
void setTimeStep( const QDateTime& dateTime );
|
||||
QDateTime timeStep() const;
|
||||
|
||||
void setSegmentBranchId( int branchId );
|
||||
void setSegmentBranchIndex( int branchIndex );
|
||||
void setSegmentBranchType( RiaDefines::RftBranchType branchType );
|
||||
|
||||
void setEclipseResultCase( RimEclipseResultCase* eclipseResultCase );
|
||||
RimEclipseResultCase* eclipseResultCase() const;
|
||||
@ -130,7 +131,7 @@ private:
|
||||
bool deriveMeasuredDepthFromObservedData( const std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& derivedMDValues );
|
||||
|
||||
int segmentBranchId() const;
|
||||
int segmentBranchIndex() const;
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimEclipseResultCase*> m_eclipseResultCase;
|
||||
@ -144,8 +145,9 @@ private:
|
||||
|
||||
caf::PdmField<caf::AppEnum<RimWellLogRftCurve::RftDataType>> m_rftDataType;
|
||||
|
||||
caf::PdmField<QString> m_segmentResultName;
|
||||
caf::PdmField<int> m_segmentBranchId;
|
||||
caf::PdmField<QString> m_segmentResultName;
|
||||
caf::PdmField<int> m_segmentBranchIndex;
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::RftBranchType>> m_segmentBranchType;
|
||||
|
||||
std::map<size_t, size_t> m_idxInWellPathToIdxInRftFile;
|
||||
caf::PdmField<caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>> m_wellLogChannelName;
|
||||
|
22
ThirdParty/custom-opm-common/custom-opm-parser-tests/TestData/test_wseglink.DATA
vendored
Normal file
22
ThirdParty/custom-opm-common/custom-opm-parser-tests/TestData/test_wseglink.DATA
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
-- WSEGLINK
|
||||
-- well-name segment-no-1 segment-no-2
|
||||
-- If item #2 and #3 are undefined, all segment links for the well are removed.
|
||||
-- If either item #2 or #3 is undefined, all segment links are removed for the well and segment given.
|
||||
--
|
||||
|
||||
WSEGLINK
|
||||
PROD 22 30 /
|
||||
PROD2 25 37 /
|
||||
/
|
||||
|
||||
WSEGLINK
|
||||
PROD_A 20 30 /
|
||||
/
|
||||
|
||||
WSEGLINK
|
||||
PROD_A 20 /
|
||||
/
|
||||
|
||||
WSEGLINK
|
||||
PROD_A /
|
||||
/
|
@ -3,13 +3,14 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
||||
#include "opm/input/eclipse/Parser/ParseContext.hpp"
|
||||
#include "opm/input/eclipse/Parser/ParseContext.hpp"
|
||||
#include "opm/input/eclipse/Schedule/VFPInjTable.hpp"
|
||||
#include "opm/input/eclipse/Schedule/VFPProdTable.hpp"
|
||||
#include "opm/input/eclipse/Parser/Parser.hpp"
|
||||
#include "opm/input/eclipse/Deck/Deck.hpp"
|
||||
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/V.hpp>
|
||||
#include "opm/input/eclipse/Parser/ParserKeywords/W.hpp"
|
||||
|
||||
#include "OpmTestDataDirectory.h"
|
||||
|
||||
@ -24,9 +25,9 @@ TEST(OpmParserTest, ReadFromFile)
|
||||
|
||||
{
|
||||
Parser parser(false);
|
||||
const ::Opm::ParserKeywords::VFPPROD kw1;
|
||||
const ::Opm::ParserKeywords::VFPPROD kw1;
|
||||
|
||||
parser.addParserKeyword(kw1);
|
||||
parser.addParserKeyword(kw1);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << TEST_DATA_DIR << "/B1BH.Ecl";
|
||||
@ -50,12 +51,12 @@ TEST(OpmParserTest, ReadFromFile)
|
||||
}
|
||||
}
|
||||
{
|
||||
Parser parser(false);
|
||||
const ::Opm::ParserKeywords::VFPINJ kw1;
|
||||
const ::Opm::ParserKeywords::VFPIDIMS kw2;
|
||||
Parser parser(false);
|
||||
const ::Opm::ParserKeywords::VFPINJ kw1;
|
||||
const ::Opm::ParserKeywords::VFPIDIMS kw2;
|
||||
|
||||
parser.addParserKeyword(kw1);
|
||||
parser.addParserKeyword(kw2);
|
||||
parser.addParserKeyword(kw1);
|
||||
parser.addParserKeyword(kw2);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << TEST_DATA_DIR << "/C1H.Ecl";
|
||||
@ -80,6 +81,59 @@ TEST(OpmParserTest, ReadFromFile)
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(OpmParserTest, ReadAndParseWSEGLINK)
|
||||
{
|
||||
Parser parser(false);
|
||||
const ::Opm::ParserKeywords::WSEGLINK kw1;
|
||||
|
||||
parser.addParserKeyword(kw1);
|
||||
|
||||
|
||||
std::stringstream ss;
|
||||
ss << TEST_DATA_DIR << "/test_wseglink.DATA";
|
||||
std::string testFile = ss.str();
|
||||
|
||||
auto deck = parser.parseFile(testFile);
|
||||
|
||||
std::string myKeyword = "WSEGLINK";
|
||||
auto keywordList = deck.getKeywordList(myKeyword);
|
||||
for (auto kw : keywordList)
|
||||
{
|
||||
auto name = kw->name();
|
||||
|
||||
for (size_t i = 0; i < kw->size(); i++)
|
||||
{
|
||||
auto deckRecord = kw->getRecord(i);
|
||||
|
||||
std::string wellName;
|
||||
int segment1 = -1;
|
||||
int segment2 = -1;
|
||||
|
||||
{
|
||||
auto itemName = ::Opm::ParserKeywords::WSEGLINK::WELL::itemName;
|
||||
if (deckRecord.hasItem(itemName) && deckRecord.getItem(itemName).hasValue(0))
|
||||
{
|
||||
wellName = deckRecord.getItem(itemName).getTrimmedString(0);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto itemName = ::Opm::ParserKeywords::WSEGLINK::SEGMENT1::itemName;
|
||||
if (deckRecord.hasItem(itemName) && deckRecord.getItem(itemName).hasValue(0))
|
||||
{
|
||||
segment1 = deckRecord.getItem(itemName).get<int>(0);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto itemName = ::Opm::ParserKeywords::WSEGLINK::SEGMENT2::itemName;
|
||||
if (deckRecord.hasItem(itemName) && deckRecord.getItem(itemName).hasValue(0))
|
||||
{
|
||||
segment2 = deckRecord.getItem(itemName).get<int>(0);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << wellName << " " << segment1 << " " << segment2 << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user