diff --git a/ApplicationLibCode/Application/CMakeLists_files.cmake b/ApplicationLibCode/Application/CMakeLists_files.cmake index 0bd6d1abfc..cb87a9bae2 100644 --- a/ApplicationLibCode/Application/CMakeLists_files.cmake +++ b/ApplicationLibCode/Application/CMakeLists_files.cmake @@ -25,6 +25,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaStimPlanModelDefines.h ${CMAKE_CURRENT_LIST_DIR}/RiaResultNames.h ${CMAKE_CURRENT_LIST_DIR}/RiaNumberFormat.h + ${CMAKE_CURRENT_LIST_DIR}/RiaRftDefines.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -54,6 +55,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaStimPlanModelDefines.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaResultNames.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaNumberFormat.cpp + ${CMAKE_CURRENT_LIST_DIR}/RiaRftDefines.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/Application/RiaRftDefines.cpp b/ApplicationLibCode/Application/RiaRftDefines.cpp new file mode 100644 index 0000000000..410dde165b --- /dev/null +++ b/ApplicationLibCode/Application/RiaRftDefines.cpp @@ -0,0 +1,67 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaRftDefines.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::segmentStartDepthResultName() +{ + return "SEGLENST"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::segmentEndDepthResultName() +{ + return "SEGLENEN"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::segmentTvdDepthResultName() +{ + return "SEGDEPTH"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::segmentNumberResultName() +{ + return "SEGMENTNUMBER"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::allBranches() +{ + return "All"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::segmentBranchNumberResultName() +{ + return "SegmenBranchNumber"; +} diff --git a/ApplicationLibCode/Application/RiaRftDefines.h b/ApplicationLibCode/Application/RiaRftDefines.h new file mode 100644 index 0000000000..2f5aa238bb --- /dev/null +++ b/ApplicationLibCode/Application/RiaRftDefines.h @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +namespace RiaDefines +{ +QString segmentStartDepthResultName(); +QString segmentEndDepthResultName(); +QString segmentTvdDepthResultName(); +QString segmentNumberResultName(); + +QString allBranches(); +QString segmentBranchNumberResultName(); + +}; // namespace RiaDefines diff --git a/ApplicationLibCode/Commands/RicWellLogTools.cpp b/ApplicationLibCode/Commands/RicWellLogTools.cpp index 02ce78e04e..91464ac211 100644 --- a/ApplicationLibCode/Commands/RicWellLogTools.cpp +++ b/ApplicationLibCode/Commands/RicWellLogTools.cpp @@ -108,7 +108,11 @@ bool RicWellLogTools::hasRftDataForWell( const QString& wellName ) { if ( resultCase->rftReader() ) { - return resultCase->rftReader()->wellHasRftData( wellName ); + auto wellNames = resultCase->rftReader()->wellNames(); + for ( const auto& w : wellNames ) + { + if ( w == wellName ) return true; + } } } } diff --git a/ApplicationLibCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.cpp b/ApplicationLibCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.cpp index 13885dc809..7cebe4fbcf 100644 --- a/ApplicationLibCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.cpp +++ b/ApplicationLibCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.cpp @@ -25,6 +25,7 @@ #include "RimWellLogCurve.h" #include "RimWellLogExtractionCurve.h" #include "RimWellLogFileCurve.h" +#include "RimWellLogRftCurve.h" #include "RimWellLogTrack.h" #include "RimWellMeasurementCurve.h" @@ -46,8 +47,7 @@ bool RicPasteWellLogCurveFeature::isCommandEnabled() if ( RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot() ) return false; if ( RicWellLogPlotCurveFeatureImpl::parentWellRftPlot() ) return false; - caf::PdmObjectHandle* destinationObject = - dynamic_cast( caf::SelectionManager::instance()->selectedItem() ); + auto* destinationObject = dynamic_cast( caf::SelectionManager::instance()->selectedItem() ); if ( !destinationObject ) return false; RimWellLogTrack* wellLogTrack = nullptr; @@ -62,16 +62,16 @@ bool RicPasteWellLogCurveFeature::isCommandEnabled() std::vector> sourceObjects = RicPasteWellLogCurveFeature::curves(); - for ( size_t i = 0; i < sourceObjects.size(); i++ ) + for ( const auto& sourceObject : sourceObjects ) { RimWellBoreStabilityPlot* originalWbsPlot = nullptr; - sourceObjects[i]->firstAncestorOrThisOfType( originalWbsPlot ); + sourceObject->firstAncestorOrThisOfType( originalWbsPlot ); if ( originalWbsPlot && originalWbsPlot != wbsPlotToPasteInto ) { return false; } } - return RicPasteWellLogCurveFeature::curves().size() > 0; + return !RicPasteWellLogCurveFeature::curves().empty(); } //-------------------------------------------------------------------------------------------------- @@ -81,8 +81,7 @@ void RicPasteWellLogCurveFeature::onActionTriggered( bool isChecked ) { if ( RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot() ) return; - caf::PdmObjectHandle* destinationObject = - dynamic_cast( caf::SelectionManager::instance()->selectedItem() ); + auto* destinationObject = dynamic_cast( caf::SelectionManager::instance()->selectedItem() ); if ( !destinationObject ) return; RimWellLogTrack* wellLogTrack = nullptr; @@ -97,39 +96,23 @@ void RicPasteWellLogCurveFeature::onActionTriggered( bool isChecked ) std::vector> sourceObjects = RicPasteWellLogCurveFeature::curves(); - for ( size_t i = 0; i < sourceObjects.size(); i++ ) + for ( const auto& sourceObject : sourceObjects ) { RimWellBoreStabilityPlot* originalWbsPlot = nullptr; - sourceObjects[i]->firstAncestorOrThisOfType( originalWbsPlot ); + sourceObject->firstAncestorOrThisOfType( originalWbsPlot ); if ( originalWbsPlot && originalWbsPlot != wbsPlotToPasteInto ) { continue; } - RimWellLogFileCurve* fileCurve = dynamic_cast( sourceObjects[i].p() ); - RimWellMeasurementCurve* measurementCurve = dynamic_cast( sourceObjects[i].p() ); - if ( fileCurve || measurementCurve ) + auto* fileCurve = dynamic_cast( sourceObject.p() ); + auto* measurementCurve = dynamic_cast( sourceObject.p() ); + auto* extractionCurve = dynamic_cast( sourceObject.p() ); + auto* rftCurve = dynamic_cast( sourceObject.p() ); + if ( fileCurve || measurementCurve || extractionCurve || rftCurve ) { - RimWellLogFileCurve* newObject = dynamic_cast( - sourceObjects[i]->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) ); - CVF_ASSERT( newObject ); - - wellLogTrack->addCurve( newObject ); - - // Resolve references after object has been inserted into the project data model - newObject->resolveReferencesRecursively(); - newObject->initAfterReadRecursively(); - - newObject->loadDataAndUpdate( true ); - - wellLogTrack->updateConnectedEditors(); - } - - RimWellLogExtractionCurve* extractionCurve = dynamic_cast( sourceObjects[i].p() ); - if ( extractionCurve ) - { - RimWellLogExtractionCurve* newObject = dynamic_cast( - sourceObjects[i]->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) ); + auto* newObject = dynamic_cast( + sourceObject->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) ); CVF_ASSERT( newObject ); wellLogTrack->addCurve( newObject ); diff --git a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake index a45e86fc81..5da763a486 100644 --- a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake @@ -71,6 +71,8 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RifEclipseKeywordContent.h ${CMAKE_CURRENT_LIST_DIR}/RifMultipleSummaryReaders.h ${CMAKE_CURRENT_LIST_DIR}/RifProjectSummaryDataWriter.h + ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmRft.h + ${CMAKE_CURRENT_LIST_DIR}/RifRftSegment.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -143,6 +145,8 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RifEclipseTextFileReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifMultipleSummaryReaders.cpp ${CMAKE_CURRENT_LIST_DIR}/RifProjectSummaryDataWriter.cpp + ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmRft.cpp + ${CMAKE_CURRENT_LIST_DIR}/RifRftSegment.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/FileInterface/RifDataSourceForRftPlt.cpp b/ApplicationLibCode/FileInterface/RifDataSourceForRftPlt.cpp index b500e6ddd3..aa2ebdd264 100644 --- a/ApplicationLibCode/FileInterface/RifDataSourceForRftPlt.cpp +++ b/ApplicationLibCode/FileInterface/RifDataSourceForRftPlt.cpp @@ -17,15 +17,19 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RifDataSourceForRftPlt.h" + +#include "RifReaderEclipseRft.h" + #include "RimEclipseCase.h" +#include "RimEclipseResultCase.h" #include "RimObservedFmuRftData.h" #include "RimSummaryCase.h" #include "RimSummaryCaseCollection.h" #include "RimWellLogFile.h" -#include "RimEclipseResultCase.h" #include "cafAppEnum.h" #include "cvfAssert.h" + #include #include diff --git a/ApplicationLibCode/FileInterface/RifEclipseRftAddress.cpp b/ApplicationLibCode/FileInterface/RifEclipseRftAddress.cpp index 1c2f7041ee..25b210d2da 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseRftAddress.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseRftAddress.cpp @@ -23,9 +23,103 @@ //-------------------------------------------------------------------------------------------------- RifEclipseRftAddress::RifEclipseRftAddress( QString wellName, QDateTime timeStep, RftWellLogChannelType wellLogChannelName ) : m_wellName( wellName ) + , m_timeStep( timeStep ) , m_wellLogChannel( wellLogChannelName ) + , m_segmentBranchNumber( -1 ) { - m_timeStep = timeStep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseRftAddress RifEclipseRftAddress::createSegmentResult( const QString& wellName, + const QDateTime& dateTime, + const QString& resultName ) +{ + auto adr = RifEclipseRftAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES ); + + adr.setSegmentResultName( resultName ); + + return adr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRftAddress::setSegmentResultName( const QString& resultName ) +{ + m_segmentResultName = resultName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RifEclipseRftAddress::segmentResultName() const +{ + return m_segmentResultName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRftAddress::setSegmentBranchNumber( int branchNumber ) +{ + m_segmentBranchNumber = branchNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifEclipseRftAddress::segmentBranchNumber() const +{ + return m_segmentBranchNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString& RifEclipseRftAddress::wellName() const +{ + return m_wellName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QDateTime RifEclipseRftAddress::timeStep() const +{ + return m_timeStep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RifEclipseRftAddress::RifEclipseRftAddress::RftWellLogChannelType& RifEclipseRftAddress::wellLogChannel() const +{ + return m_wellLogChannel; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RifEclipseRftAddress::rftPlotChannelTypes() +{ + return { RifEclipseRftAddress::RftWellLogChannelType::PRESSURE, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90 }; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RifEclipseRftAddress::pltPlotChannelTypes() +{ + return { RifEclipseRftAddress::RftWellLogChannelType::ORAT, + RifEclipseRftAddress::RftWellLogChannelType::WRAT, + RifEclipseRftAddress::RftWellLogChannelType::GRAT }; } //-------------------------------------------------------------------------------------------------- @@ -36,6 +130,8 @@ bool operator==( const RifEclipseRftAddress& first, const RifEclipseRftAddress& if ( first.wellName() != second.wellName() ) return false; if ( first.timeStep() != second.timeStep() ) return false; if ( first.wellLogChannel() != second.wellLogChannel() ) return false; + if ( first.segmentResultName() != second.segmentResultName() ) return false; + if ( first.segmentBranchNumber() != second.segmentBranchNumber() ) return false; return true; } @@ -49,6 +145,10 @@ bool operator<( const RifEclipseRftAddress& first, const RifEclipseRftAddress& s if ( first.timeStep() != second.timeStep() ) return ( first.timeStep() < second.timeStep() ); if ( first.wellLogChannel() != second.wellLogChannel() ) return ( first.wellLogChannel() < second.wellLogChannel() ); + if ( first.segmentResultName() != second.segmentResultName() ) + return first.segmentResultName() < second.segmentResultName(); + if ( first.segmentBranchNumber() != second.segmentBranchNumber() ) + return first.segmentBranchNumber() < second.segmentBranchNumber(); return false; } diff --git a/ApplicationLibCode/FileInterface/RifEclipseRftAddress.h b/ApplicationLibCode/FileInterface/RifEclipseRftAddress.h index ed0e610b5e..bd8cf929a7 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseRftAddress.h +++ b/ApplicationLibCode/FileInterface/RifEclipseRftAddress.h @@ -31,7 +31,7 @@ class RifEclipseRftAddress { public: - enum RftWellLogChannelType + enum class RftWellLogChannelType { NONE, TVD, @@ -47,35 +47,38 @@ public: PRESSURE_P50, PRESSURE_P90, PRESSURE_MEAN, - PRESSURE_ERROR + PRESSURE_ERROR, + SEGMENT_VALUES }; public: RifEclipseRftAddress( QString wellName, QDateTime timeStep, RftWellLogChannelType wellLogChannel ); - const QString& wellName() const { return m_wellName; } - QDateTime timeStep() const { return m_timeStep; } - const RftWellLogChannelType& wellLogChannel() const { return m_wellLogChannel; } + static RifEclipseRftAddress + createSegmentResult( const QString& wellName, const QDateTime& dateTime, const QString& resultName ); - static std::set rftPlotChannelTypes() - { - return {RifEclipseRftAddress::PRESSURE, - RifEclipseRftAddress::PRESSURE_ERROR, - RifEclipseRftAddress::PRESSURE_MEAN, - RifEclipseRftAddress::PRESSURE_P10, - RifEclipseRftAddress::PRESSURE_P50, - RifEclipseRftAddress::PRESSURE_P90}; - } + QString segmentResultName() const; - static std::set pltPlotChannelTypes() - { - return {RifEclipseRftAddress::ORAT, RifEclipseRftAddress::WRAT, RifEclipseRftAddress::GRAT}; - } + void setSegmentBranchNumber( int branchNumber ); + int segmentBranchNumber() const; + + const QString& wellName() const; + QDateTime timeStep() const; + const RftWellLogChannelType& wellLogChannel() const; + + static std::set rftPlotChannelTypes(); + static std::set pltPlotChannelTypes(); + +private: + void setSegmentResultName( const QString& resultName ); private: QString m_wellName; QDateTime m_timeStep; RftWellLogChannelType m_wellLogChannel; + + QString m_segmentResultName; + int m_segmentBranchNumber; }; bool operator==( const RifEclipseRftAddress& first, const RifEclipseRftAddress& second ); diff --git a/ApplicationLibCode/FileInterface/RifReaderEclipseRft.cpp b/ApplicationLibCode/FileInterface/RifReaderEclipseRft.cpp index 152e43c26b..474de5ad53 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEclipseRft.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderEclipseRft.cpp @@ -89,39 +89,39 @@ void RifReaderEclipseRft::open() QDateTime timeStep = RiaQDateTimeTools::createUtcDateTime(); timeStep.setTime_t( timeStepTime_t ); - RifEclipseRftAddress addressPressure( wellName, timeStep, RifEclipseRftAddress::PRESSURE ); + RifEclipseRftAddress addressPressure( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); m_eclipseRftAddresses.insert( addressPressure ); m_rftAddressToLibeclNodeIdx[addressPressure] = i; - RifEclipseRftAddress addressDepth( wellName, timeStep, RifEclipseRftAddress::TVD ); + RifEclipseRftAddress addressDepth( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::TVD ); m_eclipseRftAddresses.insert( addressDepth ); m_rftAddressToLibeclNodeIdx[addressDepth] = i; if ( ecl_rft_node_is_RFT( node ) ) { - RifEclipseRftAddress addressSwat( wellName, timeStep, RifEclipseRftAddress::SWAT ); + RifEclipseRftAddress addressSwat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::SWAT ); m_eclipseRftAddresses.insert( addressSwat ); m_rftAddressToLibeclNodeIdx[addressSwat] = i; - RifEclipseRftAddress addressSoil( wellName, timeStep, RifEclipseRftAddress::SOIL ); + RifEclipseRftAddress addressSoil( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::SOIL ); m_eclipseRftAddresses.insert( addressSoil ); m_rftAddressToLibeclNodeIdx[addressSoil] = i; - RifEclipseRftAddress addressSgas( wellName, timeStep, RifEclipseRftAddress::SGAS ); + RifEclipseRftAddress addressSgas( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::SGAS ); m_eclipseRftAddresses.insert( addressSgas ); m_rftAddressToLibeclNodeIdx[addressSgas] = i; } else if ( ecl_rft_node_is_PLT( node ) ) { - RifEclipseRftAddress addressWrat( wellName, timeStep, RifEclipseRftAddress::WRAT ); + RifEclipseRftAddress addressWrat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::WRAT ); m_eclipseRftAddresses.insert( addressWrat ); m_rftAddressToLibeclNodeIdx[addressWrat] = i; - RifEclipseRftAddress addressOrat( wellName, timeStep, RifEclipseRftAddress::ORAT ); + RifEclipseRftAddress addressOrat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::ORAT ); m_eclipseRftAddresses.insert( addressOrat ); m_rftAddressToLibeclNodeIdx[addressOrat] = i; - RifEclipseRftAddress addressGrat( wellName, timeStep, RifEclipseRftAddress::GRAT ); + RifEclipseRftAddress addressGrat( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::GRAT ); m_eclipseRftAddresses.insert( addressGrat ); m_rftAddressToLibeclNodeIdx[addressGrat] = i; } @@ -166,7 +166,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v switch ( wellLogChannelName ) { - case RifEclipseRftAddress::TVD: + case RifEclipseRftAddress::RftWellLogChannelType::TVD: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -174,7 +174,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v } break; } - case RifEclipseRftAddress::PRESSURE: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -182,7 +182,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v } break; } - case RifEclipseRftAddress::SWAT: + case RifEclipseRftAddress::RftWellLogChannelType::SWAT: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -190,7 +190,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v } break; } - case RifEclipseRftAddress::SOIL: + case RifEclipseRftAddress::RftWellLogChannelType::SOIL: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -198,7 +198,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v } break; } - case RifEclipseRftAddress::SGAS: + case RifEclipseRftAddress::RftWellLogChannelType::SGAS: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -206,7 +206,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v } break; } - case RifEclipseRftAddress::WRAT: + case RifEclipseRftAddress::RftWellLogChannelType::WRAT: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -214,7 +214,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v } break; } - case RifEclipseRftAddress::ORAT: + case RifEclipseRftAddress::RftWellLogChannelType::ORAT: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -222,7 +222,7 @@ void RifReaderEclipseRft::values( const RifEclipseRftAddress& rftAddress, std::v } break; } - case RifEclipseRftAddress::GRAT: + case RifEclipseRftAddress::RftWellLogChannelType::GRAT: { for ( int i = 0; i < ecl_rft_node_get_size( node ); i++ ) { @@ -351,7 +351,7 @@ std::set RifReaderEclipseRft::avail if ( !pressureFound ) { - if ( name == RifEclipseRftAddress::PRESSURE ) + if ( name == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) { pressureFound = true; if ( rftFound && pltFound ) break; @@ -381,7 +381,7 @@ std::set RifReaderEclipseRft::avail if ( pressureFound ) { - wellLogChannelNames.insert( RifEclipseRftAddress::PRESSURE ); + wellLogChannelNames.insert( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); } if ( rftFound ) { diff --git a/ApplicationLibCode/FileInterface/RifReaderEclipseRft.h b/ApplicationLibCode/FileInterface/RifReaderEclipseRft.h index 11352f874b..931ebaa0dd 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEclipseRft.h +++ b/ApplicationLibCode/FileInterface/RifReaderEclipseRft.h @@ -45,7 +45,7 @@ public: std::set eclipseRftAddresses() override; void values( const RifEclipseRftAddress& rftAddress, std::vector* values ) override; - void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector* indices ); + void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector* indices ) override; std::set availableTimeSteps( const QString& wellName ) override; std::set diff --git a/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp b/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp index b47c0ef84d..9efaa1b232 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp @@ -53,16 +53,17 @@ std::set RifReaderEnsembleStatisticsRft::eclipseRftAddress std::set statisticsAddresses; for ( const RifEclipseRftAddress& regularAddress : allAddresses ) { - if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::TVD ) + if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::TVD ) { statisticsAddresses.insert( regularAddress ); } - else if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE ) + else if ( regularAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) { - std::set statChannels = { RifEclipseRftAddress::PRESSURE_P10, - RifEclipseRftAddress::PRESSURE_P50, - RifEclipseRftAddress::PRESSURE_P90, - RifEclipseRftAddress::PRESSURE_MEAN }; + std::set statChannels = + { RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN }; for ( auto channel : statChannels ) { statisticsAddresses.insert( @@ -78,12 +79,12 @@ std::set RifReaderEnsembleStatisticsRft::eclipseRftAddress //-------------------------------------------------------------------------------------------------- void RifReaderEnsembleStatisticsRft::values( const RifEclipseRftAddress& rftAddress, std::vector* values ) { - CAF_ASSERT( rftAddress.wellLogChannel() == RifEclipseRftAddress::TVD || - rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_MEAN || - rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P10 || - rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P50 || - rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P90 || - rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_ERROR ); + CAF_ASSERT( rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::TVD || + rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN || + rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10 || + rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50 || + rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90 || + rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR ); auto it = m_cachedValues.find( rftAddress ); if ( it == m_cachedValues.end() ) @@ -191,13 +192,13 @@ void RifReaderEnsembleStatisticsRft::calculateStatistics( const RifEclipseRftAdd { const QString& wellName = rftAddress.wellName(); const QDateTime& timeStep = rftAddress.timeStep(); - RifEclipseRftAddress depthAddress( wellName, timeStep, RifEclipseRftAddress::TVD ); - RifEclipseRftAddress pressAddress( wellName, timeStep, RifEclipseRftAddress::PRESSURE ); + RifEclipseRftAddress depthAddress( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::TVD ); + RifEclipseRftAddress pressAddress( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); - RifEclipseRftAddress p10Address( wellName, timeStep, RifEclipseRftAddress::PRESSURE_P10 ); - RifEclipseRftAddress p50Address( wellName, timeStep, RifEclipseRftAddress::PRESSURE_P50 ); - RifEclipseRftAddress p90Address( wellName, timeStep, RifEclipseRftAddress::PRESSURE_P90 ); - RifEclipseRftAddress meanAddress( wellName, timeStep, RifEclipseRftAddress::PRESSURE_MEAN ); + RifEclipseRftAddress p10Address( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10 ); + RifEclipseRftAddress p50Address( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50 ); + RifEclipseRftAddress p90Address( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90 ); + RifEclipseRftAddress meanAddress( wellName, timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN ); RiaCurveMerger curveMerger; diff --git a/ApplicationLibCode/FileInterface/RifReaderFmuRft.cpp b/ApplicationLibCode/FileInterface/RifReaderFmuRft.cpp index dfc9bc6314..ea4d7d9653 100644 --- a/ApplicationLibCode/FileInterface/RifReaderFmuRft.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderFmuRft.cpp @@ -194,10 +194,14 @@ std::set RifReaderFmuRft::eclipseRftAddresses() { if ( observation.valid() ) { - RifEclipseRftAddress tvdAddress( wellName, dateTime, RifEclipseRftAddress::TVD ); - RifEclipseRftAddress mdAddress( wellName, dateTime, RifEclipseRftAddress::MD ); - RifEclipseRftAddress pressureAddress( wellName, dateTime, RifEclipseRftAddress::PRESSURE ); - RifEclipseRftAddress pressureErrorAddress( wellName, dateTime, RifEclipseRftAddress::PRESSURE_ERROR ); + RifEclipseRftAddress tvdAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::TVD ); + RifEclipseRftAddress mdAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::MD ); + RifEclipseRftAddress pressureAddress( wellName, + dateTime, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); + RifEclipseRftAddress pressureErrorAddress( wellName, + dateTime, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR ); allAddresses.insert( tvdAddress ); allAddresses.insert( mdAddress ); allAddresses.insert( pressureAddress ); @@ -230,16 +234,16 @@ void RifReaderFmuRft::values( const RifEclipseRftAddress& rftAddress, std::vecto { switch ( rftAddress.wellLogChannel() ) { - case RifEclipseRftAddress::TVD: + case RifEclipseRftAddress::RftWellLogChannelType::TVD: values->push_back( observation.tvdmsl ); break; - case RifEclipseRftAddress::MD: + case RifEclipseRftAddress::RftWellLogChannelType::MD: values->push_back( observation.mdrkb ); break; - case RifEclipseRftAddress::PRESSURE: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE: values->push_back( observation.pressure ); break; - case RifEclipseRftAddress::PRESSURE_ERROR: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR: values->push_back( observation.pressureError ); break; default: @@ -309,8 +313,9 @@ std::set RifReaderFmuRft::availableTimeSteps( const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName ) { - if ( wellLogChannelName == RifEclipseRftAddress::TVD || wellLogChannelName == RifEclipseRftAddress::MD || - wellLogChannelName == RifEclipseRftAddress::PRESSURE ) + if ( wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::TVD || + wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::MD || + wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) { return availableTimeSteps( wellName ); } @@ -342,8 +347,9 @@ std::set RifReaderFmuRft::availableTimeSteps( const QString& wellName, const std::set& relevantChannels ) { - if ( relevantChannels.count( RifEclipseRftAddress::TVD ) || relevantChannels.count( RifEclipseRftAddress::MD ) || - relevantChannels.count( RifEclipseRftAddress::PRESSURE ) ) + if ( relevantChannels.count( RifEclipseRftAddress::RftWellLogChannelType::TVD ) || + relevantChannels.count( RifEclipseRftAddress::RftWellLogChannelType::MD ) || + relevantChannels.count( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) ) { return availableTimeSteps( wellName ); } @@ -362,7 +368,9 @@ std::set RifReaderFmuRft::available if ( !m_allWellObservations.empty() ) { - return { RifEclipseRftAddress::TVD, RifEclipseRftAddress::MD, RifEclipseRftAddress::PRESSURE }; + return { RifEclipseRftAddress::RftWellLogChannelType::TVD, + RifEclipseRftAddress::RftWellLogChannelType::MD, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE }; } return {}; } diff --git a/ApplicationLibCode/FileInterface/RifReaderOpmRft.cpp b/ApplicationLibCode/FileInterface/RifReaderOpmRft.cpp new file mode 100644 index 0000000000..b73840b077 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifReaderOpmRft.cpp @@ -0,0 +1,488 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifReaderOpmRft.h" + +#include "RiaLogging.h" +#include "RiaQDateTimeTools.h" +#include "RiaRftDefines.h" +#include "RiaStdStringTools.h" + +#include "opm/io/eclipse/ERft.hpp" + +#include "cafAssert.h" +#include "cafVecIjk.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderOpmRft::RifReaderOpmRft( const QString& fileName ) +{ + try + { + m_opm_rft = std::make_unique( fileName.toStdString() ); + + buildMetaData(); + } + catch ( ... ) + { + RiaLogging::error( QString( "Failed to open RFT file %1" ).arg( fileName ) ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RifReaderOpmRft::eclipseRftAddresses() +{ + return m_addresses; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vector* values ) +{ + auto wellName = rftAddress.wellName().toStdString(); + auto resultName = rftAddress.segmentResultName().toStdString(); + + auto qDate = rftAddress.timeStep().date(); + int y = qDate.year(); + int m = qDate.month(); + int d = qDate.day(); + + if ( rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES ) + { + auto key = std::make_pair( wellName, RftDate{ y, m, d } ); + auto segment = m_rftWellDateSegments[key]; + + if ( rftAddress.segmentResultName() == RiaDefines::segmentNumberResultName() ) + { + auto data = segment.topology(); + + auto indices = segment.indicesForBranchNumber( rftAddress.segmentBranchNumber() ); + for ( const auto& i : indices ) + { + CAF_ASSERT( i < data.size() ); + values->push_back( data[i].segNo() ); + } + } + else if ( rftAddress.segmentResultName() == RiaDefines::segmentBranchNumberResultName() ) + { + auto branchNumbers = segment.branchIds(); + for ( const auto& branchNumber : branchNumbers ) + { + values->push_back( branchNumber ); + } + } + } + + if ( resultName.empty() ) + { + resultName = RifReaderOpmRft::resultNameFromChannelType( rftAddress.wellLogChannel() ); + } + + try + { + auto data = m_opm_rft->getRft( resultName, wellName, y, m, d ); + if ( !data.empty() ) + { + if ( rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES ) + { + auto key = std::make_pair( wellName, RftDate{ y, m, d } ); + auto segment = m_rftWellDateSegments[key]; + + auto indices = segment.indicesForBranchNumber( rftAddress.segmentBranchNumber() ); + for ( const auto& i : indices ) + { + CAF_ASSERT( i < data.size() ); + values->push_back( data[i] ); + } + } + else + { + values->insert( values->end(), data.begin(), data.end() ); + } + } + } + catch ( ... ) + { + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RifReaderOpmRft::availableTimeSteps( const QString& wellName ) +{ + std::set timeSteps; + + for ( const auto& address : m_addresses ) + { + if ( address.wellName() == wellName ) + { + timeSteps.insert( address.timeStep() ); + } + } + return timeSteps; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set + RifReaderOpmRft::availableTimeSteps( const QString& wellName, + const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName ) +{ + std::set timeSteps; + + for ( const auto& address : m_addresses ) + { + if ( address.wellName() == wellName && address.wellLogChannel() == wellLogChannelName ) + { + timeSteps.insert( address.timeStep() ); + } + } + return timeSteps; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set + RifReaderOpmRft::availableTimeSteps( const QString& wellName, + const std::set& relevantChannels ) +{ + std::set timeSteps; + + for ( const auto& address : m_addresses ) + { + if ( address.wellName() == wellName && relevantChannels.count( address.wellLogChannel() ) ) + { + timeSteps.insert( address.timeStep() ); + } + } + return timeSteps; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RifReaderOpmRft::availableWellLogChannels( const QString& wellName ) +{ + std::set types; + + for ( const auto& a : m_addresses ) + { + if ( ( a.wellName() == wellName ) && ( a.wellLogChannel() != RifEclipseRftAddress::RftWellLogChannelType::NONE ) ) + { + types.insert( a.wellLogChannel() ); + } + } + + return types; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RifReaderOpmRft::wellNames() +{ + return m_wellNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderOpmRft::cellIndices( const RifEclipseRftAddress& rftAddress, std::vector* indices ) +{ + auto wellName = rftAddress.wellName().toStdString(); + + auto date = rftAddress.timeStep().date(); + int y = date.year(); + int m = date.month(); + int d = date.day(); + + try + { + auto resultNameI = "CONIPOS"; + auto dataI = m_opm_rft->getRft( resultNameI, wellName, y, m, d ); + + auto resultNameJ = "CONJPOS"; + auto dataJ = m_opm_rft->getRft( resultNameJ, wellName, y, m, d ); + + auto resultNameK = "CONKPOS"; + auto dataK = m_opm_rft->getRft( resultNameK, wellName, y, m, d ); + + if ( !dataI.empty() && ( dataI.size() == dataJ.size() ) && ( dataI.size() == dataK.size() ) ) + { + for ( size_t n = 0; n < dataI.size(); n++ ) + { + // NB: Transform to zero-based cell indices + indices->push_back( caf::VecIjk( dataI[n] - 1, dataJ[n] - 1, dataK[n] - 1 ) ); + } + } + } + catch ( ... ) + { + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderOpmRft::buildMetaData() +{ + // TODO: Assert better than return? + if ( !isOpen() ) return; + + importWellNames(); + + auto reports = m_opm_rft->listOfRftReports(); + for ( const auto& report : reports ) + { + auto [wellName, reportDate, reportTime] = report; + auto rftVectors = m_opm_rft->listOfRftArrays( wellName, reportDate ); + + for ( const auto& rftVec : rftVectors ) + { + auto [resultDataName, arrType, itemCount] = rftVec; + + int y = std::get<0>( reportDate ); + int m = std::get<1>( reportDate ); + int d = std::get<2>( reportDate ); + + auto dt = RiaQDateTimeTools::createUtcDateTime( QDate( y, m, d ) ); + + auto channelTypes = identifyChannelType( resultDataName ); + if ( channelTypes != RifEclipseRftAddress::RftWellLogChannelType::NONE ) + { + auto adr = RifEclipseRftAddress( QString::fromStdString( wellName ), dt, channelTypes ); + m_addresses.insert( adr ); + } + } + } + + buildSegmentData(); + + // Create segment result addresses + for ( const auto& segmentWellData : m_rftWellDateSegments ) + { + auto [wellName, reportDate] = segmentWellData.first; + auto segmentData = segmentWellData.second; + + auto resultNameAndSizes = segmentData.resultNameAndSize(); + + int y = std::get<0>( reportDate ); + int m = std::get<1>( reportDate ); + int d = std::get<2>( reportDate ); + + auto dt = RiaQDateTimeTools::createUtcDateTime( QDate( y, m, d ) ); + + auto segmentCount = segmentData.topology().size(); + + for ( const auto& resultNameAndSize : resultNameAndSizes ) + { + auto resultValueCount = std::get<2>( resultNameAndSize ); + + if ( static_cast( resultValueCount ) != segmentCount ) continue; + + auto resultName = std::get<0>( resultNameAndSize ); + auto adr = RifEclipseRftAddress::createSegmentResult( QString::fromStdString( wellName ), + dt, + QString::fromStdString( resultName ) ); + + m_addresses.insert( adr ); + } + + auto adr = RifEclipseRftAddress::createSegmentResult( QString::fromStdString( wellName ), + dt, + RiaDefines::segmentNumberResultName() ); + + m_addresses.insert( adr ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderOpmRft::buildSegmentData() +{ + m_rftWellDateSegments.clear(); + + auto wellNames = m_opm_rft->listOfWells(); + auto dates = m_opm_rft->listOfdates(); + + for ( const auto& wellName : wellNames ) + { + for ( const auto& date : dates ) + { + std::vector segmentsForWellDate; + + std::vector segnxt = importWellData( wellName, "SEGNXT", date ); + std::vector segbrno = importWellData( wellName, "SEGBRNO", date ); + std::vector brnstValues = importWellData( wellName, "BRNST", date ); + std::vector brnenValues = importWellData( wellName, "BRNEN", date ); + + if ( segnxt.empty() ) continue; + if ( segnxt.size() != segbrno.size() ) continue; + if ( brnenValues.empty() || brnstValues.empty() ) continue; + + std::vector segNo; + for ( size_t i = 0; i < segnxt.size(); i++ ) + { + int branchIndex = segbrno[i] - 1; + int nextBranchIndex = -1; + if ( i + 1 < segbrno.size() ) nextBranchIndex = segbrno[i + 1] - 1; + + bool isLastSegmentOnBranch = branchIndex != nextBranchIndex; + + int brnst = brnstValues[branchIndex]; + int brnen = brnenValues[branchIndex]; + + int segmentId = -1; + if ( !isLastSegmentOnBranch ) + { + if ( i + 1 < segnxt.size() ) segmentId = segnxt[i + 1]; + } + else + { + segmentId = brnen; + } + + segNo.push_back( segmentId ); + + segmentsForWellDate.emplace_back( RifRftSegmentData( segnxt[i], segbrno[i], brnst, brnen, segmentId ) ); + } + + if ( segmentsForWellDate.empty() ) continue; + + RifRftSegment segment; + segment.setSegmentData( segmentsForWellDate ); + + auto arraysAtWellDate = m_opm_rft->listOfRftArrays( wellName, date ); + for ( const auto& rftResultMetaData : arraysAtWellDate ) + { + auto [name, arrayType, size] = rftResultMetaData; + if ( name.find( "SEG" ) == 0 ) + { + segment.addResultNameAndSize( rftResultMetaData ); + } + } + + auto wellDateKey = std::make_pair( wellName, date ); + + m_rftWellDateSegments[wellDateKey] = segment; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderOpmRft::segmentDataDebugLog() const +{ + for ( const auto& a : m_rftWellDateSegments ) + { + auto [wellName, date] = a.first; + auto segmentData = a.second; + + std::cout << "\nWell: " << wellName << "Date : " << std::get<0>( date ) << " " << std::get<1>( date ) << " " + << std::get<2>( date ) << " \n"; + + for ( const auto& r : segmentData.topology() ) + { + std::cout << "SEGNXT " << std::setw( 2 ) << r.segNext() << ", "; + std::cout << "SEGBRNO " << std::setw( 2 ) << r.segBrno() << ", "; + std::cout << "BNRST " << std::setw( 2 ) << r.segBrnst() << ", "; + std::cout << "BRNEN " << std::setw( 2 ) << r.segBrnen() << ", "; + std::cout << "SEGNO " << std::setw( 2 ) << r.segNo() << "\n"; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderOpmRft::isOpen() const +{ + return m_opm_rft != nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderOpmRft::importWellNames() +{ + auto names = m_opm_rft->listOfWells(); + for ( const auto& w : names ) + { + m_wellNames.insert( QString::fromStdString( w ) ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector + RifReaderOpmRft::importWellData( const std::string& wellName, const std::string& propertyName, const RftDate& date ) const +{ + if ( m_opm_rft->hasArray( propertyName, wellName, date ) ) + { + return m_opm_rft->getRft( propertyName, wellName, date ); + } + + return {}; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseRftAddress::RftWellLogChannelType RifReaderOpmRft::identifyChannelType( const std::string& resultName ) +{ + if ( resultName == "DEPTH" ) return RifEclipseRftAddress::RftWellLogChannelType::TVD; + if ( resultName == "PRESSURE" ) return RifEclipseRftAddress::RftWellLogChannelType::PRESSURE; + if ( resultName == "SWAT" ) return RifEclipseRftAddress::RftWellLogChannelType::SWAT; + if ( resultName == "SOIL" ) return RifEclipseRftAddress::RftWellLogChannelType::SOIL; + if ( resultName == "SGAS" ) return RifEclipseRftAddress::RftWellLogChannelType::SGAS; + if ( resultName == "WRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::WRAT; + if ( resultName == "ORAT" ) return RifEclipseRftAddress::RftWellLogChannelType::ORAT; + if ( resultName == "GRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::GRAT; + + return RifEclipseRftAddress::RftWellLogChannelType::NONE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::string RifReaderOpmRft::resultNameFromChannelType( RifEclipseRftAddress::RftWellLogChannelType channelType ) +{ + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::TVD ) return "DEPTH"; + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) return "PRESSURE"; + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SWAT ) return "SWAT"; + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SOIL ) return "SOIL"; + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SGAS ) return "SGAS"; + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::WRAT ) return "WRAT"; + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::ORAT ) return "ORAT"; + if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::GRAT ) return "GRAT"; + + return {}; +} diff --git a/ApplicationLibCode/FileInterface/RifReaderOpmRft.h b/ApplicationLibCode/FileInterface/RifReaderOpmRft.h new file mode 100644 index 0000000000..c0982c5037 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifReaderOpmRft.h @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RifReaderEclipseRft.h" +#include "RifRftSegment.h" + +#include "cvfObject.h" + +#include + +namespace Opm +{ +namespace EclIO +{ + class ERft; +} // namespace EclIO +} // namespace Opm + +class RifReaderOpmRft : public RifReaderRftInterface, public cvf::Object +{ +public: + RifReaderOpmRft( const QString& fileName ); + + std::set eclipseRftAddresses() override; + void values( const RifEclipseRftAddress& rftAddress, std::vector* values ) override; + + std::set availableTimeSteps( const QString& wellName ) override; + std::set availableTimeSteps( const QString& wellName, + const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName ) override; + std::set + availableTimeSteps( const QString& wellName, + const std::set& relevantChannels ) override; + std::set availableWellLogChannels( const QString& wellName ) override; + std::set wellNames() override; + + void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector* indices ) override; + +private: + // Segment data + // RftDate must be synced with definition in Opm::EclIO::ERft::RftDate + using RftDate = std::tuple; + using RftSegmentKey = std::pair; + + void buildMetaData(); + void buildSegmentData(); + void segmentDataDebugLog() const; + bool isOpen() const; + void importWellNames(); + + std::vector importWellData( const std::string& wellName, const std::string& propertyName, const RftDate& date ) const; + + static RifEclipseRftAddress::RftWellLogChannelType identifyChannelType( const std::string& resultName ); + static std::string resultNameFromChannelType( RifEclipseRftAddress::RftWellLogChannelType channelType ); + +private: + std::unique_ptr m_opm_rft; + + // RFT and PLT addresses + std::set m_addresses; + std::set m_wellNames; + + std::map m_rftWellDateSegments; +}; diff --git a/ApplicationLibCode/FileInterface/RifReaderRftInterface.cpp b/ApplicationLibCode/FileInterface/RifReaderRftInterface.cpp index bfb6838d25..b84861c2b8 100644 --- a/ApplicationLibCode/FileInterface/RifReaderRftInterface.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderRftInterface.cpp @@ -34,3 +34,10 @@ std::set RifReaderRftInterface::eclipseRftAddresses( const } return matchingAddresses; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderRftInterface::cellIndices( const RifEclipseRftAddress& rftAddress, std::vector* indices ) +{ +} diff --git a/ApplicationLibCode/FileInterface/RifReaderRftInterface.h b/ApplicationLibCode/FileInterface/RifReaderRftInterface.h index 3fe405fb1e..790109ebae 100644 --- a/ApplicationLibCode/FileInterface/RifReaderRftInterface.h +++ b/ApplicationLibCode/FileInterface/RifReaderRftInterface.h @@ -26,6 +26,11 @@ #include #include +namespace caf +{ +class VecIjk; +}; + class RifReaderRftInterface { public: @@ -42,4 +47,6 @@ public: const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName ) = 0; virtual std::set availableWellLogChannels( const QString& wellName ) = 0; virtual std::set wellNames() = 0; + + virtual void cellIndices( const RifEclipseRftAddress& rftAddress, std::vector* indices ); }; diff --git a/ApplicationLibCode/FileInterface/RifRftSegment.cpp b/ApplicationLibCode/FileInterface/RifRftSegment.cpp new file mode 100644 index 0000000000..5b74115de4 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifRftSegment.cpp @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifRftSegment.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// segnxt : Int ID for the next segment +/// brno : Branch ID number +/// brnst : Branch ID number for start of segment +/// brnen : Branch ID number for end of segment +/// segNo : Segment ID number +/// +//-------------------------------------------------------------------------------------------------- +RifRftSegmentData::RifRftSegmentData( int segnxt, int brno, int brnst, int brnen, int segNo ) + : m_segNext( segnxt ) + , m_segbrno( brno ) + , m_brnst( brnst ) + , m_brnen( brnen ) + , m_segmentNo( segNo ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifRftSegmentData::segNext() const +{ + return m_segNext; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifRftSegmentData::segBrno() const +{ + return m_segbrno; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifRftSegmentData::segBrnst() const +{ + return m_brnst; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifRftSegmentData::segBrnen() const +{ + return m_brnen; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifRftSegmentData::segNo() const +{ + return m_segmentNo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifRftSegment::setSegmentData( std::vector segmentData ) +{ + m_topology = segmentData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifRftSegment::topology() const +{ + return m_topology; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifRftSegment::addResultNameAndSize( const Opm::EclIO::EclFile::EclEntry& resultNameAndSize ) +{ + m_resultNameAndSize.push_back( resultNameAndSize ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifRftSegment::resultNameAndSize() const +{ + return m_resultNameAndSize; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifRftSegment::branchIds() const +{ + std::unordered_set s; + for ( const auto& segData : m_topology ) + { + s.insert( segData.segBrno() ); + } + + std::vector v; + v.assign( s.begin(), s.end() ); + std::sort( v.begin(), v.end() ); + + return v; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifRftSegment::indicesForBranchNumber( int branchNumber ) const +{ + std::vector v; + for ( size_t i = 0; i < m_topology.size(); i++ ) + { + auto segment = m_topology[i]; + if ( branchNumber <= 0 || segment.segBrno() == branchNumber ) + { + v.push_back( i ); + } + } + + return v; +} diff --git a/ApplicationLibCode/FileInterface/RifRftSegment.h b/ApplicationLibCode/FileInterface/RifRftSegment.h new file mode 100644 index 0000000000..428b858df9 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifRftSegment.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + +#include "opm/io/eclipse/EclFile.hpp" + +class RifRftSegmentData +{ +public: + RifRftSegmentData( int segnxt, int brno, int brnst, int brnen, int segNo ); + + int segNext() const; + int segBrno() const; + int segBrnst() const; + int segBrnen() const; + int segNo() const; + +private: + int m_segNext; + int m_segbrno; + int m_brnst; + int m_brnen; + int m_segmentNo; +}; + +class RifRftSegment +{ +public: + void setSegmentData( std::vector segmentData ); + std::vector topology() const; + + void addResultNameAndSize( const Opm::EclIO::EclFile::EclEntry& resultNameAndSize ); + std::vector resultNameAndSize() const; + + std::vector branchIds() const; + + std::vector indicesForBranchNumber( int branchNumber ) const; + +private: + std::vector m_topology; + std::vector m_resultNameAndSize; +}; diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp index c52f4c1155..ebbdba1bad 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp @@ -951,7 +951,7 @@ std::map> RimWellPlotTools::calculat const std::vector& selSources, const std::set& interestingRFTResults ) { - bool addFirstTimestep = ( interestingRFTResults.count( RifEclipseRftAddress::PRESSURE ) == 1 ); + bool addFirstTimestep = ( interestingRFTResults.count( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) == 1 ); const QString simWellName = RimWellPlotTools::simWellName( wellPathNameOrSimWellName ); diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp index 4fb250e1d8..bedeef7dc9 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp @@ -302,13 +302,13 @@ public: { RifEclipseRftAddress gasRateAddress( RimWellPlotTools::simWellName( wellPathName ), m_timeStep, - RifEclipseRftAddress::GRAT ); + RifEclipseRftAddress::RftWellLogChannelType::GRAT ); RifEclipseRftAddress oilRateAddress( RimWellPlotTools::simWellName( wellPathName ), m_timeStep, - RifEclipseRftAddress::ORAT ); + RifEclipseRftAddress::RftWellLogChannelType::ORAT ); RifEclipseRftAddress watRateAddress( RimWellPlotTools::simWellName( wellPathName ), m_timeStep, - RifEclipseRftAddress::WRAT ); + RifEclipseRftAddress::RftWellLogChannelType::WRAT ); std::vector rftIndices; eclCase->rftReader()->cellIndices( gasRateAddress, &rftIndices ); diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp index 5ca8ea8455..613f7bba63 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp @@ -500,7 +500,9 @@ void RimWellRftPlot::updateCurvesInPlot( const std::setsetEclipseResultCase( dynamic_cast( rftCase ) ); - RifEclipseRftAddress address( simWellName, curveDefToAdd.timeStep(), RifEclipseRftAddress::PRESSURE ); + RifEclipseRftAddress address( simWellName, + curveDefToAdd.timeStep(), + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); curve->setRftAddress( address ); curve->setZOrder( 1 ); curve->setSimWellBranchData( m_branchDetection, m_branchIndex ); @@ -516,7 +518,7 @@ void RimWellRftPlot::updateCurvesInPlot( const std::setsetObservedFmuRftData( observedFmuRftData ); RifEclipseRftAddress address( m_wellPathNameOrSimWellName, curveDefToAdd.timeStep(), - RifEclipseRftAddress::PRESSURE ); + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); curve->setRftAddress( address ); curve->setZOrder( RiuQwtPlotCurveDefines::zDepthForIndex( RiuQwtPlotCurveDefines::ZIndex::Z_SINGLE_CURVE_OBSERVED ) ); @@ -533,7 +535,7 @@ void RimWellRftPlot::updateCurvesInPlot( const std::setfindObservedFmuData( m_wellPathNameOrSimWellName, curveDefToAdd.timeStep() ) ); RifEclipseRftAddress address( m_wellPathNameOrSimWellName, curveDefToAdd.timeStep(), - RifEclipseRftAddress::PRESSURE ); + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); curve->setRftAddress( address ); curve->setZOrder( 1 ); applyCurveAppearance( curve ); @@ -551,7 +553,7 @@ void RimWellRftPlot::updateCurvesInPlot( const std::setaddCurve( curve ); @@ -1164,13 +1166,13 @@ RiuPlotCurveSymbol::PointSymbolEnum RimWellRftPlot::statisticsCurveSymbolFromAdd { switch ( address.wellLogChannel() ) { - case RifEclipseRftAddress::PRESSURE_P10: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10: return RiuPlotCurveSymbol::SYMBOL_TRIANGLE; - case RifEclipseRftAddress::PRESSURE_P50: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50: return RiuPlotCurveSymbol::SYMBOL_DOWN_TRIANGLE; - case RifEclipseRftAddress::PRESSURE_P90: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90: return RiuPlotCurveSymbol::SYMBOL_LEFT_TRIANGLE; - case RifEclipseRftAddress::PRESSURE_MEAN: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN: return RiuPlotCurveSymbol::SYMBOL_RIGHT_TRIANGLE; } return RiuPlotCurveSymbol::SYMBOL_RIGHT_TRIANGLE; @@ -1183,13 +1185,13 @@ RiuPlotCurveSymbol::LabelPosition RimWellRftPlot::statisticsLabelPosFromAddress( { switch ( address.wellLogChannel() ) { - case RifEclipseRftAddress::PRESSURE_P10: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10: return RiuPlotCurveSymbol::LabelLeftOfSymbol; - case RifEclipseRftAddress::PRESSURE_P50: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50: return RiuPlotCurveSymbol::LabelAboveSymbol; - case RifEclipseRftAddress::PRESSURE_P90: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90: return RiuPlotCurveSymbol::LabelRightOfSymbol; - case RifEclipseRftAddress::PRESSURE_MEAN: + case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN: return RiuPlotCurveSymbol::LabelBelowSymbol; } return RiuPlotCurveSymbol::LabelAboveSymbol; diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.cpp index 80fc5d7f94..6d6b96186c 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.cpp @@ -393,14 +393,6 @@ RimGeoMechCase::CaseOpenStatus RimGeoMechCase::openGeoMechCase( std::string* err return CASE_OPEN_OK; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimGeoMechCase::updateFilePathsFromProjectPath( const QString& newProjectPath, const QString& oldProjectPath ) -{ - // No longer in use. Filepaths are now of type caf::FilePath, and updated in RimProject on load. -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.h b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.h index 588e790bd5..8a5cb73cc6 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.h +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechCase.h @@ -84,8 +84,6 @@ public: RimGeoMechView* createAndAddReservoirView(); RimGeoMechView* createCopyAndAddView( const RimGeoMechView* sourceView ); - void updateFilePathsFromProjectPath( const QString& projectPath, const QString& oldProjectPath ) override; - std::vector timeStepDates() const override; QStringList timeStepStrings() const override; QString timeStepName( int frameIdx ) const override; diff --git a/ApplicationLibCode/ProjectDataModel/RimCase.h b/ApplicationLibCode/ProjectDataModel/RimCase.h index b0ee0d9074..58dc1df104 100644 --- a/ApplicationLibCode/ProjectDataModel/RimCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimCase.h @@ -67,8 +67,6 @@ public: std::vector views() const; std::vector gridViews() const; - virtual void updateFilePathsFromProjectPath( const QString& projectPath, const QString& oldProjectPath ) = 0; - virtual std::vector timeStepDates() const = 0; virtual QStringList timeStepStrings() const = 0; virtual QString timeStepName( int frameIdx ) const = 0; diff --git a/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.cpp b/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.cpp index f9fed18592..2aa90e6691 100644 --- a/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.cpp @@ -1176,6 +1176,28 @@ RimDepthTrackPlot::DepthOrientation RimDepthTrackPlot::depthOrientation() const return m_depthOrientation(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuPlotAxis RimDepthTrackPlot::depthAxis() const +{ + if ( m_depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) + return RiuPlotAxis::defaultLeft(); + else + return RiuPlotAxis::defaultBottom(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuPlotAxis RimDepthTrackPlot::valueAxis() const +{ + if ( m_depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) + return RiuPlotAxis::defaultTop(); + else + return RiuPlotAxis::defaultLeft(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.h b/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.h index bfb3677d58..a65d01bb90 100644 --- a/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.h +++ b/ApplicationLibCode/ProjectDataModel/RimDepthTrackPlot.h @@ -42,6 +42,7 @@ class RimWellLogCurveCommonDataSource; class RiuWellLogPlot; class RimPlot; class RimEnsembleCurveSet; +class RiuPlotAxis; class QKeyEvent; @@ -103,6 +104,8 @@ public: AxisGridVisibility depthAxisGridLinesEnabled() const; RimDepthTrackPlot::DepthOrientation depthOrientation() const; + RiuPlotAxis depthAxis() const; + RiuPlotAxis valueAxis() const; void setAutoScaleXEnabled( bool enabled ); void setAutoScaleDepthEnabled( bool enabled ); diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.cpp index c0103ef88b..07ede4cb78 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.cpp @@ -322,27 +322,6 @@ QString RimEclipseInputCase::locationOnDisc() const return fi.absolutePath(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseInputCase::updateFilePathsFromProjectPath( const QString& newProjectPath, const QString& oldProjectPath ) -{ - // bool foundFile = false; - // std::vector searchedPaths; - - // m_gridFileName = RimTools::relocateFile( m_gridFileName().path(), newProjectPath, oldProjectPath, &foundFile, - // &searchedPaths ); - - // for ( RimEclipseInputProperty* inputProperty : m_inputPropertyCollection()->inputProperties() ) - //{ - // inputProperty->fileName = RimTools::relocateFile( inputProperty->fileName, - // newProjectPath, - // oldProjectPath, - // &foundFile, - // &searchedPaths ); - //} -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.h b/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.h index 4d45c92067..20f97edb05 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseInputCase.h @@ -55,8 +55,6 @@ public: // Overrides from RimCase QString locationOnDisc() const override; - void updateFilePathsFromProjectPath( const QString& projectPath, const QString& oldProjectPath ) override; - void updateAdditionalFileFolder( const QString& newFolder ); protected: diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp index c17eeb53bc..704a1517c9 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -33,6 +33,7 @@ #include "RifReaderEclipseOutput.h" #include "RifReaderEclipseRft.h" #include "RifReaderMockModel.h" +#include "RifReaderOpmRft.h" #include "RifReaderSettings.h" #include "RigCaseCellResultsData.h" @@ -68,7 +69,9 @@ CAF_PDM_SOURCE_INIT( RimEclipseResultCase, "EclipseCase" ); /// //-------------------------------------------------------------------------------------------------- RimEclipseResultCase::RimEclipseResultCase() - : RimEclipseCase() + : m_gridAndWellDataIsReadFromFile( false ) + , m_activeCellInfoIsReadFromFile( false ) + , m_useOpmRftReader( true ) { CAF_PDM_InitScriptableObject( "Eclipse Case", ":/Case48x48.png", "", "The Regular Eclipse Results Case" ); @@ -90,9 +93,6 @@ RimEclipseResultCase::RimEclipseResultCase() #ifndef USE_HDF5 m_sourSimFileName.uiCapability()->setUiHidden( true ); #endif - - m_activeCellInfoIsReadFromFile = false; - m_gridAndWellDataIsReadFromFile = false; } //-------------------------------------------------------------------------------------------------- @@ -212,17 +212,25 @@ bool RimEclipseResultCase::importGridAndResultMetaData( bool showTimeStepFilter if ( rftFileInfo.exists() ) { RiaLogging::info( QString( "RFT file found" ) ); - m_readerEclipseRft = new RifReaderEclipseRft( rftFileInfo.filePath() ); + + if ( m_useOpmRftReader ) + { + m_readerOpmRft = new RifReaderOpmRft( rftFileInfo.filePath() ); + } + else + { + m_readerEclipseRft = new RifReaderEclipseRft( rftFileInfo.filePath() ); + } } - if ( m_flowDiagSolutions.size() == 0 ) + if ( m_flowDiagSolutions.empty() ) { m_flowDiagSolutions.push_back( new RimFlowDiagSolution() ); } if ( !m_sourSimFileName().path().isEmpty() ) { - RifReaderEclipseOutput* outReader = dynamic_cast( readerInterface.p() ); + auto* outReader = dynamic_cast( readerInterface.p() ); outReader->setHdf5FileName( m_sourSimFileName().path() ); } @@ -336,7 +344,7 @@ void RimEclipseResultCase::loadAndUpdateSourSimData() // Deselect SourSimRL cell results for ( Rim3dView* view : views() ) { - RimEclipseView* eclipseView = dynamic_cast( view ); + auto* eclipseView = dynamic_cast( view ); if ( eclipseView != nullptr ) { if ( eclipseView->cellResult()->resultType() == RiaDefines::ResultCatType::SOURSIMRL ) @@ -487,41 +495,12 @@ void RimEclipseResultCase::readGridDimensions( std::vector>& gr RifEclipseOutputFileTools::readGridDimensions( gridFileName(), gridDimensions ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultCase::updateFilePathsFromProjectPath( const QString& newProjectPath, const QString& oldProjectPath ) -{ - // bool foundFile = false; - // std::vector searchedPaths; - - // Update filename and folder paths when opening project from a different file location - // caseFileName = RimTools::relocateFile( caseFileName(), newProjectPath, oldProjectPath, &foundFile, - // &searchedPaths ); - - // std::vector relocatedFaultFiles; - // const std::vector& orgFilesContainingFaults = filesContainingFaults(); - // for ( auto faultFileName : orgFilesContainingFaults ) - // { - // QString relocatedFaultFile = - // RimTools::relocateFile( faultFileName, newProjectPath, oldProjectPath, &foundFile, &searchedPaths ); - // relocatedFaultFiles.push_back( relocatedFaultFile ); - // } - // - // setFilesContainingFaults( relocatedFaultFiles ); - -#if 0 // Output the search path for debugging - for (size_t i = 0; i < searchedPaths.size(); ++i) - qDebug() << searchedPaths[i]; -#endif -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimFlowDiagSolution* RimEclipseResultCase::defaultFlowDiagSolution() { - if ( m_flowDiagSolutions.size() > 0 ) + if ( !m_flowDiagSolutions.empty() ) { return m_flowDiagSolutions[0]; } @@ -554,8 +533,10 @@ RigFlowDiagSolverInterface* RimEclipseResultCase::flowDiagSolverInterface() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifReaderEclipseRft* RimEclipseResultCase::rftReader() +RifReaderRftInterface* RimEclipseResultCase::rftReader() { + if ( m_useOpmRftReader ) return m_readerOpmRft.p(); + return m_readerEclipseRft.p(); } @@ -638,7 +619,7 @@ void RimEclipseResultCase::defineEditorAttribute( const caf::PdmFieldHandle* fie { if ( field == &m_sourSimFileName ) { - caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast( attribute ); + auto* myAttr = dynamic_cast( attribute ); if ( myAttr ) { myAttr->m_fileSelectionFilter = "SourSim (*.sourres)"; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h index cc3bdfc319..cdaad13290 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h @@ -25,9 +25,11 @@ #include "RimEclipseCase.h" #include "cafFilePath.h" -#include +#include "cafPdmProxyValueField.h" +class RifReaderRftInterface; class RifReaderEclipseRft; +class RifReaderOpmRft; class RifReaderInterface; class RigFlowDiagSolverInterface; class RigMainGrid; @@ -63,15 +65,13 @@ public: caf::AppEnum unitSystem(); - // Overrides from RimCase QString locationOnDisc() const override; - void updateFilePathsFromProjectPath( const QString& newProjectPath, const QString& oldProjectPath ) override; RimFlowDiagSolution* defaultFlowDiagSolution(); std::vector flowDiagSolutions(); RigFlowDiagSolverInterface* flowDiagSolverInterface(); - RifReaderEclipseRft* rftReader(); + RifReaderRftInterface* rftReader(); protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; @@ -90,6 +90,7 @@ private: cvf::ref m_flowDagSolverInterface; cvf::ref m_readerEclipseRft; + cvf::ref m_readerOpmRft; // Fields: caf::PdmProxyValueField> m_unitSystem; @@ -98,4 +99,5 @@ private: bool m_gridAndWellDataIsReadFromFile; bool m_activeCellInfoIsReadFromFile; + bool m_useOpmRftReader; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h index adc5015186..6731fbbe73 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h @@ -71,7 +71,6 @@ public: }; caf::PdmField m_calculateEditCommand; - void updateFilePathsFromProjectPath( const QString& projectPath, const QString& oldProjectPath ) override {} void populateResultSelectionAfterLoadingGrid(); diff --git a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp index c144df4a13..1beb44c0a3 100644 --- a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp @@ -118,7 +118,7 @@ RimPlotCurve::RimPlotCurve() m_curveAppearance.uiCapability()->setUiTreeHidden( true ); m_curveAppearance.uiCapability()->setUiTreeChildrenHidden( true ); m_curveAppearance->appearanceChanged.connect( this, &RimPlotCurve::onCurveAppearanceChanged ); - m_curveAppearance->appearanceChanged.connect( this, &RimPlotCurve::onFillColorChanged ); + m_curveAppearance->fillColorChanged.connect( this, &RimPlotCurve::onFillColorChanged ); m_plotCurve = nullptr; m_parentPlot = nullptr; diff --git a/ApplicationLibCode/ProjectDataModel/RimProject.cpp b/ApplicationLibCode/ProjectDataModel/RimProject.cpp index c38ab0dc05..c5983cbce4 100644 --- a/ApplicationLibCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimProject.cpp @@ -456,15 +456,6 @@ void RimProject::setProjectFileNameAndUpdateDependencies( const QString& project filePath->setPath( newFilePath ); } - // Loop over all cases and update file path - - std::vector cases; - allCases( cases ); - for ( size_t i = 0; i < cases.size(); i++ ) - { - cases[i]->updateFilePathsFromProjectPath( newProjectPath, oldProjectPath ); - } - // Update path to well path file cache for ( RimOilField* oilField : oilFields ) { diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.cpp index a9addfcda2..b126b847f3 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.cpp @@ -31,6 +31,8 @@ #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiTreeSelectionEditor.h" +#include + #include namespace caf diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h index 9f69a2c564..a430a3833a 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h @@ -46,6 +46,7 @@ #include "cafPdmPtrArrayField.h" #include "cafPdmPtrField.h" +#include #include class RimSummaryCase; @@ -71,7 +72,6 @@ class QwtPlot; class QwtPlotCurve; class QKeyEvent; class QFrame; -class QDate; //================================================================================================== /// diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp index 3c361f6f38..6ec9752c3f 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp @@ -41,6 +41,7 @@ #include "cafPdmFieldScriptingCapability.h" #include "cafPdmUiTreeOrdering.h" +#include #include #include diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h index 394050c9e3..461e997560 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h @@ -19,9 +19,7 @@ #pragma once #include "RiaDefines.h" -#include "RifEclipseRftAddress.h" #include "RifEclipseSummaryAddress.h" -#include "RifReaderEnsembleStatisticsRft.h" #include "RigEnsembleParameter.h" @@ -33,6 +31,8 @@ #include "cafPdmObject.h" #include "cafPdmProxyValueField.h" +#include "cvfObject.h" + #include #include diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.cpp index 7461dd2745..d01839d60b 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.cpp @@ -27,6 +27,7 @@ #include "RimEclipseResultCase.h" #include "RimTools.h" #include "RimWellLogCurve.h" +#include "RimWellLogRftCurve.h" #include "RimWellLogRftCurveNameConfig.h" #include "RimWellPath.h" @@ -117,8 +118,8 @@ QString Rim3dWellLogRftCurve::createAutoName() const { name.push_back( m_eclipseResultCase->caseUserDescription() ); } - if ( m_wellLogChannelName().text() != - caf::AppEnum::text( RifEclipseRftAddress::NONE ) ) + if ( m_wellLogChannelName().text() != caf::AppEnum::text( + RifEclipseRftAddress::RftWellLogChannelType::NONE ) ) { RifEclipseRftAddress::RftWellLogChannelType channelNameEnum = m_wellLogChannelName(); name.push_back( caf::AppEnum::uiText( channelNameEnum ) ); @@ -172,7 +173,7 @@ QList { if ( m_eclipseResultCase ) { - RifReaderEclipseRft* reader = m_eclipseResultCase()->rftReader(); + RifReaderRftInterface* reader = m_eclipseResultCase()->rftReader(); if ( reader ) { for ( const RifEclipseRftAddress::RftWellLogChannelType& channelName : @@ -187,8 +188,8 @@ QList if ( options.empty() ) { options.push_back( caf::PdmOptionItemInfo( caf::AppEnum::uiText( - RifEclipseRftAddress::NONE ), - RifEclipseRftAddress::NONE ) ); + RifEclipseRftAddress::RftWellLogChannelType::NONE ), + RifEclipseRftAddress::RftWellLogChannelType::NONE ) ); } } } @@ -196,7 +197,7 @@ QList { if ( m_eclipseResultCase ) { - RifReaderEclipseRft* reader = m_eclipseResultCase()->rftReader(); + RifReaderRftInterface* reader = m_eclipseResultCase()->rftReader(); if ( reader ) { QString dateFormat = "dd MMM yyyy"; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.h b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.h index 5dee8b1c78..6272a7db55 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogRftCurve.h @@ -25,10 +25,10 @@ #include "cafPdmPtrField.h" #include "RifEclipseRftAddress.h" -#include "RimWellLogRftCurve.h" class RimEclipseResultCase; class RimWellLogRftCurveNameConfig; +class RimWellLogRftCurve; class QString; //================================================================================================== diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.cpp index d46fabba9c..dc1dc71753 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.cpp @@ -148,6 +148,24 @@ void RimWellLogCurve::setPropertyValuesAndDepths( const std::vector& pro calculateCurveDataPropertyValueRange(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurve::setPropertyAndDepthValuesToPlotCurve( const std::vector& propertyValues, + const std::vector& depthValues ) +{ + if ( !m_plotCurve ) return; + + if ( isVerticalCurve() ) + { + m_plotCurve->setSamplesValues( propertyValues, depthValues ); + } + else + { + m_plotCurve->setSamplesValues( depthValues, propertyValues ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -234,21 +252,15 @@ QString RimWellLogCurve::wellLogCurveIconName() //-------------------------------------------------------------------------------------------------- void RimWellLogCurve::setOverrideCurveData( const std::vector& propertyValues, const std::vector& depthValues, - const RiaCurveDataTools::CurveIntervals& curveIntervals, - bool isVerticalPlot ) + const RiaCurveDataTools::CurveIntervals& curveIntervals ) { auto minmax_it = std::minmax_element( propertyValues.begin(), propertyValues.end() ); this->setOverrideCurveDataPropertyValueRange( *( minmax_it.first ), *( minmax_it.second ) ); + if ( m_plotCurve ) { - if ( isVerticalPlot ) - { - m_plotCurve->setSamplesValues( propertyValues, depthValues ); - } - else - { - m_plotCurve->setSamplesValues( depthValues, propertyValues ); - } + setPropertyAndDepthValuesToPlotCurve( propertyValues, depthValues ); + m_plotCurve->setLineSegmentStartStopIndices( curveIntervals ); } } @@ -357,9 +369,12 @@ void RimWellLogCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField, { RimStackablePlotCurve::fieldChangedByUi( changedField, oldValue, newValue ); - if ( changedField == &m_showCurve && m_showCurve() ) + if ( changedField == &m_showCurve ) { - updateZoomInParentPlot(); + if ( m_isStacked() || m_showCurve() ) + { + updateZoomInParentPlot(); + } } if ( changedField == &m_isStacked ) @@ -367,3 +382,39 @@ void RimWellLogCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField, loadDataAndUpdate( true ); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogCurve::isVerticalCurve() const +{ + RimDepthTrackPlot::DepthOrientation orientation = RimDepthTrackPlot::DepthOrientation::VERTICAL; + + RimDepthTrackPlot* depthTrackPlot = nullptr; + firstAncestorOrThisOfType( depthTrackPlot ); + if ( depthTrackPlot ) orientation = depthTrackPlot->depthOrientation(); + + return orientation == RimDepthTrackPlot::DepthOrientation::VERTICAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuPlotAxis RimWellLogCurve::depthAxis() const +{ + RimDepthTrackPlot* depthTrackPlot; + this->firstAncestorOrThisOfTypeAsserted( depthTrackPlot ); + + return depthTrackPlot->depthAxis(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuPlotAxis RimWellLogCurve::valueAxis() const +{ + RimDepthTrackPlot* depthTrackPlot; + this->firstAncestorOrThisOfTypeAsserted( depthTrackPlot ); + + return depthTrackPlot->valueAxis(); +} diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.h index 7451fb5f19..bbfaa414fa 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurve.h @@ -71,6 +71,9 @@ public: bool useLogarithmicScale, const QString& propertyUnit = RiaWellLogUnitTools::noUnitString() ); + void setPropertyAndDepthValuesToPlotCurve( const std::vector& propertyValues, + const std::vector& depthValues ); + const RigWellLogCurveData* curveData() const; void updateCurveAppearance() override; @@ -85,8 +88,7 @@ public: void setOverrideCurveData( const std::vector& propertyValues, const std::vector& depthValues, - const RiaCurveDataTools::CurveIntervals& curveIntervals, - bool isVerticalPlot ); + const RiaCurveDataTools::CurveIntervals& curveIntervals ); virtual RiaDefines::PhaseType resultPhase() const; @@ -97,6 +99,10 @@ protected: void calculateCurveDataPropertyValueRange(); void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + bool isVerticalCurve() const; + RiuPlotAxis depthAxis() const; + RiuPlotAxis valueAxis() const; + private: cvf::ref m_curveData; std::pair m_curveDataPropertyValueRange; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.cpp index b295dbf6c4..78460e82dd 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.cpp @@ -22,6 +22,7 @@ #include "RiaEclipseUnitTools.h" #include "RiaQDateTimeTools.h" #include "RiaResultNames.h" +#include "RiaRftDefines.h" #include "RiaSimWellBranchTools.h" #include "RifEclipseRftAddress.h" @@ -69,27 +70,73 @@ namespace caf template <> void caf::AppEnum::setUp() { - addItem( RifEclipseRftAddress::NONE, "NONE", "None" ); - addItem( RifEclipseRftAddress::TVD, "DEPTH", "Depth" ); - addItem( RifEclipseRftAddress::PRESSURE, "PRESSURE", "Pressure" ); - addItem( RifEclipseRftAddress::SWAT, RiaResultNames::swat(), "Water Saturation" ); - addItem( RifEclipseRftAddress::SOIL, RiaResultNames::soil(), "Oil Saturation" ); - addItem( RifEclipseRftAddress::SGAS, RiaResultNames::sgas(), "Gas Saturation" ); - addItem( RifEclipseRftAddress::WRAT, "WRAT", "Water Flow" ); - addItem( RifEclipseRftAddress::ORAT, "ORAT", "Oil Flow" ); - addItem( RifEclipseRftAddress::GRAT, "GRAT", "Gas flow" ); - addItem( RifEclipseRftAddress::MD, "MD", "Measured Depth" ); - addItem( RifEclipseRftAddress::PRESSURE_P10, "PRESSURE_P10", "P10: Pressure" ); - addItem( RifEclipseRftAddress::PRESSURE_P50, "PRESSURE_P50", "P50: Pressure" ); - addItem( RifEclipseRftAddress::PRESSURE_P90, "PRESSURE_P90", "P90: Pressure" ); - addItem( RifEclipseRftAddress::PRESSURE_MEAN, "PRESSURE_MEAN", "Mean: Pressure" ); - addItem( RifEclipseRftAddress::PRESSURE_ERROR, "PRESSURE_ERROR", "Error: Pressure" ); - setDefault( RifEclipseRftAddress::NONE ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::NONE, "NONE", "None" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::TVD, "DEPTH", "Depth" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE, "PRESSURE", "Pressure" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::SWAT, RiaResultNames::swat(), "Water Saturation" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::SOIL, RiaResultNames::soil(), "Oil Saturation" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::SGAS, RiaResultNames::sgas(), "Gas Saturation" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::WRAT, "WRAT", "Water Flow" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::ORAT, "ORAT", "Oil Flow" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::GRAT, "GRAT", "Gas flow" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::MD, "MD", "Measured Depth" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P10, "PRESSURE_P10", "P10: Pressure" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P50, "PRESSURE_P50", "P50: Pressure" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_P90, "PRESSURE_P90", "P90: Pressure" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_MEAN, "PRESSURE_MEAN", "Mean: Pressure" ); + addItem( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR, "PRESSURE_ERROR", "Error: Pressure" ); + setDefault( RifEclipseRftAddress::RftWellLogChannelType::NONE ); +} +} // namespace caf + +namespace caf +{ +template <> +void caf::AppEnum::setUp() +{ + addItem( RimWellLogRftCurve::RftDataType::RFT_DATA, "RFT_DATA", "RFT" ); + addItem( RimWellLogRftCurve::RftDataType::RFT_SEGMENT_DATA, "RFT_SEGMENT_DATA", "RFT Segment" ); + setDefault( RimWellLogRftCurve::RftDataType::RFT_DATA ); } } // namespace caf CAF_PDM_SOURCE_INIT( RimWellLogRftCurve, "WellLogRftCurve" ); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::PhaseType RimWellLogRftCurve::phaseType() const +{ + if ( m_rftDataType() == RimWellLogRftCurve::RftDataType::RFT_DATA ) + { + if ( m_wellLogChannelName() == RifEclipseRftAddress::RftWellLogChannelType::SWAT || + m_wellLogChannelName() == RifEclipseRftAddress::RftWellLogChannelType::WRAT ) + { + return RiaDefines::PhaseType::WATER_PHASE; + } + + if ( m_wellLogChannelName() == RifEclipseRftAddress::RftWellLogChannelType::SGAS || + m_wellLogChannelName() == RifEclipseRftAddress::RftWellLogChannelType::GRAT ) + { + return RiaDefines::PhaseType::GAS_PHASE; + } + + if ( m_wellLogChannelName() == RifEclipseRftAddress::RftWellLogChannelType::SOIL || + m_wellLogChannelName() == RifEclipseRftAddress::RftWellLogChannelType::ORAT ) + { + return RiaDefines::PhaseType::OIL_PHASE; + } + } + else if ( m_rftDataType() == RimWellLogRftCurve::RftDataType::RFT_SEGMENT_DATA ) + { + if ( m_segmentResultName().startsWith( "SEGO" ) ) return RiaDefines::PhaseType::OIL_PHASE; + if ( m_segmentResultName().startsWith( "SEGW" ) ) return RiaDefines::PhaseType::WATER_PHASE; + if ( m_segmentResultName().startsWith( "SEGG" ) ) return RiaDefines::PhaseType::GAS_PHASE; + } + + return RiaDefines::PhaseType::PHASE_NOT_APPLICABLE; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -122,6 +169,10 @@ RimWellLogRftCurve::RimWellLogRftCurve() "" ); CAF_PDM_InitFieldNoDefault( &m_wellLogChannelName, "WellLogChannelName", "Well Property" ); + 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", RiaResultNames::undefinedResultName(), "Segment Branch" ); } //-------------------------------------------------------------------------------------------------- @@ -234,7 +285,7 @@ void RimWellLogRftCurve::setRftAddress( RifEclipseRftAddress address ) //-------------------------------------------------------------------------------------------------- RifEclipseRftAddress RimWellLogRftCurve::rftAddress() const { - return RifEclipseRftAddress( m_wellName, m_timeStep, m_wellLogChannelName() ); + return { m_wellName, m_timeStep, m_wellLogChannelName() }; } //-------------------------------------------------------------------------------------------------- @@ -259,12 +310,12 @@ void RimWellLogRftCurve::setDefaultAddress( QString wellName ) if ( !wellNameHasRftData ) { - m_wellLogChannelName = RifEclipseRftAddress::NONE; + m_wellLogChannelName = RifEclipseRftAddress::RftWellLogChannelType::NONE; m_timeStep = QDateTime(); return; } - m_wellLogChannelName = RifEclipseRftAddress::PRESSURE; + m_wellLogChannelName = RifEclipseRftAddress::RftWellLogChannelType::PRESSURE; std::set timeSteps = reader->availableTimeSteps( m_wellName, m_wellLogChannelName() ); if ( !timeSteps.empty() ) @@ -282,7 +333,7 @@ void RimWellLogRftCurve::setDefaultAddress( QString wellName ) //-------------------------------------------------------------------------------------------------- void RimWellLogRftCurve::updateWellChannelNameAndTimeStep() { - if ( !m_timeStep().isValid() || m_wellLogChannelName() == RifEclipseRftAddress::NONE ) + if ( !m_timeStep().isValid() || m_wellLogChannelName() == RifEclipseRftAddress::RftWellLogChannelType::NONE ) { setDefaultAddress( m_wellName ); return; @@ -295,11 +346,11 @@ void RimWellLogRftCurve::updateWellChannelNameAndTimeStep() if ( channelNames.empty() ) { - m_wellLogChannelName = RifEclipseRftAddress::NONE; + m_wellLogChannelName = RifEclipseRftAddress::RftWellLogChannelType::NONE; } else if ( !channelNames.count( m_wellLogChannelName() ) ) { - m_wellLogChannelName = RifEclipseRftAddress::PRESSURE; + m_wellLogChannelName = RifEclipseRftAddress::RftWellLogChannelType::PRESSURE; } std::set timeSteps = reader->availableTimeSteps( m_wellName, m_wellLogChannelName() ); @@ -353,14 +404,26 @@ QString RimWellLogRftCurve::createCurveAutoName() { name.push_back( m_observedFmuRftData->name() ); } - if ( wellLogChannelUiName() != - caf::AppEnum::text( RifEclipseRftAddress::NONE ) ) + + if ( m_rftDataType() == RftDataType::RFT_DATA ) { - RifEclipseRftAddress::RftWellLogChannelType channelNameEnum = - caf::AppEnum::fromText( wellLogChannelUiName() ); - QString channelName = caf::AppEnum::uiText( channelNameEnum ); - name.push_back( channelName ); + if ( wellLogChannelUiName() != caf::AppEnum::text( + RifEclipseRftAddress::RftWellLogChannelType::NONE ) ) + { + RifEclipseRftAddress::RftWellLogChannelType channelNameEnum = + caf::AppEnum::fromText( wellLogChannelUiName() ); + QString channelName = caf::AppEnum::uiText( channelNameEnum ); + name.push_back( channelName ); + } } + else if ( m_rftDataType() == RftDataType::RFT_SEGMENT_DATA ) + { + name.push_back( m_segmentResultName ); + + QString branchText = "Branch " + m_segmentBranchId(); + name.push_back( branchText ); + } + if ( !m_timeStep().isNull() ) { name.push_back( m_timeStep().toString( RiaQDateTimeTools::dateFormatString() ) ); @@ -376,7 +439,7 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) { this->RimPlotCurve::updateCurvePresentation( updateParentPlot ); - DerivedMDSource derivedMDSource = NO_SOURCE; + DerivedMDSource derivedMDSource = DerivedMDSource::NO_SOURCE; if ( isCurveVisible() ) { @@ -384,9 +447,9 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) firstAncestorOrThisOfType( wellLogPlot ); CVF_ASSERT( wellLogPlot ); - RimWellRftPlot* rftPlot = dynamic_cast( wellLogPlot ); - bool showErrorBarsInObservedData = rftPlot ? rftPlot->showErrorBarsForObservedData() : false; - m_showErrorBars = showErrorBarsInObservedData; + auto* rftPlot = dynamic_cast( wellLogPlot ); + bool showErrorBarsInObservedData = rftPlot ? rftPlot->showErrorBarsForObservedData() : false; + m_showErrorBars = showErrorBarsInObservedData; std::vector measuredDepthVector = measuredDepthValues(); std::vector tvDepthVector = tvDepthValues(); @@ -428,17 +491,17 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) { if ( deriveMeasuredDepthValuesFromWellPath( tvDepthVector, measuredDepthVector ) ) { - derivedMDSource = WELL_PATH; + derivedMDSource = DerivedMDSource::WELL_PATH; } else if ( deriveMeasuredDepthFromObservedData( tvDepthVector, measuredDepthVector ) ) { - derivedMDSource = OBSERVED_DATA; + derivedMDSource = DerivedMDSource::OBSERVED_DATA; } } if ( tvDepthVector.size() != measuredDepthVector.size() ) { - derivedMDSource = NO_SOURCE; + derivedMDSource = DerivedMDSource::NO_SOURCE; measuredDepthVector = tvDepthVector; } @@ -470,22 +533,21 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) { m_plotCurve->setPerPointLabels( perPointLabels ); - auto xValues = this->curveData()->propertyValuesByIntervals(); - auto yValues = - this->curveData()->depthValuesByIntervals( RiaDefines::DepthTypeEnum::MEASURED_DEPTH, displayUnit ); + auto propertyValues = this->curveData()->propertyValues(); + auto depthValues = this->curveData()->depths( RiaDefines::DepthTypeEnum::MEASURED_DEPTH, displayUnit ); bool useLogarithmicScale = false; if ( !errors.empty() ) { - this->setSamplesFromXYErrorValues( xValues, - yValues, + this->setSamplesFromXYErrorValues( propertyValues, + depthValues, errors, useLogarithmicScale, RiaCurveDataTools::ErrorAxis::ERROR_ALONG_X_AXIS ); } else { - m_plotCurve->setSamplesFromXValuesAndYValues( xValues, yValues, useLogarithmicScale ); + setPropertyAndDepthValuesToPlotCurve( propertyValues, depthValues ); } RimWellLogTrack* wellLogTrack; @@ -495,21 +557,25 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot ) RiuQwtPlotWidget* viewer = wellLogTrack->viewer(); if ( viewer ) { - if ( derivedMDSource != NO_SOURCE ) + QString text; + + if ( derivedMDSource != DerivedMDSource::NO_SOURCE ) { - if ( derivedMDSource == WELL_PATH ) + if ( derivedMDSource == DerivedMDSource::WELL_PATH ) { - viewer->setAxisTitleText( RiuPlotAxis::defaultLeft(), "WELL/" + wellLogPlot->depthAxisTitle() ); + text = "WELL/" + wellLogPlot->depthAxisTitle(); } else { - viewer->setAxisTitleText( RiuPlotAxis::defaultLeft(), "OBS/" + wellLogPlot->depthAxisTitle() ); + text = "OBS/" + wellLogPlot->depthAxisTitle(); } } else // Standard depth title set from plot { - viewer->setAxisTitleText( RiuPlotAxis::defaultLeft(), wellLogPlot->depthAxisTitle() ); + text = wellLogPlot->depthAxisTitle(); } + + viewer->setAxisTitleText( wellLogPlot->depthAxis(), text ); } } else @@ -559,14 +625,23 @@ void RimWellLogRftCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Curve Data" ); curveDataGroup->add( &m_eclipseResultCase ); curveDataGroup->add( &m_wellName ); - - RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromWellName( curveDataGroup, - m_wellName, - m_branchDetection, - m_branchIndex ); - - curveDataGroup->add( &m_wellLogChannelName ); curveDataGroup->add( &m_timeStep ); + curveDataGroup->add( &m_rftDataType ); + + if ( m_rftDataType() == RimWellLogRftCurve::RftDataType::RFT_DATA ) + { + curveDataGroup->add( &m_wellLogChannelName ); + + RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromWellName( curveDataGroup, + m_wellName, + m_branchDetection, + m_branchIndex ); + } + else + { + curveDataGroup->add( &m_segmentResultName ); + curveDataGroup->add( &m_segmentBranchId ); + } caf::PdmUiGroup* stackingGroup = uiOrdering.addNewGroup( "Stacking" ); RimStackablePlotCurve::stackingUiOrdering( *stackingGroup ); @@ -591,7 +666,7 @@ QList RimWellLogRftCurve::calculateValueOptions( const c options = RimWellLogCurve::calculateValueOptions( fieldNeedingOptions, useOptionsOnly ); - if ( options.size() > 0 ) return options; + if ( !options.empty() ) return options; if ( fieldNeedingOptions == &m_eclipseResultCase ) { @@ -628,8 +703,8 @@ QList RimWellLogRftCurve::calculateValueOptions( const c if ( options.empty() ) { options.push_back( caf::PdmOptionItemInfo( caf::AppEnum::uiText( - RifEclipseRftAddress::NONE ), - RifEclipseRftAddress::NONE ) ); + RifEclipseRftAddress::RftWellLogChannelType::NONE ), + RifEclipseRftAddress::RftWellLogChannelType::NONE ) ); } } else if ( fieldNeedingOptions == &m_timeStep ) @@ -656,6 +731,49 @@ QList RimWellLogRftCurve::calculateValueOptions( const c options = RiaSimWellBranchTools::valueOptionsForBranchIndexField( simulationWellBranches ); } + else if ( fieldNeedingOptions == &m_segmentResultName ) + { + options.push_front( + caf::PdmOptionItemInfo( RiaResultNames::undefinedResultName(), RiaResultNames::undefinedResultName() ) ); + + RifReaderRftInterface* reader = rftReader(); + if ( reader ) + { + options.push_back( caf::PdmOptionItemInfo( RiaDefines::segmentNumberResultName(), + RiaDefines::segmentNumberResultName() ) ); + + for ( const auto& resultAdr : reader->eclipseRftAddresses( m_wellName(), m_timeStep() ) ) + { + if ( resultAdr.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES ) + { + options.push_back( + caf::PdmOptionItemInfo( resultAdr.segmentResultName(), resultAdr.segmentResultName() ) ); + } + } + } + } + else if ( fieldNeedingOptions == &m_segmentBranchId ) + { + options.push_front( caf::PdmOptionItemInfo( RiaDefines::allBranches(), RiaDefines::allBranches() ) ); + + RifReaderRftInterface* reader = rftReader(); + if ( reader ) + { + std::vector values; + + auto adr = RifEclipseRftAddress::createSegmentResult( m_wellName(), + m_timeStep, + RiaDefines::segmentBranchNumberResultName() ); + + reader->values( adr, &values ); + for ( const auto& v : values ) + { + int intValue = v; + auto txt = QString::number( intValue ); + options.push_back( caf::PdmOptionItemInfo( txt, txt ) ); + } + } + } return options; } @@ -669,21 +787,23 @@ void RimWellLogRftCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedFie { m_idxInWellPathToIdxInRftFile.clear(); + bool loadData = false; + RimWellLogCurve::fieldChangedByUi( changedField, oldValue, newValue ); if ( changedField == &m_eclipseResultCase ) { m_timeStep = QDateTime(); m_wellName = ""; - m_wellLogChannelName = RifEclipseRftAddress::NONE; + m_wellLogChannelName = RifEclipseRftAddress::RftWellLogChannelType::NONE; - this->loadDataAndUpdate( true ); + loadData = true; } else if ( changedField == &m_wellName ) { m_branchIndex = 0; updateWellChannelNameAndTimeStep(); - this->loadDataAndUpdate( true ); + loadData = true; } else if ( changedField == &m_branchDetection || changedField == &m_branchIndex ) { @@ -692,20 +812,23 @@ void RimWellLogRftCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedFie m_branchIndex = RiaSimWellBranchTools::clampBranchIndex( simWellName, m_branchIndex, m_branchDetection ); updateWellChannelNameAndTimeStep(); - this->loadDataAndUpdate( true ); + loadData = true; } else if ( changedField == &m_wellLogChannelName ) { - if ( m_wellLogChannelName == RifEclipseRftAddress::NONE ) + if ( m_wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::NONE ) { m_timeStep = QDateTime(); } - this->loadDataAndUpdate( true ); + loadData = true; } - else if ( changedField == &m_timeStep ) + else if ( changedField == &m_timeStep || changedField == &m_segmentResultName || + changedField == &m_segmentBranchId || changedField == &m_rftDataType ) { - this->loadDataAndUpdate( true ); + loadData = true; } + + if ( loadData ) this->loadDataAndUpdate( true ); } //-------------------------------------------------------------------------------------------------- @@ -715,7 +838,7 @@ std::vector RimWellLogRftCurve::perPointLabels() const { if ( m_observedFmuRftData() ) { - RifEclipseRftAddress address( m_wellName(), m_timeStep, RifEclipseRftAddress::PRESSURE ); + RifEclipseRftAddress address( m_wellName(), m_timeStep, RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ); return m_observedFmuRftData()->labels( address ); } return {}; @@ -730,18 +853,22 @@ RifReaderRftInterface* RimWellLogRftCurve::rftReader() const { return m_eclipseResultCase()->rftReader(); } - else if ( m_summaryCase() ) // Summary RFT curves have both summary and ensemble set. Prioritize summary for reader. + + if ( m_summaryCase() ) // Summary RFT curves have both summary and ensemble set. Prioritize summary for reader. { return m_summaryCase()->rftReader(); } - else if ( m_ensemble() ) + + if ( m_ensemble() ) { return m_ensemble()->rftStatisticsReader(); } - else if ( m_observedFmuRftData() ) + + if ( m_observedFmuRftData() ) { return m_observedFmuRftData()->rftReader(); } + return nullptr; } @@ -770,7 +897,7 @@ RigEclipseWellLogExtractor* RimWellLogRftCurve::extractor() QString simWellName = RimWellPlotTools::simWellName( m_wellName ); std::vector wellPaths = RiaSimWellBranchTools::simulationWellBranches( simWellName, m_branchDetection ); - if ( wellPaths.size() == 0 ) return nullptr; + if ( wellPaths.empty() ) return nullptr; m_branchIndex = RiaSimWellBranchTools::clampBranchIndex( simWellName, m_branchIndex, m_branchDetection ); @@ -809,12 +936,11 @@ bool RimWellLogRftCurve::createWellPathIdxToRftFileIdxMapping() globCellIndicesToIndexInWell[intersections[idx].globCellIndex] = idx; } - RifEclipseRftAddress depthAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::TVD ); + RifEclipseRftAddress depthAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::RftWellLogChannelType::TVD ); std::vector rftIndices; - RifReaderEclipseRft* eclipseRftReader = dynamic_cast( rftReader() ); - if ( !eclipseRftReader ) return false; + if ( !rftReader() ) return false; - eclipseRftReader->cellIndices( depthAddress, &rftIndices ); + rftReader()->cellIndices( depthAddress, &rftIndices ); const RigMainGrid* mainGrid = eclExtractor->caseData()->mainGrid(); @@ -861,9 +987,9 @@ std::vector RimWellLogRftCurve::sortedIndicesInRftFile() } std::vector indices; - for ( auto it = m_idxInWellPathToIdxInRftFile.begin(); it != m_idxInWellPathToIdxInRftFile.end(); it++ ) + for ( auto& it : m_idxInWellPathToIdxInRftFile ) { - indices.push_back( it->second ); + indices.push_back( it.second ); } return indices; @@ -879,6 +1005,16 @@ std::vector RimWellLogRftCurve::xValues() if ( !reader ) return values; + if ( m_rftDataType() == RftDataType::RFT_SEGMENT_DATA ) + { + auto depthAddress = RifEclipseRftAddress::createSegmentResult( m_wellName(), m_timeStep, m_segmentResultName() ); + depthAddress.setSegmentBranchNumber( segmentBranchNumber() ); + + reader->values( depthAddress, &values ); + + return values; + } + RifEclipseRftAddress address( m_wellName(), m_timeStep, m_wellLogChannelName() ); reader->values( address, &values ); @@ -899,10 +1035,8 @@ std::vector RimWellLogRftCurve::xValues() return valuesSorted; } - else - { - return values; - } + + return values; } //-------------------------------------------------------------------------------------------------- @@ -913,11 +1047,14 @@ std::vector RimWellLogRftCurve::errorValues() RifReaderRftInterface* reader = rftReader(); std::vector errorValues; - if ( reader ) + if ( reader && m_rftDataType() == RftDataType::RFT_DATA ) { - RifEclipseRftAddress errorAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::PRESSURE_ERROR ); + RifEclipseRftAddress errorAddress( m_wellName(), + m_timeStep, + RifEclipseRftAddress::RftWellLogChannelType::PRESSURE_ERROR ); reader->values( errorAddress, &errorValues ); } + return errorValues; } @@ -931,7 +1068,17 @@ std::vector RimWellLogRftCurve::tvDepthValues() if ( !reader ) return values; - RifEclipseRftAddress depthAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::TVD ); + if ( m_rftDataType() == RftDataType::RFT_SEGMENT_DATA ) + { + auto depthAddress = + RifEclipseRftAddress::createSegmentResult( m_wellName(), m_timeStep, RiaDefines::segmentTvdDepthResultName() ); + depthAddress.setSegmentBranchNumber( segmentBranchNumber() ); + + reader->values( depthAddress, &values ); + return values; + } + + RifEclipseRftAddress depthAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::RftWellLogChannelType::TVD ); reader->values( depthAddress, &values ); bool wellPathExists = createWellPathIdxToRftFileIdxMapping(); @@ -950,10 +1097,8 @@ std::vector RimWellLogRftCurve::tvDepthValues() return valuesSorted; } - else - { - return values; - } + + return values; } //-------------------------------------------------------------------------------------------------- @@ -961,6 +1106,23 @@ std::vector RimWellLogRftCurve::tvDepthValues() //-------------------------------------------------------------------------------------------------- std::vector RimWellLogRftCurve::measuredDepthValues() { + if ( m_rftDataType() == RftDataType::RFT_SEGMENT_DATA ) + { + std::vector values; + + RifReaderRftInterface* reader = rftReader(); + if ( reader ) + { + auto depthAddress = RifEclipseRftAddress::createSegmentResult( m_wellName(), + m_timeStep, + RiaDefines::segmentStartDepthResultName() ); + depthAddress.setSegmentBranchNumber( segmentBranchNumber() ); + + reader->values( depthAddress, &values ); + } + return values; + } + if ( m_observedFmuRftData && !m_ensemble && !m_summaryCase ) { RifReaderRftInterface* reader = rftReader(); @@ -968,7 +1130,7 @@ std::vector RimWellLogRftCurve::measuredDepthValues() if ( !reader ) return values; - RifEclipseRftAddress depthAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::MD ); + RifEclipseRftAddress depthAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::RftWellLogChannelType::MD ); reader->values( depthAddress, &values ); return values; } @@ -1044,8 +1206,8 @@ bool RimWellLogRftCurve::deriveMeasuredDepthFromObservedData( const std::vector< std::vector tvdValuesOfObservedData; std::vector mdValuesOfObservedData; - RifEclipseRftAddress tvdAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::TVD ); - RifEclipseRftAddress mdAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::MD ); + RifEclipseRftAddress tvdAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::RftWellLogChannelType::TVD ); + RifEclipseRftAddress mdAddress( m_wellName(), m_timeStep, RifEclipseRftAddress::RftWellLogChannelType::MD ); reader->values( tvdAddress, &tvdValuesOfObservedData ); reader->values( mdAddress, &mdValuesOfObservedData ); @@ -1062,3 +1224,18 @@ bool RimWellLogRftCurve::deriveMeasuredDepthFromObservedData( const std::vector< } return false; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimWellLogRftCurve::segmentBranchNumber() const +{ + if ( m_segmentBranchId() != RiaDefines::allBranches() ) + { + QString text = m_segmentBranchId(); + auto intValue = text.toInt(); + return intValue; + } + + return -1; +} diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.h index fc37b7b697..0bcfbb8f25 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogRftCurve.h @@ -28,6 +28,7 @@ #include "cvfObject.h" +#include #include class RifReaderRftInterface; @@ -47,10 +48,18 @@ class RimWellLogRftCurve : public RimWellLogCurve CAF_PDM_HEADER_INIT; public: - enum DerivedMDSource + enum class RftDataType + { + RFT_DATA, + RFT_SEGMENT_DATA + }; + +private: + enum class DerivedMDSource { NO_SOURCE, WELL_PATH, + SEGMENT, OBSERVED_DATA }; @@ -78,14 +87,14 @@ public: RifEclipseRftAddress rftAddress() const; void setDefaultAddress( QString wellName ); - void updateWellChannelNameAndTimeStep(); void setSimWellBranchData( bool branchDetection, int branchIndex ); protected: // Overrides from RimWellLogPlotCurve - QString createCurveAutoName() override; - void onLoadDataAndUpdate( bool updateParentPlot ) override; + QString createCurveAutoName() override; + void onLoadDataAndUpdate( bool updateParentPlot ) override; + RiaDefines::PhaseType phaseType() const override; // Pdm overrrides void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; @@ -103,6 +112,7 @@ private: bool createWellPathIdxToRftFileIdxMapping(); size_t rftFileIndex( size_t wellPathIndex ); std::vector sortedIndicesInRftFile(); + void updateWellChannelNameAndTimeStep(); std::vector xValues(); std::vector errorValues(); @@ -114,6 +124,8 @@ private: bool deriveMeasuredDepthFromObservedData( const std::vector& tvDepthValues, std::vector& derivedMDValues ); + int segmentBranchNumber() const; + private: caf::PdmPtrField m_eclipseResultCase; caf::PdmPtrField m_summaryCase; @@ -124,6 +136,11 @@ private: caf::PdmField m_branchIndex; caf::PdmField m_branchDetection; + caf::PdmField> m_rftDataType; + + caf::PdmField m_segmentResultName; + caf::PdmField m_segmentBranchId; + std::map m_idxInWellPathToIdxInRftFile; caf::PdmField> m_wellLogChannelName; }; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp index e07017bf76..f31b700f00 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp @@ -505,7 +505,18 @@ void RimWellLogTrack::updateDepthZoom() { if ( !m_plotWidget ) return; - m_plotWidget->setAxisRange( getDepthAxis(), m_visibleDepthRangeMin(), m_visibleDepthRangeMax() ); + RimDepthTrackPlot* wellLogPlot; + this->firstAncestorOrThisOfTypeAsserted( wellLogPlot ); + + if ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) + { + m_plotWidget->setAxisRange( depthAxis(), m_visibleDepthRangeMin(), m_visibleDepthRangeMax() ); + } + else + { + m_plotWidget->setAxisRange( RiuPlotAxis::defaultTop(), m_visibleDepthRangeMin(), m_visibleDepthRangeMax() ); + m_plotWidget->setAxisRange( RiuPlotAxis::defaultBottom(), m_visibleDepthRangeMin(), m_visibleDepthRangeMax() ); + } } //-------------------------------------------------------------------------------------------------- @@ -542,8 +553,8 @@ void RimWellLogTrack::fieldChangedByUi( const caf::PdmFieldHandle* changedField, { if ( m_plotWidget ) { - m_majorTickInterval = m_plotWidget->majorTickInterval( getValueAxis() ); - m_minorTickInterval = m_plotWidget->minorTickInterval( getValueAxis() ); + m_majorTickInterval = m_plotWidget->majorTickInterval( valueAxis() ); + m_minorTickInterval = m_plotWidget->minorTickInterval( valueAxis() ); } m_majorTickInterval.uiCapability()->setUiHidden( !m_explicitTickIntervals() ); m_minorTickInterval.uiCapability()->setUiHidden( !m_explicitTickIntervals() ); @@ -764,13 +775,13 @@ void RimWellLogTrack::updatePropertyValueAxisAndGridTickIntervals() bool emptyRange = isEmptyVisibleXRange(); if ( emptyRange ) { - m_plotWidget->enableGridLines( getValueAxis(), false, false ); - m_plotWidget->setAxisRange( getValueAxis(), 0.0, 1.0 ); - m_plotWidget->setAxisLabelsAndTicksEnabled( getValueAxis(), false, false ); + m_plotWidget->enableGridLines( valueAxis(), false, false ); + m_plotWidget->setAxisRange( valueAxis(), 0.0, 1.0 ); + m_plotWidget->setAxisLabelsAndTicksEnabled( valueAxis(), false, false ); } else { - m_plotWidget->setAxisLabelsAndTicksEnabled( getValueAxis(), true, true ); + m_plotWidget->setAxisLabelsAndTicksEnabled( valueAxis(), true, true ); if ( m_minAndMaxTicksOnly ) { auto roundToDigits = []( double value, int numberOfDigits, bool useFloor ) { @@ -805,11 +816,20 @@ void RimWellLogTrack::updatePropertyValueAxisAndGridTickIntervals() div.setTicks( QwtScaleDiv::TickType::MajorTick, majorTicks ); - m_plotWidget->qwtPlot()->setAxisScaleDiv( QwtPlot::xTop, div ); + RimDepthTrackPlot* wellLogPlot; + this->firstAncestorOrThisOfTypeAsserted( wellLogPlot ); + if ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) + { + m_plotWidget->qwtPlot()->setAxisScaleDiv( QwtPlot::xTop, div ); + } + else + { + m_plotWidget->qwtPlot()->setAxisScaleDiv( QwtPlot::yLeft, div ); + } } else if ( m_explicitTickIntervals ) { - m_plotWidget->setMajorAndMinorTickIntervals( getValueAxis(), + m_plotWidget->setMajorAndMinorTickIntervals( valueAxis(), m_majorTickInterval(), m_minorTickInterval(), m_visiblePropertyValueRangeMin(), @@ -819,11 +839,11 @@ void RimWellLogTrack::updatePropertyValueAxisAndGridTickIntervals() { int majorTickIntervals = 5; int minorTickIntervals = 10; - m_plotWidget->setAutoTickIntervalCounts( getValueAxis(), majorTickIntervals, minorTickIntervals ); - m_plotWidget->setAxisRange( getValueAxis(), m_visiblePropertyValueRangeMin, m_visiblePropertyValueRangeMax ); + m_plotWidget->setAutoTickIntervalCounts( valueAxis(), majorTickIntervals, minorTickIntervals ); + m_plotWidget->setAxisRange( valueAxis(), m_visiblePropertyValueRangeMin, m_visiblePropertyValueRangeMax ); } - m_plotWidget->enableGridLines( getValueAxis(), + m_plotWidget->enableGridLines( valueAxis(), m_propertyValueAxisGridVisibility() & RimWellLogPlot::AXIS_GRID_MAJOR, m_propertyValueAxisGridVisibility() & RimWellLogPlot::AXIS_GRID_MINOR ); } @@ -832,7 +852,7 @@ void RimWellLogTrack::updatePropertyValueAxisAndGridTickIntervals() this->firstAncestorOrThisOfType( wellLogPlot ); if ( wellLogPlot ) { - m_plotWidget->enableGridLines( getDepthAxis(), + m_plotWidget->enableGridLines( depthAxis(), wellLogPlot->depthAxisGridLinesEnabled() & RimWellLogPlot::AXIS_GRID_MAJOR, wellLogPlot->depthAxisGridLinesEnabled() & RimWellLogPlot::AXIS_GRID_MINOR ); } @@ -1008,8 +1028,8 @@ QString RimWellLogTrack::asciiDataForPlotExport() const //-------------------------------------------------------------------------------------------------- void RimWellLogTrack::updateZoomFromParentPlot() { - auto [xIntervalMin, xIntervalMax] = m_plotWidget->axisRange( getValueAxis() ); - auto [depthIntervalMin, depthIntervalMax] = m_plotWidget->axisRange( getDepthAxis() ); + auto [xIntervalMin, xIntervalMax] = m_plotWidget->axisRange( valueAxis() ); + auto [depthIntervalMin, depthIntervalMax] = m_plotWidget->axisRange( depthAxis() ); m_visiblePropertyValueRangeMin = xIntervalMin; m_visiblePropertyValueRangeMax = xIntervalMax; @@ -1228,8 +1248,19 @@ void RimWellLogTrack::onLoadDataAndUpdate() if ( wellLogPlot && m_plotWidget ) { - m_plotWidget->setAxisTitleText( getValueAxis(), m_propertyValueAxisTitle ); - m_plotWidget->setAxisTitleText( getDepthAxis(), wellLogPlot->depthAxisTitle() ); + m_plotWidget->setAxisTitleText( valueAxis(), m_propertyValueAxisTitle ); + m_plotWidget->setAxisTitleText( depthAxis(), wellLogPlot->depthAxisTitle() ); + + if ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) + { + m_plotWidget->setAxisEnabled( QwtPlot::xTop, true ); + m_plotWidget->setAxisEnabled( QwtPlot::xBottom, false ); + } + else + { + m_plotWidget->setAxisEnabled( QwtPlot::xTop, false ); + m_plotWidget->setAxisEnabled( QwtPlot::xBottom, true ); + } } for ( size_t cIdx = 0; cIdx < m_curves.size(); ++cIdx ) @@ -1981,27 +2012,42 @@ void RimWellLogTrack::updateAxisScaleEngine() if ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) { m_plotWidget->setAxisInverted( RiuPlotAxis::defaultLeft(), true ); + + if ( m_isLogarithmicScaleEnabled ) + { + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xTop, new QwtLogScaleEngine ); + + // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xBottom, new QwtLogScaleEngine ); + } + else + { + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xTop, new RiuQwtLinearScaleEngine ); + + // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xBottom, new RiuQwtLinearScaleEngine ); + } } else { m_plotWidget->setAxisInverted( RiuPlotAxis::defaultLeft(), false ); + + if ( m_isLogarithmicScaleEnabled ) + { + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::yLeft, new QwtLogScaleEngine ); + + // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::yRight, new QwtLogScaleEngine ); + } + else + { + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::yLeft, new RiuQwtLinearScaleEngine ); + + // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work + m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::yRight, new RiuQwtLinearScaleEngine ); + } } } - - if ( m_isLogarithmicScaleEnabled ) - { - m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xTop, new QwtLogScaleEngine ); - - // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work - m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xBottom, new QwtLogScaleEngine ); - } - else - { - m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xTop, new RiuQwtLinearScaleEngine ); - - // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work - m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtPlot::xBottom, new RiuQwtLinearScaleEngine ); - } } //-------------------------------------------------------------------------------------------------- @@ -2055,8 +2101,18 @@ void RimWellLogTrack::handleWheelEvent( QWheelEvent* event ) { if ( event->modifiers() & Qt::ControlModifier ) { - QwtScaleMap scaleMap = m_plotWidget->qwtPlot()->canvasMap( QwtPlot::yLeft ); - double zoomCenter = scaleMap.invTransform( event->pos().y() ); + double zoomCenter = 0.0; + + if ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) + { + QwtScaleMap scaleMap = m_plotWidget->qwtPlot()->canvasMap( QwtPlot::yLeft ); + zoomCenter = scaleMap.invTransform( event->pos().y() ); + } + else + { + QwtScaleMap scaleMap = m_plotWidget->qwtPlot()->canvasMap( QwtPlot::xTop ); + zoomCenter = scaleMap.invTransform( event->pos().x() ); + } if ( event->delta() > 0 ) { @@ -2501,14 +2557,6 @@ void RimWellLogTrack::updateStackedCurveData() if ( allDepthValues.empty() ) continue; - bool isVerticalTrack = true; - RimDepthTrackPlot* wellLogPlot; - this->firstAncestorOrThisOfType( wellLogPlot ); - if ( wellLogPlot ) - { - isVerticalTrack = ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ); - } - size_t stackIndex = 0u; std::vector allStackedValues( allDepthValues.size(), 0.0 ); for ( auto curve : stackedCurvesInGroup ) @@ -2535,7 +2583,7 @@ void RimWellLogTrack::updateStackedCurveData() auto plotDepthValues = tempCurveData.depths( depthType ); auto polyLineStartStopIndices = tempCurveData.polylineStartStopIndices(); - curve->setOverrideCurveData( allStackedValues, plotDepthValues, polyLineStartStopIndices, isVerticalTrack ); + curve->setOverrideCurveData( allStackedValues, plotDepthValues, polyLineStartStopIndices ); curve->setZOrder( zPos ); if ( !dynamic_cast( curve ) ) @@ -3253,27 +3301,21 @@ void RimWellLogTrack::setEnsembleWellLogCurveSet( RimEnsembleWellLogCurveSet* cu //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RiuPlotAxis RimWellLogTrack::getDepthAxis() const +RiuPlotAxis RimWellLogTrack::depthAxis() const { RimDepthTrackPlot* wellLogPlot; this->firstAncestorOrThisOfTypeAsserted( wellLogPlot ); - if ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) - return RiuPlotAxis::defaultLeft(); - else - return RiuPlotAxis::defaultTop(); + return wellLogPlot->depthAxis(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RiuPlotAxis RimWellLogTrack::getValueAxis() const +RiuPlotAxis RimWellLogTrack::valueAxis() const { RimDepthTrackPlot* wellLogPlot; this->firstAncestorOrThisOfTypeAsserted( wellLogPlot ); - if ( wellLogPlot->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) - return RiuPlotAxis::defaultTop(); - else - return RiuPlotAxis::defaultLeft(); + return wellLogPlot->valueAxis(); } diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.h index a15aaf3ff8..d22fca5172 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.h @@ -250,8 +250,8 @@ private: void updatePropertyValueZoom(); void updateDepthZoom(); - RiuPlotAxis getDepthAxis() const; - RiuPlotAxis getValueAxis() const; + RiuPlotAxis depthAxis() const; + RiuPlotAxis valueAxis() const; int axisFontSize() const; diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.cpp b/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.cpp index aa30bbc07b..cda550113a 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.cpp @@ -186,6 +186,15 @@ std::vector RigWellLogCurveData::depths( RiaDefines::DepthTypeEnum depth return std::vector(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCurveData::depths( RiaDefines::DepthTypeEnum depthType, + RiaDefines::DepthUnitType destinationDepthUnit ) const +{ + return depthsForDepthUnit( depths( depthType ), m_depthUnit, destinationDepthUnit ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -232,22 +241,11 @@ std::vector RigWellLogCurveData::propertyValuesByIntervals() const std::vector RigWellLogCurveData::depthValuesByIntervals( RiaDefines::DepthTypeEnum depthType, RiaDefines::DepthUnitType destinationDepthUnit ) const { - std::vector filteredValues; + const std::vector depthValues = + RigWellLogCurveData::depthsForDepthUnit( depths( depthType ), m_depthUnit, destinationDepthUnit ); - const std::vector depthValues = depths( depthType ); - if ( !depthValues.empty() ) - { - if ( destinationDepthUnit == m_depthUnit ) - { - RiaCurveDataTools::getValuesByIntervals( depthValues, m_intervalsOfContinousValidValues, &filteredValues ); - } - else - { - std::vector convertedValues = - RiaWellLogUnitTools::convertDepths( depthValues, m_depthUnit, destinationDepthUnit ); - RiaCurveDataTools::getValuesByIntervals( convertedValues, m_intervalsOfContinousValidValues, &filteredValues ); - } - } + std::vector filteredValues; + RiaCurveDataTools::getValuesByIntervals( depthValues, m_intervalsOfContinousValidValues, &filteredValues ); return filteredValues; } @@ -502,6 +500,20 @@ void RigWellLogCurveData::calculateIntervalsOfContinousValidValues() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCurveData::depthsForDepthUnit( const std::vector& depths, + RiaDefines::DepthUnitType sourceDepthUnit, + RiaDefines::DepthUnitType destinationDepthUnit ) +{ + if ( destinationDepthUnit == sourceDepthUnit ) return depths; + + std::vector convertedValues = + RiaWellLogUnitTools::convertDepths( depths, sourceDepthUnit, destinationDepthUnit ); + return convertedValues; +} + //-------------------------------------------------------------------------------------------------- /// Splits the start stop interval between cells that are not close enough. //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.h b/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.h index 807b7c9d96..e44097f7e3 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.h +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogCurveData.h @@ -65,6 +65,7 @@ public: QString propertyValueUnit() const; std::vector depths( RiaDefines::DepthTypeEnum depthType ) const; + std::vector depths( RiaDefines::DepthTypeEnum depthType, RiaDefines::DepthUnitType destinationDepthUnit ) const; std::set availableDepthTypes() const; @@ -93,6 +94,10 @@ public: private: void calculateIntervalsOfContinousValidValues(); + static std::vector depthsForDepthUnit( const std::vector& depths, + RiaDefines::DepthUnitType sourceDepthUnit, + RiaDefines::DepthUnitType destinationDepthUnit ); + static void splitIntervalAtEmptySpace( const std::vector& depthValues, size_t startIdx, size_t stopIdx, diff --git a/ApplicationLibCode/UnitTests/opm-summary-Test.cpp b/ApplicationLibCode/UnitTests/opm-summary-Test.cpp index c65b554a67..8e38300d4d 100644 --- a/ApplicationLibCode/UnitTests/opm-summary-Test.cpp +++ b/ApplicationLibCode/UnitTests/opm-summary-Test.cpp @@ -1,11 +1,17 @@ #include "gtest/gtest.h" +#include "RiaRftDefines.h" #include "RiaTestDataDirectory.h" -#include "RifOpmCommonSummary.h" +#include "RifOpmCommonSummary.h" +#include "RifReaderOpmRft.h" + +#include "opm/io/eclipse/ERft.hpp" #include "opm/io/eclipse/ESmry.hpp" #include "opm/io/eclipse/ExtESmry.hpp" +#include + static const QString H5_TEST_DATA_DIRECTORY = QString( "%1/h5-file/" ).arg( TEST_DATA_DIR ); //-------------------------------------------------------------------------------------------------- @@ -43,3 +49,246 @@ TEST( OpmSummaryTests, ReadOpmSummaryDataListContent ) EXPECT_TRUE( eclAdr.isValid() ); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( OpmSummaryTests, DISABLED_OpmImportRftData ) +{ + std::vector esmryKeywords; + { + // QString filePath = "e:/gitroot/opm-tests/model1/opm-simulation-reference/flow/MSW_MODEL_1.RFT"; + // QString filePath = "e:/gitroot/opm-tests/norne/ECL.2014.2/NORNE_ATW2013.RFT"; + // QString filePath = "d:/Models/Statoil/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT"; + QString filePath = "e:/models/from_equinor_sftp/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT"; + + Opm::EclIO::ERft eRft( filePath.toStdString() ); + + auto wells = eRft.listOfWells(); + auto dates = eRft.listOfdates(); + auto reports = eRft.listOfRftReports(); + + std::cout << "\nWells:\n"; + for ( const auto& w : wells ) + { + std::cout << w << "\n"; + } + + std::cout << "\nDates:\n"; + for ( const auto& date : dates ) + { + auto [year, month, day] = date; + + std::cout << year << ", " << month << ", " << day << "\n"; + } + + std::cout << "\nReports:\n"; + for ( const auto& report : reports ) + { + auto [text, date, floatValue] = report; + + std::cout << text << ", " << floatValue << "\n"; + } + + std::cout << "\nRFT Arrays:\n"; + for ( int i = 0; i < eRft.numberOfReports(); i++ ) + { + std::cout << "\n"; + + auto rftVectors = eRft.listOfRftArrays( i ); + + for ( const auto& rftVec : rftVectors ) + { + auto [name, arrType, itemCount] = rftVec; + + std::cout << name << ", " << itemCount << "\n"; + } + } + } +} + +// std::vector getValues(Opm::EclIO::ERft& fileReader, std::) + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( OpmSummaryTests, DISABLED_OpmComputeSegmentTopology ) +{ + std::vector esmryKeywords; + { + // QString filePath = "e:/gitroot/opm-tests/model1/opm-simulation-reference/flow/MSW_MODEL_1.RFT"; + // QString filePath = "e:/gitroot/opm-tests/norne/ECL.2014.2/NORNE_ATW2013.RFT"; + // QString filePath = "d:/Models/Statoil/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT"; + // QString filePath = "e:/models/from_equinor_sftp/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT"; + QString filePath = "e:/models/from_equinor_sftp/MSWRFT_toCS/MSWLOOPED_UN_RFT.RFT"; + + Opm::EclIO::ERft eRft( filePath.toStdString() ); + + auto wells = eRft.listOfWells(); + auto dates = eRft.listOfdates(); + + class RftSegmentData + { + public: + RftSegmentData( int segnxt, int brno, int brnst, int brnen, int segNo ) + : m_segNext( segnxt ) + , m_segbrno( brno ) + , m_brnst( brnst ) + , m_brnen( brnen ) + , m_segmentNo( segNo ) + { + } + + int segNext() const { return m_segNext; } + int segBrno() const { return m_segbrno; } + int segBrnst() const { return m_brnst; } + int segBrnen() const { return m_brnen; } + int segNo() const { return m_segmentNo; } + + private: + int m_segNext; + int m_segbrno; + int m_brnst; + int m_brnen; + int m_segmentNo; + }; + + using RftSegmentKey = std::pair; + std::map> rftWellDateSegments; + + for ( const auto& well : wells ) + { + for ( const auto& date : dates ) + { + std::vector segmentsForWellDate; + + std::vector segnxt; + std::vector segbrno; + std::vector brnstValues; + std::vector brnenValues; + std::vector segNo; + + { + std::string resultName = "SEGNXT"; + if ( eRft.hasArray( resultName, well, date ) ) + { + segnxt = eRft.getRft( resultName, well, date ); + } + } + { + std::string resultName = "SEGBRNO"; + if ( eRft.hasArray( resultName, well, date ) ) + { + segbrno = eRft.getRft( resultName, well, date ); + } + } + { + std::string resultName = "BRNST"; + if ( eRft.hasArray( resultName, well, date ) ) + { + brnstValues = eRft.getRft( resultName, well, date ); + } + } + { + std::string resultName = "BRNEN"; + if ( eRft.hasArray( resultName, well, date ) ) + { + brnenValues = eRft.getRft( resultName, well, date ); + } + } + + if ( segnxt.empty() ) continue; + if ( segnxt.size() != segbrno.size() ) continue; + if ( brnenValues.empty() || brnstValues.empty() ) continue; + + for ( size_t i = 0; i < segnxt.size(); i++ ) + { + int branchIndex = segbrno[i] - 1; + int nextBranchIndex = -1; + if ( i + 1 < segbrno.size() ) nextBranchIndex = segbrno[i + 1] - 1; + + bool isLastSegmentOnBranch = branchIndex != nextBranchIndex; + + int brnst = brnstValues[branchIndex]; + int brnen = brnenValues[branchIndex]; + + int segmentId = -1; + if ( !isLastSegmentOnBranch ) + { + if ( i + 1 < segnxt.size() ) segmentId = segnxt[i + 1]; + } + else + { + segmentId = brnen; + } + + segNo.push_back( segmentId ); + + segmentsForWellDate.emplace_back( RftSegmentData( segnxt[i], segbrno[i], brnst, brnen, segmentId ) ); + } + + auto wellDateKey = std::make_pair( well, date ); + + rftWellDateSegments[wellDateKey] = segmentsForWellDate; + } + } + + for ( const auto& a : rftWellDateSegments ) + { + auto [wellName, date] = a.first; + auto segmentData = a.second; + + std::cout << "\nWell: " << wellName << "Date : " << std::get<0>( date ) << " " << std::get<1>( date ) << " " + << std::get<2>( date ) << " \n"; + + for ( const auto& r : segmentData ) + { + std::cout << "SEGNXT " << std::setw( 2 ) << r.segNext() << ", "; + std::cout << "SEGBRNO " << std::setw( 2 ) << r.segBrno() << ", "; + std::cout << "BNRST " << std::setw( 2 ) << r.segBrnst() << ", "; + std::cout << "BRNEN " << std::setw( 2 ) << r.segBrnen() << ", "; + std::cout << "SEGNO " << std::setw( 2 ) << r.segNo() << "\n"; + } + } + } +} + +TEST( OpmSummaryTests, OpmComputeSegmentTopology ) +{ + std::vector esmryKeywords; + { + // QString filePath = "e:/gitroot/opm-tests/model1/opm-simulation-reference/flow/MSW_MODEL_1.RFT"; + // QString filePath = "e:/gitroot/opm-tests/norne/ECL.2014.2/NORNE_ATW2013.RFT"; + // QString filePath = "d:/Models/Statoil/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT"; + // QString filePath = "e:/models/from_equinor_sftp/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT"; + QString filePath = "e:/models/from_equinor_sftp/MSWRFT_toCS/MSWLOOPED_UN_RFT.RFT"; + + RifReaderOpmRft reader( filePath ); + + auto adresses = reader.eclipseRftAddresses(); + + std::vector segStartDepth; + std::vector segEndDepth; + std::vector segNumber; + + std::set segmentAdresses; + for ( const auto& adr : adresses ) + { + if ( adr.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES ) + { + segmentAdresses.insert( adr ); + } + } + + for ( const auto& adr : segmentAdresses ) + { + qDebug() << adr.timeStep().toString( "YYYY MM dd" ) << " " << adr.segmentResultName(); + + if ( adr.segmentResultName() == RiaDefines::segmentNumberResultName() ) + { + std::vector values; + reader.values( adr, &values ); + } + } + } +} diff --git a/ApplicationLibCode/UserInterface/RiuWellLogTrack.cpp b/ApplicationLibCode/UserInterface/RiuWellLogTrack.cpp index 1cf1a08779..3a3766b95f 100644 --- a/ApplicationLibCode/UserInterface/RiuWellLogTrack.cpp +++ b/ApplicationLibCode/UserInterface/RiuWellLogTrack.cpp @@ -41,8 +41,9 @@ class RiuWellLogCurvePointTracker : public RiuQwtCurvePointTracker { public: - RiuWellLogCurvePointTracker( QwtPlot* plot, IPlotCurveInfoTextProvider* curveInfoTextProvider ) + RiuWellLogCurvePointTracker( QwtPlot* plot, IPlotCurveInfoTextProvider* curveInfoTextProvider, RimWellLogTrack* track ) : RiuQwtCurvePointTracker( plot, false, curveInfoTextProvider ) + , m_wellLogTrack( track ) { } @@ -66,7 +67,19 @@ protected: closestCurvePoint( pos, &curveInfoText, &xAxisValueString, &depthAxisValueString, &relatedXAxis, &relatedYAxis ); if ( !closestPoint.isNull() ) { - QString str = QString( "%1\nDepth: %2" ).arg( xAxisValueString ).arg( depthAxisValueString ); + QString str; + + RimWellLogPlot* wlp = nullptr; + m_wellLogTrack->firstAncestorOfType( wlp ); + + if ( wlp && wlp->depthOrientation() == RimDepthTrackPlot::DepthOrientation::VERTICAL ) + { + str = QString( "%1\nDepth: %2" ).arg( xAxisValueString ).arg( depthAxisValueString ); + } + else + { + str = QString( "%1\nDepth: %2" ).arg( depthAxisValueString ).arg( xAxisValueString ); + } if ( !curveInfoText.isEmpty() ) { @@ -84,6 +97,9 @@ protected: return txt; } + +private: + caf::PdmPointer m_wellLogTrack; }; //-------------------------------------------------------------------------------------------------- @@ -122,9 +138,9 @@ RiuWellLogTrack::RiuWellLogTrack( RimWellLogTrack* track, QWidget* parent /*= nu setAxisEnabled( QwtPlot::yLeft, true ); setAxisEnabled( QwtPlot::yRight, false ); setAxisEnabled( QwtPlot::xTop, true ); - setAxisEnabled( QwtPlot::xBottom, false ); + setAxisEnabled( QwtPlot::xBottom, true ); - new RiuWellLogCurvePointTracker( this->qwtPlot(), &wellLogCurveInfoTextProvider ); + new RiuWellLogCurvePointTracker( this->qwtPlot(), &wellLogCurveInfoTextProvider, track ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/UserInterface/RiuWellLogTrack.h b/ApplicationLibCode/UserInterface/RiuWellLogTrack.h index 9979e1c1f7..117a2c5ba8 100644 --- a/ApplicationLibCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationLibCode/UserInterface/RiuWellLogTrack.h @@ -38,6 +38,5 @@ public: RiuWellLogTrack( RimWellLogTrack* track, QWidget* parent = nullptr ); ~RiuWellLogTrack() override; -private: void setAxisEnabled( QwtPlot::Axis axis, bool enabled ); }; diff --git a/ThirdParty/custom-opm-common/CMakeLists.txt b/ThirdParty/custom-opm-common/CMakeLists.txt index 3428bb6a50..5956aa84d0 100644 --- a/ThirdParty/custom-opm-common/CMakeLists.txt +++ b/ThirdParty/custom-opm-common/CMakeLists.txt @@ -88,6 +88,7 @@ add_library(${PROJECT_NAME} opm-common/src/opm/io/eclipse/ESmry.cpp opm-common/src/opm/io/eclipse/ExtESmry.cpp opm-common/src/opm/io/eclipse/EInit.cpp + opm-common/src/opm/io/eclipse/ERft.cpp # Required for use of static function RstConnection::inverse_peaceman opm-common/src/opm/io/eclipse/rst/connection.cpp