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:
Magne Sjaastad
2022-08-16 12:40:25 +02:00
committed by GitHub
parent e6af123094
commit 1f2e9babe6
25 changed files with 952 additions and 261 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 );
};

View File

@@ -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] );

View File

@@ -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})

View File

@@ -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() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -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;
};

View 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();
}

View 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;
};

View File

@@ -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 )

View File

@@ -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 );
};

View File

@@ -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" );

View File

@@ -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;
};

View File

@@ -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();
}

View File

@@ -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;